Skip to content

Correct the theme, website-docs, tutorial, deploy, and webgl specs; fix three small bugs - #714

Draft
nedtwigg wants to merge 7 commits into
specs-dor-auditfrom
specs-website-audit
Draft

nedtwigg wants to merge 7 commits into
specs-dor-auditfrom
specs-website-audit

Conversation

@nedtwigg

@nedtwigg nedtwigg commented Sep 20, 2026

Copy link
Copy Markdown
Member

Spec audit, group 6 (theme / website-docs / tutorial / deploy / webgl-text / AGENTS.md). Stacked on #713 (the spec-audit PRs merge in order #708#715); independent of the alert series. Touches AGENTS.md's lint-table sentence and two Design/Specs duplicates (#711 touches one other AGENTS.md line; both are small).

Commit 1 — docs and comments. Corrections: the lib dev server does not run the consumed-token resolver; no /latest/download/ URL exists (the homepage reads the committed versioned manifest); a stale "fourteen entries" count; localizeSiteLinks appends a trailing slash; the e2e-lint self-test has both mutation kinds; loopback-lint's self-test was unnamed; two tutorial countdown mechanics; a Future paragraph that was shipped behavior; a rationale paragraph backing no rule; the .vsix rides Stage 1's unsigned upload; the canopy pins; and more. Condensed ≈700 words: the Public-doc validation list (13 of 16 bullets restated their owning sections), theme-picker mechanics → the modules, deploy signing mechanics → sign-and-deploy.sh comments, tutorial hook why-clauses → code.

Commit 2 — code.

  • Bug: Pocket Select mode credited the desktop tutorial's cp-override item through the shared storage key; markComplete is now scoped to its own profile.
  • Bug: bump-version.sh accepted a prerelease suffix the signing pipeline rejects only after tag + push + a full CI build.
  • Bug: the tutorial reset copy omitted that the Flappy high score is cleared too.
  • The two --mt-* pass-through tokens deleted; getTerminalTheme()'s 20 hex fallbacks reduced to the rostered bg/fg pair (cursor derives from fg); one countdown guard for both demos; four unread fields stripped from the generated docs JSON and docs.guide.json no longer written; dead tutorial exports removed; xterm-lint now pins the canopy addon/core/commit triple (with its test); redundant invalidate_updates calls dropped; standalone/package.json's unread version removed.

Budgets: website-docs 5050→4800, deploy 1850 (cut to fit), others unchanged.

Deferred: one helper for the four "ensure a shell" entry points; emitting theme-colors.css's body mirror at build time.

🤖 Generated with Claude Code

nedtwigg and others added 2 commits September 20, 2026 00:51
…ork specs

Fixes claims that no longer match the code and moves evidence to the
rationale files so five specs fit under smaller budgets.

Corrections:
- theme.md scopes the "every path resolves consumed tokens" claim to
  shipping hosts and names `pnpm dev:lib` as the exception; the
  same-theme applyTheme no-op is keyed on object identity, not the id.
- deploy.md drops the `/latest/download/` story (the homepage reads the
  committed versioned manifest), names the four files bump-version.sh
  touches, says Stage 1 also uploads the .vsix, and records that the
  release environment gates are GitHub settings no lint can see.
- website-docs.md spells out the trailing slash `localizeSiteLinks`
  adds, drops a per-command rail count that rots, rewords the
  README-link rule to follow `linkedFrom`, and moves shipped behavior
  out from under `## Future`.
- tutorial.md names the layout test, stops claiming the detector reads
  `tut-items.ts`, and narrows the `q` shortcut, which is buffer input on
  the reset screen.
- webgl-text.md carries the fork version canopy actually ships.
- AGENTS.md: only two of the sibling lints fail on a missing spec line,
  the e2e self-test mutates in both directions, and loopback-lint has a
  self-test too.

The Door pair tie-break and the rail's command nesting gain comments at
the code that decides them.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Bugs:
- `TutorialState.markComplete` now rejects an id outside its own profile's
  sections. Both profiles share `dormouse-tut-v3`, and Pocket's Select
  mode credits `cp-override` on every mouse-capturing session, so a
  Pocket-first visitor opened the desktop tutorial with that item already
  checked and Flappy one item nearer unlock.
- `bump-version.sh` accepted `X.Y.Z-prerelease`, which `sign-and-deploy.sh`
  rejects — after the bump, commit, tag, push and a full CI build.
- The reset-confirm screen promised to clear the checkmarks and the star
  prompt; it also clears the FlappyTerm high score, and now says so.
