Files
boxmaker/docs/plans/M5b/files/runbook-memory-write-refused.md
kyleandClaude Opus 5.5 10d2e41f43 M5b plan: task 06, memoryd refuses and flags through sanitize
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>
2026-09-26 05:14:10 -07:00

1.6 KiB

memory-write-refused

What you see. The agent says memory refused something: its memory call was answered memory refused this entry: it contains … (what looks like a GitHub token, an invisible or direction-changing character, and so on), and memoryd logged memoryd: a memory write from session <id> was refused by the rule <rule>; see docs/runbook.md#memory-write-refused. Nothing was written to memory/, staged for review or journalled.

Why. Every text a memory write would store is checked against the sanitizer's refuse rules (M5b spec, section 6.1): control characters other than line feed and tab, invisible and direction-changing characters, private-use characters, noncharacters, secrets known by their prefix (GitHub, GitLab, sk- keys, Slack, AWS, private-key blocks), and the model's chat-template tags. Such text is only ever an attack or a leaked secret, and identity goes into every prompt. The log names the rule, never the text.

Confirm. The rule in the log line. bxctl sanitize check with the text (as an argument or on standard input) names each rule that fires and writes nothing. The session's log holds the call's arguments.

Fix. A real secret: rotate it, since it has been in the conversation; keep it out of memory. Ordinary text refused by mistake: add it to the code-work corpus and narrow the rule, as the M5b spec's section 6.5 says; the change reaches the agent when it is rebuilt.

Check. bxctl sanitize check with the text prints nothing and exits 0, and the agent's next write of it is answered … updated or saved in notes.md.