A gate must separate the artifact from a description of it
The class
A gate scans text for a pattern that identifies a violation. The violation and a description of the violation share that pattern. So the gate fires on documentation, comments, commit messages, work journals, and eventually on its own rulebook.
The failure is not a bad regex. It is a missing distinction: the scanner has no model of which regions of its input are the artifact and which are prose about the artifact. Tightening the pattern moves the false positive around; only masking the non-artifact regions removes it.
Both directions cost real work:
- False deny blocks legitimate work, and characteristically blocks the investigation of the very failure the gate reported.
- Over-masking opens an escape hatch — a real violation hidden inside a string, a comment, or a heredoc.
So the mask needs an exception list of regions that look like data but are
executed: ${...} interpolations, -c payloads, heredocs fed to a shell.
The seven measured instances (session 260, 2026-08-05/06)
| # | Gate | Fired on | Fix |
|---|---|---|---|
| 1 | kimi agent-level gate (check_kimi_agent_level.py) |
a context.json work-journal entry that described a violation |
exempt the journal; its markdown twin was already exempt |
| 2 | requirement-id format gate (check_req_format.py) |
a code comment naming the id it had just rejected | rewrite the comment without spelling the literal id |
| 3 | RUL-026 workflow guard (workflow-default-sonnet.sh) |
agent() inside the script's own meta description string |
character-level code mask; ${...} stays code |
| 4 | test-observation guard (force-test-observation.sh) |
|pytest inside a quoted grep alternation — a search read as a pipeline |
quote mask for invocation detection only |
| 5 | test-observation guard, again | the commit message fixing instance 4, which quoted the command | mask heredoc bodies, except those fed to a shell |
| 6 | forbidden-doubles Stop hook (forbidden-doubles-stop.sh) |
_check_no_mocks / _check_mocks — the names of the checks enforcing the ban |
closed list of enforcement identifiers |
| 7 | forbidden-doubles Stop hook, again | MOCK_IMPORT, the issue code for flagging exactly this |
scope the exemption to the SENTENCE, not the token |
Instance 5 is the sharpest statement of the class: the gate blocked the commit that fixed the gate, because the commit message quoted the command.
Instances 6 and 7 add the cost that is easy to miss. That hook is a reminder, not a blocker, so each false fire is cheap — but it fired twice in three turns while a rule inventory was being written, i.e. precisely while the policy was being enforced. A gate that cries wolf during its own enforcement is one you learn to dismiss, which is more expensive than the noise.
Instance 7 also shows why token-level exemption is not enough: a sentence that names the mechanism then has to say what it catches, so the bare word lives in the description. Scoping the exemption to the sentence fixes it without licensing a real violation in the next one.
What to do when writing a gate
- Decide what the artifact region is before writing the pattern. For code: not strings, not comments. For shell: not quoted arguments, not heredoc payloads. For a repo scan: not the journal, not the docs, not the rulebook.
- List the executed-but-data-shaped exceptions and keep them as artifact:
${...},-c,bash <<EOF. Each one is an escape hatch if you miss it, so each one gets its own test. - Write the negative corpus first, and as large as the positive one. A
gate that only ever fires is as dishonest as one that never does. Both hook
test modules here follow that rule
(
tests/scripts/test_workflow_default_sonnet.py,tests/scripts/test_force_test_observation.py). - Test the gate against its own documentation. If a gate cannot survive scanning the page that explains it, it will fire on the next person who writes about it.
Instrumented mechanisms
.claude/hooks/workflow-default-sonnet.sh—code_mask()state machine (quotes,//,/* */,${...}re-entry). See RUL-026..claude/hooks/force-test-observation.sh— quote mask + heredoc mask, with-cand shell-fed heredocs kept as code. See RUL-009..claude/hooks/forbidden-doubles-stop.sh— sentence-scoped exemption over a closed list of enforcement identifiers, plus explicit negation. See RUL-002.
Related: RUL-014 (a ruling must resolve to a mechanism — and a mechanism that misfires is not yet a mechanism), RUL-024 (instance 4's fix exposed a pre-existing hole in the same regex; it was closed in the same change, not noted).