Files
boxmaker/docs/plans/M5c2/README.md
T
2026-09-28 16:21:03 -07:00

7.3 KiB

M5c-2 implementation plan: Honcho, the read path

For the implementer: each task file is one closed task for one fresh session. Read AGENTS.md, then the task file, and do exactly that task. The driver is tools/run-plan.sh.

Goal: the agent reads what the fleet knows. recall searches the other agents' trusted workspaces and the fleet workspace alongside the local index, each source on its own limit, and a new core tool, ask_memory, asks Honcho's dialectic about one or two workspaces. What comes back is labelled, and taints the session, as a local recall hit does.

Architecture: bxcore gains ask_memory's arguments; brokerd runs it as a built-in memory tool with its own wait; loopd declares it as a core tool with its own wait; memoryd gains read-only Honcho clients, turns Honcho's messages and conclusions into recall items, runs its Honcho sources and chats outside its state lock, and answers ask_memory.

Tech stack: Rust 1.98.1, edition 2024; roncho 1.0.0 (already a dependency of memoryd, features = ["tls"]); no new crate.

Spec: docs/specs/2026-09-27-m5c-honcho.md, sections 3, 8, 9, 10 and 13, as amended on 2026-09-28 (8e56261).

The owner's decisions (2026-09-28)

  1. Queries from any session. recall searches Honcho, and ask_memory asks it, from a session of any class, secret included: Honcho stores no query, and on rift a query reaches only the owner's hosts. It is an assumption about rift's configuration, written into the spec (section 8) and docs/egress.md. A query holding a known-prefix secret is refused before anything is sent.
  2. Two workspaces per ask_memory call, both asked at once, so both answer inside brokerd's wait; the model asks again for more.
  3. New recordings from rift for the fake server (task 00), in a throwaway workspace deleted afterwards, as in M5c-1. They changed two things (spec, 891f413): ask_memory always asks at minimal, since a low chat on rift returned raw tool-call markup; and a Honcho hit is kept only when it shares a term with the query, since search has no relevance cutoff.

What the code already has, and what it lacks

  • A session keeps the tools array it was created with (loopd's baseline is saved at the start and sent on every request): ask_memory appears in sessions started after deployment, and no epoch code is needed.
  • brokerd waits 30 s for any memory tool (memory_port.rs, MEMORY_WAIT), and loopd 120 s for any tool ([broker] timeout_ms). Neither has a per-tool wait; ask_memory needs 170 s and 180 s (spec 9).
  • memoryd holds its one state lock for the whole of a recall. Honcho searches (5 s) and chats (150 s) must run outside it, or every memory call waits behind them.
  • M5c-1's Clients are the sync worker's, for writes, and move into its thread. Reading needs its own clients: one per [[honcho.read]] workspace, the fleet, and the agent's own two (for ask_memory).
  • roncho's blocking client has what is needed: search_workspace, query_conclusions (it requires the observer and the observed) and workspace_chat.

Global constraints

  • Roles depend on bxcore only; memoryd also on roncho. No unsafe, no async runtime.
  • Every roncho client is built with .without_config_file(); keys come from bxcore::secrets and are never logged; errors are logged by kind and status only.
  • Text from Honcho is neutralised on arrival and capped like a local recall snippet (600 characters); a result's labels raise the session as a local hit's do.
  • No Honcho call runs under memoryd's state lock.
  • Without a [honcho] section, recall is exactly M5b's and ask_memory answers that Honcho is not configured.
  • No file the implementer reads holds a chat-template tag whole (T33), nor a fake key whole.
  • Every path a given test creates is removed by a guard (T44); every process a test starts has a deadline.
  • Each task gives its baseline and its gate count with what the count includes (T50, T53); the branch line is a check, never git switch (T51); import changes are single added lines (T54); whitespace-checked literals are marked on every edit (T55); the task's table of roncho's API is complete, and the Cargo registry is off limits (T56).

Tasks (outline, for the owner's review)

# Delivers Crates
00 (done by the design model, 718e66d) recordings from rift: workspace search with a limit and with no match, conclusion queries for two peers, and what a missing workspace answers memoryd fixtures
01 Wire: AskMemoryArgs { question, workspaces }, its name and its checks (question at most 2,000 characters; one or two workspace names, no repeats); fixtures bxcore
02 brokerd: ask_memory as a built-in memory tool (grant, parsing, routing to memoryd); a per-tool wait on memoryd, 170 s for ask_memory and 30 s for the others brokerd
03 loopd: ask_memory's schema as a core tool in a new registry; a per-tool wait on brokerd, 180 s for ask_memory and [broker] timeout_ms for the others; the system prompt's line on memory tools loopd
04 memoryd: read clients, one per [[honcho.read]] workspace, the fleet and the agent's own two, with a 5 s limit for searches and 150 s for chat memoryd
05 memoryd, pure: Honcho messages and conclusions as recall items (tag, source name, class, neutralised, capped), kept only when they share a term with the query, interleaved with the local hits to k, the local index first memoryd
06 memoryd: recall's Honcho sources, each on its own thread with its own limit, after the local search and outside the lock; <source>: unavailable; a query holding a secret sends nothing memoryd
07 memoryd: ask_memory: workspace names checked against [honcho], both chats at once, each answer tagged and capped, labels, <workspace>: unavailable; a question holding a secret sends nothing memoryd
08 memoryd serves ask_memory beside recall and memory, outside the lock; bxctl's usage and the runbook where a new message needs a pointer memoryd, bxctl

After task 08, the design model runs the M5c-2 device check (spec 13) on straylight, rift and the owner's Mattermost: a second memoryd under its own name writes a fleet note that recall finds, tagged memory-tainted, turning the session untrusted; ask_memory answers from the agent's own trusted workspace within its limit; with rift down, recall answers from the local index with unavailable lines. The baseline is measured again against the 3,000-token budget (make verify-device).

Before hand-over

Every task is worked through docs/plans/CHECKLIST.md with a reference in a scratch worktree with its own build directory, replayed from its task text; mutations; /tmp compared around a gate run; scratch files in the worktree's .state/; the whole workspace stressed under load (T52); the reference moved to straylight as a bundle before the run. Task files name their log row (T47). For every class or trust rule, each path that reads from Honcho gets a test at the forbidden label (T58).

Running it

git switch -c m5c2 master
OPENCODE_MODEL=straylight/ornith-1.5-35b-a3b RESUME=1 \
  SLOTS_URL='http://straylight:11434/slots?model=ornith-1.5-35b-a3b' \
  tools/run-plan.sh docs/plans/M5c2 01