docs+gate: instruction files cannot silently regrow (R-229)
gates / gates (push) Successful in 7s

New shared scripts/instructions_gate.py, registered in controller_gates.py and
agent_gates.py, never copied into a sibling repo (the reuse_refs_check.py
precedent). 20 fixture tests, all asserting the effect: exit code AND that the
message names the file and the reason.

It is a consistency gate, not a budget gate, and the failure message says so. A
/context reading measured the instruction files at 15k tokens against 869k free in
a 1M window -- space is not the constraint, and a future reader must not re-derive
the wrong reason. The 200-line ceiling is adherence guidance; a file nobody can
hold in their head is where contradictions hide, and five were found here.

Checks run against effective text (HTML comments stripped, because they are
stripped before injection): the line ceiling; every .claude/rules/*.md declares
paths: or an explicit unconditional: true; no component version literal; no
TEMPORARY block carrying a past date; and the workspace-root CLAUDE.md is
byte-identical to its versioned copy -- the live file sits outside any git repo,
so that copy is its only version-controlled record.

Two traps recorded so they are not reintroduced: a bare \d+\.\d+\.\d+ matches the
first three octets of every IPv4 (the gate excludes dotted quads, or it fails on
192.168.0.180 in the agent's own file); and unconditional: true is NOT a Claude
Code feature but this project's own marker.

Workspace-root CLAUDE.md 208 -> 182 lines (142 effective), copy kept identical.
The nine-instance invariant table moved into the felhom-testing skill, which
triggers when writing or reviewing a test; all three directive bullets stayed in
the core. felhom.eu/CLAUDE.md got surgical corrections only and is knowingly still
over the ceiling at 227 effective lines -- closing it needs the restructure R-229
defers, said plainly rather than quietly absorbed.

CONTEXT.md gains standing ruling S-35. OPEN-ITEMS.md gains R-229.

Docs only -- no Go, no version bump, nothing built or deployed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JJc8sAGRWmavP3rMtdpkr2
This commit is contained in:
2026-08-06 09:38:52 +02:00
parent d30c2a51ed
commit c21bcf84f7
10 changed files with 1125 additions and 333 deletions
+31
View File
@@ -1,3 +1,34 @@
## instructions_gate.py 1.0.0 — instruction files cannot silently regrow (2026-08-06, R-229)
New shared gate, registered in `controller_gates.py` and `agent_gates.py`, never copied into a
sibling repo (the `reuse_refs_check.py` precedent). `--fast` safe.
**It is a consistency gate, not a budget gate, and the failure message says so.** A `/context`
reading on 2026-08-06 measured the instruction files at 15k tokens against **869k free** in a 1M
window — space is not the constraint, and a future reader must not re-derive the wrong reason. The
200-line ceiling is Anthropic's *adherence* guidance, and a file nobody can hold in their head is
where contradictions hide: four were found in this project on the same day, two of which decided
where a destructive drill runs.
Checks, all against **effective** text (HTML comments stripped, because they are stripped before
injection): the line ceiling; every `.claude/rules/*.md` declares `paths:` or an explicit
`unconditional: true`; no component version literal; no TEMPORARY block carrying a past date; and the
workspace-root `CLAUDE.md` is byte-identical to its versioned copy — the live file sits outside any
git repo, so that copy is its only version-controlled record.
**Two traps found while building it, recorded so they are not reintroduced:**
- A bare `\d+\.\d+\.\d+` matches the first three octets of **every IPv4 address**. The gate
excludes dotted quads; without that it fails on `192.168.0.180` in the agent's own file.
- `unconditional: true` is **not** a Claude Code feature — it is this project's marker, asserting
that always-loading was deliberate. The docstring says so, so nobody looks for it in the product.
`test_instructions_gate.py`: 20 fixture assertions, all on the **effect** (exit code *and* that the
message names the file and the reason). Includes the load-bearing negatives — 400 commented lines
must not trip the ceiling, and a version literal inside a comment must be allowed — because the gate
must not punish the very move it exists to encourage. Companion red-proof recorded in the ledger:
ceiling temporarily set to 100 against the real trimmed files, `felhom-agent` (173) FAILED and was
named, `felhom-controller` (92) still passed; threshold restored, suite re-run green.
## 1.25.0 — the off-site tier stops asking to prune (2026-08-04, R-191)
**A backup that worked must not report failure.** The off-site tier was written with `keep_last: 2`,