c21bcf84f7
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
170 lines
10 KiB
Markdown
170 lines
10 KiB
Markdown
# REPORT — instruction-file rightsizing (core + path-scoped rules), 2026-08-06
|
||
|
||
**Docs and gate only. No Go changed, no version bumped, no image built, nothing deployed, no
|
||
customer machine touched.** One read-only command ran against live hardware (`ssh demo-hp "qm list"`),
|
||
permitted by the task for exactly one purpose.
|
||
|
||
**The headline is the contradiction count, not a token saving.** A `/context` reading measured the
|
||
instruction files at **15k tokens against 869k free** in a 1M window. Space was never the constraint;
|
||
five stale or conflicting facts were.
|
||
|
||
---
|
||
|
||
## 1. Baselines
|
||
|
||
| Repo | `main` @ start | Clean | Note |
|
||
|---|---|---|---|
|
||
| felhom-controller | `a62bb3874b25` | yes | matched spec |
|
||
| felhom-agent | `a2e914f683bd` | yes | matched spec |
|
||
| felhom.eu | `d30c2a51ed2a` | yes | matched spec |
|
||
| app-catalog-felhom.eu | `ee2c8102016a` | yes | **untouched** — 79 lines, already the target shape, cited as the model |
|
||
|
||
**One correction:** the workspace-root `CLAUDE.md` measured **16,642 B / 208 lines**, not the spec's
|
||
15,431 / 207 — it was edited at 08:32 that morning, after the spec was written. The other five files
|
||
matched exactly. Also structural: `/mnt/5_hdd/felhom.eu/git` **is not a git repository**, so the live
|
||
root `CLAUDE.md` is untracked; only its copy under `felhom.eu/` is version-controlled.
|
||
|
||
## 2. Contradictions: 5 before → 0 after
|
||
|
||
| # | What conflicted | Resolution |
|
||
|---|---|---|
|
||
| 1 | agent said demo-hp hosts drill VM `300`; controller said none was provisioned | **Measured live:** `qm list` → `300 drill-r50 stopped`. **felhom-agent was right.** `nodes.md:96` already said so correctly — both `CLAUDE.md` blocks became pointers, no new text needed |
|
||
| 2 | agent's `TEMPORARY` block (expired 2026-08-02) said felhom-pve was remote; controller said it was back on the LAN | both deleted; the audit holds the record. The gate now fails any past-dated TEMPORARY block |
|
||
| 3 | controller pinned `agent 0.93.0`, against the root file's own no-versions rule | every version literal removed from effective text in all four files |
|
||
| 4 | controller gave `demo-felhom` as the LAN *fallback* address as if it were the route | host tables removed from all three `CLAUDE.md` files → `nodes.md` |
|
||
| 5 | root file said memory held `(119 files)`; it holds 157 + the index | parenthetical deleted, not corrected — derivable, and it would go stale again |
|
||
|
||
The sweep found **none beyond the five**.
|
||
|
||
## 3. Before / after (effective = HTML comments stripped, i.e. what the model receives)
|
||
|
||
| File | before | after raw | after effective | gate |
|
||
|---|---|---|---|---|
|
||
| workspace-root `CLAUDE.md` | 208 ln / 16,642 B | 182 / 11,280 | **142 / 8,105** | pass |
|
||
| versioned copy | 208 / 16,642 | 182 / 11,280 | **142 / 8,105** | pass — `cmp` identical |
|
||
| `felhom-controller/CLAUDE.md` | 215 / 14,775 | 110 / 6,341 | **92 / 4,881** | pass |
|
||
| `felhom-agent/CLAUDE.md` | 216 / 15,554 | 205 / 13,619 | **173 / 11,491** | pass |
|
||
| `felhom.eu/CLAUDE.md` | 241 / 17,471 | 235 / 17,003 | **227 / 16,286** | **over — deferred** |
|
||
|
||
**A controller session's instruction load: 31,417 → 12,986 effective bytes (−59%).**
|
||
|
||
Figures are bytes, deliberately. The measured `/context` ratio shows a bytes/4 token estimate
|
||
understates the true cost by **1.59–1.90×**, so byte counts are the honest unit here.
|
||
|
||
**`felhom.eu/CLAUDE.md` is knowingly left over the ceiling.** Getting it under 200 needs the
|
||
core+rules restructure the spec explicitly forbade for reviewability, and the gate is registered only
|
||
in the controller and agent runners. Deferred as **R-229**, said plainly rather than quietly absorbed.
|
||
|
||
## 4. Files created / modified
|
||
|
||
**Created:** `felhom-controller/.claude/rules/{gates,ui-hungarian,backup-paths,agent-coupling}.md` ·
|
||
`felhom-agent/.claude/rules/health-checks.md` · `felhom.eu/scripts/instructions_gate.py` ·
|
||
`felhom.eu/scripts/test_instructions_gate.py` ·
|
||
`felhom.eu/documentation/audits/LEDGER-instruction-trim-2026-08-06.md`
|
||
|
||
**Modified:** the four `CLAUDE.md` files + the versioned copy · `controller_gates.py` ·
|
||
`agent_gates.py` · `skills/felhom-testing/SKILL.md` (gained the nine-instance table) ·
|
||
three `CHANGELOG.md` · `CONTEXT.md` (S-35) · `OPEN-ITEMS.md` (R-229)
|
||
|
||
## 5. Mechanism verification — done before relying on it
|
||
|
||
The whole design rests on three claims. Two were confirmed, one was **false**:
|
||
|
||
| Claim | Verdict |
|
||
|---|---|
|
||
| `.claude/rules/*.md` + `paths:` loads only on a matching file read | confirmed against the installed 2.1.222 build |
|
||
| HTML comments are stripped before injection | **confirmed empirically** — control (both markers plain → both reported) vs treatment (one commented → not reported, twice) |
|
||
| `unconditional: true` frontmatter | **NOT a product feature.** It is this project's own marker; the gate's docstring says so, so nobody hunts for it in the docs |
|
||
|
||
The HTML-comment test **failed its first red-proof** — an open-ended prompt returned one marker in
|
||
both arms, so the instrument was dropping a result silently. Rewritten as forced yes/no questions
|
||
with a both-plain control, it discriminated. Worth recording: this project's own rule ("an instrument
|
||
that can drop results silently is not a measurement") caught a measurement made *for* this task.
|
||
|
||
## 6. Amnesty list (the list to review)
|
||
|
||
Deliberately short — **one** item qualified:
|
||
|
||
- Three generic code-quality bullets in `felhom.eu/CLAUDE.md` ("always double-check generated code",
|
||
"handle edge cases without overcomplicating", "add debug capabilities"). No recorded production
|
||
violation, recoverable worst case, and duplicated in the workspace root. **"ask first — don't
|
||
guess" was kept** — that one is a real behavioural directive.
|
||
|
||
**Nothing on the protected list was touched.** The nine-row invariant table, "presence is not
|
||
success", the four R-96 rules, the F9 fence, secrets handling, trunk-based, the DooPlex protections,
|
||
the destructive-target fences with their permitted targets, and the clean-tree gate all survive —
|
||
moved or compressed, never dropped, each compressed fence keeping its target and its reason.
|
||
|
||
## 7. Gate results
|
||
|
||
- `controller_gates.py --fast` → **all 9 gates OK**, including the new `instructions`.
|
||
- `agent_gates.py --fast` → **both gates OK**.
|
||
- `test_instructions_gate.py` → **20 passed, 0 failed**.
|
||
- `go build ./... && go vet ./... && go test ./...` → **green in all three modules**
|
||
(`felhom-controller/controller`, `felhom.eu/hub`, `felhom-agent`) — and unchanged, as required: no
|
||
Go was touched.
|
||
- **Registration seam asserted by parsing each runner's `GATES` list from the AST**, not by grepping
|
||
the source — a commented-out registration would not satisfy it.
|
||
|
||
**Red-proof** (ceiling temporarily 100, real trimmed files):
|
||
|
||
```
|
||
CLAUDE.md effective lines : 92 (ceiling 100) [felhom-controller]
|
||
CLAUDE.md effective lines : 173 (ceiling 100) [felhom-agent]
|
||
instructions_gate: 1 FAILURE(S)
|
||
- .../felhom-agent/CLAUDE.md: 173 effective lines, ceiling 100. This is an ADHERENCE limit,
|
||
not a space limit — long instruction files get followed less reliably and hide contradictions.
|
||
```
|
||
|
||
It discriminated: agent failed and was named, controller still passed. Threshold restored, suite
|
||
re-run green.
|
||
|
||
## 8. `MEMORY.md` — measured only, unchanged
|
||
|
||
146 lines / 17,688 B (17.3 KB) against the 200-line / 25 KB limits: **within both, nothing
|
||
truncated.** The expected finding is absent; a different one is present — the index references **113**
|
||
memory files while **157** exist on disk, and **zero** referenced files are missing. So 44 memory
|
||
files are unindexed. Recorded, not acted on (the ruling deferred this).
|
||
|
||
## 9. Delegation
|
||
|
||
**No subagent was used.** All search, inventory and verification was done in-session. Nothing was
|
||
delegated, so nothing needs the read-only caveat.
|
||
|
||
## 10. Which files actually load
|
||
|
||
Settled from the supplied `/context`, not assumed: at the workspace root exactly **two** memory files
|
||
load — the root `CLAUDE.md` (6.6k tokens) and `MEMORY.md` (8.4k). Per-repo `CLAUDE.md` files are
|
||
**not** loaded at launch; they load on demand when a file in that directory is read. This is why the
|
||
irreversible fences were kept in the root file.
|
||
|
||
**Still outstanding (HUMAN):** `/context all` from **inside `felhom-controller`** after this trim, to
|
||
give the measured after-figure and confirm which rule files a repo session actually pulls in. Claude
|
||
Code cannot invoke a slash command on itself. The after-figures above are byte counts from disk, not
|
||
measured tokens, and are labelled as such.
|
||
|
||
## 11. Register
|
||
|
||
`OPEN-ITEMS.md` row taken: **R-229** (READY, owner Viktor) — covering `felhom.eu/CLAUDE.md`'s
|
||
restructure, `felhom-agent`'s remaining headroom, the auto-memory decision, and the
|
||
spec-as-failing-test pilot.
|
||
|
||
## 12. Observations — not acted on
|
||
|
||
1. `target-selection.md`'s known t740 off-site-tier error is still there (out of scope).
|
||
2. **The root `CLAUDE.md` could be a symlink** to its versioned copy, removing the divergence class
|
||
entirely — same filesystem, and Claude Code reads through symlinks (the four skills already are).
|
||
Not done, per the spec. If adopted, the gate's copy-identity check should become a symlink-target
|
||
check.
|
||
3. **A blanket version-literal ban has a false-positive class the spec did not anticipate:** a bare
|
||
`\d+\.\d+\.\d+` matches the first three octets of every IPv4. Without the dotted-quad exclusion the
|
||
gate fails on `192.168.0.180` in the agent's own file.
|
||
4. The spec calls the invariant table "the eight-invariant table"; **it has nine rows** and its own
|
||
text says "Nine instances". Flagged so the protected list is not later applied to eight of nine.
|
||
5. `demo-hp` also hosts VM `321 c11-appliance`, **running** — seen in the same `qm list`, not
|
||
mentioned in `nodes.md`. Not investigated.
|
||
6. Two unused Claude Code plugins (`typescript-lsp`, `context7`) and a broad user-scope allowlist
|
||
(`Bash(python3:*)`, `Bash(curl:*)`, `Bash(scp:*)` — standing arbitrary execution and network
|
||
egress in every project) were found by the earlier setup audit. **They live in
|
||
`~/.claude/settings.json`, not in any repo, and are deliberately out of scope.** Recorded only.
|