Skip to content

docs: collapse duplicated reference inventories in AGENTS.md to pointers - #4062

Open
Lyxterai wants to merge 6 commits into
kunchenguid:mainfrom
Lyxterai:fm/fm-agents-md-size-trim
Open

docs: collapse duplicated reference inventories in AGENTS.md to pointers#4062
Lyxterai wants to merge 6 commits into
kunchenguid:mainfrom
Lyxterai:fm/fm-agents-md-size-trim

Conversation

@Lyxterai

@Lyxterai Lyxterai commented Sep 9, 2026

Copy link
Copy Markdown

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:

  • 65d8653 fixed a real defect the trim introduced: docs/configuration.md:45 said "AGENTS.md's state/ inventory routes the branch's runtime files to their format and lifecycle owners", pointing at the inventory this branch deleted. It now routes those files directly to bin/fm-branch-outcome.sh, bin/fm-lease-lib.sh, docs/watcher-continuity.md and docs/pi-supervision-branch.md. It also dropped a stale hardcoded step count from the section 3 pointer and moved STATUS OUTCOME BACKSTOP into section 8 beside its three siblings (OPEN DECISIONS, UNREAD STATUS, RECORD DIVERGENCE).
  • c2e822a narrowed the section 3 pointer so it no longer claims bin/fm-session-start.sh's header owns lock-refused behavior or ABSENT marker semantics. That claim was wrong: the header prints the ABSENT marker and defers its MEANING back to AGENTS.md section 3, and AGENTS.md states the lock-refusal rule inline. The ownership direction is deliberate and must not be re-reversed. Note the original commit message on a1f166e still carries that incorrect claim; it cannot be corrected without rewriting the branch and dropping these fix commits, so it stays and the PR body records the correct direction.

