M5b spec: the flag port as planned in task 05

Records what porting Hermes' patterns decided: seven rules kept,
"dump the conversation" narrowed, agent-configuration changes left out
(Boxmaker's agent loads no such files), about fifty look-alikes,
apostrophes folded, and a flag in bxctl names only its rule. A false
positive also marks a session that recalls the note untrusted.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-26 04:32:14 -07:00
co-authored by Claude Opus 5.5
parent 0c2946c99e
commit ad60f84a65
+14 -6
View File
@@ -146,13 +146,20 @@ ordinary tokens.
**Patterns** are ported from Hermes' strict threat patterns (`hermes-agent`, **Patterns** are ported from Hermes' strict threat patterns (`hermes-agent`,
`tools/threat_patterns.py`, MIT; attribution in the module and in `docs/dependencies.md`), whose `tools/threat_patterns.py`, MIT; attribution in the module and in `docs/dependencies.md`), whose
rule is "match attack behaviour, not bossy English": instructions to ignore or replace earlier rule is "match attack behaviour, not bossy English": instructions to ignore or replace earlier
instructions, to send data to a URL, to dump the conversation, to persist in SSH or agent instructions, to send data to a URL, to dump the conversation, to persist in SSH
configuration. M5a's six instruction phrases join this list: they flag from M5b on, where M5a configuration. M5a's six instruction phrases join this list: they flag from M5b on, where M5a
refused. refused.
The port (plan task 05, Hermes at `d0288be`) keeps seven of Hermes' rules and narrows those that
caught ordinary code work, because a recalled flagged note makes the reading session untrusted:
"dump the conversation" needs the object to end the clause, so "include the conversation id"
passes. Changes to agent configuration files are not a rule: Boxmaker's agent never loads
`AGENTS.md` or similar as instructions. `flag.rs`'s module comment lists every rule left out.
**Normalisation** before matching, written by hand with no new crate: lower case; full-width ASCII **Normalisation** before matching, written by hand with no new crate: lower case; full-width ASCII
folded to ASCII; runs of whitespace and zero-width characters collapsed; common leetspeak folded; folded to ASCII; runs of whitespace collapsed to one space and zero-width characters dropped;
and about forty Cyrillic and Greek letters that look Latin mapped to them. common leetspeak folded; about fifty Cyrillic and Greek letters that look Latin mapped to them
(from Unicode's confusables); and typographic apostrophes folded to `'`.
**What a flag does**: the text is kept, one tier lower, and marked **untrusted**. That reuses what **What a flag does**: the text is kept, one tier lower, and marked **untrusted**. That reuses what
M5a has, with no new header or tag: M5a has, with no new header or tag:
@@ -165,7 +172,7 @@ M5a has, with no new header or tag:
- `recall` returns such a note as `memory-tainted`, which makes the reading session untrusted. - `recall` returns such a note as `memory-tainted`, which makes the reading session untrusted.
A flag never refuses and never loses text: the worst case of a false positive is a fact one tier A flag never refuses and never loses text: the worst case of a false positive is a fact one tier
lower, which the owner can move back by hand. lower, which the owner can move back by hand, and a session that recalls it marked untrusted.
### 6.4 The two corpora ### 6.4 The two corpora
@@ -197,11 +204,12 @@ the corpora and review, and a typo cannot switch a rule off.
### 6.6 `bxctl sanitize check` ### 6.6 `bxctl sanitize check`
`bxctl sanitize check <text>` (or the text on standard input) runs the three actions and prints `bxctl sanitize check <text>` (or the text on standard input) runs the three actions and prints
each rule that fires, and what it would do, writing nothing: each rule that fires, and what it would do, writing nothing. A flag names only its rule: it
matches the normalised text, whose offsets do not map back to the input.
```text ```text
refuse secret-github ghp_… at 12 refuse secret-github ghp_… at 12
flag exfil-url "send … to https://…" flag exfil-url
neutralise 1 tag neutralise 1 tag
``` ```