Skip to content

Correct the glossary, layout, and tiling specs against the code; gate hidden-Wall reveals - #708

Draft
nedtwigg wants to merge 2 commits into
mainfrom
specs-layout-audit
Draft

nedtwigg wants to merge 2 commits into
mainfrom
specs-layout-audit

Conversation

@nedtwigg

Copy link
Copy Markdown
Member

Spec audit, group 1 of several (glossary / layout / shortcuts / tiling-engine). Independent of the alert-system series (#706, #707); it stays clear of the layout.md regions those PRs edit.

Commit 1 — docs. Eighteen inaccuracies fixed against the code (tool Surfaces park on minimize; restore inserts into an empty tree; replace/swap bypass normalize; the marching-ants outline is re-dashed per frame; cfg.marchingAnts.paused is a real pause; createAnimator returns no easing; persistableLeafMeta strips tool fields on save; restore-token fields; stale bare filenames; DRAG_THRESHOLD_PX; and more). Condensed: the Corner cases list (only #2 and #6 are cited externally), Animations/Spawn/Kill restating tiling-engine, the Workspace lifecycle prose blob → bullets, glossary's rollout note and Containers duplicate, the LathHost component inventories → one rule + pointer.

Commit 2 — code.

  • A dormouse:reveal-note-source event was gated on Tool ownership, not on the Wall being active, so a hidden Workspace could mount its Terminal Context and refit a detached element. Gated on active; test leaves a reveal for a hidden Workspace unanswered.
  • Wall showBaseboard deleted (no caller passed false). initialMode kept — the playground uses it.
  • SurfaceView's dead 'hidden' member deleted; it contradicted the glossary.
  • Cross-window tab drag read a stale 180px literal; design.tsx now exports the 220px DOOR_TAB_MAX_WIDTH_PX.

Budgets: glossary 3000→2950, layout 10000→9900, tiling-engine 4500→4650 (corrections outweighed the inventory cut).

Deferred (reported, not done): the header-context-menu choreography move (conflicts with the alert series), one keyboard path for the terminal context, folding the Door array into the Lath store.

🤖 Generated with Claude Code

nedtwigg and others added 2 commits September 20, 2026 00:16
Audit corrections across glossary / layout / tiling-engine, funded by
condensing sections that restated their neighbours.

Corrections:
- restore reinserts into an empty tree; only add/split/insert refuse one,
  and replace/swap write through replaceAtPath rather than normalize
- tool Surfaces park on minimize, keep their session while Doored, and
  resolve body/header/overlay slots through the same registry
- persistableLeafMeta strips a Tool's derived browser fields and demotes a
  pending Tool to a plain terminal, so a restart reloads it as its terminal
- the cold restore path carries the same leaf-set gate as resume, and
  synthesizes a single-row layout when a visible pane is a Tool
- restore tokens carry leafId, write the sibling fields on every non-root
  removal, and consult them only for a multi-leaf sibling
- the marching ants are re-dashed every frame and also pause under
  cfg.marchingAnts.paused; only the smear's non-interference is absolute
- a key inside the terminal context never reaches dual-tap
- a hidden Wall gates every listener that dispatches, forwards, or
  preventDefaults window input, custom events included
- unzoom also fires on selecting a Workspace tab
- rate callers read slope() off cubicBezier/LATH_EASING, not the animator
- corrected Source-of-truth pointers for zoom, window focus, and
  persistence; bare test filenames expanded to repo paths

Condensed: the glossary's rollout note and host-count bullets; layout's
corner cases (only #2 and #6 are cited elsewhere), its restatements of the
tiling engine's DnD and animation models, and the Workspace lifecycle prose.

Budgets: glossary 3000 -> 2950, layout 10000 -> 9950, tiling-engine
4500 -> 4650.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
A `dormouse:reveal-note-source` event was gated on Tool ownership rather
than on the Wall being active, so a hidden Workspace mounted its Terminal
Context and refit a detached element for a pin the user clicked elsewhere.
Gate it on `active`, like every other window listener.

Also drops three things the code carries but nobody uses:
- `Wall showBaseboard`: no caller ever passed false, so the baseboard is
  unconditional and the drag-to-minimize gate goes with it. The mobile
  composition is `MobileWall`, not a baseboard-less Wall.
- `SurfaceView`'s `'hidden'` member: nothing produced it and the `--view`
  filter never accepted it; a Surface in an inactive Workspace stays
  `paned` or `minimized`.
- the 180px literal in the cross-window tab drag, which disagreed with the
  220px `DOOR_TAB_CLASS` bound it was standing in for. `design.tsx` now
  exports that bound and the tab height beside it.

Budget: layout 9950 -> 9900.

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: 52f2d26
Status: ✅  Deploy successful!
Preview URL: https://e126de18.mouseterm.pages.dev
Branch Preview URL: https://specs-layout-audit.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.

Work-in-progress feedback, not a merge verdict — mark it ready when you want the full review.

One suggestion inline, on the one new rule in this pass that doesn't name its test.

Comment thread docs/specs/layout.md
- **A hidden Wall consumes no window input**: every listener it keeps is gated on `active`, so nothing it hears is dispatched, forwarded, or `preventDefault`ed. **Only the active Wall renders the modal hosts and the overlays that trap keys** — the kill confirmation, the refused-archive prompt, a terminal's selection popup (rationale): a staged prompt survives the switch and is answered only where the user can see it.
- **Must preserve mounted leaves across switches**: no re-seed, no re-parent, no leaf unmount, and no `resumeTerminal` / `restoreTerminal`; the only mount work is the terminal reattach below, which replays nothing, so I8 holds by construction (`lib/src/components/WorkspaceWindow.test.tsx`).
- **A hidden Wall's terminals hold no element and no GL context**: completion of the outgoing fade runs `unmountElement` on every terminal pane, exactly as minimize does ([Renderer](#renderer)); activation runs `mountElement` and fits through the [Animations](#animations) gate, so an unchanged grid sends no PTY resize (`lib/src/components/TerminalPane.test.tsx`). Browser Surfaces keep their live documents (rationale).
- **A hidden Wall consumes no window input**: every listener that dispatches, forwards, or `preventDefault`s window input is gated on `active`, keyboard and custom events alike, so a hidden Wall neither mounts chrome nor refits a detached element in answer to one. **Only the active Wall renders the modal hosts and the overlays that trap keys** — the kill confirmation, the refused-archive prompt, a terminal's selection popup (rationale): a staged prompt survives the switch and is answered only where the user can see it.

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.

This is the one rule the audit adds without naming its test, in the pass that gave its neighbours in this section full test paths — and it's also the only rule here whose test the PR writes itself, so there's a name available. AGENTS.md → "Specs": Name the test that pins a rule. The addition is 10 words, leaving layout.md at 9,876 against its 9,900 budget.

Suggested change
- **A hidden Wall consumes no window input**: every listener that dispatches, forwards, or `preventDefault`s window input is gated on `active`, keyboard and custom events alike, so a hidden Wall neither mounts chrome nor refits a detached element in answer to one. **Only the active Wall renders the modal hosts and the overlays that trap keys** — the kill confirmation, the refused-archive prompt, a terminal's selection popup (rationale): a staged prompt survives the switch and is answered only where the user can see it.
- **A hidden Wall consumes no window input**: every listener that dispatches, forwards, or `preventDefault`s window input is gated on `active`, keyboard and custom events alike, so a hidden Wall neither mounts chrome nor refits a detached element in answer to one (`leaves a reveal for a hidden Workspace unanswered` in `lib/src/components/Wall.test.tsx`). **Only the active Wall renders the modal hosts and the overlays that trap keys** — the kill confirmation, the refused-archive prompt, a terminal's selection popup (rationale): a staged prompt survives the switch and is answered only where the user can see it.

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