memoryd's writes go through bxcore::sanitize::refuse, then flag; check.rs and its test go. A refused write answers with the rule's sentence and is logged with the rule's name; a flagged identity write becomes untrusted notes with the rule in the answer, the journal (new optional field `flag`) and the log, and is never staged for review; the block leaves out an entry that breaks a refuse rule and logs the rule. The three runbook entries the new pointers need are given here as fragments, because the gate's runbook check fails on a pointer without its entry. Checks, on titan (rustc 1.98.1, clippy 0.1.98): - given tests fail before as the task says: 7 failing in edit, serve and serve_sanitize; files and sanitize do not compile (E0609; E0432, E0609, E0615) - the task's edits, parsed from the task file and applied to a fresh ref-05 worktree with its own target/, give a tree byte-identical to the reference; its gate: ok, 1033 tests; /private/tmp unchanged - 26 one-line mutations of the reference, each caught by the given tests - new tests stressed under load: 30 runs, 0 failures - no chat-template tag and no whole fake key in the task or given files Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
30 lines
2.0 KiB
Markdown
30 lines
2.0 KiB
Markdown
## memory-write-flagged
|
|
|
|
**What you see.** A memory write was kept one tier lower. The `memory` call was answered `not
|
|
added to memory.md: it matches the rule <rule>, so it was saved in notes.md as an untrusted note`
|
|
(or `user.md`), or, for a note, `saved in notes.md, marked untrusted: it matches the rule <rule>`.
|
|
`memoryd` logged `memoryd: a memory write from session <id> matches the rule <rule>; it was saved
|
|
in notes.md as an untrusted note (edit <edit id>); see docs/runbook.md#memory-write-flagged`, and
|
|
`bxctl memory log` shows that edit with `flagged <rule>`.
|
|
|
|
**Why.** The text is shaped like an attack (M5b spec, section 6.3): it tells the reader to ignore
|
|
or replace earlier instructions, to send data to a URL, to dump the conversation, or to write into
|
|
SSH configuration, or it holds one of M5a's six instruction phrases. A flag never refuses and
|
|
never loses text: `memory.md` and `user.md`, which are in every prompt, are not changed, and every
|
|
text of the write is saved at the end of `notes.md` under an `untrusted` header. `recall` returns
|
|
it as `memory-tainted`, so a session that recalls it becomes untrusted. With review on, a flagged
|
|
write is not staged: it is a note at once. The log names the rule, never the text.
|
|
|
|
**Confirm.** `bxctl memory log`: the edit, `flagged <rule>`. The text is at the end of
|
|
`<home>/memory/notes.md`, under a line `§ noted <time> in session <id> · <class> · untrusted`.
|
|
`bxctl sanitize check` with the text names the rule.
|
|
|
|
**Fix.** If it is an attack, leave it: the note is the record of what was tried, and it never
|
|
reaches the prompt. If it is a true fact wrongly flagged, move it into identity by hand: add it to
|
|
`<home>/memory/memory.md` (or `user.md`) with an editor, as an entry of its own, with a line
|
|
holding only `§` between it and the entry before, keeping the file within its limit. The note
|
|
stays in `notes.md`, which is append-only. If the rule catches ordinary text, narrow it as the M5b
|
|
spec's section 6.5 says.
|
|
|
|
**Check.** Start a new conversation and ask the agent what `memory.md` holds; the entry is there.
|