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
+92
View File
@@ -0,0 +1,92 @@
# M5a task 14: `bxctl reindex` and `bxctl memory`
**Branch:** `m5a` (run `git switch m5a`; `git status --short` must be empty, otherwise stop)
**Commit subject:** `bxctl: reindex, and memory log, undo, pending, accept, reject`
## Goal
The owner's memory commands (M5a spec, section 10), over `memoryd`'s owner socket
(`{home}/run/owner-memory/admin.sock`, or `--memory-socket PATH`; `--admin-socket` stays
`brokerd`'s):
- `bxctl reindex` prints `reindexed: 42 logs, 1,208 records, 7 notes`.
- `bxctl memory log [N] | undo <id> | pending | accept <id> | reject <id>` prints what `memoryd`
answers. An error from `memoryd` is printed escaped, as approvals are, and exits 1.
## Files
- Copy (skeleton): `crates/bxctl/src/memory.rs`
- Copy (test): `crates/bxctl/tests/cli_memory.rs`
- Modify: `crates/bxctl/src/lib.rs` (`pub mod memory;` after `pub mod escape;`),
`crates/bxctl/src/cli.rs`, `crates/bxctl/src/main.rs`, `docs/implementer-log.md`
## The skeleton
Written: `MEMORY_TIMEOUT`, `default_socket`, `Ask`. Fill: `parse_reindex`, `parse_memory`,
`socket_flag`, `grouped`, `run`.
## The edits, exactly
**`cli.rs`:**
1. In `USAGE`, the last entry's line ` Check the audit log's hash chain, reading the files
directly.";` loses its closing `";`, and after it come (the blank lines included):
```text
bxctl reindex [--memory-socket PATH]
Rebuild memoryd's index from the session logs and notes.
bxctl memory log [N] | undo <id> | pending | accept <id> | reject <id> [--memory-socket PATH]
List memory edits, undo the latest edit of a file, or answer writes waiting for review.";
```
2. In `enum Command`, after the `AuditVerify { home: PathBuf, },` variant add
```rust
Memory {
socket: PathBuf,
ask: crate::memory::Ask,
},
```
3. In `parse`, after `"audit" => parse_audit(rest, home),` add
```rust
"reindex" => crate::memory::parse_reindex(rest, home),
"memory" => crate::memory::parse_memory(rest, home),
```
**`main.rs`:** in the `match command`, just before the `Command::AuditVerify { home } => {` arm,
add
```rust
Command::Memory { socket, ask } => {
let mut out = std::io::stdout().lock();
match bxctl::memory::run(&socket, &ask, bxctl::memory::MEMORY_TIMEOUT, &mut out) {
Ok(()) => ExitCode::SUCCESS,
Err(e) => {
eprintln!("bxctl: {e}");
ExitCode::from(1)
}
}
}
```
## Steps
- [ ] **1. Copy** the two files; make the edits; `cargo check -p bxctl --all-targets`.
- [ ] **2. See it fail.** `cargo test -p bxctl --test cli_memory`: 4 failed.
- [ ] **3. Fill** the five functions. `cargo fmt --all`.
- [ ] **4. See it pass.** The same command: 4 passed. Then `cargo test -p bxctl`: every suite
passes (the usage tests read `USAGE`).
- [ ] **5. Run the gate.** `make gate`: `gate: ok`, 4 more tests than before (about 936).
- [ ] **6. Log and commit.** `git add -A crates/bxctl docs/implementer-log.md Cargo.lock && git commit`
## Done when
- `make gate` prints `gate: ok`.
## Stop and report if
- A test fails after the functions follow their comments exactly.