Skip to content

docs(specs): audit all 24 specs against the code - #476

Open
nedtwigg wants to merge 3 commits into
mainfrom
spec-tighten
Open

docs(specs): audit all 24 specs against the code#476
nedtwigg wants to merge 3 commits into
mainfrom
spec-tighten

Conversation

@nedtwigg

Copy link
Copy Markdown
Member

One agent per spec, fanned out across all 24, verifying every above-the-fold
claim against the implementation. Goals were to shrink the specs, remove
redundant code comments, correct drift, and fix bugs that surfaced along the
way.

Specs net −218 lines (+3,259 / −3,477). That number understates the work:
most agents cut heavy duplication and spent it back on invariants that were
missing entirely. Biggest shrinks were layout.md (−90), mobile-terminal-ui.md
(−61) and terminal-state.md (−38); remote-security-model.md deliberately
grew, being the one place accuracy clearly outweighed brevity.

Recovered lost documentation

Commit afbf9b9b ("keep a minimized browser surface's DOM alive by parking it")
accidentally replaced three whole sections of tiling-engine.md — the wall
store, the LathHost adapter, and the 273-line animator — with the new Parked
leaves section. Five source files and layout.md still pointed at those section
names. Restored, rewritten against current code.

Corrections that would have misled someone acting on them

Spec Was Actually
remote-security-model.md, SECURITY.md Editing the ACL revokes at the client's next authorizeConnection The Host snapshots the store at startup — a restart is required. You'd have believed a device was revoked while it still had access.
vscode.md Deactivate teardown ordering Documented backwards, in the one place ordering bugs silently lose sessions
deploy.md APPLE_SIGNING_IDENTITY, APPLE_TEAM_ID are secrets Neither exists anywhere in the repo; APPLE_ID was mislabeled as one; a required makensis prerequisite was missing
4 specs Scrollback is persisted and replayed on restore Never persisted — normalizeSessionV3 actively scrubs the field
remote-api.md One WebSocket per session bound to a sessionId No sessionId exists; the Host multiplexes every session over one relay socket keyed by clientId
dor-browser.md The iframe proxy strips frame-blocking headers Drops the entire CSP — the injected shim is an inline script — so the upstream loses its own XSS policy inside the frame
glossary.md (I4) Registry: Orphaned is transient A minimized terminal sits Orphaned indefinitely, breaking the stated leak signal
dor-cli.md Never documented ELECTRON_RUN_AS_NODE=1, without which dor under VS Code launches Electron's GUI, ignores the script, and exits 0