Deliberate decisions a reviewer reading only the diff would not know:

  1. 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.

  2. .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.

  3. 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

  • Collapsed the two reference inventories in the always-loaded AGENTS.md contract to pointers: section 2's config/, 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 to docs/configuration.md and each producing script's header), and section 3's per-step session-start enumeration is now a pointer at bin/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%).
  • Kept the agent obligations that lived inside those blocks rather than deleting them with the surrounding detail: the never-hand-edit-a-script-owned-state/-record boundary, the fact that bin/fm-crew-state.sh current-state reconciliation is a read the digest's fast liveness check deliberately skips, the ABSENT marker'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 the ABSENT marker and defers its meaning back to AGENTS.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.toml and .env stay as top-level entries because they are not config/*, data/*, or state/* children.
  • Repointed everything that depended on the deleted text instead of merely duplicating it: docs/configuration.md now routes the supervision branch's runtime files straight to bin/fm-branch-outcome.sh, bin/fm-lease-lib.sh, docs/watcher-continuity.md, and docs/pi-supervision-branch.md; bin/fm-session-start.sh's drain comment now cites AGENTS.md section 8 alone; STATUS OUTCOME BACKSTOP moved into section 8 beside OPEN DECISIONS, UNREAD STATUS, and RECORD 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.

  • Evidence: Rendered before/after of AGENTS.md sections 2 and 3 with the measured size table (local file: /var/folders/jk/xsyg_svd2zxb1n3_h3nb7z000000gn/T/no-mistakes-evidence/01M217X9NYM595YB8EW7W3JRYX/agents-md-trim.png)
Evidence: Same before/after as a rendered HTML page
<!doctype html><meta charset="utf-8">
<title>AGENTS.md size trim</title>
<style>
 body { font: 13px/1.5 -apple-system, "SF Pro Text", system-ui, sans-serif; margin: 28px; background:#0f1115; color:#e6e8ee; }
 h1 { font-size: 20px; margin:0 0 4px; }
 h2 { font-size: 15px; margin: 28px 0 8px; color:#9fb4ff; }
 p.sub { color:#98a0b3; margin:0 0 18px; }
 table { border-collapse: collapse; margin-bottom: 6px; }
 th, td { border:1px solid #2a2f3a; padding:6px 14px; text-align:right; font-variant-numeric: tabular-nums; }
 th:first-child, td:first-child { text-align:left; }
 th { background:#171b23; color:#98a0b3; font-weight:600; }
 td.save { color:#5fd08a; font-weight:700; }
 .cols { display:flex; gap:14px; align-items:flex-start; }
 .col { flex:1; min-width:0; border:1px solid #2a2f3a; border-radius:8px; overflow:hidden; }
 .before { border-color:#5a2f34; } .after { border-color:#2f5a3c; }
 .lbl { padding:7px 12px; background:#171b23; font-weight:700; letter-spacing:.02em; }
 .before .lbl { background:#2a1a1d; color:#ff9aa5; } .after .lbl { background:#152a1e; color:#7ee2a8; }
 .lbl .n { float:right; font-weight:500; color:#98a0b3; }
 pre { margin:0; padding:12px; white-space:pre-wrap; word-break:break-word;
        font: 11px/1.45 "SF Mono", ui-monospace, Menlo, monospace; max-height:640px; overflow:auto; color:#cdd3e0; }
 .note { color:#98a0b3; margin:10px 0 0; max-width:1100px; }
</style>
<h1>AGENTS.md trim: what every firstmate session now reads</h1>
<p class="sub">base <code>b84e0e3</code> to head <code>29c48c1</code> on <code>fm/fm-agents-md-size-trim</code>.
AGENTS.md is loaded unconditionally at every session start of every fleet member, so this cost is paid once per session per home.</p>
<table>
 <tr><th>AGENTS.md</th><th>lines</th><th>bytes</th><th>estimated tokens</th></tr>
 <tr><td>before (b84e0e3)</td><td>598</td><td>76,014</td><td>25,338</td></tr>
 <tr><td>after (29c48c1)</td><td>510</td><td>57,608</td><td>19,203</td></tr>
 <tr><td>saved per session</td><td class="save">88</td><td class="save">18,406</td>
     <td class="save">6,135 (24.2%)</td></tr>
</table>
<p class="note">Estimator: the repo's own <code>fm_startup_memory_measure_file</code> in
<code>bin/fm-startup-memory-budget-lib.sh</code>, ceil(UTF-8 bytes / 3).</p>

<h2>Block 1 &mdash; section 2 "Layout and state"</h2>
<div class="cols"><div class="col before"><div class="lbl">BEFORE <span class="n">102 lines</span></div><pre>## 2. Layout and state

`docs/configuration.md` is the single owner of the top-level operational-home layout and configuration schemas; each producing script&#x27;s header and help own exact child fields and mutation mechanics.
`FM_HOME` selects an instance&#x27;s private `data/`, `state/`, `config/`, and `projects/`, while scripts continue to come from their tracked code root.
Each secondmate has a persistent isolated `FM_HOME`, including its own state, backlog, projects, and session lock.
`bin/fm-send.sh` fails closed unless `FM_HOME` is explicit, so a steer cannot silently resolve against another home.

Tracked files hold shared instructions and tooling; `data/` holds durable private fleet records; `state/` holds runtime records and append-only status events; `config/` holds local operating choices; and `projects/` contains clones that are read-only to firstmate except under hard rule 1&#x27;s concrete captain-approved project operation exception.

`` `
AGENTS.md            this file (CLAUDE.md is a real @AGENTS.md pointer to it)
CONTRIBUTING.md      contributor workflow and repo conventions
README.md            public overview and development notes
.github/workflows/   shared CI and PR enforcement, committed
.tasks.toml          tracked tasks-axi markdown backend config for the default backlog backend (section 10)
.agents/skills/      firstmate-loaded internal skills, committed; each carries metadata.internal=true for installers
.claude/skills       symlink to .agents/skills for claude compatibility
skills/              standalone public installer-facing skills, committed; not loaded by firstmate
bin/                 helper scripts, committed; read each script&#x27;s header before first use
.env                 optional Relay pairing token; LOCAL, gitignored; presence-gates section 14
config/crew-harness  crewmate harness override; LOCAL, gitignored; absent or &quot;default&quot; = same as firstmate. Inherited as the literal file: a concrete primary adapter value also controls a secondmate home&#x27;s own crewmates (section 4)
config/crew-dispatch.json  optional crewmate dispatch profiles; LOCAL, gitignored; firstmate-maintained but human-editable natural-language rules that choose a per-task harness/model/effort profile (section 4). Inherited by secondmate homes
config/secondmate-harness  harness the PRIMARY uses to launch SECONDMATE agents, optionally followed by a model and effort token on the same line (&quot;&lt;harness&gt; [&lt;model&gt;] [&lt;effort&gt;]&quot;; section 4); LOCAL, gitignored; absent or &quot;default&quot; harness falls back to config/crew-harness then firstmate&#x27;s own. The primary&#x27;s own setting; NOT inherited into secondmate homes (secondmates do not spawn secondmates)
config/backlog-backend  backlog backend override; LOCAL, gitignored; absent or &quot;tasks-axi&quot; = default tasks-axi backend, &quot;manual&quot; = force routine backlog updates to hand-editing; inherited by secondmate homes (section 10)
config/backend  runtime session-provider backend override for new tasks; LOCAL, gitignored; absent = falls through to runtime auto-detection (the runtime firstmate itself is executing inside), then tmux; tmux is the verified reference backend (docs/tmux-backend.md), herdr has its own required CI lane (docs/herdr-backend.md), while zellij, orca, and cmux remain experimental with no dedicated real-backend CI lane (docs/zellij-backend.md, docs/orca-backend.md, docs/cmux-backend.md) - herdr and cmux can also be selected by runtime auto-detection, zellij and orca never are (always explicit), and codex-app is not accepted; see docs/codex-app-backend.md; inherited by secondmate homes under the primary-authoritative contract in secondmate-provisioning
config/calm     Pi Calm presentation preference; LOCAL, gitignored, and not inherited; see docs/configuration.md &quot;Pi Calm preference&quot;
config/supervision-branch-model config/supervision-branch-effort  Pi supervision-branch model and reasoning-effort pins written by /supervision-model; LOCAL, gitignored, independently settable, and not inherited; see docs/configuration.md &quot;Pi supervision branch model and effort&quot;
config/startup-memory-budget     primary-authoritative per-home startup-memory budget; LOCAL, gitignored, materialized as 7,500 estimated tokens by locked primary bootstrap and inherited into secondmate homes; see docs/configuration.md &quot;Startup memory budget&quot;
config/stow-pass-horizon  optional presence flag opting this home in to /stow&#x27;s default-off pass-count decay horizon; LOCAL, gitignored, and not inherited; see docs/configuration.md &quot;Stow pass horizon&quot;
config/herdr-presentation-spaces  optional &quot;off&quot; opt-out from, or &quot;on&quot; opt-in to, Herdr&#x27;s default-on disposable single-task visual projection, which is unconfigured-default-on only at or above a Herdr version floor; LOCAL, gitignored; inherited by secondmate homes; see docs/herdr-backend.md &quot;Presentation spaces&quot;
config/trace-context  optional presence flag enabling default-off native W3C trace-context propagation to spawned agents; LOCAL, gitignored; inherited by secondmate homes; see docs/configuration.md &quot;Trace context propagation&quot; and docs/trace-context.md
config/turnend-churn-absorb  optional presence flag opting this home into the default-off absorb of bare turn-end wakes on pane churn; LOCAL, gitignored, and not inherited; see docs/configuration.md &quot;Turn-end pane-churn absorb&quot;
config/cmux-socket-password  optional cmux control-socket password; LOCAL, gitignored; read fresh on every cmux CLI call and passed through without ever overriding an operator&#x27;s own ambient CMUX_SOCKET_PASSWORD when absent (docs/cmux-

... [19484 bytes truncated] ...

 the same guard alarm.
   Presented records remain durable until the handling turn runs the generation-bound acknowledgement printed by the drain.
   Every locked drain also prints a bounded fleet-wide `OPEN DECISIONS` section when durable decision records remain open, including when the queue itself is empty; reconcile those entries before continuing.
   A main drain may also print a bounded, one-shot `STATUS OUTCOME BACKSTOP` when a task&#x27;s newest captain-facing status event has no covering supervision-branch outcome; handle it as a recovered wake even when no queue row remains.
   The same drain prints every still-unread `note:` line and pending-reply resolution since the last presentation in an unbounded `UNREAD STATUS` section, so an answer buried under a later routine line is not dropped; those lines are not re-printed after that presentation.
   It also prints a bounded `RECORD DIVERGENCE` section naming every captain call the status log reads as resolved while its backlog task is still held; nothing is closed for you, and `captain-hold-lifecycle` owns the reconciliation.
   When the lock could not be acquired and verified, the queue is left untouched because no session mutation is authorized, and the guard&#x27;s tangle/watcher-liveness alarms still print in read-only advisory mode without drain, supervision repair, or checkout repair commands.
4. **Supervision operating instructions** - after the wake queue and before both digests, the digest emits exactly one operating block for the detected primary harness, followed by the read-once contract that governs them.
   The script itself never starts supervision; the emitted harness protocol owns the exact wait or wake mechanism.
5. **Fleet-state digest** - after that read-once contract and ahead of the context digest, the compact backlog listing owned by `bin/fm-session-start.sh`; every `state/&lt;id&gt;.meta`; a bounded tail of each task&#x27;s `state/&lt;id&gt;.status` (labeled as wake-EVENT history, not current state, with the full log path printed for a deeper read); the `state/.afk` flag; and one cheap alive/dead read of each task&#x27;s recorded backend endpoint.
   That liveness line is a fast presence check only, not a full state read - when you need a crew&#x27;s actual current state (a run-step, not just &quot;is the pane there&quot;), read it with `bin/fm-crew-state.sh &lt;id&gt;` as before; the digest deliberately skips that deeper, slower read for every task so it stays fast and bounded.
6. **Network checks** - after the fleet-state digest, the deferred stage&#x27;s result, or an explicit statement of what it has not confirmed yet.
   A read-only session runs no network checks at all and says so.
7. **Context digest and next step** - last of the bulk sections, the full contents of `data/projects.md`, `data/secondmates.md`, `data/captain.md`, `data/captain-shared.md`, and `data/learnings.md`, each clearly delimited, followed by the closing reminder.
   A file that does not exist prints an explicit `ABSENT` marker, never confused with an empty-but-present file: absence is meaningful (`captain.md` absent means use the firstmate repo&#x27;s built-in defaults, `projects.md` absent means rebuild it from the clones under `projects/`, etc.).
   The closing reminder points back to the emitted supervision block and preserves only the lock, afk, Relay, and read-once reminders.

Bootstrap detects first, asks for consent, and installs only after the captain approves in the current session.
Do not dispatch until the required tools are present and GitHub authentication is good.
Use `gh-axi` for GitHub, `chrome-devtools-axi` for browser work, and `lavish-axi` for structured decisions or reports; consult current help rather than memorizing flags.
A silent bootstrap section needs no action; for any printed actionable diagnostic line, load `bootstrap-diagnostics` and follow its owner procedure.
`BOOTSTRAP_INFO:` lines are completed no-action facts and do not require loading a skill.
`secondmate-provisioning` owns startup secondmate sync, liveness, and inherited local-material convergence.</pre></div><div class="col after"><div class="lbl">AFTER <span class="n">30 lines</span></div><pre>## 3. Session start (run once at every session start)

Run `bin/fm-session-start.sh` exactly once at session start.
Its header is the single owner of composed commands, ordering, digest contents, and the session-start steps with their exact names and what each one does; do not re-derive or duplicate that enumeration here, but the `ABSENT` marker&#x27;s meaning, the lock-refused prohibition, and the current-state reconciliation read below are agent obligations this section deliberately states rather than duplicates of that header, and none of them may be trimmed as re-derived detail.
`bin/fm-supervision-instructions.sh` renders the emitted supervision block from `docs/supervision-protocols/`.
Do not reimplement it by separately running its lock, bootstrap, initial wake-drain, or deferred-network components.
Run-tier harness surfaces run this command for you at session open while the rest only nudge it, so confirm the digest is present in this session and run it yourself when it is not; `docs/sessionstart-nudge.md` owns adapter tiers, source routing, and compatibility.

Read the complete digest once and trust it as this turn&#x27;s startup and recovery input.
If the harness shows only a preview and persists the full output to a file, read that file before acting.
Do not separately re-read the context, backlog, metadata, or bulk status inputs it just printed unless a source was reported absent or corrupt, older history is specifically needed, or a targeted workflow must inspect before writing.
An `ABSENT` captain, shared-captain, secondmate, or learnings file means the firstmate repo&#x27;s built-in defaults, no shared captain preferences, no registered secondmates, or no captured learnings; rebuild an absent or stale project registry from the clones before dispatch.

If the session lock cannot be acquired and verified, report its exact diagnostic and remain read-only; another active session is only one possible cause.
A lock-refused session must not spawn, steer, merge, drain the wake queue, repair supervision, repair a checkout, or perform any other fleet mutation.

The digest itself makes no external-network call and never waits for one.
Every network check a session start owes - GitHub auth, dead-secondmate relaunch, secondmate convergence, pending handoff delivery, and project clone refresh - runs off the digest&#x27;s blocking path in a bounded worker owned by `bin/fm-startup-network.sh` and is reported in the digest&#x27;s own `NETWORK CHECKS` section.
The locked startup inactive-outcome scan joins that worker so a slow local current-state read cannot block the digest; its findings use the ordinary durable wake queue.
When that section reports its checks still in progress it names exactly what is unconfirmed; treat none of those as passed until `bin/fm-startup-network.sh report` returns the finished result, while a failed or otherwise actionable result also arrives as a `check: startup-network` wake.

One fact from those session-start steps stays inline because it governs how you READ the digest rather than what it contains: current-state reconciliation (`bin/fm-crew-state.sh &lt;id&gt;`) is a separate read the fleet-state digest&#x27;s fast liveness check deliberately skips.

Bootstrap detects first, asks for consent, and installs only after the captain approves in the current session.
Do not dispatch until the required tools are present and GitHub authentication is good.
Use `gh-axi` for GitHub, `chrome-devtools-axi` for browser work, and `lavish-axi` for structured decisions or reports; consult current help rather than memorizing flags.
A silent bootstrap section needs no action; for any printed actionable diagnostic line, load `bootstrap-diagnostics` and follow its owner procedure.
`BOOTSTRAP_INFO:` lines are completed no-action facts and do not require loading a skill.
`secondmate-provisioning` owns startup secondmate sync, liveness, and inherited local-material convergence.</pre></div></div>
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).

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)
repo root: /Users/laurits/.no-mistakes/worktrees/d0bf493791e7/01M217X9NYM595YB8EW7W3JRYX
base commit: b84e0e362face25f3dd8945297a3df1320d7668c
removed layout lines examined: 73

[OK  ] config/crew-harness
         config/crew-harness -> docs/architecture.md, docs/configuration.md, bin/backends/herdr.sh
[OK  ] config/crew-dispatch.json
         config/crew-dispatch.json -> docs/architecture.md, docs/configuration.md, bin/fm-bootstrap.sh
[OK  ] config/secondmate-harness
         config/secondmate-harness -> docs/agent-control.md, docs/architecture.md, bin/fm-config-inherit-lib.sh
[OK  ] config/backlog-backend
         config/backlog-backend -> docs/configuration.md, bin/backends/herdr.sh, bin/fm-backlog-handoff.sh
[OK  ] config/backend
         config/backend -> docs/cmux-backend.md, docs/configuration.md, bin/backends/cmux.sh
[OK  ] config/calm
         config/calm -> docs/calm-mode-feasibility.md, docs/configuration.md
[OK  ] config/supervision-branch-model
         config/supervision-branch-model -> docs/configuration.md
         config/supervision-branch-effort -> docs/configuration.md
[OK  ] config/startup-memory-budget
         config/startup-memory-budget -> docs/configuration.md, bin/fm-bootstrap.sh, bin/fm-config-inherit-lib.sh
[OK  ] config/stow-pass-horizon
         config/stow-pass-horizon -> docs/configuration.md
[OK  ] config/herdr-presentation-spaces
         config/herdr-presentation-spaces -> docs/configuration.md, docs/herdr-backend.md, bin/backends/herdr.sh
[OK  ] config/trace-context
         config/trace-context -> docs/configuration.md, docs/trace-context.md, bin/fm-config-inherit-lib.sh
[OK  ] config/turnend-churn-absorb
         config/turnend-churn-absorb -> docs/architecture.md, docs/configuration.md, bin/fm-watch.sh
[OK  ] config/cmux-socket-password
         config/cmux-socket-password -> docs/cmux-backend.md, docs/configuration.md, bin/backends/cmux.sh
[OK  ] config/wedge-alarm
         config/wedge-alarm -> docs/configuration.md, docs/examples/wedge-alarm, bin/fm-supervise-daemon.sh
[OK  ] config/watched-tools.json
         config/watched-tools.json -> docs/configuration.md, bin/fm-tool-update-check.sh
[OK  ] config/x-mode.env
         config/x-mode.env -> docs/arm-pretool-check.md, docs/configuration.md, bin/fm-arm-command-policy.mjs
[OK  ] data/backlog.md
         backlog.md -> docs/captain-hold-lifecycle.md, docs/configuration.md, bin/fm-backlog-handoff.sh
[OK  ] data/captain.md
         captain.md -> docs/architecture.md, docs/configuration.md, bin/fm-session-start.sh
[OK  ] data/captain-shared.md
         captain-shared.md -> docs/architecture.md, docs/configuration.md, bin/fm-bootstrap.sh
[OK  ] data/learnings.md
         learnings.md -> docs/architecture.md, docs/configuration.md, bin/fm-session-start.sh
[OK  ] data/projects.md
         projects.md -> docs/architecture.md, docs/configuration.md, bin/fm-brief.sh
[OK  ] data/secondmates.md
         secondmates.md -> docs/agent-control.md, docs/architecture.md, bin/fm-backlog-handoff.sh
[OK  ] data/<id>/brief.md
         <id>/brief.md -> docs/subagent-guard.md, docs/verification/rovo.md, bin/fm-brief.sh
[OK  ] data/<id>/report.md
         <id>/report.md -> docs/architecture.md, docs/secondmate-parent-channel.md, bin/backends/cmux.sh
[OK  ] state/<id>.status
         <id>.status -> docs/agent-control.md, docs/architecture.md, bin/backends/herdr-eventwait.py
[OK  ] state/<id>.turn-ended
         <id>.turn-ended -> docs/architecture.md, docs/configuration.md, bin/fm-busy-lib.sh
[OK  ] state/<id>.grok-turnend-token
         <id>.grok-turnend-token -> bin/fm-control-lib.sh, bin/fm-spawn.sh
[OK  ] state/<id>.kimi-turnend-token
         <id>.kimi-turnend-token -> bin/fm-control-lib.sh, bin/fm-spawn.sh
[OK  ] state/<id>.gemini-settings.json
         <id>.gemini-settings.json -> docs/verification/runtime-backends.md, bin/fm-control-lib.sh, bin/fm-spawn.sh
[OK  ] state/<id>.muse-session
         <id>.muse-session -> docs/verification/muse.md, bin/fm-busy-lib.sh, bin/fm-control-lib.sh
[OK  ] state/<id>.cursor-session
         <id>.cursor-session -> docs/verification/runtime-backends.md, bin/fm-busy-lib.sh, bin/fm-control-lib.sh
[OK  ] state/<id>.reconcile-nudged
         <id>.reconcile-nudged -> bin/fm-secondmate-reconcile.sh, bin/fm-teardown.sh
[OK  ] state/<id>.backlog-close
         <id>.backlog-close -> bin/fm-backlog-transition-lib.sh, bin/fm-bootstrap.sh
[OK  ] state/<id>.inbox/
         <id>.inbox/ -> docs/architecture.md, docs/cmux-backend.md, bin/fm-brief.sh
[OK  ] state/<id>.meta
         <id>.meta -> docs/agent-control.md, docs/architecture.md, bin/backends/cmux.sh
[OK  ] state/<id>.herdr-presentation
         <id>.herdr-presentation -> docs/configuration.md, docs/herdr-backend.md, bin/backends/herdr.sh
[OK  ] state/<id>.check.sh
         <id>.check.sh -> docs/architecture.md, docs/arm-pretool-check.md, bin/fm-arm-pretool-check.sh
[OK  ] state/<id>.check-trust
         <id>.check-trust -> bin/fm-check-lib.sh, bin/fm-check-register.sh
[OK  ] state/<id>.pr-poll
         <id>.pr-poll -> docs/gitlab-merge-watch.md, docs/scripts.md, bin/fm-inactive-reconcile.sh
[OK  ] state/<id>.pr-poll-registration
         <id>.pr-poll-registration -> docs/gitlab-merge-watch.md, bin/fm-pr-lib.sh, bin/fm-teardown.sh
[OK  ] state/<id>.pr-poll-retirement
         <id>.pr-poll-retirement -> bin/fm-pr-lib.sh, bin/fm-teardown.sh
[OK  ] state/<id>.pr-poll-merge-notified
         <id>.pr-poll-merge-notified -> bin/fm-merge-outcome-lib.sh, bin/fm-pr-lib.sh
[OK  ] state/branch-outcomes.jsonl
         branch-outcomes.jsonl -> docs/configuration.md, bin/fm-branch-outcome.sh, bin/fm-wake-drain.sh
         .branch-outcomes-cursor -> bin/fm-branch-outcome.sh
         .branch-outcomes-processed -> bin/fm-branch-outcome.sh
         .<task>.branch-outcome-index -> docs/configuration.md, bin/fm-branch-outcome.sh, bin/fm-teardown.sh
         .branch-outcome-index-ready -> docs/configuration.md, bin/fm-branch-outcome.sh, bin/fm-wake-drain.sh
[OK  ] state/branch-session/
         branch-session/ -> docs/configuration.md, docs/pi-supervision-branch.md
         .branch-session -> docs/configuration.md, docs/pi-supervision-branch.md
         .branch-mirror-cursor -> docs/configuration.md, docs/pi-supervision-branch.md
[OK  ] state/.branch-eligible-rows
         .branch-eligible-rows -> docs/configuration.md, docs/pi-supervision-branch.md, bin/fm-wake-drain.sh
         .branch-eligible-owner -> docs/configuration.md, docs/watcher-continuity.md, bin/fm-wake-drain.sh
         .main-eligible-rows -> docs/configuration.md, docs/watcher-continuity.md, bin/fm-wake-drain.sh
[OK  ] state/.lease-<task>
         .lease-<task> -> docs/architecture.md, docs/calm-mode-feasibility.md, bin/backends/herdr.sh
[OK  ] state/x-watch.check.sh
         x-watch.check.sh -> docs/configuration.md, docs/turnend-guard.md, bin/fm-bootstrap.sh
[OK  ] state/tool-updates.check.sh
         tool-updates.check.sh -> docs/configuration.md, bin/fm-tool-update-check.sh
[OK  ] state/pending-replies/
         pending-replies/ -> docs/configuration.md, bin/fm-pending-reply-lib.sh, bin/fm-send.sh
[OK  ] state/procevent/
         procevent/ -> docs/captain-hold-lifecycle.md, docs/configuration.md, bin/fm-bearings-board.sh
[OK  ] state/procevent-inbox/
         procevent-inbox/ -> docs/configuration.md, docs/extension-bindings.md, bin/fm-extension.mjs
[OK  ] state/decision-bindings/
         decision-bindings/ -> docs/captain-hold-lifecycle.md, bin/fm-captain-hold.sh
[OK  ] state/reconcile-requests/
         reconcile-requests/ -> docs/captain-hold-lifecycle.md, docs/configuration.md, bin/fm-captain-hold.sh
[OK  ] state/when/
         when/ -> docs/agent-control.md, docs/architecture.md, bin/backends/cmux.sh
[OK  ] state/inbox/
         inbox/ -> docs/architecture.md, docs/cmux-backend.md, bin/fm-brief.sh
[OK  ] state/x-inbox/
         x-inbox/ -> docs/architecture.md, docs/configuration.md, bin/fm-x-lib.sh
[OK  ] state/x-context/
         x-context/ -> docs/architecture.md, docs/configuration.md, bin/fm-public-followup-lib.sh
[OK  ] state/x-outbox/
         x-outbox/ -> docs/architecture.md, docs/configuration.md, bin/fm-x-dismiss.sh
[OK  ] state/public-followup/
         public-followup/ -> docs/architecture.md, docs/configuration.md, bin/fm-backlog-handoff.sh
[OK  ] state/x-poll.error
         x-poll.error -> bin/fm-x-poll.sh
         x-poll.claim-error -> bin/fm-x-poll.sh
[OK  ] state/.startup-network.*
         .startup-network.* -> docs/architecture.md, docs/configuration.md, bin/fm-bootstrap.sh
[OK  ] state/.wake-queue
         .wake-queue -> docs/architecture.md, docs/configuration.md, bin/fm-afk-start.sh
[OK  ] state/.watcher-down
         .watcher-down -> docs/architecture.md, docs/verification/supervision.md, bin/fm-guard.sh
[OK  ] state/.<id>.open-decisions-cursor
         .<id>.open-decisions-cursor -> bin/fm-classify-lib.sh, bin/fm-test-run.sh
[OK  ] state/.status-presentation-cursor
         .status-presentation-cursor -> docs/architecture.md, bin/fm-classify-lib.sh
         .status-presentation-lock -> docs/watcher-continuity.md, bin/fm-classify-lib.sh, bin/fm-wake-drain.sh
[OK  ] state/.afk
         .afk -> docs/architecture.md, docs/configuration.md, bin/fm-afk-launch.sh
[OK  ] state/.watch.lock
         .watch.lock -> docs/architecture.md, bin/fm-wake-lib.sh, bin/fm-watch-arm.sh
         .wake-queue.lock -> bin/fm-wake-lib.sh
[OK  ] state/.claude-autoarm.lock
         .claude-autoarm.lock -> docs/turnend-guard.md, bin/fm-claude-stop-autoarm.sh, bin/fm-turnend-guard.sh
         .claude-autoarm-epoch -> docs/turnend-guard.md, bin/fm-claude-stop-autoarm.sh, bin/fm-turnend-guard.sh
         .claude-autoarm-failure-notified -> bin/fm-claude-stop-autoarm.sh, bin/fm-turnend-guard.sh
         .claude-autoarm-failure-alarmed -> bin/fm-claude-stop-autoarm.sh, bin/fm-turnend-guard.sh
         .turnend-claude-blocks -> bin/fm-turnend-guard.sh, bin/fm-wake-lib.sh
         .turnend-claude-blocks.lock -> bin/fm-turnend-guard.sh, bin/fm-wake-lib.sh
[OK  ] state/.cursor-park-owner
         .cursor-park-owner -> docs/supervision-protocols/cursor.md, docs/turnend-guard.md, bin/fm-afk-start.sh
         .cursor-park-owner.lock -> docs/supervision-protocols/cursor.md, docs/turnend-guard.md, bin/fm-afk-start.sh
         .turnend-cursor-blocks -> bin/fm-turnend-guard-cursor.sh
[OK  ] state/.hash-*
         .hash-* -> docs/architecture.md, docs/cmux-backend.md, bin/backends/cmux.sh
         .count-* -> docs/agent-control.md, docs/architecture.md, bin/backends/cmux.sh
         .stale-* -> docs/architecture.md, docs/calm-mode-feasibility.md, bin/backends/cmux.sh
         .stale-since-* -> bin/fm-supervise-daemon.sh, bin/fm-watch.sh
         .churn-since-* -> docs/architecture.md, bin/fm-watch.sh
         .paused-* -> docs/architecture.md, docs/configuration.md, bin/fm-brief.sh
         .wedge-escalations-* -> bin/fm-supervise-daemon.sh, bin/fm-watch.sh
         .writing-* -> docs/agent-control.md, docs/architecture.md, bin/fm-backend.sh
         .seen-* -> docs/architecture.md, docs/configuration.md, bin/backends/herdr-eventwait.py
         .hb-surfaced-* -> docs/architecture.md, bin/fm-classify-lib.sh, bin/fm-inactive-reconcile.sh
         .last-* -> docs/architecture.md, docs/calm.md, bin/backends/cmux.sh
         .heartbeat-streak -> bin/fm-push-transition-lib.sh, bin/fm-watch.sh
[OK  ] state/.watch-triage.log
         .watch-triage.log -> docs/architecture.md, docs/watcher-continuity.md, bin/fm-push-transition-lib.sh
[OK  ] state/.last-watcher-beat
         .last-watcher-beat -> docs/turnend-guard.md, docs/verification/supervision.md, bin/fm-supervision-lib.sh
[OK  ] state/.subsuper-*
         .subsuper-* -> docs/architecture.md, docs/configuration.md, bin/fm-afk-launch.sh
         .supervise-daemon.* -> docs/architecture.md, docs/configuration.md, bin/backends/tmux.sh

entries with an owner outside AGENTS.md: 73/73
- Evidence: Coverage-check script used to produce that table (local file: /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
docs/configuration.md:45 repoint (65d8653): do the four named owners exist and own what the sentence claims?

The branch's runtime files route straight to their owners: `bin/fm-branch-outcome.sh` owns the formats of the durable outcome store `state/branch-outcomes.jsonl`, its read cursor, main's processed marker, and the bounded per-task status-coverage caches together with their `state/.branch-outcome-index-ready` recovery marker; `bin/fm-lease-lib.sh` owns the `state/.lease-<task>` per-task supervision-lease contract that the guarded scripts enforce; [docs/watcher-continuity.md](watcher-continuity.md) owns the acknowledgement contract behind the `state/.branch-eligible-rows`, `state/.branch-eligible-owner`, and `state/.main-eligible-rows` claims; and [docs/pi-supervision-branch.md](pi-supervision-branch.md) owns the extension's own `state/branch-session/`, `state/.branch-session`, and `state/.branch-mirror-cursor` records.

  bin/fm-branch-outcome.sh           owns branch-outcomes.jsonl        hits=2
  bin/fm-branch-outcome.sh           owns .branch-outcome-index-ready  hits=3
  bin/fm-lease-lib.sh                owns .lease-                      hits=8
  docs/watcher-continuity.md         owns .branch-eligible-rows        hits=1
  docs/watcher-continuity.md         owns .main-eligible-rows          hits=1
  docs/pi-supervision-branch.md      owns branch-session               hits=4
  docs/pi-supervision-branch.md      owns .branch-mirror-cursor        hits=1

relative markdown links in that sentence resolve from docs/:
  docs/watcher-continuity.md OK
  docs/pi-supervision-branch.md OK
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: NO

bin/fm-test-run.sh --changed --base b84e0e3 (35 scripts, changed-file selection)
FM_TEST_SUMMARY total=35 failed=2 skipped_gate=1 duration_ms=285949
FM_TEST_SUMMARY_FAMILY family=pure-contract-unit count=35 duration_ms=728143 failed=2

Non-zero results, both from one missing local tool, on a branch that changes only Markdown:
FM_TEST_END 2026-09-08T19:56:19Z tests/fm-lint.test.sh exit=1 duration_ms=12303 gate_skip=false
FM_TEST_END 2026-09-08T19:58:57Z tests/fm-lint-workflows.test.sh exit=1 duration_ms=90 gate_skip=false
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 with bin/fm-install-actionlint.sh <destination-directory> and put that directory on PATH.

files this branch changes:
  AGENTS.md
  docs/configuration.md
actionlint on PATH: NO
- Outcome: ⚠️ 2 issues (1 warning, 1 info) across 1 run (12m47s)

Pipeline

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: "a state/ 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/ and state/when/ ("written only by bin/fm-procevent.sh" / "bin/fm-procevent-when.sh"), state/decision-bindings/ and state/reconcile-requests/ ("written only by bin/fm-captain-hold.sh"), state/pending-replies/, state/&lt;id&gt;.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 are bin/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:20 states 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 in bin/fm-branch-outcome.sh and bin/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.

⚠️ **Test** - 2 issues (1 warning, 1 info)
  • ⚠️ 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.sh fm_startup_memory_measure_file on 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 . b84e0e3
  • tests/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 vs sed -n &#39;26,60p&#39; bin/fm-session-start.sh stage enumeration
  • Manual ownership-direction check: sed -n &#39;366,371p&#39; bin/fm-session-start.sh (defers ABSENT meaning to AGENTS.md section 3) vs sed -n &#39;95p;97,98p&#39; AGENTS.md
  • Manual 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 owners
  • Manual relocation check: grep &#39;OPEN DECISIONS&#39; AGENTS.md in 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 &#39;^+&#39; | grep -P &#39;[\x{2013}\x{2014}]&#39; and a non-ASCII sweep (both empty)
  • Rendered before/after of AGENTS.md sections 2 and 3 in Chrome and captured a screenshot via chrome-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.

⚠️ **Lint** - 1 warning
  • ⚠️ linter found issues (exit code 1)
✅ **Push** - passed

✅ No issues found.

@greptile-apps

greptile-apps Bot commented Sep 9, 2026

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 5/5

The PR appears safe to merge.

@Lyxterai Lyxterai changed the title docs(agents): trim duplicated reference detail from AGENTS.md sections 2 and 3 docs: collapse duplicated reference inventories in AGENTS.md to pointers Sep 9, 2026
@Lyxterai
Lyxterai force-pushed the fm/fm-agents-md-size-trim branch 2 times, most recently from 10a4e51 to 473ae4c Compare September 9, 2026 14:22
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.
@Lyxterai
Lyxterai force-pushed the fm/fm-agents-md-size-trim branch from 473ae4c to ca937aa Compare September 9, 2026 22:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant