M5a: the starter soul.md, and the device checks with memoryd running
Implemented-By: OpenCode session (model recorded in docs/implementer-log.md)
This commit is contained in:
@@ -6,6 +6,7 @@ reviewer adds findings under "Reviews" once per milestone.
|
|||||||
|
|
||||||
| Task | Date | Status | Gate runs | First gate | Deviations | Notes | Model |
|
| Task | Date | Status | Gate runs | First gate | Deviations | Notes | Model |
|
||||||
|---|---|---|---|---|---|---|---|
|
|---|---|---|---|---|---|---|---|
|
||||||
|
| 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/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. | ? |
|
| 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. | ? |
|
||||||
| M5a/12-brokerd-memory-port | 2026-09-24 | done | 2 | fail | none | Copied the skeleton `crates/brokerd/src/memory_port.rs` and the test `crates/brokerd/tests/memory_port.rs` into place, a new `support/rig.rs` (its `Config` literal gains `memory: Default::default()`), and appended the `memoryd-unreachable` runbook entry. Added `pub mod memory_port;` after `pub mod ledger;` in `lib.rs`. In `policy/mod.rs` added the private `state` field to `Decision`, the `state()` accessor after `request()`, and threaded `state` through the `decide`/`redecide` literals (both already take it as a parameter). In `runner.rs` widened the `use` to `::{Decision, Label, SessionState}`; `RunSpec` gained a `state` field and `state()`; `Runtime` gained a default `run_labelled` that calls `run` and returns no label so existing runtimes are unchanged; `run` now calls `run_labelled` and keeps the stricter of the found label and the grant's (higher class via `.max`, untrusted if either). In `container.rs` added the `IN_MEMORYD` const and a `run` guard that refuses a memory tool before spawning. In `config.rs` added the `Memory` struct before `default_podman`, the `memory` field on `Config`, and `memory_socket()` before `audit_dir`. In `main.rs` imported `MemoryPort`/`Routed`/`MEMORY_WAIT` and wrapped the runtime in `Routed { memory: MemoryPort::new(cfg.memory_socket(), MEMORY_WAIT), other }`. Filled `MemoryPort::ask` (build the `MemoryCall` with the spec's session/call/tool/canonical arguments and the state's taint/untrusted, connect, set read and write timeouts to `wait`, write the final envelope, read it — `Some` only on a `Message::ToolResponse`, else `None`); `MemoryPort::run_labelled` (`Result` -> `Ok((output, Some(label)))`, `Failed` -> `Failed`, anything else or `None` -> `Unreachable`); `Routed::run_labelled` (memory tools to `memoryd`, everything else to `other`). `cargo fmt --all`; `memory_port` 5 passed and the full brokerd suite green; `make gate` printed `gate: ok` on the second run — the first failed on rustfmt import order in `memory_port.rs`, fixed by re-running `cargo fmt --all`. No new dependency, so `Cargo.lock` is unchanged. | ? |
|
| M5a/12-brokerd-memory-port | 2026-09-24 | done | 2 | fail | none | Copied the skeleton `crates/brokerd/src/memory_port.rs` and the test `crates/brokerd/tests/memory_port.rs` into place, a new `support/rig.rs` (its `Config` literal gains `memory: Default::default()`), and appended the `memoryd-unreachable` runbook entry. Added `pub mod memory_port;` after `pub mod ledger;` in `lib.rs`. In `policy/mod.rs` added the private `state` field to `Decision`, the `state()` accessor after `request()`, and threaded `state` through the `decide`/`redecide` literals (both already take it as a parameter). In `runner.rs` widened the `use` to `::{Decision, Label, SessionState}`; `RunSpec` gained a `state` field and `state()`; `Runtime` gained a default `run_labelled` that calls `run` and returns no label so existing runtimes are unchanged; `run` now calls `run_labelled` and keeps the stricter of the found label and the grant's (higher class via `.max`, untrusted if either). In `container.rs` added the `IN_MEMORYD` const and a `run` guard that refuses a memory tool before spawning. In `config.rs` added the `Memory` struct before `default_podman`, the `memory` field on `Config`, and `memory_socket()` before `audit_dir`. In `main.rs` imported `MemoryPort`/`Routed`/`MEMORY_WAIT` and wrapped the runtime in `Routed { memory: MemoryPort::new(cfg.memory_socket(), MEMORY_WAIT), other }`. Filled `MemoryPort::ask` (build the `MemoryCall` with the spec's session/call/tool/canonical arguments and the state's taint/untrusted, connect, set read and write timeouts to `wait`, write the final envelope, read it — `Some` only on a `Message::ToolResponse`, else `None`); `MemoryPort::run_labelled` (`Result` -> `Ok((output, Some(label)))`, `Failed` -> `Failed`, anything else or `None` -> `Unreachable`); `Routed::run_labelled` (memory tools to `memoryd`, everything else to `other`). `cargo fmt --all`; `memory_port` 5 passed and the full brokerd suite green; `make gate` printed `gate: ok` on the second run — the first failed on rustfmt import order in `memory_port.rs`, fixed by re-running `cargo fmt --all`. No new dependency, so `Cargo.lock` is unchanged. | ? |
|
||||||
|
|||||||
Reference in New Issue
Block a user