M5a task 15: the starter soul and device checks with memoryd, finished

The session did the task and stopped on make verify-device. The cause
was not the server: run-plan.sh and the device tests both read
BOXMAKER_MODEL, and the run's value (OpenCode's provider-prefixed id)
reached llama-server as the model name. With it unset, verify-device
passes 6 of 6. The copied files are identical to the plan's, and the
gate prints gate: ok, 936 tests.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-25 16:41:44 -07:00
committed by kyle
co-authored by Claude Opus 5.5
parent 9f57cfc381
commit 6f093fcd8e
5 changed files with 103 additions and 15 deletions
+1
View File
@@ -6,6 +6,7 @@ reviewer adds findings under "Reviews" once per milestone.
| Task | Date | Status | Gate runs | First gate | Deviations | Notes | Model |
|---|---|---|---|---|---|---|---|
| M5a/15-soul-and-device | 2026-09-24 | done (by the design model) | 1 | pass | none | Finished by the design model from the session's work, which was right and left uncommitted. The stop was not the server: `tools/run-plan.sh` and the device tests both read `BOXMAKER_MODEL`. The run set it to OpenCode's id `straylight/ornith-1.5-35b-a3b`, which the device tests then sent to `llama-server` as the model name, and it answered 400. With it unset, `make verify-device` passed 6 of 6 (72.7 s). The three copied files are identical to the plan's; `make gate` prints `gate: ok`, 936 tests. | Ornith-1.5-35B-A3B (the session); design model (the commit) |
| M5a/15-soul-and-device | 2026-09-24 | stopped | 1 | pass | none | Copied `config/soul.md`, `crates/loopd/tests/support/memoryd.rs` and a new version of `crates/loopd/tests/device.rs` from `docs/plans/M5a/files/` into place; in the Makefile `verify-device` added the `BOXMAKER_MEMORYD=$(CURDIR)/target/debug/memoryd \` line after the `BOXMAKER_INFERPROXY=...BOXMAKER_BXCTL=... \` line. `cargo fmt --all`; `make gate` printed `gate: ok` on the first run (device tests ignored there, count unchanged ~936). straylight is reachable and `/models` lists `ornith-1.5-35b-a3b` as `loaded` with slot 0 `is_processing:false`, but `make verify-device` fails identically on a second run: every inference request returns `400 "model 'straylight/ornith-1.5-35b-a3b' not found"` (the server prefixes the bare name with a `straylight/` namespace and cannot resolve it even though `/models` reports it loaded) and the conversation test also fails with "loopd did not come up within 60 s". Root cause is server-side model routing on straylight, not the copied files or Makefile line (the gate passes and the request model name is fixed by the task). Did not change the test or the soul to force a pass; committing only this log row per AGENTS.md. | ? |
| M5a/14-bxctl-memory | 2026-09-24 | done | 1 | pass | none | Copied the skeleton `crates/bxctl/src/memory.rs` and the test `crates/bxctl/tests/cli_memory.rs` into place, and added `pub mod memory;` after `pub mod escape;` in `lib.rs`. In `cli.rs` opened the last USAGE entry (the audit line lost its closing `";`) and appended the `reindex` and `memory` blocks, added the `Memory { socket, ask }` variant to `Command` after `AuditVerify`, and the `reindex`/`memory` arms to `parse`. In `main.rs` added the `Command::Memory` arm before `AuditVerify`. Filled the five functions the skeleton left as `todo!()` in `memory.rs`: `parse_reindex` (`socket_flag`, then any argument left is a usage error, else `Ask::Reindex`); `parse_memory` (`socket_flag`, then a slice match on the rest — `["log"]`, `["log", n]` when `n` parses as usize, `["pending"]`, `["undo"|"accept"|"reject", id]`, anything else a usage error); `socket_flag` (walk args, `--memory-socket` takes the next argument as the socket, a second one or a missing value is a usage error, every other argument kept in order, the socket defaults to `default_socket(home)`); `grouped` (the digits of n with a comma before each char at index i>0 where `len-i` is a multiple of 3); and `run` (connect to the socket, set read and write timeouts, write the id-1 final envelope, read the reply, print the reindexed counts or the reply text, escape an error detail, a write error as a String). `cargo fmt --all`; `cli_memory` 4 passed (they failed on the `todo!()`s first), the full bxctl suite green; `make gate` printed `gate: ok` on the first run. No new dependency, so `Cargo.lock` is unchanged. | ? |
| M5a/13-loopd-memory | 2026-09-24 | done | 1 | pass | none | Copied the skeleton `crates/loopd/src/memory.rs` and the tests `crates/loopd/tests/memory.rs` plus new versions of `crates/loopd/tests/baseline.rs`, `crates/loopd/tests/pointers.rs` and `crates/loopd/tests/channel.rs` into place, and made the runbook changes (replaced `## core-memory-unreadable` with the contents of `runbook-memory-unavailable.md`, appended `runbook-memory-index-damaged.md` to the end). Added `pub mod memory;` after `pub mod llama;` in `lib.rs`. In `config.rs` added `#[serde(default)] pub memory: Memory,` after `pub broker: Broker,` in `Config`, the `Memory` struct (empty socket means the default under `home`) after `struct Config`, and `memory_socket()` before `channel_socket`. In `baseline.rs` changed the module comment ("the memory block and core tool schemas"), removed the `Core(PathBuf, io::Error)` variant and its Display arm (the `#core-memory-unreadable` one), and replaced `assemble` whole with `assemble` (calls `assemble_with(cfg, registry, "")`) and `assemble_with` (system trimmed, then a blank line and the trimmed block when non-empty). In `tools.rs` added `m5a()` before `core_schemas`: `m3a().entries` with `recall` (id 1) and `memory` (id 2) inserted as core. In `channel.rs` added `use crate::memory::MemorySource;`, the `memory: Box<dyn MemorySource>` field on `Context` and a last `memory` param on `Context::new`; in `handle` replaced the `Baseline::assemble` call with `ctx.memory.block().and_then(|block| Baseline::assemble_with(...))`, and after `drop(held)` in step 5 added the best-effort `ctx.memory.updated(&turn.session)` for a finished turn. In `main.rs` imported `MEMORY_WAIT, MemoryPort` and built `MemoryPort::new(cfg.memory_socket(), MEMORY_WAIT)` with `Registry::m5a()`. Appended the memory sentence to `config/system.md`. Filled the three `todo!()`s in `memory.rs`: `MemoryPort::ask` (connect, set read and write timeouts to `self.wait`, write the final id-1 envelope, read it — `Ok(its msg)`; every error `format!("memoryd at {}: {e}; {UNAVAILABLE}", socket)`); `block` (`MemoryBlock(Empty)` -> `MemoryBlockReply.reply.text`; `Error` -> `memoryd: {detail}; {UNAVAILABLE}`; else `wrong message; {UNAVAILABLE}`); `updated` (`SessionUpdated` -> `Ok(())`; `Error` -> `memoryd: {detail}`; else `wrong message`). `cargo fmt --all`; `memory` 4 and `pointers` 7 passed, the full loopd suite green; `make gate` printed `gate: ok` on the first run. No new dependency, so `Cargo.lock` is unchanged. | ? |