docs(agents): trim the always-loaded contract from 569 to 472 lines - #2522
Open
IanQiu979 wants to merge 3 commits into
Open
docs(agents): trim the always-loaded contract from 569 to 472 lines#2522IanQiu979 wants to merge 3 commits into
IanQiu979 wants to merge 3 commits into
Conversation
Documentation-only restructure of AGENTS.md, firstmate's always-loaded core
contract. No behavior, contract, capability, or rule substance changed -
detail was routed to its existing owner and prose was consolidated per the
firstmate-coding-guidelines knowledge-placement decision tree and one-owner
rule. This re-applies the method of 039747a (483 -> 393) to current main,
which has since grown to 569 lines.
What moved / tightened:
- Section 2: replaced the 78-line annotated directory tree (an exhaustive
restatement of per-file fields, config semantics, and inheritance rules)
with a compact top-level tree plus pointers. Verified every removed
semantic against its owner before removing it: docs/configuration.md's
"Operational home layout and state" section states outright that it is the
single owner of the top-level layout and that producer script headers own
exact child-file fields, and it documents crew-harness, secondmate-harness
("not inherited because secondmates do not launch secondmates"),
crew-dispatch.json, backlog-backend, backend, calm, startup-memory-budget,
herdr-presentation-spaces, trace-context, cmux-socket-password, wedge-alarm,
x-mode.env, captain.md/captain-shared.md, learnings.md, secondmates.md,
procevent, and public-followup. metadata.internal=true is owned by
CONTRIBUTING.md and README.md. Every remaining state/ artifact was traced
to a producing script (fm-check-register, fm-pr-poll, fm-pr-check-migrate,
fm-classify-lib, fm-decision-hold, fm-procevent, fm-startup-network,
fm-wake-lib, fm-pending-reply-lib, fm-spawn, fm-teardown).
- Section 2: two facts had NO other owner and were kept, not dropped. The
"never touch watcher / Claude and Cursor turn-end / sub-supervisor /
wake-recovery internals" class stays inline as one sentence, worded to be
exactly as strict as the per-entry lines it replaces and no stricter -
delete-safety for every other state/ record now routes to that record's
producing script rather than being asserted either way. "Registered
process-to-event sources keep supervision required" moved to section 8,
its actual owner, beside the identical Relay rule.
- Section 3: compressed the step 1-7 mechanism narrative and its positional
ordering phrases, which bin/fm-session-start.sh's header already owns as
stated in this section's own first sentence. Kept the run-once rule, the
lock-refused read-only boundary, the trust-the-digest-once rule, the ABSENT
semantics, the NETWORK CHECKS "treat none as passed until it lands" rule,
the wake-durability-until-acknowledgement rule, the OPEN DECISIONS and
UNREAD STATUS reconciliation duties, and the liveness-read-vs-current-state
distinction.
- Section 4: routed the quota-array selection procedure to
quota-array-dispatch, which declares itself the single owner of it and
declares AGENTS.md section 4 the owner of the intake boundary, load
trigger, malformed-config refusal, every-candidate accounting, and
strongest-reasoning/tie rules - all five kept inline. Every hard "never"
in the removed lines was preserved inline: never infer a credential store,
provider family, or quota mapping from a name; never launch another
harness's CLI to judge a candidate; missing evidence is disclosed
uncertainty, never a credential or login escalation; only concrete
contradictory evidence blocks.
- Section 7: folded the watcher's custom-check security model (only trusted
repository scripts and hash-validated registered checks execute; every
other state check is rejected without running) into the existing
fm-check-register.sh rule, its actionable point, since no doc owns it.
- Section 9: merged the duplicated "do not expose" term list and the 11-row
rewrite table into the boundary plus one compressed rewrite guide; every
term->plain-English mapping is preserved, and the "adapter" term was added
to the do-not-expose list to match the rewrite guide.
- Sections 1,3,4,5,6,7,8,10,11,12,13: joined adjacent single-purpose
sentences into one sentence each (clause joins, no substance dropped).
Sequencing: PR kunchenguid#2520 also edits AGENTS.md, adding a two-sentence note that
the directory map is a navigational excerpt rather than an inventory and
that an absent entry never proves a state/ file is foreign or safe to
remove. That note is directly load-bearing for this restructure, so it is
reproduced verbatim here rather than left to a rebase conflict. Nothing else
from kunchenguid#2520 is touched.
Safety-inventory audit (every item still present inline or as an inline
stub+trigger; none lost):
- Section 1 hard rules 1-5 (never write to project + its exceptions and the
concrete captain-approved operation boundary; never merge without captain
word; never tear down unlanded work; crewmates never address captain;
report faithfully) + shared-tracked-material list + no agent co-author:
PRESENT.
- Section 2: fm-send fails closed unless FM_HOME explicit; never touch
watcher/turn-end/sub-supervisor/wake-recovery internals; producing script
decides edit/delete safety for every other state record; absent map entry
is not proof a state file is foreign; status = wake event not current
state; captain/shared-captain/learnings canonical regardless of harness
memory: PRESENT.
- Section 3: run once; do not reimplement its components; lock-refused
read-only boundary (no spawn/steer/merge/drain/repair/mutate); read-once
and read-the-persisted-file rules; ABSENT semantics; mutating sweeps only
when locked; wake records durable until the generation-bound
acknowledgement; OPEN DECISIONS and UNREAD STATUS reconciliation;
network checks not passed until they land; bootstrap consent + do not
dispatch until tools and GH auth are good; bootstrap-diagnostics trigger:
PRESENT.
- Section 4: harness-adapters trigger; verified harnesses only / never
unverified / never launch one named by static config; every-candidate
accounting; malformed config is an error, not something to select around;
strongest-reasoning class preserved; ties broken without array-order bias;
never infer a credential store or provider family; never launch another
harness's CLI; uncertainty is not a credential escalation;
quota-array-dispatch trigger; never max effort without captain; backend
blocker never silently retried; per-spawn --backend is never later-task
precedent: PRESENT.
- Section 5: reconcile only this home's own reports / never claim another
home's work; stuck-crewmate-recovery, secondmate-provisioning, and /afk
triggers; restart is a non-event: PRESENT.
- Section 6: project-management and secondmate-provisioning triggers; no
unmentioned remote / removal preflight and unlanded-work checks; secondmate
idle by default / no self-directed sweep / no child-tree reconstruction;
knowledge-routing list; firstmate never writes a project AGENTS.md; /stow
trigger and its scope limit: PRESENT.
- Section 7: evidence != authorization; diagnostic-reasoning trigger;
delivery mode and yolo resolved at intake and passed explicitly;
no-mistakes-prod-only surface rule; unregistered project defaults to
no-mistakes with yolo off; serialization criteria; spawn worktree-isolation
stop; fm-send is data plane only / fm-control owns lifecycle; no-mistakes
owns its own pipeline / no manual gate / no stacked reviews; yolo authority
split and its expansion boundary; ask-user-authority trigger; implementation
worker never answers its own finding; never merge a red PR and yolo cannot
authorize one; fm-pr-merge / fm-merge-local only; firstmate never runs axi
respond for a crew-owned run; single supported abort and validate-once
against the final head; forbid --yes; custom check.sh contract plus the
watcher's execution boundary; teardown only after landing / refusal is
stop-and-investigate / never force without discard authority; secondmate
retirement safety; decision-hold-lifecycle trigger; promotion carries only
intended fix changes and turns a reproduced bug into the regression test:
PRESENT.
- Section 8: one live cycle / no other harness's wait shape / no shell & / no
second cycle; Relay and registered process-event sources require the cycle
with no fleet work; no turn ends blind; drain the queue before other work;
acknowledge only after handling; wake-type handling list; never broadly
kill watchers (sibling homes) and forced repair uses the home-scoped owner
path; guard warnings do not replace the contract; spawn + brief isolation;
turn-end guards are backstops not a substitute; full Away-mode stub
(FM_INJECT_MARK + U+2063 marker format; daemon owns supervision; marked
message stays internal; unmarked message means the captain returned and its
catch-up gate must clear; no approval-authority expansion; bias to exit);
stuck-crewmate-recovery trigger: PRESENT.
- Section 9: talk-in-outcomes; captain's nouns; never expose internal terms;
all 11 rewrite mappings; scout and second mate stay untranslated; never
relay verbatim; private-report exemption; evidence-first escalation form;
reach-captain-immediately list; "Captain, shipshape." reply rule; PR full
https URL: PRESENT.
- Section 10: work items only / secondmates never backlog items / routed work
lives in that home's backlog; captain-gated hold command;
decision-hold-lifecycle trigger; update on every dispatch, completion, and
decision; note-hygiene and handoff-safety owners: PRESENT.
- Section 11: fm-brief owns the scaffold; every {TASK} replaced before
dispatch; ship-brief isolation assertion; firstmate-coding-guidelines
trigger; --herdr-lab guard and regenerate-rather-than-hand-edit rule;
secondmate-provisioning charter trigger; sparse status appends; scaffold is
a safety contract: PRESENT.
- Section 12: only AGENTS.md/bin/.agents/skills are loaded; /updatefirstmate
trigger; never touches projects/: PRESENT.
- Section 13: all 14 agent-only skill load triggers, including the
never-run-a-source's-blocking-command-yourself rule: PRESENT.
- Section 14: inert until FMX_PAIRING_TOKEN; token is not destructive
authority; Relay-only home still needs the live cycle; fmx-respond
triggers; promised final reply is durable state and only the owning home
posts it: PRESENT.
- Captain instruction precedence and "Maintaining this file": PRESENT,
unchanged.
Verification: bin/fm-doc-audience-check.sh passes (surfaces=68,
local_links=251); CLAUDE.md remains the canonical @AGENTS.md pointer file;
no other file changed; every cross-reference from docs/, .agents/skills/,
CONTRIBUTING.md, README.md, and bin/ headers into an AGENTS.md section still
resolves, since no section was renumbered and each referenced rule survives.
Section 9's term-rewrite table is a lookup surface: an agent consults it mid-response, one term at a time, while rewriting an internal label out of a captain-facing message. It is not prose read once at session start like the rest of the file, so an agent scanning for a single term needs rows rather than a semicolon-chained sentence. Ten lines is cheap insurance against leaking internal jargon to the captain, a rule enforced on every message. Commit 039747a's consolidate-adjacent-sentences method merged that table into prose. That method is right for prose and wrong for a table, so this note goes in the file's own "Maintaining this file" section rather than in a commit body: it travels with the file and lands in front of whoever next runs a consolidation pass over it.
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.
Why
AGENTS.mdis firstmate's always-loaded contract: every session of every fleet member pays its token cost on every turn, whether or not that session ever hits the situation a given line describes. It has grown to 569 lines, largely by accumulating conditional and reference detail inline instead of routing it to the owner that already documents it - exactly the failure modefirstmate-coding-guidelinesexists to prevent.This applies that skill's knowledge-placement decision tree and one-owner rule to the current file, taking it to 472 lines. It is the same restructure as
039747a(483 -> 393), redone against currentmain.039747anever reached this repo. It sat unpushed on a localmainthat was 163 commits behindorigin/main, and because/updatefirstmateis fast-forward-only, that one local commit silently blocked every self-update for 25 days. Landing the restructure here is what ends that.What this is not
Documentation only. No behavior, contract, capability, or rule substance changes. No script, test, or workflow is touched, and
CLAUDE.mdremains the canonical@AGENTS.mdpointer file.There was deliberately no target line count. Nothing was cut to hit a number - only content with a verified owner elsewhere was routed, and the verification for each removal is recorded in the commit body.
What moved
state//config//data/tree became a compact top-level map plus pointers.docs/configuration.md's "Operational home layout and state" section states outright that it is the single owner of the top-level layout and that producer script headers own exact child-file fields; every removed entry was traced to it, toCONTRIBUTING.md/README.md(metadata.internal), or to a named producing script (fm-check-register,fm-pr-poll,fm-pr-check-migrate,fm-classify-lib,fm-decision-hold,fm-procevent,fm-startup-network,fm-wake-lib,fm-pending-reply-lib,fm-spawn,fm-teardown) before removal.bin/fm-session-start.sh's header already owns as this very section states in its first sentence.quota-array-dispatch, which declares itself its single owner.What deliberately did not move: section 9's rewrite table
039747a's consolidate-adjacent-sentences method would merge section 9's 11-row rewrite table into prose, and it did exactly that. This PR deliberately does not, and the deviation is the point.That table is a lookup surface, not prose. An agent consults it mid-response, one term at a time, while rewriting an internal label out of a captain-facing message - not once at session start like the rest of the file. An agent scanning for a single term needs rows; compressing a lookup table into a semicolon-chained sentence optimises the wrong thing. Ten lines is cheap insurance against leaking internal jargon to the captain, a rule enforced on every message all session long.
039747a's method is right for prose and wrong for a table. Please do not re-merge it.That reasoning is now recorded in
AGENTS.md's own## Maintaining this filesection rather than only here, so it travels with the file and lands in front of whoever next runs a consolidation pass over it.Restoring the table also restored the "do not expose" sentence above it verbatim. The merged draft had quietly added
adapterto that prohibition list - a new rule, which a documentation-only restructure must not introduce, by the same reasoning that governs the two restorations below.What was deliberately kept, not dropped
Three facts had no other owner. Removing them would have been a real loss, so they stayed inline:
state/record now routes to that record's producing script rather than being asserted either way, so no permission was silently removed.fm-check-register.shrule, at its actionable point.Section 4's hard "never"s were preserved inline for the same reason: never infer a credential store, provider family, or quota mapping from a name; never launch another harness's CLI to judge a candidate; missing evidence is disclosed uncertainty, never a credential or login escalation; only concrete contradictory evidence blocks.
quota-array-dispatchitself names AGENTS.md section 4 as the owner of five things - intake boundary, load trigger, malformed-config refusal, every-candidate accounting, and the strongest-reasoning/tie rules - and all five remain inline.Two substance changes the review caught, both reverted
The gate's review flagged two places where a "prose tightening" had quietly changed the contract. Both were put back:
Relay may requirehad becomeRelay ... require. A modal verb is substance: may require is a permission, require is an obligation. It reads back exactly as before, and the process-to-event fact that moved here from section 2 keeps its own original strength rather than the two sharing one flattened verb.always runguarantee. That clause is the contrast with the very next sentence's mutating sweeps, which run only under the lock; without it a session could infer that a lock-refused start skips detection entirely. Restored.Both are the same class of error: a restructure that must not change substance had changed it in prose that looked like condensation.
Safety inventory
The commit body carries a section-by-section inventory naming every hard rule, refusal condition, fail-closed behaviour, and skill trigger and marking it PRESENT, in the same shape as
039747a's. If an item could not honestly be marked PRESENT, something was removed that needed putting back.Relationship to #2520
#2520 is open against this same file and adds a two-sentence note that the directory map is a navigational excerpt rather than an inventory, and that an absent entry never proves a
state/file is foreign or safe to remove. That note is directly load-bearing for this restructure, so it is reproduced verbatim here rather than left to a rebase conflict where it could be lost. None of #2520's other seven fixes are touched.Merge-order caution: because both branches add that same note, whichever lands second needs a quick check that it ends up present exactly once - not duplicated, not dropped. Everything else in the two branches is disjoint.
Verification
bin/fm-doc-audience-check.shpasses (surfaces=68 local_links=251).AGENTS.md section Ncross-reference fromdocs/,.agents/skills/,CONTRIBUTING.md,README.md, andbin/script headers still resolves. Each was checked, and each referenced rule still exists.CLAUDE.mdis unchanged and still the canonical@AGENTS.mdpointer file, not a symlink.AGENTS.mdis the only changed file across all three commits.no-mistakespipeline passed on this branch: review, test, document, and lint all clean. Push/PR/CI ran outside it because this repo is pull-only for the author, so the branch is delivered from a fork.Commits
may requiremodality, thealways runguarantee, and section 9's bulleted table.## Maintaining this filerecording why that table stays a list.