Make CLAUDE.md a router: 47,797 → 20,983 bytes, with a pointer per moved file - #263
Conversation
…iles `CLAUDE.md` auto-loads into every turn of any session whose cwd is this repo — the vetter's, because `review-run.sh` cds to the install dir. The producer's cwd is `$WORK_DIR`, which holds no `CLAUDE.md`, so it pays nothing: measured 2026-08-10, first context 48,060 against 14,199. What auto-loads is now what governs judgement and binds every reader: the FSM framing, the tool surface, the invariants. The `pr-review-report` CLI reference (41% of the file, and the vetter has no `Bash` to invoke any of it) moves to `TRANSITIONS.md` with the slash-command layer above it, and the clone lifecycle to `WORK-CLONES.md`. Each has a one-line pointer in the router: a rule an agent never learns is not one it errors on, it is one it silently violates. Closes #261 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
`.gitignore` is a whitelist, so a new root file is untracked by default. These two would then exist on this box and nowhere else, and every pointer in the router would dangle on a fresh checkout. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
WalkthroughCLAUDE.md now routes readers to dedicated transition and work-clone references. New tests validate documentation pointers, section placement, file existence, and the CLAUDE.md size limit. Git tracking exceptions preserve both reference files. ChangesDocumentation routing
Estimated code review effort: 3 (Moderate) | ~20 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ast-grep (0.45.0)pr-review-report-rs/src/main.rsast-grep timed out on this file Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
🤖 ai:producer — merge-update against Head is now The conformance-test premise: it holds, and here is the assertion it holds against#258 landed
const RUNNER_CONTEXT_FILES: &[&str] = &[
"campaign-prompt.txt",
"campaign-worker-prompt.txt",
"review-prompt.txt",
"CLAUDE.md",
];What the router would have to do to break it is add a fifth shipped file. It does not, and the check is mechanical rather than rhetorical: the two pointers are ordinary markdown links, The two tests, run by name on the merge commit, both pass, and neither was touched:
The sibling consequence this PR's body already raised stands unchanged and unbuilt: a citation written into The three properties, verified rather than assertedSections were split at their own
Gates
Raised, not built
QA
|
|
Reviewed d267d45: approve |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@CLAUDE.md`:
- Around line 7-9: Update the measurement statement in CLAUDE.md to remove the
unsupported claim that two forced runs were performed; either rewrite the
context values as predictions or replace them with verified recorded forced-run
evidence, while preserving the surrounding comparison and Bash limitation
context.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: ba08dc7f-f01c-4b80-aced-a82e3dc9e39c
📒 Files selected for processing (5)
.gitignoreCLAUDE.mdTRANSITIONS.mdWORK-CLONES.mdpr-review-report-rs/src/main.rs
| Measured 2026-08-10 across two forced runs: first context 48,060 for the vetter | ||
| against 14,199 for the producer, with 41% of this file a CLI reference the | ||
| vetter has no `Bash` to invoke (#261). |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Remove the unsupported forced-run measurement claim.
The PR objectives state that no forced run was performed. Line 7 instead states, “Measured 2026-08-10 across two forced runs.” Replace the measured values with prediction language, or add the recorded forced-run evidence before merging.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@CLAUDE.md` around lines 7 - 9, Update the measurement statement in CLAUDE.md
to remove the unsupported claim that two forced runs were performed; either
rewrite the context values as predictions or replace them with verified recorded
forced-run evidence, while preserving the surrounding comparison and Bash
limitation context.
Closes #261
What this is
CLAUDE.mdkeeps auto-loading; what auto-loads is now only what governsJUDGEMENT and binds every reader. The reference material moves to two files,
each named by a one-line pointer in the router.
47,797 bytes → 20,983 bytes (−26,814, −56%.) The issue measured 47,556; the
file gained 241 bytes between that measurement and
origin/main, so against theissue's baseline it is −26,573.
f5f685b)## The pipeline is a finite state machine— 6,113CLAUDE.md## The FSM as a tool surface (MCP)— 5,491CLAUDE.md## Invariants— 7,863CLAUDE.md## Transitions (subcommands)— 19,561 (41%)TRANSITIONS.md## The layer a human types: slash commands…— 2,304TRANSITIONS.md## Work-clone lifecycle— 6,429WORK-CLONES.mdEvery moved byte is verbatim. The two new files carry a header saying who reads
them and why they are not in the router, and
.gitignore— a whitelist — gainsboth, without which they would exist on this box and nowhere else.
Who reads each section
## The pipeline is a finite state machine— STAYS. Read by the vetter,which is the only actor that receives this file, and by everyone authoring the
pipeline. It is not background: the north star ("a raw
ghin a prompt is aloose transition") is the ground a vetter rejects a PR on, "a gate on one edge
needs a transition on the other" is how a send-back with no exit gets caught,
and the PreToolUse-guard doctrine decides whether a PR's new guard belongs in
bash or in the binary. That is judgement.
## The FSM as a tool surface (MCP)— STAYS. The vetter reading aboutitself: its own eight tools, that a profile is a surface and not a permission,
that it has TWO subjects with the same three moves, that it dispatches and the
verdict stays in the main loop, and that it is read-only on the filesystem.
Every one of those decides its next turn.
## Invariants— STAYS. The ruleset every verdict is measured against.## Transitions (subcommands)— MOVES. Read by an interactive session: theonly actor that both holds a shell and can read a repo file on demand.
review-settings.jsondeniesBashoutright, and run
20260810T103008Z's own tool census confirms the shape:mcp__fsm__*×14,Read×40,Grep×15,Glob×11,Skill×3,Agent×3,and zero Bash calls — not one
pr-review-reportinvocation across 48turns, all of which paid for the table.
campaign-run.sh:266cds to$WORK_DIR;cron.envsets that to$HOME/code, which holds noCLAUDE.md)and invokes the transitions correctly anyway: run
20260810T083614Zmade 23pr-review-reportcalls —await×11,trusted-comments×6,--help×3,state-load,worklist— plus five clone/push/repair MCP tools. It reachesfor
--help, which is the reference it actually uses.## The layer a human types: slash commands as a plugin— MOVES, into thesame file, because its first sentence is "The transitions above are what a tool
call reaches" — the two are one document and splitting them would dangle that
reference. Read by a human installing the plugin or typing
/nr, and by whoeverauthors a command; the vetter can do neither. Its one binding rule ("the
commands are prompts and nothing else") is a corollary of the north star that
stays in the router, and is held by a test rather than by memory.
## Work-clone lifecycle— MOVES. Its readers are the producer (whoseclones these are, and which does not load this file), the vetter's dispatched
pr-auditor(briefed fromreview-auditor-prompt.txt, handed thedirpr_checkoutreturned, reading nothing else), and whoever changesclone_name_in_root/release_decision. What follows from "neither readerloads this file" is that the section was being paid for by the one actor it is
not addressed to — but only after checking the one rule in it that could change
a VERDICT: never search the filesystem for a checkout. That rule is not lost,
because the vetter already meets it where it acts, in
review-prompt.txt("NEVER SEARCH FOR A CHECKOUT. The
dirinpr_checkout's own result isthe only path that is this PR's source", with the 2026-07-27 incident attached),
and the vetter's read-only-on-the-filesystem property is stated in the MCP
section, which stays.
WORK-CLONES.md's header says so at the top, so a readerwho arrives from the pointer is told where the binding half lives.
The claim I was asked not to take on trust
"The producer already runs without the file, so the transitions reference is not
load-bearing at runtime." Checked:
/home/gildlab/code(the producer'sWORK_DIR) contains noCLAUDE.md, and the tool censuses above are read out ofthe two 2026-08-10 traces rather than inferred. It holds — and the vetter census
is the stronger half: the role that pays for the table is structurally incapable
of using it.
#258 premise still holds
the_journal_is_never_shipped_to_a_runners_contextrests on four files beingthe complete set of bytes a model receives,
CLAUDE.mdamong them as the oneimplicit channel. This change does not add a fifth.
TRANSITIONS.mdandWORK-CLONES.mdare ordinary repo files, reachable through exactly the--add-dir "$DIR"read membership every other file in this repo already has —the class 258's own body puts outside that list ("
--add-diris deliberatelynot on that list: it confers read membership, which makes a file reachable on
request, not shipped on every turn").
CLAUDE.mdkeeps its status; only itssize changes. No test of 258's was touched or needs to be.
One consequence for 258 to decide, raised not built: its sibling
every_journal_citation_in_a_prompt_resolves_to_an_entryscans the same fourfiles, so an
[LJ-…]citation written intoTRANSITIONS.mdorWORK-CLONES.mdlater would be outside the scan and could dangle. That is a question about the
citation scan's scope, not about the shipped-bytes set.
Expected effect — a PREDICTION, not a measurement
No run was forced. Both kill switches are in place and the two runs behind these
numbers cost $5.95 and $12.51.
The numbers to beat, from the vetter run
20260810T103008Z:context first48,060 and
cache read / call41,775.The issue's own estimate is that dropping the transitions table alone takes the
floor to ~33k. This also removes 8,733 bytes of ordinary prose (~2,200 tokens),
so the prediction is
context first≈ 30–31k andcache read / calllowerby about the same absolute amount on a comparable run — with the caveat that
per-call cache read also moves with turn count and with how much source a run
reads, so the floor is the honest half of the comparison.
pr-review-report token-profile, via/observe-run, is what settles it.Raised, not built
the_router_stays_a_routercapsCLAUDE.mdat 22,528 bytes — belowrouter + smallest moved section, so any reference section coming back tripsit, with 1,545 bytes of headroom for a rule to grow. When invariants
legitimately outgrow that, the right move is to raise the constant with the
arithmetic in the doc comment in front of you, not to widen it pre-emptively
now.
CLAUDE.mdnor thesetwo. Left alone: the router is the index for this set, and adding rows for
docs the table has never carried is a different decision. Should that table
carry the doc set?
pr-review-report-rs/src/main.rs(test module only, ~146 added lines in
settings_tests), whichJournal LLM mistakes separately from the prompt, so rules can be deleted #258 and the PR for
observe-run step 1 tells the caller to hold a foreground call that outlives the 600s ceiling — runs read as hangs #260 also touch. No
coordination attempted; whichever lands first, this one takes a merge of
main.QA
Discriminating tests:
settings_tests::every_router_pointer_resolves_to_a_file_that_exists,settings_tests::every_documented_section_is_in_exactly_one_home_and_a_moved_one_is_pointed_at,settings_tests::the_router_stays_a_router— all three fail on base,verified by reverting the docs (
git checkout origin/main -- CLAUDE.md, bothnew files removed) and re-running the filter — 37 passed, 3 failed: the
pointer test because the base router names no file at all, the homes test
because that router still carries
## Transitions (subcommands), the ceilingtest at 47,797 bytes against 22,528. Full suite:
nix develop .#rust -c cargo test— 1,229 unit + 113 integration, 0 failed.Mutations applied: 9 applied, 9 behaved as specified — 7 killed, 2 controls
survived. Each was applied to the real tree with an exact-anchor check (a
non-unique anchor is recorded as NEVER APPLIED, not as a kill), the suite was
re-run with the baseline verified green and 40 tests proven to have RUN, and
the file was reverted from git afterwards.
TRANSITIONS.md→TRANSITIONS-MOVED.md)every_router_pointer…+every_documented_section…every_router_pointer…+every_documented_section…every_documented_section…## Invariants→## The rules)every_documented_section…every_documented_section…every_router_pointer…+every_documented_section…the_router_stays_a_routerThe two controls are the point: the tests read the RULE (which section lives
where, and whether the reader is told) and not the paragraphs, so ordinary
editing of the material that stayed does not touch them. M6 is the one that
turns "exists" into a real check — a pointer to an empty file passes a bare
existence test.
Oracle: who reads what is derived from
campaign-run.sh:266/review-run.sh:247(the two cwds),
review-settings.json's deny list,cron.env'sWORK_DIR,and the per-tool censuses of the live traces
runs/20260810T083614Z.jsonlandreview-runs/20260810T103008Z.jsonl— not from this change's belief aboutthem. Byte figures are
wc -con the pre-change file, split at its ownheadings. The "already stated elsewhere" claim for the checkout rule is quoted
out of
review-prompt.txt.Category check: the issue asks for (a)
CLAUDE.mdkeeps auto-loading whilewhat auto-loads is cut to judgement material — done; (b) role-specific and
reference material in files named by whoever needs them —
TRANSITIONS.md,WORK-CLONES.md; (c) one line per moved file in the router — two pointers,gated by
every_router_pointer…; (d) the vetter keeps what it judges from —invariants, FSM semantics and tool surface are byte-identical; (e) 258's
premise unbroken — argued above, no test of its adjusted. Not covered, and
deliberately: no forced run, so the effect is a prediction and the issue's two
numbers stand unbeaten until
token-profilesays otherwise.Summary by CodeRabbit
Documentation
Tests