- `xterm-lint` check 4 now reads the UpstreamVsFork baseline triple out of
  `GlTerminal.stories.tsx` and `canopy/README.md` and holds it against
  canopy's pins, with self-test cases in `xterm-bump.test.mjs`. It was a
  hand-copy with nothing but a printed reminder behind it.

Simplifications, each removing a second owner of something:
- `getTerminalTheme()`'s 20 hex fallbacks duplicated `REGISTRY_DEFAULTS`
  and had already drifted from it. An unset key is now omitted; the
  background/foreground pair stays as a last resort for `pnpm dev:lib`
  and is rostered in DESIGN.md, and the cursor derives from the
  foreground the way the registry does.
- `--mt-font-size` / `--mt-font-family` aliased two `--vscode-*` vars for
  one consumer, which now reads them directly.
- The generated docs JSON shipped four fields no page reads, and a
  `docs.guide.json` no page imports. Both stop at the write; the
  in-memory result the tests and the lint read is unchanged.
- The generator rewrote site links in `dor/skill.md`, where the spec says
  there are none — it now asserts that instead of silently repairing it.
- `TutRunner`'s `s` guard now spans the whole fake command, so the page's
  own cancel of a live pump and exit timer is gone.
- Dead `tut-items` exports, `standalone/package.json`'s unread `version`,
  a `POCKET_THEME_ID` re-export used as the desktop playground's
  fallback, and a redundant `invalidate_updates`.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Sep 20, 2026

Copy link
Copy Markdown

Deploying mouseterm with  Cloudflare Pages  Cloudflare Pages

Latest commit: ec83937
Status: ✅  Deploy successful!
Preview URL: https://f32d8b33.mouseterm.pages.dev
Branch Preview URL: https://specs-website-audit.mouseterm.pages.dev

View logs

# Conflicts:
#	scripts/spec-word-budgets.json

@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.

Feedback on work in progress — not a merge verdict. Mark it ready for review when you want the full pass.

The spec corrections check out against the code I sampled: localizeSiteLinks's trailing-slash rule matches op 5's new wording, dor/skill.md carries no dormouse.sh URL so buildSkill's new assert won't fire on the current tree, reset() does clear dormouse-flappy-high-v1, the reset screen really does swallow q into the confirm buffer ahead of the q-pops-back branch, and the four version files in the new Versioning rule are exactly the ones bump-version.sh edits. pnpm lint:xterm and node --test scripts/xterm-bump.test.mjs pass here (15/15), and spec-lint is clean apart from two standalone/sidecar/node_modules path failures that come from this checkout having no install.

Two things on the code, both inline. The third is a judgment call:

buildSkill's new throw has no test. The new xterm-lint rule got four self-test cases, on the reasoning you quote in scripts/xterm-bump.test.mjs — "a finding check that never goes red is a claim rather than a control (AGENTS.md -> Specs)". The site-link assert in buildSkill is the same kind of check and gets none, and it's unexercised today precisely because dor/skill.md is clean. It isn't reachable from a test as written, since buildSkill is module-private and reads the real file; lifting the walk into an exported assertNoSiteLinks(blocks, source) would make it a one-case test against a synthetic block tree. Your call whether that's worth the export.

Comment thread website/src/pages/PlaygroundDesktop.tsx Outdated
Comment thread scripts/bump-version.sh Outdated
@nedtwigg
nedtwigg changed the base branch from main to specs-dor-audit September 20, 2026 08:18
nedtwigg and others added 2 commits September 20, 2026 01:58
The `s` alert demo's re-press guard lives on the TutRunner, but the
playground page's pump handle and finish timer are per page. Exiting
`tut` and re-running it, or running `tut` in a second pane, builds a
fresh runner whose cleared guard lets a second demo start while the
first demo's pump and `commandMs` timeout are still live, so the stale
timer finishes the fake command mid-countdown. The page cancels both
again before starting a demo.

Also tighten bump-version.sh's version check to the exact regex
sign-and-deploy.sh validates with, so a leading-zero component such as
`01.2.3` fails at the bump instead of after the tag, push and CI build.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@nedtwigg

Copy link
Copy Markdown
Member Author

The unthreaded generator-test suggestion is fixed in baeebb7: assertNoSiteLinks is exported for a synthetic violating block tree, the new test drives the check red, and website-docs.md names the pinning test. The targeted website tests pass (65/65).

@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.

Feedback on work in progress — not a merge verdict. Mark it ready for review when you want the full pass.

