Skip to content

docs(specs): the house form — corpus-wide spec compression and the word-budget ratchet - #488

Merged
nedtwigg merged 17 commits into
mainfrom
spec-compress
Aug 30, 2026
Merged

docs(specs): the house form — corpus-wide spec compression and the word-budget ratchet#488
nedtwigg merged 17 commits into
mainfrom
spec-compress

Conversation

@nedtwigg

Copy link
Copy Markdown
Member

Follow-up to #487: the corpus-wide compression pass. #487 moved the forensic evidence out; this PR changes how the remaining normative text is written and pins the corpus against regrowth.

The house form (AGENTS.md)

Three convention additions, ~150 words total: a rule leads with a bolded imperative (Never … / Must … / May …) plus at most one clause of why — the bold carries the emphasis, so scaffolding words ("deliberately", "note that") are deleted; rule lists, ladders, and flows render as invariant bullets or tables, not narrative; mechanism constraining a single module lives as a comment at that code (spec keeps rule + Source of truth:), while cross-file mechanism stays in the spec. Plus the front-matter norm: a spec's opening blockquotes state ownership once (Owns / Defers / read-first), replacing per-section re-disclaimers, and the glossary callout licenses bare use of glossary terms.

The pass

Piloted on transport.md, then 20 specs via parallel per-spec passes, each verified against a full deletion ledger (every dropped clause classified: scaffolding-deleted / moved-to-rationale / moved-to-code-comment / restated-in-table / deduped-to-owning-spec) before landing. Nothing moved to a code comment required writing one — in every case the module already carried the mechanism verbatim, so the spec-side text was a duplicate; the one exception is a 3-line addition in alert-speech.ts and one nuance added to lib/.storybook/preview.ts, where the three Chromatic caveats compressed out of layout.md now point.

Spec Before → after Notes
layout.md 10,625 → 9,984 front-matter Owns/Defers; + fold fix (below)
vscode.md 11,197 → 10,874 recovery constants stay inline beside what they size
alert.md 8,573 → 8,350 sanitization/security untouched
server.md 8,250 → 8,019 every security check at full force
dor-cli.md 6,917 → 6,607 new dor-cli.rationale.md (571)
tiling-engine.md 6,224 → 6,042 the five-tax Why is now a table
standalone.md 5,953 → 5,689 new standalone.rationale.md (290) — the WebKit-WAL narrative
dor-browser.md 5,379 → 5,151 new dor-browser.rationale.md (665)
transport.md 5,300 → 5,242 the pilot
mouse-and-clipboard.md 5,092 → 4,730 section numbers untouched
terminal-escapes.md 4,452 → 4,332 tables untouched
9 thin specs −458 combined light pass, batched

