M5a spec: recall hits carry a source tag: identity, memory or memory-tainted

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-24 13:51:46 -07:00
co-authored by Claude Opus 5.5
parent 0ce3bfc641
commit 775aa853ed
+21 -10
View File
@@ -134,19 +134,29 @@ Both are core tools: declared in the `tools` array of every session, so the mode
Arguments: `{"query": string, "k": integer}`; `query` 1 to 500 characters, `k` 1 to 10, default 5.
`memoryd` searches the index (section 6) and answers with at most `k` hits, best first, each with
its source and label, and each snippet at most 600 characters:
`memoryd` searches the index (section 6) and answers with at most `k` hits, best first, each
snippet at most 600 characters. Each hit starts with a **source tag** (owner, 2026-09-24), one of
three fixed words, so the model can weigh a hit and not only read it:
| Tag | Hits |
|---|---|
| `identity` | `notes.md` entries marked `moved`: identity that `consolidate` took out of the prompt, still held true |
| `memory` | notes and session records from sessions that had not read untrusted content, and `dropped` entries (the agent stopped holding them true, so they do not come back as identity) |
| `memory-tainted` | notes and session records from sessions that had read untrusted content |
M5b uses the same three words for Honcho: `memory` from a trusted workspace, `memory-tainted`
from an untrusted one. After the tag come where the hit is from and its class:
```text
[1] session mm-8ass9m…, 2026-09-20 14:02 UTC, the owner said · private
…the launch window moved to Thursday…
[2] you knew this: moved 2026-09-24 from memory.md · private
[1] identity · moved 2026-09-24 from memory.md · private
Owner prefers answers in UTC.
[3] session chat-1789…, 2026-09-21 09:15 UTC, the assistant said · private · untrusted
[2] memory · session mm-8ass9m…, 2026-09-20 14:02 UTC, the owner said · private
…the launch window moved to Thursday…
[3] memory-tainted · session chat-1789…, 2026-09-21 09:15 UTC, the assistant said · private
…
[4] you noted this, 2026-09-22 18:20 UTC, in a session that had read untrusted content · private · untrusted
[4] memory-tainted · note, 2026-09-22 18:20 UTC, session mm-dh45qg… · private
example.org says the release moved to March.
[5] session mm-dh45qg…, 2026-09-22 18:17 UTC, the assistant called · private
[5] memory · session mm-dh45qg…, 2026-09-22 18:17 UTC, the assistant called · private
http_fetch {"url":"https://example.org/notes"}
```
@@ -156,7 +166,7 @@ terms are joined with `OR`, so no FTS5 operator from the model ever reaches SQLi
FTS5's `bm25`.
**The label.** The result's class is the highest class among the hits (at least `private`), and
it is untrusted if any hit is. `brokerd` combines that with the grant's label and keeps the
it is untrusted if any hit is tagged `memory-tainted`. `brokerd` combines that with the grant's label and keeps the
stricter of each (section 8).
### `memory`
@@ -416,7 +426,8 @@ New entries: `memoryd-start-failed` (configuration, `memory/` or `index/` unusab
Offline, in `make gate`:
- `memoryd`: entries parsing and rendering; each edit's rules, including a stale `old`, a
- `memoryd`: entries parsing and rendering; the source tag of every kind of hit (moved, dropped,
noted clean and tainted, session records before and after the session read untrusted content); each edit's rules, including a stale `old`, a
duplicate, the limit sentence, and `consolidate` missing an entry or naming one twice; every
rule of the check, on write and on building the block; routing by the session's state (an
untrusted `add` becoming a note, the other identity actions refused; `note` in both kinds of