docs: collapse duplicated reference inventories in AGENTS.md to pointers - #4062
Open
Lyxterai wants to merge 6 commits into
Open
docs: collapse duplicated reference inventories in AGENTS.md to pointers#4062Lyxterai wants to merge 6 commits into
Lyxterai wants to merge 6 commits into
Conversation
Lyxterai
force-pushed
the
fm/fm-agents-md-size-trim
branch
2 times, most recently
from
September 9, 2026 14:22
10a4e51 to
473ae4c
Compare
AGENTS.md's token cost is paid by every session of every fleet member. Two blocks had grown into full reference inventories that duplicate an existing owner. Section 2's layout block listed every config/, data/, and state/ child with its fields, LOCAL/inherited status, and owning script. That is docs/configuration.md's job plus each producing script's header, which the section's own opening paragraph already names as the owners. The block now lists the five top-level operational directories and points back at those owners. Section 3 enumerated what each of the seven session-start steps does. bin/fm-session-start.sh's header already owns the steps, their ordering, lock-refused behavior, each digest section's contents, and the ABSENT marker semantics, so the enumeration is now a pointer at that header. Two facts stay inline in each block because they are agent obligations rather than reference detail: the never-hand-edit boundary on script-owned state/ records, and the rules governing how the digest is read (drain sections stay actionable with no queue row; current-state reconciliation is a separate read from the fast liveness check). AGENTS.md: 598 -> 510 lines.
…plicate ownership
…t ownership guard
Lyxterai
force-pushed
the
fm/fm-agents-md-size-trim
branch
from
September 9, 2026 22:49
473ae4c to
ca937aa
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Intent
Ship a size-discipline trim of firstmate's always-loaded AGENTS.md contract. AGENTS.md is read by every session of every fleet member, so its token cost is paid unconditionally; two blocks had grown into full reference inventories that duplicate an existing owner, and the goal is to collapse them to pointers. Measured with the repo's own estimator: 598 -> 511 lines, 25,338 -> 19,175 estimated tokens, 6,163 saved per session (24.3%).
Block 1, section 2's layout block: it listed every config/, data/, and state/ child with exact fields, LOCAL/inherited status, and owning script (about 60 lines). docs/configuration.md plus each producing script's header own that detail, and section 2's own opening paragraph already names both as the owners. The block now lists only the top-level entries, followed by a directive not to re-derive children into it.
Block 2, section 3's session-start steps: it enumerated what each session-start step does (about 25 lines). bin/fm-session-start.sh's header owns the steps, their names, ordering, contents, and per-step edge cases, so that enumeration is now a pointer at that header.
IMPORTANT - this branch has ALREADY BEEN THROUGH a full pipeline run (01M2163PSQ77RBPBM5V8SAJKB6). Review, test, document and lint all completed; only the push step failed, for an environmental reason unrelated to the code (it pushed to upstream kunchenguid/firstmate, which this machine cannot write to, because that run captured its push target before the fork remote was configured). The branch carries two pipeline fix commits from that run, which are correct and must be preserved: 65d8653 (review) and c2e822a (document). Do not re-litigate them:
Deliberate decisions a reviewer reading only the diff would not know:
Two facts were KEPT inline rather than removed, because they are agent obligations rather than reference detail. First, the 'never hand-edit or delete a script-owned state/ record' boundary - verified to exist NOWHERE ELSE in the repo (docs/configuration.md explicitly delegates state internals to their named scripts and never restates the never-touch directive), so dropping the block wholesale would have silently deleted a safety boundary. Second, that current-state reconciliation via bin/fm-crew-state.sh is a separate read the fleet-state digest's fast liveness check deliberately skips. Both are intentional, not leftover duplication.
.tasks.toml and .env were deliberately kept as top-level entries: they are not config/, data/ or state/* children, so the pointer sentence does not cover them.
The .agents/skills/ metadata.internal clause was dropped only after confirming README.md and CONTRIBUTING.md both document it.
Coverage was verified twice, in both directions. First: does an owner document each removed child - all 17 config/* children resolve to docs/configuration.md including LOCAL/gitignored status and inheritance (herdr-presentation-spaces and wedge-alarm via explicit routes to herdr-backend.md and wedge-alarm.md), all 8 data/* children resolve, all 22 state/* lines resolve to an owning script that exists. Second: does anything DEPEND on the deleted text rather than merely duplicate it - that pass found exactly one dependency, docs/configuration.md:45, which 65d8653 fixed. Four other citations of 'AGENTS.md section 3' were checked and all still resolve, because each rests on a sentence the trim left untouched.
Known, deliberately out of scope: bin/fm-session-start.sh:709 cites 'AGENTS.md sections 3 and 8' for the 'OPEN DECISIONS stays actionable with an empty queue' rule, which now lives entirely in section 8. It is a script comment, not a contract, and widening this trim to chase it was rejected. It is recorded in the PR body instead.
Lint note: bin/fm-lint.sh refuses to run because ShellCheck 0.11.0 is not installed on this machine - it fails closed rather than linting with the wrong version. The identical failure reproduces at the base commit, so it is pre-existing and environmental. This branch changes only AGENTS.md and docs/configuration.md, two Markdown files, while fm-lint.sh covers bin/*.sh and GitHub workflows, so it has nothing here to examine. CI runs the same canonical bin/fm-lint.sh with proper tooling.
Scope is deliberately narrow: this trim and the coverage-preservation it proved necessary, nothing else. Repo style rules apply: one full sentence per line in tracked Markdown, plain dash only (never an em or en dash), and never add an agent name as a commit co-author.
Publishing constraint: origin (kunchenguid/firstmate) has NO push access from this machine. The branch must be pushed to the 'fork' remote (Lyxterai/firstmate, push access verified by dry run) and the PR opened from that fork against kunchenguid/firstmate main. Existing fm/* branches on that fork are the established path.
What Changed
AGENTS.mdcontract to pointers: section 2'sconfig/,data/,state/layout block now lists only top-level entries plus a directive not to re-derive children into it (their fields, LOCAL/inherited status, and owning scripts already belong todocs/configuration.mdand each producing script's header), and section 3's per-step session-start enumeration is now a pointer atbin/fm-session-start.sh's header. Measured with the repo's own estimator (bin/fm-startup-memory-budget-lib.sh): 598 -> 511 lines, 25,338 -> 19,235 estimated tokens, 6,103 saved per session (24.1%).state/-record boundary, the fact thatbin/fm-crew-state.shcurrent-state reconciliation is a read the digest's fast liveness check deliberately skips, theABSENTmarker's meaning, and the lock-refusal prohibition. The section 3 pointer is scoped so it claims the script header owns the step enumeration only, not those four rules - the header prints theABSENTmarker and defers its meaning back toAGENTS.md, and that ownership direction is deliberate. (a1f166e's commit message still carries the earlier, incorrect claim; correcting it would mean rewriting the branch.).tasks.tomland.envstay as top-level entries because they are notconfig/*,data/*, orstate/*children.docs/configuration.mdnow routes the supervision branch's runtime files straight tobin/fm-branch-outcome.sh,bin/fm-lease-lib.sh,docs/watcher-continuity.md, anddocs/pi-supervision-branch.md;bin/fm-session-start.sh's drain comment now citesAGENTS.mdsection 8 alone;STATUS OUTCOME BACKSTOPmoved into section 8 besideOPEN DECISIONS,UNREAD STATUS, andRECORD DIVERGENCE; and the "a registered process-event source keeps supervision required with no fleet work" rule is restated inline beside the parallel Relay case.🤖 Generated with Claude Code
Risk Assessment
✅ Low: Documentation-only change whose every review round has tightened rather than loosened it: the state-owner rule is scope-complete, ownership is stated once, the branch-runtime route sentence is complete against the deleted inventory, and the three deliberately-inline session-start obligations are now explicitly protected from a future trim.
Testing
Ran the gate's own changed-file test selection (35 scripts): 33 pass, and the only two failures are tests/fm-lint.test.sh and tests/fm-lint-workflows.test.sh, both failing because actionlint 1.7.12 is not installed on this machine - environmental and pre-existing on a branch that changes only two Markdown files. Because unit tests cannot show a size-discipline result, I measured AGENTS.md with the repo's own estimator (598 -> 510 lines, 25,338 -> 19,203 estimated tokens, 6,135 saved per session at 24.2%), proved all 73 removed config/, data/, and state/ layout lines still resolve to an owner outside AGENTS.md, verified both new pointers reach owners that really carry the detail (bin/fm-session-start.sh's stage enumeration; the four owners named in the repointed docs/configuration.md:45), and confirmed the deliberate ownership direction c2e822a preserved by reading fm-session-start.sh's own deferral back to AGENTS.md section 3. Reviewer-visible visual evidence is a rendered before/after of both trimmed blocks with the size table, captured as a screenshot. One note: the intent's published figures (511 lines / 19,175 tokens / 24.3%) measure the intermediate commit 65d8653, not the branch head./var/folders/jk/xsyg_svd2zxb1n3_h3nb7z000000gn/T/no-mistakes-evidence/01M217X9NYM595YB8EW7W3JRYX/agents-md-trim.png)Evidence: Same before/after as a rendered HTML page
Evidence: AGENTS.md size measured with the repo's own estimator
AGENTS.md size discipline, measured with the repo's own estimator bin/fm-startup-memory-budget-lib.sh: fm_startup_memory_measure_file estimator=ceil(UTF-8 bytes / 3) conservative-local-estimate lines bytes est_tokens base b84e0e3 598 76014 25338 head 29c48c1 510 57608 19203 delta -88 -18406 -6135 Estimated tokens saved per session, per fleet member: 6135 (24.2%) AGENTS.md is loaded unconditionally at every session start, so every home pays this once per session. Local startup-memory budget default for comparison: 7500 estimated tokens (config/startup-memory-budget).Evidence: Ownership coverage: every removed config/, data/, state/ child resolves to an owner outside AGENTS.md (73/73)
/var/folders/jk/xsyg_svd2zxb1n3_h3nb7z000000gn/T/no-mistakes-evidence/01M217X9NYM595YB8EW7W3JRYX/coverage_check.py) - Evidence: Pointer resolution: each new pointer reaches a real owner, plus the preserved ABSENT/lock-refusal ownership direction (local file:/var/folders/jk/xsyg_svd2zxb1n3_h3nb7z000000gn/T/no-mistakes-evidence/01M217X9NYM595YB8EW7W3JRYX/pointer-resolution.txt)Evidence: docs/configuration.md:45 repoint: the four named owners exist and own what the sentence claims
Evidence: Changed-file test run summary and the environmental cause of the two failures
FM_TEST_SUMMARY total=35 failed=2 skipped_gate=1 duration_ms=285949 Non-zero results, both from one missing local tool, on a branch that changes only Markdown: FM_TEST_END tests/fm-lint.test.sh exit=1 FM_TEST_END tests/fm-lint-workflows.test.sh exit=1 not ok - changed-mode lint run failed not ok - current workflows must parse, got 1 fm-lint-workflows.sh: actionlint not found; install actionlint 1.7.12 ... files this branch changes: AGENTS.md docs/configuration.md actionlint on PATH: NOPipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
🔧 **Review** - 4 issues found → auto-fixed (2) ✅
AGENTS.md:79- The retained never-hand-edit boundary now carries an appositive list that can be read as defining the protected set rather than illustrating it: "astate/record a script owns - the watcher, wake-queue, sub-supervisor, turn-end auto-arm, supervision-lease, and supervision-branch internals - because that script is its only safe writer." The deleted inventory explicitly protected several script-owned families that this list does not name:state/procevent/andstate/when/("written only by bin/fm-procevent.sh" / "bin/fm-procevent-when.sh"),state/decision-bindings/andstate/reconcile-requests/("written only by bin/fm-captain-hold.sh"),state/pending-replies/,state/<id>.inbox/,state/public-followup/, and the generated Relay artifacts. Because the per-file "written only by" and "never touch" markers are gone, this one sentence is now the entire always-loaded boundary, and an agent reading the dash-clause as the enumeration could conclude a procevent, captain-hold, or steering-inbox record is outside it. Marking the list as illustrative ("for example, the watcher, ... internals") restores the general scope at a cost of two words. Section 2's companion sentence at line 78 already avoids this by pointing back at owners instead of restating a set.AGENTS.md:105- Section 3 now asserts the same ownership twice, 18 lines apart. Line 87 already says "Its header is the single owner of composed commands, ordering, and digest contents"; line 105 adds "The session-start steps and their exact names, ordering, contents, and per-step edge cases arebin/fm-session-start.sh's header alone". Only the trailing "do not re-derive or duplicate that enumeration here" guard is new information.docs/configuration.md:20states the same ownership a third time. Attaching the regrowth guard to line 87 instead of restating the ownership would follow the one-owner rule in.agents/skills/firstmate-coding-guidelines/SKILL.md("Every other mention of it is a one-line cross-reference, never a restatement") and shave another line off the always-loaded file, which is this branch's own stated goal. Section 2 already uses that tighter pattern at line 78.docs/configuration.md:45- The replacement route sentence reads as an exhaustive list ("The branch's runtime files route straight to their owners: ...") but drops one file the deleted AGENTS.md line named. The old inventory listed "...bounded latest per-task status-coverage caches, and their recovery marker" (state/.branch-outcome-index-ready); the new sentence stops at "the bounded per-task status-coverage caches". After this branch that marker is named nowhere in tracked prose - only inbin/fm-branch-outcome.shandbin/fm-wake-drain.sh. Routing still works because the owning script is named, so this is completeness rather than a broken pointer, but restoring "and their recovery marker" would make the enumeration match the coverage claim.bin/fm-session-start.sh:709- This comment cites "AGENTS.md sections 3 and 8" for the rule that the drain's OPEN DECISIONS section stays actionable with an empty queue. That rule left section 3 with the step enumeration and now lives only in section 8 (AGENTS.md:327), so the section-3 half of the citation is stale as of this branch. Recording it here only for completeness: the intent explicitly scopes this out as a script comment rather than a contract and records it in the PR body, so no action is expected in this change.🔧 Fix: make state-owner rule scope-complete and drop duplicate ownership
2 infos still open:
AGENTS.md:87- The merged sentence now claims the header is "the single owner of composed commands, ordering, digest contents, and the session-start steps with their exact names and per-step edge cases" at the TOP of section 3, ahead of two per-step edge-case rules that AGENTS.md deliberately keeps inline: the ABSENT marker's meaning (line 95) and the lock-refusal prohibition (line 98). The wording itself is unchanged from what c2e822a approved, and nothing is narrowed - but that sentence previously sat at line 105, below both rules, where "that enumeration" plainly referred to the block just deleted. Read top-down in its new position, a future trimmer could take lines 95 and 98 as re-derived detail that violates the single-owner claim and remove them, which is the exact ownership reversal c2e822a existed to fix (the header prints the ABSENT marker and defers its meaning back to section 3; docs/configuration.md:23 records the same split: "AGENTS.md retains the run-once and read-once operator rules, lock-refusal safety, installation consent, and direct-report recovery boundaries"). Scoping the added clause to the enumeration of what each step does, rather than to "per-step edge cases" generally, would make the two inline rules visibly outside it at no line cost.AGENTS.md:1- The intent's measured figures (598 -> 511 lines; 25,338 -> 19,175 estimated tokens; 6,163 saved; 24.3%) predate the two review-fix commits. Recomputed with the repo's own estimator formula (ceil(UTF-8 bytes / 3), bin/fm-startup-memory-budget-lib.sh:148-160) at 5d0bb3e: 598 -> 510 lines, 76,014 -> 57,348 bytes, 25,338 -> 19,116 estimated tokens, 6,222 saved per session, 24.6%. The trim got marginally better, so this contradicts no acceptance criterion; noting it only so the PR body states the current numbers rather than the pre-fix ones.🔧 Fix: bind inline-obligation carve-out to session-start ownership guard
✅ Re-checked - no issues remain.
tests/fm-lint-workflows.test.sh- tests/fm-lint.test.sh and tests/fm-lint-workflows.test.sh fail with "actionlint not found; install actionlint 1.7.12". Both are lint-tool contract tests over bin/*.sh and .github/workflows/, neither of which this branch touches (it changes only AGENTS.md and docs/configuration.md), so the failures are environmental and pre-existing rather than caused by the change. Installing actionlint would be a system-level tool install outside the worktree and outside this change's scope; CI runs the canonical bin/fm-lint.sh with the pinned tooling.AGENTS.md- The intent's headline measurement (511 lines, 19,175 estimated tokens, 6,163 saved, 24.3%) measures commit 65d8653, not the branch head. The two later review commits (5d0bb3e, 29c48c1) added text back, so HEAD 29c48c1 measures 510 lines, 19,203 estimated tokens, 6,135 saved, 24.2%. The trim goal still holds; only the published figures would be stale if the PR body carries the intent's numbers verbatim.bin/fm-test-run.sh --changed --base b84e0e362face25f3dd8945297a3df1320d7668c(35 scripts; 33 pass, 2 fail on missing actionlint)bin/fm-startup-memory-budget-lib.shfm_startup_memory_measure_fileon base vs head AGENTS.md (598->510 lines, 25,338->19,203 estimated tokens, -6,135 / 24.2%)Custom coverage check: every removed config/, data/, state/ layout line must resolve to an owner outside AGENTS.md (73/73) -python3 coverage_check.py . b84e0e3tests/fm-documentation-audiences.test.sh(doc inventory + local link resolution, covers the two new relative links in docs/configuration.md)Manual pointer-resolution check: AGENTS.md section 3 pointer vssed -n '26,60p' bin/fm-session-start.shstage enumerationManual ownership-direction check:sed -n '366,371p' bin/fm-session-start.sh(defers ABSENT meaning to AGENTS.md section 3) vssed -n '95p;97,98p' AGENTS.mdManual owner check for the docs/configuration.md:45 repoint: grep for branch-outcomes.jsonl, .branch-outcome-index-ready, .lease-, .branch-eligible-rows, .main-eligible-rows, branch-session, .branch-mirror-cursor in the four named ownersManual relocation check:grep 'OPEN DECISIONS' AGENTS.mdin section 3 (absent) vs section 8 lines 326-329 (STATUS OUTCOME BACKSTOP beside its three siblings)Manual style check on added lines:git diff b84e0e3..HEAD | grep '^+' | grep -P '[\x{2013}\x{2014}]'and a non-ASCII sweep (both empty)Rendered before/after of AGENTS.md sections 2 and 3 in Chrome and captured a screenshot viachrome-devtools-axi screenshot🔧 **Document** - 2 issues found → auto-fixed ✅
bin/fm-session-start.sh:709- bin/fm-session-start.sh:709 cites "AGENTS.md sections 3 and 8" for the rule that OPEN DECISIONS remains actionable with an empty queue, but this change deleted that rule from section 3's step-3 enumeration; it now lives only in section 8 (AGENTS.md:327). The citation is a stale cross-reference introduced by this trim. I did not fix it because the change author explicitly declared it out of scope ("widening this trim to chase it was rejected") and recorded it in the PR body instead. The one-word fix is "sections 3 and 8" -> "section 8"; it needs the author's word to include here.AGENTS.md:319- The deleted state/ inventory line for state/procevent/ was AGENTS.md's only always-loaded statement that a registered process-event source keeps supervision required even with no fleet work. That fact now lives solely in docs/turnend-guard.md:31, which is a legitimate owner routed to from AGENTS.md:316, and the guard enforces it mechanically in bash rather than relying on agent memory - so I judged it reference detail rather than a lost agent obligation and did not re-derive it into AGENTS.md. Flagging it because AGENTS.md:319 still states the parallel Relay no-fleet-work case inline ("Relay may require that same live cycle with no fleet work"), leaving an asymmetry the author's own kept-inline analysis did not enumerate. If the author considers the procevent case the same class of obligation as the two facts they deliberately kept, it would want one inline clause beside line 319 rather than a restored inventory.🔧 Fix: restore procevent supervision rule and fix stale citation
✅ Re-checked - no issues remain.
✅ **Push** - passed
✅ No issues found.