Apply P21: identity and experience; memory writes without approval; built-in policy

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-24 13:53:02 -07:00
co-authored by Claude Opus 5.5
parent 775aa853ed
commit c7f3895c3f
4 changed files with 38 additions and 29 deletions
+32 -22
View File
@@ -176,39 +176,49 @@ a multi-turn tool conversation and tool parsing had no failures in 20 trials.
Memory is what carries continuity across epoch compaction, so it is required. It must not break
the inference contract, and it must not become a way for injected text to persist.
1. **Memory files.** Three files, read once per epoch into the baseline, in this order after the
system prompt: `memory/soul.md`, the persona, written only by the owner (at most 4,000
characters); `memory/memory.md`, the agent's core notes on its work (at most 2,200 characters);
and `memory/user.md`, its core notes on the owner (at most 1,375 characters). Each file is shown
with how full it is. The agent edits the last two with a `memory` tool: `add`, `replace` and
`remove` an entry, and `consolidate`, one edit that marks every entry of a file kept,
rewritten, moved or dropped. Moved entries are appended to `memory/archive.md` (append-only,
each entry with the date and session it was first approved in), where `recall` finds them;
nothing leaves `memory.md` silently. Every edit is `ask`, and the approval shows `consolidate`
as a diff. An approved edit takes effect at the next epoch, never mid-session. A write over a
file's limit is refused with a pointer to `consolidate`.
1. **Identity and experience.** Memory is two things. **Identity** is who the agent is and what
it holds true about its work and its owner: three files read once per epoch into the baseline,
in this order after the system prompt: `memory/soul.md`, the persona, written only by the owner
(at most 4,000 characters); `memory/memory.md`, the agent's core notes on its work (at most
2,200 characters); and `memory/user.md`, its core notes on the owner (at most 1,375
characters), each shown with how full it is. **Experience** is what it has seen or been told:
`memory/notes.md` (append-only) and the session logs, never in the prompt, found with
`recall`, each item labelled with its source and trust. Not everything remembered is believed.
The agent writes memory with a `memory` tool, without asking: `note` records something seen,
in any session; `add`, `replace`, `remove` and `consolidate` (one edit marking every entry of a
file kept, rewritten, moved or dropped) edit identity, and only a session that has not read
untrusted content may use them. In a session that has, an identity `add` becomes a `note` and
the other edits are refused. What leaves an identity file goes to `notes.md` as moved or
dropped; nothing is deleted. A write takes effect at the next epoch, never mid-session. A
write over a file's limit is refused with a pointer to `consolidate`.
2. **Everything else is retrieved, not injected.** A `recall(query, k)` tool returns size-capped
snippets with their source (a file and line, or a Honcho workspace). An `ask_memory` tool asks
Honcho's dialectic. Results are appended like any tool result, so the cache prefix is untouched.
3. **Local index.** SQLite FTS5 over the session logs and `memory/archive.md`, kept by `memoryd`
snippets, each with a source tag (`identity` for entries moved out of identity, `memory` for
trusted experience, `memory-tainted` for experience from sessions or workspaces that are not
trusted), where it came from, and its class. An `ask_memory` tool asks Honcho's dialectic.
Results are appended like any tool result, so the cache prefix is untouched.
3. **Local index.** SQLite FTS5 over the session logs and `memory/notes.md`, kept by `memoryd`
and rebuildable with `bxctl reindex`. It needs no network and no model, so it still answers
when Honcho is down. `memoryd` counts `recall` hits per archive entry and when each was last
found. Retrieval sits behind a `Retriever` trait.
when Honcho is down. `memoryd` counts `recall` hits per note and when each was last found. Retrieval sits behind a `Retriever` trait.
4. **Honcho.** The fleet's memory service; it and the models it calls run on the owner's hosts. Each
Boxmaker writes finished turns to its own workspace, and only turns from sessions that saw no
untrusted content and are within a configured data class; `memoryd` enforces this itself. Entries
moved by `consolidate` are written there too. Honcho's own extraction, summaries and
consolidation replace a flush job of ours. What Honcho holds is derived from the session logs and
`memory/archive.md`, and can be rebuilt from them.
`memory/notes.md`, and can be rebuilt from them.
5. **Workspaces and trust.** `memoryd` can read other workspaces. The owner marks each one
trusted or untrusted; untrusted is the default. Results from an untrusted workspace are marked
untrusted and taint the session. Honcho's conclusions carry no per-entry provenance, so the
filter is applied when writing and the label is per workspace.
6. **Provenance on recall.** Recalled text is presented as data with its source and data class,
never placed in the system prompt, and taints the session with that class. Entries from
`memory/archive.md` come back as approved memory.
7. **The tools go through `brokerd`** under ordinary grants and run in `memoryd`: `recall` and
`ask_memory` `auto`, every `memory` edit `ask`.
never placed in the system prompt, and taints the session with that class; a `memory-tainted` hit
marks the session untrusted.
7. **The tools go through `brokerd`** and run in `memoryd`. Their policy is built in, and no grant
file can change it: `recall`, `ask_memory` and `memory` are all `auto`. What protects the
prompt is which sessions may edit identity (item 1), plus a check on every write (no control
or invisible characters, no chat-template markup, a short list of instruction phrases), run
again when the prompt is built. Every write is journalled in `memory/edits/`, listed by
`bxctl memory log`, and the latest edit of a file can be undone. An owner setting stages
identity writes for review instead (off by default).
8. **No memory text leaves the owner's hosts.** Honcho and the models it calls run on the owner's
hosts, and each is listed in `docs/egress.md`.
@@ -217,7 +227,7 @@ the inference contract, and it must not become a way for injected text to persis
Files are the source of truth. SQLite is allowed only for rebuildable indexes and queues.
- `sessions/<id>/<epoch>.jsonl` — append-only session log
- `memory/soul.md`, `memory/memory.md`, `memory/user.md`, `memory/archive.md` — owner-readable memory
- `memory/soul.md`, `memory/memory.md`, `memory/user.md`, `memory/notes.md`, `memory/edits/` — owner-readable memory
- `index/` — FTS5, kept by `memoryd`; disposable and rebuildable from `memory/` and `sessions/`
- `grants/*.toml` — owner-written
- `audit/*.jsonl` — hash-chained