Skip to the content.

The AGENTS.md instruction-pulled floor — measured baseline (#5445)

Part of epic #3229 (shrink the always-sent token floor). This is the measured baseline for the epic’s largest unmeasured slice.

The category this names: instruction-pulled, not resident

The two floors this directory already prices are resident: bytes the harness seats in context before turn 1, which /context and fak footprint (#3230) can both see and internal/mcpfootprint can ratchet.

AGENTS.md is not one of those, and it is bigger than all of them. CLAUDE.md is resident and genuinely lean — 2,227 B ≈ 556 est. tokens — but its third line is an instruction: read AGENTS.md first. Every agent that obeys pays AGENTS.md’s 49,882 B ≈ 13,301 est. tokens as a turn-1 Read. Because those bytes are pulled by an instruction rather than seated in the system prompt, they appear in neither surface this epic built to make the floor visible: not in /context, not in fak footprint. A floor in effect but not in form.

Call it the instruction-pulled floor, and price it separately from the resident floor. The two compose but do not substitute, and they arrive differently: a resident byte is in the stable prefix from turn 0, so it is a cache-read on every turn after the first. An instruction-pulled byte is paid at full price on the turn it is read, then joins the message history — riding every later turn and occupying window until compaction sheds it. Neither surface the epic built reports the second, which is why 13,301 tokens per agent have gone unpriced.

Where it sits next to the slices the epic already gates:

Slice est. tokens form gated? measured by
AGENTS.md (turn-1 Read) 13,301 instruction-pulled no fak footprint --doc AGENTS.md
.claude/skills resident descriptions 11,809 resident not yet — #5444 fak skill footprint
fak MCP tool schemas 5,888 resident yes — floorgate.go fak footprint
‣ of which description prose 1,966 resident yes — descbudget.go fak footprint
CLAUDE.md 556 resident no (already lean) fak footprint --doc CLAUDE.md

Every row is a command a reader can re-run, not a quoted estimate; the skills row is 47,236 B across 58 skills at the same ~4 B/token divisor.

The per-agent pull chain is CLAUDE.md + AGENTS.md = 17,282 est. tokens, of which 96.8% is the pulled half.

Regenerate it

fak footprint --doc prices any markdown doc’s instruction-pulled floor per section. It reuses agent.RequestFootprint verbatim — the same char-walk and the same ~4-byte/token divisor as EstimateAnthropicTokens — so a doc floor can never drift from the estimator #3230 and the gateway already use.

fak footprint --doc AGENTS.md            # human table, heaviest section first
fak footprint --doc AGENTS.md --json     # schema fak-doc-footprint/1
fak footprint --doc AGENTS.md --top 5    # just the heaviest N
fak footprint --doc CLAUDE.md            # the resident half of the same pull chain

The section is the report’s unit because the lever this epic wants is “page this subsection out to a queryable store”, and a section is the smallest thing that can be relocated without breaking a link.

Two reading rules for the table below:

Measured inventory after paging the refusal cookbook

Regenerate from the repository root:

fak footprint --doc AGENTS.md
fak footprint --doc AGENTS.md --json

Post-trim result on 2026-08-23:

doc-footprint: AGENTS.md · 13301 est. tokens (49882 bytes, ESTIMATED, instruction-pulled) · 17 section(s)
EST. tokens Bytes Share Section
6,075 22,782 45.7% Hard rules
1,528 5,733 11.5% New work defaults
1,465 5,495 11.0% Build / test / run
1,158 4,343 8.7% Which build am I asking about?
754 2,830 5.7% Planning
557 2,091 4.2% Releasing
431 1,617 3.2% If the kernel refuses you

The refusal section fell from 36,028 B / 9,608 estimated tokens to 1,617 B / 431 estimated tokens: 22.3× smaller. Whole-file AGENTS.md fell from the immediately-preceding 83,681 B / 22,314 estimated tokens to 49,882 B / 13,301 estimated tokens: 1.68× smaller. The section now carries only the preventive commit-lane rules, one-hop query commands, setup check, and appeal route.

Follow-on Hard-rules trim (#8698)

The next pass reduced Hard rules from 22,782 B / 6,075 estimated tokens to 6,036 B / 1,609 estimated tokens: 3.77× smaller. Whole-file AGENTS.md is now 33,136 B / 8,836 estimated tokens, a 2.53× reduction from the 83,681 B / 22,314-token pre-cleanup baseline. Preventive invariants remain inline; detailed runbooks stay behind their linked project verbs and documents.

Whole-file 3× threshold (#8705)

The final orientation, build, new-work, release, and planning pass reduced whole-file AGENTS.md to 21,769 B / 5,805 estimated tokens: 3.84× smaller than the 83,681 B / 22,314-token pre-cleanup baseline and below the 7,438-token 3× target. Shared-trunk, native-inference, proof, commit, scratch, private-control, Windows, and external-write invariants remain inline; detailed procedures remain one hop away.

Recovery stays queryable

The removed table duplicated the authoritative [reasons.*] records in dos.toml. Every actual refusal row in the old table already resolved through:

dos man wedge <TOKEN> --explain
fak recover <TOKEN>

dos man wedge OFF_TRUNK --explain returns the category, detailed fix, and references; fak recover OFF_TRUNK returns concrete dry-run commands. Apparent missing items in older counts were not refusal reasons: ENOENT is an OS error, DENY is a journal outcome, and FAK_CHURN_BURST_THRESHOLD / FAK_RATELIMIT_MIN_429 are tuning environment variables. No reason-record migration was necessary.

Fan-out effect

A 15-agent run pays the instruction-pulled floor once per agent. At that width, the whole-file floor drops from about 334,710 to 199,515 estimated tokens, while the refusal slice drops from 144,120 to 6,465 estimated tokens. These are house-estimator values, not provider-billed measurements.

What is deliberately NOT gated here

There is still no ratchet on AGENTS.md bytes; this page records measured reductions rather than defining a policy ceiling. internal/mcpfootprint/floorgate.go earns its FLOOR_BUDGET_STALE direction precisely because a ceiling pinned at today’s number banks today’s bloat: the gate would have defended 49,882 B as acceptable. The current 21,769 B baseline is now a defensible input for a separate ratchet; pin the ceiling at the post-trim number. Until then this page is a dated measurement, not a contract, and the regeneration command above is how a reader gets a current one.

Witness

Open follow-ons

The cookbook and Hard-rules paging are complete. A separate ratchet can now pin the post-trim ceiling without banking the old bloat.