Plan M5a: local memory in 15 tasks

memoryd (files, the check, edits, journal, index, recall, serving),
the memory tools and built-in grants in brokerd, the memory block in
loopd, bxctl reindex and memory, and the device checks with memoryd.

Each task was built as a reference and gated. Each was replayed on its
own at its end state (854 to 936 tests) and mutation-checked. Each
skeleton compiles and fails its tests. Every todo comment was read
beside its signature.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-24 15:32:54 -07:00
co-authored by Claude Opus 5.5
parent 19fd74db6e
commit de1032157b
76 changed files with 8382 additions and 0 deletions
@@ -0,0 +1,45 @@
//! Entries: split at `§` lines, rendered back, and measured in characters (M5a spec, section 3).
//! Do not edit.
use memoryd::entries::{parse, render, size};
fn owned(entries: &[&str]) -> Vec<String> {
entries.iter().map(|e| e.to_string()).collect()
}
#[test]
fn parse_splits_at_separator_lines_and_trims() {
assert_eq!(parse(""), Vec::<String>::new());
assert_eq!(parse("\n\n"), Vec::<String>::new());
assert_eq!(parse("one"), owned(&["one"]));
assert_eq!(
parse("one\n§\ntwo\nlines\n § \n\n three \n§\n§\n"),
owned(&["one", "two\nlines", "three"])
);
assert_eq!(
parse("a § b\n§\nc"),
owned(&["a § b", "c"]),
"§ inside a line is text"
);
}
#[test]
fn render_is_what_parse_reads() {
let entries = owned(&["Owner prefers UTC.", "Works on\nboxmaker."]);
let text = render(&entries);
assert_eq!(text, "Owner prefers UTC.\n§\nWorks on\nboxmaker.\n");
assert_eq!(parse(&text), entries);
assert_eq!(render(&[]), "");
}
#[test]
fn size_counts_characters_with_separators() {
assert_eq!(size(&[]), 0);
assert_eq!(size(&owned(&["abc"])), 3);
assert_eq!(
size(&owned(&["abc", "de"])),
3 + 3 + 2,
"a separator line is \\n§\\n"
);
assert_eq!(size(&owned(&["ééé"])), 3, "characters, not bytes");
}