Both inline findings from the last pass are fixed and verified: bump-version.sh now carries validate_version's exact regex from sign-and-deploy.sh, and the page's cancel is back ahead of the pump and finish timer. assertNoSiteLinks is a real control now — visit in website/scripts/docs-parser.js walks every object value, so the synthetic {type: 'paragraph', children: [{type: 'link', …}]} tree does reach the link node and drives the throw. spec-lint is clean here apart from the two standalone/sidecar/node_modules path failures this uninstalled checkout produces.

One inline, on a comment the fix contradicted. One observation on the sibling demo:

The x demo has the same cross-instance gap s just closed. onTriggerCommandExitDemo in website/src/pages/PlaygroundDesktop.tsx pushes its finish timer onto demoTimersRef and never cancels a prior one, and commandExitDemoInProgress() is per TutRunner exactly like busyDemoInProgress(). So the two entrances you identified for s — Ctrl+C out of tut and re-run it, or run tut in a second pane — let a second slowbuild start while the first timer is live, and that stale timer fires finishFakeCommand(adapter, PANE_SPLASH) plus reportRunningCommand() mid-countdown. Since the exit bell is what the demo is showing, the failure is louder here than for s: the bell rings early, against a countdown still showing time left. It's outside this PR's diff and predates it, so it's your call whether it rides along; I can push the cancel if you want it here.

Comment thread website/src/lib/tut-runner.ts Outdated
@nedtwigg

Copy link
Copy Markdown
Member Author

Also fixed the sibling x command-exit replay gap in ec83937. The page now keeps one command-exit timer, cancels it before a new runner starts the demo, clears it when it fires, and clears it on unmount. The tutorial spec records the cross-runner invariant. CI=true pnpm --dir website test passes all 254 tests and TypeScript checking.

@dormouse-bot

Copy link
Copy Markdown
Collaborator

The x fix in ec83937 is sound and verified on the branch head: demoTimersRef is gone with no remaining references, the single commandExitDemoFinishTimerRef is cancelled before a new runner starts the demo, nulled when it fires, and cleared on unmount. pnpm --dir website exec vitest run passes 254/254 here. (pnpm --dir website test's TypeScript half fails in my checkout only because remote-lib-common isn't built — unrelated to this PR.)

The two demos still collide with each other on tut-splash, inside one runner. Both fixes close the cross-runner replay of the same demo. The remaining gap is cross-demo: s's guard and x's guard are independent, so one runner accepts x while the s demo is live and vice versa — and ALERT_DEMO_PANES includes PANE_SPLASH, which is the same pane onTriggerCommandExitDemo runs slowbuild on. The page's two timers are per demo, so neither knows the other owns a live fake command on that pane.

No re-run of tut is needed — s and x are adjacent prompts on the same Alert screen, and commandMs is durationMs + mightNeedAttention + needsAttentionConfirm + 2000, so s's fake command outlives x's whole countdown.

I drove this against the real TutRunner on a FakePtyAdapter, with the page's two handlers transcribed verbatim from PlaygroundDesktop.tsx at ec83937, recording what gets written to tut-splash:

keys tut-splash fake-command sequence
s alone start longtaskexit
x alone start slowbuildexit
s, then x 500 ms later start longtaskstart slowbuildexitexit
x, then s 500 ms later start slowbuildstart longtaskexitexit

Two things go wrong in both interleaved orders: the first demo's command on tut-splash is silently replaced by the second's, and the trailing exit is a command-exit report with nothing running — no start between it and the previous exit.

The fix shape that covers all three cases is one cancel keyed on the pane rather than one per demo: before either handler starts a fake command on PANE_SPLASH, cancel whatever fake command is live there. That subsumes both per-demo cancels already added.

Harness and what I did not pin down

Scratch test (not committed): mount TutRunner on a FakePtyAdapter with onTriggerBusyDemo/onTriggerCommandExitDemo transcribed from PlaygroundDesktop.tsx, navigate Esc + ↓↓ + Enter into Alert, send the keys above, then advance fake timers past commandMs. Both busyLaunches and exitLaunches reach 1 in both interleaved orders, which is the guard-independence result directly.

One gotcha if you reproduce it: FakePtyAdapter.writePty returns early while activeTimers holds the pane, so calling setScenario(id, {name: "none", chunks: []}) on the runner's own pane under fake timers swallows every keystroke. tut-runner.test.ts avoids this by not setting a scenario on the runner pane.

I did not establish the downstream alert-track consequence. Counting COMMAND_EXIT notifications on tut-splash in my harness gave results that moved with alert settings and attention history rather than with the interleave, and x alone rang zero times there, so the harness wasn't measuring what I needed. The pane-level sequence above is what I'm confident in; how loudly it reads in the running tutorial is a judgment I'd leave to you.

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