Exact-size ceilings turned every two-word wording fix into a gate
event. The policy amends to: a ceiling sits at least 5% above the
doc's current size (pre-rewrite) and keeps that margin when ratcheted
to target — routine edits pass, real growth still trips the gate.
Amended together in all four policy homes (docs/AGENTS.md § Budgets,
the doc-tiers RFC, the gate script's module comment, the skill's
ratchet rule) plus the manifest values, so prose and mechanics stay
consistent.
The gate joined the doc-sync chain in this PR; the root file's two
enumerations of that chain must name it in the same change. The frozen
ceiling re-records the exact new count (8134).
- The manifest now freezes each budgeted doc at its exact current wc -w
count, matching the documented policy (a ceiling starts at the doc's
current size); the headroom that contradicted the freeze claim is
gone. Post-rewrite ratchets may still land at new-size-plus-headroom,
per the skill's ratchet rule — that is a different moment than the
initial freeze.
- --list now renders MISS/BAD rows for missing files and malformed
ceilings instead of silently dropping them (gate mode already failed
correctly; the report mode no longer under-reports).
Maintainer decision: the subagent seam's deferred capability vocabulary
(outputSchema/structured, toolFilter, sendMessage/resume) is
intentionally reserved — the seam advertises the full intended contract
ahead of its implementations so providers and consumers grow into a
stable shape. Moved to rejected/ with the rationale on the status line;
the consumer-evidence analysis stays as the record of what is currently
unimplemented.
Standing docs accrete a paragraph per PR with nothing pushing back; the
root AGENTS.md reached 8,130 words in 50 commits with the same rule
stated two and three times. This encodes the counter-pressure:
- docs/AGENTS.md becomes the documentation standard: the tier taxonomy
(one home per fact), target word budgets, and the slop checklist.
- verify-doc-budgets joins doc-sync: word ceilings for the six
accretion-prone standing docs, manifest-driven, frozen at current
sizes and ratcheted down as each doc is brought to target.
- .agents/skills/dsh-doc-standards: the thin placement/audit/red-gate
workflow over the standard, mirroring the dsh-translate-docs split.
- RFC (implemented/process) records the decision, alternatives, and
the first audit cycle's deferred work list.
The gate's first catch was the standard itself (1,057 > 1,000); it
ships condensed to 984 words rather than with a raised ceiling.
The fold-stdio RFC claimed the two e2e doc comments and packages/README
were the only non-runtime references; the package name also appears in
the generated module graph, sibling READMEs, and tsconfig references —
rescope the sentence to the runtime-importer census (the load-bearing
claim) and fold the mechanical references into the update list. The web
RFC's status-caller census now says 'the web packages' own tests'
(the seam's tests use the methods too, not only provider tests).
Deduplicate the parallel sweep from codex/exhaustive-simplification-rfcs
(merged in the parent commit) against the twelve RFCs already here, on
the merits per item:
Ported (rewritten to this set's evidence standard):
- fold-stdio-ui-helper — verified: dsh-stdio-agent is the only runtime
importer; the fold resolves the documented product-app-depends-on-
support-package tension. The false acp-agent analogy is replaced with
the real distinction (protocol product surface vs one app's front-door
scaffolding).
- generate-rfc-index-tables — verified: the classification RFC records
rejecting generation; the index tables are the repo's only
systematically conflicting docs region. Process framing made timeless.
Consolidated into existing owners:
- web searchStatus()/fetchStatus()/WebCapabilityStatus (verified: zero
production callers; the tool-web README and architecture.md claims are
drift) → drop-web-providers-change-event, renamed
drop-unconsumed-web-observation-surface.
- hook/result.durationMs (unread, nondeterministic, normalizer-scrubbed)
and the double-defaulted defaultTimeoutMs knob →
tighten-hook-protocol-contract.
- the exercised-but-unadvertised exec.arguments mutation path (a
tool-bash integration shim rewrites through it) → a sanction-or-seal
note in the pre-tool-input-rewrite proposal.
- the dormant-guard critique of subagent depth machinery → recorded in
prune-unimplemented-subagent-vocabulary as the considered-and-rejected
alternative, with the keep sharpened (uncapped-today acknowledged;
wiring the cap is the completion, not deletion). getProvider()/list()
and lastAssistantMessage recorded as examined-and-kept (bash-revert
precedent; observe-enrich recorded keep).
Not ported (with reasons):
- tools/change + system-prompt/change removal — recorded keeps in the
adapter-change RFC, unengaged by the sweep; no new facts.
- LlmService.models() — flagged by both surveys, but two lines with a
plausible consumer: TODO-or-drive-by territory per the RFC bar, not
a proposal.
- SchemaProp.default RFC — already XXX(unused-default)-tagged; the RFC
bar excludes TODO-tracked provisional cleanups.
- PreToolDecision 'ask' removal — FIXME(permissions)-anchored deferral
with the permission system as its named consumer.
- Codex bridge Config.model, merged systemMessages — wire-faithful
tested surface / README-documented deferral.
Their in-code TODO notes (acp-test-harness, hook-snapshot-noise,
catalog-type-links) and the stale hook-prompt-block name fixes ride the
merge unchanged.
Rewrite the hook-protocol RFC's process-relative wording (freshly-landed
/ days-old / week-old) as timeless evidence anchored to the recorded
RFCs, and sweep the same class from the steering, replay-config,
subagent-vocabulary, and vocabulary RFCs. Narrow the fs RFC's acceptance
criterion: replaceAll survives on the request spec and version on other
outcome types by design — name the exact removed surfaces instead of
claiming the spellings vanish.
The branch now bases on the hooks stack (PR #138's head), so every
'in-flight' reference to stack content became a current-state fact.
Audited all nine RFCs + three supplements claim-by-claim against the
merged tree (none invalidated; several strengthened):
- prune-dead-core-spine-surface: describe the landed tools/pre-execute →
dispatch → tools/post-execute pipeline — listeners return Decisions,
the registry builds every result and snapshots it to protect callId,
and a second (mutation-guard) test pins the field; drop the resolved
wait-for-interception hedge; scope the additionalContext ferry out.
- prune-producerless-vocabulary-variants: the ui-stdio fixture migrated
off the continuation trigger (llm-replay is the sole writer now); the
stack's own additions (rejected, prompt/blocked, hook/invoked+result)
all arrived with producers — the admission policy demonstrated live.
- prune-unimplemented-subagent-vocabulary: enrichment landed as
lastAssistantMessage only (agentType was dropped in the stack's own
review — the same judgment this RFC extends); the seam RFC now names
tools/pre-execute deny, which exists, sharpening the re-add path.
- drop-inert-request-knobs / drop-image-content-block /
trim-acp-bridge-unreachable-surface: current-state rewordings (shipped
bridges set no request fields; only compact-basic has explicit image
arms; 13 hook goldens also pin agentInfo).
- generic-long-running-tool-runtime census: second production seam
consumer (hook-protocol runHook: resolve+run, stdin/env, foreground
only — background machinery stays single-consumer); scrub-duplication
blast radius.
- discover-package-inventory: identical 54-entry tsconfig reference
sets; the comparesLog scenario knob (fixture-derivable, like recorded).
- unify-agent-and-session-id: third divergence site (in-process subagent
children mint two UUIDs), the hooks bridge id-lookups, and ui-stdio's
labelBySession map as a consumer that deletes under unification.
New RFCs from the post-stack survey:
- remove-agent-steering-mirror: the last mirror-of-durable event; zero
production listeners; both retention RFCs deferred its fate, and the
'no durable twin' rationale is contradicted by the adjacent append.
- tighten-hook-protocol-contract: producer-less 'native' dialect,
parsed-and-discarded suppressOutput, and hook/result semantics
(truncation + decision-string) defined twice in the bridges instead
of the lib that owns the event.
- single-source-acp-replay-config: cordis.yml/cordis.snapshot.yml differ
by exactly one plugin entry, with no gate on the forced symmetry.
The core-spine RFC's acceptance criterion still asserted all three
surfaces 'appear only in this RFC', contradicting the corrected scope
(runLoop/Inbox stay as package-internal symbols; only the public
re-exports go). Also add the deepseek README image-skip row and the
compact-basic [image]-placeholder row to the image RFC's removal set.
Two overstated evidence claims, reworded to the precise fact:
- prune-dead-core-spine-surface: runLoop has no importer OUTSIDE the
package (its own agent.ts drives the loop with it); the dead surface
is the public re-export, not the function.
- generic-long-running-tool-runtime census: BashTask.done has no
consumer through the public seam, but is production-load-bearing
inside dsh-bash-local (disposal awaits it); only the public
completion surface is single-consumer.
Also fold the reviewer-located doc sites into the removal sets so the
implementing PRs need no re-discovery: the llm/pi-ai/compact-basic
README rows and the adding-an-llm-adapter cookbook line (prefill/image),
the content-block-vocabulary RFC's has-a-home consequence lines
(cache/prefill/image), the tools.md paste + type-equiv manifest row +
tools README row (callId), and the session-surface RFC's
full-rebuild-after-replacement sentence (invalidate).