Also newly documented because they lived in no spec: MAX_TERMINAL_DIMENSION
(the clamp on peer-supplied terminal sizes), OSC_INCOMPLETE_LIMIT (the OSC
parser's only unbounded-growth guard), and the input-side report filters that two
other specs already pointed at.

Bugs fixed

  • KillConfirm.tsx — the confirm alphabet excluded x so the kill shortcut
    couldn't accept its own prompt, but k is equally a kill shortcut
    (handle-pane-shortcuts.ts:81) and was still in the set. Double-tapping k
    confirmed the kill ~1/25 of the time.
  • lib/.storybook/themes.ts — skipped flattenSelectionAlpha(), so stories
    under Selenized/Solarized rendered translucent header and AppBar fills the app
    never shows. No story pins those themes, so no snapshots change.

Housekeeping

Promoted dormouse.focus above the fold in vscode.md (it was under ## Future
while fully contributed and registered), repointed five stale "Host webview CSP"
references to that section's current name, and removed ~40 redundant or stale
code comments — including a false one claiming PasskeySetupFields is used in
two places when it has exactly one caller.

Left for a decision, not changed here

Both are behavior changes wanting a visual review or a product call, not
documentation fixes.

Verification

pnpm test green: all 4 lints (spec-lint 24 specs, xterm-lint,
loopback-lint, deploy-lint + selftest) and 2,555 tests across 9 packages.

🤖 Generated with Claude Code

https://claude.ai/code/session_01H9HtFUodtF1UsWX6UpRwnn

nedtwigg and others added 3 commits August 28, 2026 16:33
The alphabet already excluded `x` so that double-tapping the kill shortcut
could not accept its own confirmation prompt. But `k` is equally a kill
shortcut — `handle-pane-shortcuts.ts:81` fires on `e.key === 'k' || e.key
=== 'x'` — and it was still in the set, so double-tapping `k` confirmed the
kill roughly 1 time in 25.

Found while auditing docs/specs/shortcuts.md against the code.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H9HtFUodtF1UsWX6UpRwnn
`applyTheme()` runs `flattenSelectionAlpha()` so the list-selection colors,
which Dormouse uses as solid fills, are composited over the sidebar
background. Storybook built its maps with `completeThemeVars()` alone, so
stories under the four bundled themes that carry alpha there (Selenized,
Solarized) rendered translucent header and AppBar fills the app never shows.

No story pins those themes today, so no snapshots change.

Found while auditing docs/specs/theme.md against the code.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H9HtFUodtF1UsWX6UpRwnn
Fanned out one agent per spec to verify every above-the-fold claim against
the implementation, cut duplication, and correct drift. Specs net -218 lines
(+3259 / -3477); most agents cut restatement and spent it back on invariants
that were missing entirely.

Recovered lost documentation: commit afbf9b9 accidentally replaced three
whole sections of tiling-engine.md — the wall store, the LathHost adapter,
and the animator — with the new Parked leaves section. Five source files and
layout.md still referenced them by name. Restored against current code.

Corrections that would have misled someone acting on them:

- remote-security-model.md and SECURITY.md both said revoking a device by
  editing the ACL takes effect at its next authorizeConnection. The Host
  snapshots the store at startup, so a restart is required — you would have
  believed a device was revoked while it still had access.
- vscode.md documented the deactivate teardown ordering backwards, in the
  one place where ordering bugs silently lose sessions.
- deploy.md's secrets table named two secrets that exist nowhere in the repo
  (APPLE_SIGNING_IDENTITY, APPLE_TEAM_ID) and mislabeled APPLE_ID as one. It
  also omitted a makensis prerequisite the signing script hard-requires.
- Four specs claimed scrollback is persisted and replayed. It never is;
  normalizeSessionV3 actively scrubs the field.
- remote-api.md described the wrong protocol topology: a per-session
  sessionId that does not exist. The Host multiplexes every session over one
  relay socket keyed by the relay-assigned clientId.
- dor-browser.md said the iframe proxy strips frame-blocking headers. It
  drops the entire CSP, because the injected shim is an inline script — so
  the upstream loses its own XSS policy inside the frame.
- glossary.md I4 called Registry: Orphaned transient; a minimized terminal
  sits Orphaned indefinitely, which broke the stated leak signal.
- dor-cli.md never documented ELECTRON_RUN_AS_NODE=1, without which `dor`
  under VS Code launches Electron's GUI, ignores the script, and exits 0.

Also promoted dormouse.focus above the fold in vscode.md, repointed five
stale "Host webview CSP" references to the section's current name, and
removed ~40 redundant or stale code comments across the tree.

Two findings left for a decision rather than changed here: #474 (body
font-size falls back to 16px outside VS Code) and #475 (BrowserSidecarAdapter
persists sessions production drops).

pnpm test green: 4 lints + 2555 tests across 9 packages.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H9HtFUodtF1UsWX6UpRwnn
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying mouseterm with  Cloudflare Pages  Cloudflare Pages

Latest commit: b465d4a
Status: ✅  Deploy successful!
Preview URL: https://05a6c46a.mouseterm.pages.dev
Branch Preview URL: https://spec-tighten.mouseterm.pages.dev

View logs

@dormouse-bot dormouse-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I spot-checked the audit's load-bearing claims against the code rather than the prose, and they hold: the ACL snapshot (loadAcl: () => records handed to RemoteHost once in RemoteHostService.#startHost, so an edit really does need a restart), the deactivate() ordering, normalizeSessionV3's scrollback/resumeCommand scrub, clientId-keyed multiplexing with no sessionId anywhere in wire.ts, instrumentHtml dropping the whole in-document CSP, Orphaned outliving a minimized pane, the ELECTRON_RUN_AS_NODE=1 set inside both dor launchers, and the missing APPLE_SIGNING_IDENTITY / APPLE_TEAM_ID (APPLE_ID is a literal in sign-and-deploy.sh). Every backticked constant the specs newly cite resolves, and the numbers match (MAX_TERMINAL_DIMENSION 2000, OSC_INCOMPLETE_LIMIT 16 KiB, PANE_GUTTER_PX 7, LATH_MOTION_MS 440, PAIRING_PRESENCE_WINDOW_MS 30s, WS_CLOSE_HOST_REPLACED 4000, MAX_PARKED_SURFACES 8). Both behavior fixes check out: handleKillConfirm hijacks every key so k/x were the only self-accepting chars, and the four alpha-carrying themes (Selenized/Solarized × light/dark) are pinned by no story, so the Storybook flatten is snapshot-neutral. The poppedOut field removal is safe — nothing writes it into params; this.poppedOut = params.renderMode === 'ab-popout' is the only producer.

