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

26 lines
1.6 KiB
Markdown

## 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`.