Spec bodies shed −3,392 words net; the three new rationale files add 1,526 of quarantined (pruneable) evidence. Excluded on purpose: glossary.md (definitional — its density is its content), shortcuts.md (already a table), dor-tool.md (design-stage, all ## Future), SELF_HOST.md (runbook; deferred again, same call as #487).

Every heading in every spec is byte-identical to main — cross-spec anchors, rationale keying, and the mouse-and-clipboard § numbers all hold.

The ratchet (new lint check)

scripts/spec-word-budgets.json gives every spec, rationale file, and AGENTS.md a word budget (current size + 25–75 words headroom); spec-lint fails on growth past it, on a new file with no budget, and on a stale entry. The fix is spelled out in the failure: cut, or raise the budget deliberately in the same PR. No selftest — like the other presence/threshold checks, it was mutation-tested by hand (over-budget, missing entry, stale entry all fire).

Accuracy fixes the pass surfaced

  • layout.md stated the Window-snapshot persistence (flag-on behavior) unconditionally above the fold — now qualified by dormouse.flags.workspaces.
  • tutorial.md pointed TutorialShell at a section that never mentions it (Architecture → Layout).
  • Five code comments cited a spec heading "Headed Pop-Out" that doesn't exist (the heading is "Pop-Out").
  • alert.md carried a latent contradiction ("the two places" vs "the only place" a closed pane's WATCHING rule can be removed) — deduped to one statement.

Follow-up seeds (not done here)

Natural first entries if these opt-in rationale files are ever opened: pocket-app.rationale.md (the SPA-fallback incident, push-endpoint rotation), theme.rationale.md (the Kimbie Dark block, two dead-approach stories), auto-update.rationale.md (the Design-decisions Q&A), deploy.rationale.md (the security-audit job's dead-approach notes).

🤖 Generated with Claude Code

https://claude.ai/code/session_01TFmGuuAAEc7UvCc1WhtQeu

nedtwigg and others added 17 commits August 30, 2026 15:07
Three additions ahead of the corpus compression pass: rules lead with a
bolded imperative and at most one clause of why (the bold replaces the
rhetorical scaffolding); rule lists, ladders, and flows render as bullets
or tables rather than narrative; single-module mechanism moves to a
comment at that code while cross-file mechanism stays in the spec. Plus
the front-matter norm: a spec's opening blockquotes state ownership once,
and the glossary callout licenses bare use of glossary terms.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TFmGuuAAEc7UvCc1WhtQeu
Bold imperatives absorb the rhetorical scaffolding (must preserve / must
mirror / must not require), two restating sentences deleted, and one
production-cost clause moved to the rationale file. transport.md was
already near house form after the rationale split, so the shed is small
by design — the pilot demonstrates the marker style for the corpus pass.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TFmGuuAAEc7UvCc1WhtQeu
Bold imperatives absorb the scaffolding (must ship / must revalidate /
never advertise / must fail inertly), two cross-section dedupes point at
the surviving copy, Source of truth lines consolidate at section end,
and the strip-only remote parser paragraph sheds prose already carried
verbatim by pty-strip.ts's own comments. Registry tables untouched.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TFmGuuAAEc7UvCc1WhtQeu
Light pass: scaffolding adverbs deleted, rules promoted to bold
imperatives (never parse the user-agent string; every peer-supplied
dimension passes clampTerminalDimension; no single layer is sufficient),
the pairing ceremony rendered as a numbered list, and two cross-spec
duplicates deduped to the owning spec. Every trust statement, ceremony
step, wire shape, Reserved: paragraph, and the protocol-v1 scope block
untouched; the same-origin deployment rule now leads its section.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TFmGuuAAEc7UvCc1WhtQeu
Bold imperatives absorb the scaffolding across the Await ladder, WATCHING
invariants, and completion-event ordering (never reorder 3 and 4; a
retired id must stay retired; a failed await absorbs nothing); two
ordering rules and the detector invariants become bullets; Source of
truth lines consolidate at section end; three speech-teardown mechanism
clauses land where alert-speech.ts's own comments already carry them,
plus one new comment absorbing the token-clearing rule. The sw.js
boundedPushText mirror now names its pinning test. Text And Security
untouched.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TFmGuuAAEc7UvCc1WhtQeu
Bold imperatives absorb scaffolding across the guardrails, connect-src
enforcement, and store contract; four narrative clusters (enforcement
points, push-subscription rules, store contract, the four connect
checks) become bullets; Source of truth lines consolidate per section;
two mechanism restatements drop where host-status-store.ts and
activation.ts already carry them, and one lifecycle-chain why moves to
the rationale file. Every security check, ordering rule, and the
final-authority statement keep full force; tables and the
saas-multitenant scope untouched.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TFmGuuAAEc7UvCc1WhtQeu
The five-tax Why becomes a table naming each owning section, the DnD
gesture and restore-token degradation paragraphs become invariant
bullets, front matter gains Owns/Defers blockquotes, and five mechanism
restatements shrink to rule + pointer where the constraining modules
(cumulativeRound, setLayoutGeometry, admit, OVERLAY_COMPONENTS, slope)
already carry the mechanism in comments. The zero-size parking why moves
to the rationale file; the cross-file StrictMode trap stays inline. All
headings and the acceptance matrix untouched.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TFmGuuAAEc7UvCc1WhtQeu
Front matter gains the ownership line, the override-ending paragraph
becomes three invariant bullets, rules promoted to bold imperatives
(must defang the bracketed payload; never filter the unbracketed branch;
never reuse the cmd rule; every spawn must pass windowsHide), five
mechanism restatements shrink to rule + pointer where the router,
clipboard, and observer modules already carry them verbatim, two
cross-spec duplicates dedupe to their owning specs, and three Files
rows trim to short roles. Section numbers, matrices, and both leading
blockquotes untouched; shell-escape.test.ts and clipboard.test.ts named
as pins.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TFmGuuAAEc7UvCc1WhtQeu
…al, mobile-terminal-ui

Light pass over four already-dense specs: rules promoted to bold
imperatives, terminal-state's Grouping section restructured into
invariant bullets with one consolidated pointer, cross-spec duplicates
deduped to the owning spec (the keystroke-fallback limitation to
alert.md, the Pocket override rule to mobile-terminal-ui.md), one
git-history self-citation deleted outright, and a wrong section pointer
in tutorial.md fixed (TutorialShell is introduced under Layout, not
Architecture). Priority chains, localStorage keys, hook contracts, the
coverage matrix, and both consumed-keys pin references untouched.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TFmGuuAAEc7UvCc1WhtQeu
deploy.md and webgl-text.md gain front-matter blockquotes stating
ownership once; release-pipeline rules become bold imperatives (never
--deep-sign the outer .app; dispatch, never uses:; never select
artifacts with a broad find | head). auto-update.md's shed is pure
dedupe — two why-paragraphs were verbatim copies of sections that own
the rules — and the Windows sidecar-teardown section reorders so the
rule leads with the full ConPTY chain preserved. Checklist steps,
verification checks, the secrets table, the Reserved: texel paragraph,
and every xterm-lint reference untouched.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TFmGuuAAEc7UvCc1WhtQeu
Front matter grows Owns/Defers/Convention blockquotes absorbing the
ownership disclaimers six sections repeated; swap semantics dedupe to
one canonical statement; the save-trigger ladder becomes bullets; rules
promote to bold imperatives (never inherit a remote cwd; never measure
the overflow arrow into the fit; never reintroduce per-frame React
state; fallback must stay automatic). Three mechanism restatements
shrink to rule + pointer where cornerPath, acceptKill, and the
Baseboard right-cluster comment already carry them; the Renderer
lazy-claim why moves to the rationale file; three Chromatic caveats
compress to one-line preview.ts pointers. Also fixes a fold error the
pass surfaced: the Window-snapshot persistence sentence stated flag-on
behavior unconditionally — now qualified by dormouse.flags.workspaces.
Corner-case numbers, headings, ASCII tree, and Future untouched.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TFmGuuAAEc7UvCc1WhtQeu
Front matter splits into Owns/Defers blockquotes absorbing the repeated
transport deferrals; the VS Code invariants and peer-link rules promote
to bold imperatives (never let a resuming router steal a PTY; never key
routes by a raw ptyId; never unify the two reply budgets; never widen
the stub); the fixture-limit and WebSocket-boundary archaeology move to
the rationale file; the socket-identity mechanism shrinks to rule +
pointer where peer-link.ts already carries it. Every recovery-timing
constant stays inline beside what it sizes, and every security sentence
in message authentication survives verbatim.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TFmGuuAAEc7UvCc1WhtQeu
First pass for this spec: timing derivations, cold-boot narratives, and
the stray-blank-tab race move to a new dor-browser.rationale.md (three
headings); parking and input rules become invariant bullets; the host
capabilities become a Method/Contract table; rules promote to bold
imperatives. The iframe proxy / CSP / shim security material stays at
full force. Also fixes five code comments citing a heading (Headed
Pop-Out) that does not exist — the spec heading is Pop-Out.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TFmGuuAAEc7UvCc1WhtQeu
First pass for this spec: symptom strings (the Windows verbatim-path and
CRLF failures), the sun_path byte arithmetic, the POSIX double-fork
explanation, and the skill-stub dead approach move to a new
dor-cli.rationale.md; front matter gains ownership blockquotes; rules
promote to bold imperatives (never forward a literal %VAR%; every valid
request must preserve the deadline ladder; read/send/kill must not grow
their own match syntax); the browser-open dispatch becomes a table. The
spawnAndCapture contract stays at full force, and the proof-domain sync
claim now names mirrored-constants.test.ts.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TFmGuuAAEc7UvCc1WhtQeu
First pass for this spec: the WebKit-WAL measurement narrative, the old
teardown-flush loss, and two cost clauses move to a new
standalone.rationale.md; the three not-forwarded bridge carve-outs
become a table; the dirty-gated write ladder becomes six invariant
bullets; four store-contract clauses dedupe to server.md's generic
contract; the (async) freeze story, DefTerm evidence, and DACL detail
shrink to rule + pointer where lib.rs, build.rs, and shell-store.ts
already carry them verbatim. The beforeDevCommand caveat, quit-flow
ordering, and mirrored-constants reference untouched.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TFmGuuAAEc7UvCc1WhtQeu
The three Chromatic caveats compressed out of layout.md point here; two
reasons were already in these comments verbatim, and this adds the one
missing nuance — the author !important outranks inline transition
declarations, so a finished unfocus-saturate fade in a snapshot is
expected, not a regression.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TFmGuuAAEc7UvCc1WhtQeu
…AGENTS.md

Every checked file gets a budget in scripts/spec-word-budgets.json —
current size rounded up with 25-75 words of headroom — and growth past
it fails the lint with the fix spelled out: cut, or raise the budget
deliberately in the same PR. Missing and stale entries also fail, so a
new spec must declare a budget and a deleted one must retire it. This is
what keeps the compression from silently regrowing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TFmGuuAAEc7UvCc1WhtQeu
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Aug 30, 2026

Copy link
Copy Markdown

Deploying mouseterm with  Cloudflare Pages  Cloudflare Pages

Latest commit: 723ca88
Status: ✅  Deploy successful!
Preview URL: https://dc46bc1e.mouseterm.pages.dev
Branch Preview URL: https://spec-compress.mouseterm.pages.dev

View logs

@nedtwigg
nedtwigg merged commit 040bb98 into main Aug 30, 2026
13 checks passed
@nedtwigg
nedtwigg deleted the spec-compress branch August 30, 2026 22:46
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.

2 participants