Four dangling section pointers, all the same class of staleness the PR set out to fix — renamed or deleted headings whose referrers weren't repointed. None are on a diff line, so no inline suggestions; happy to push a commit with these if you want it.

1. SECURITY.md:11 and docs/specs/server.md:1042 point at a heading this PR deleted. The diff removes ### Server deployment modes from remote-api.md, folding it into one sentence under ## Transport. Both referrers survive:

  • SECURITY.md:11Two deployment modes are defined (`docs/specs/remote-api.md` → "Server deployment modes")
  • docs/specs/server.md:1042model are unchanged from selfhost ([remote-api.md](./remote-api.md), Server deployment modes)

Both files are edited by this PR, so the rename sweep reached them but not these lines. remote-api.md → "Transport" is the surviving home.

2. docs/specs/server.md:1044 cites content this diff deleted. The saas-multitenant scope says the SaaS account model is staged in remote-api.md:

Complementary front-door work is staged elsewhere and this scope does not restate it: the SaaS account model (email + passkey self-serve signup) in remote-api.md

The deleted Server deployment modes bullet was the only place remote-api.md described email + passkey self-serve signup; what's left there is only how accounts come to exist differs, which doesn't say how. Per AGENTS.md's "a scope is defined in exactly one spec; other specs link to it by name and never restate its contents", the scope now links to nothing — either restore the account-model sentence in remote-api.md or move it into this scope.

3. lib/src/index.css still names the pre-restore heading. The .lath-host block comment reads The HTML adapter for Lath (docs/specs/tiling-engine.md → "Adapters"). tiling-engine.md's restored heading is ## The HTML adapter (LathHost) — the same repoint LathHost.tsx got in this diff.

4. lib/src/components/MobileTerminalUi.tsx points at a heading this diff removed. In the blur-retry callback: repeat across rAF and a few staggered ticks. See mobile-terminal-ui.md (Touch interactions). The diff drops ## Touch interactions; that exact rule now lives under ## Keyboard focus invariant ("Since Wall may defer xterm focus to requestAnimationFrame, the wrapper repeats that blur across a rAF and staggered timers"). The file is in the diff, so this one was in reach.

Notes
  • Checked mechanically: extracted every spec.md → "Section", spec.md (Section), and spec.md §Section reference from .ts/.tsx/.css/.mjs/.sh/.rs and from the specs themselves, and resolved each against the actual heading set. Findings 1, 3, 4 came out of that; finding 2 was a follow-on from reading the deleted hunk. All other references resolve, including the five repointed "Host webview CSP" sites and the "Animation contract""Animation" rename.
  • pnpm lint:specs now fails on a pre-install checkout: docs/specs/webgl-text.md:14 backticks canopy/node_modules, which spec-lint.mjs requires on disk. canopy is a workspace package so pnpm install creates it and CI is unaffected — flagging only because lint:specs is documented as a standalone command.
  • docs/specs/server.md also overlaps with #472, which edits it; no conflicting content that I could see, but they'll want ordering.

@dormouse-bot

Copy link
Copy Markdown
Collaborator

Heads-up on a conflict, not a review comment: #478 edits the same docs/specs/theme.md paragraph this PR rewrites, and the two versions differ in what they say rather than only in wording.

#478 fixes a real bug — --mt-font-size was declared at document level while the --vscode-font-size it reads is written to body.style, so body { font-size: var(--mt-font-size) } was invalid-at-computed-value-time and body inherited the UA 16px. Alongside the one-line CSS fix it widens lib/src/lib/themes/consumed-keys.test.ts into a guard that fails when a theme.css token whose value contains any var() chain isn't declared with the same value at both document and body level. The paragraph in #478 states that rule; this PR's condensed version ("the parallel @theme declarations exist so Tailwind can generate utility classes, but the body-level ones are the runtime source of truth") plus the checklist bullet state the intent but not the enforced condition, and don't mention the typography tokens.

So if the conflict gets resolved toward this PR's wording, the spec loses the sentence describing a test that will fail people. Taking #478's paragraph for that one block and this PR's edits everywhere else keeps both. Nothing else collides — this PR's lib/src/theme.css hunks are comment rewrites inside @theme, above the body block #478 touches.

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