Review follow-up. provenLocalCallee inferred file-local calls from module
scoping but borrowed non-exportedness from its one caller and never checked
module-ness: a helper in a global script file (no import/export) is
program-visible and callable cross-file with no same-file reference, so the
proof passed and those call sites were dropped as silently missing matrix
cells. Guard both premises at the proof entry, failing toward the global
fallback.
- State the EVENT_API_METHODS obligation: a visitSource branch for an
unlisted method name is dead because the prefilter drops the call first.
- Add gen-doc-graphs.spec.ts pinning fast path vs global fallback equivalence
on fixture programs: a proven-local helper, an alias-escaping helper, and a
global-script helper (negative control that keeps the fallback exercised).
- Record the demand-driven indexing decision in the Program-backed semantic
gates Agent Note (both languages, pairing re-recorded).
Generated docs stay byte-identical (verify-doc-graphs green).
- .loadingFloat moved after the .status/.error block (its padding was
losing the same-specificity race) and re-anchored bottom-right: the
truncated/error rows own the bottom left and keep rendering through a
scan, so the pill can never cover them; confirmCreate's relist now
clears the stale failure text like every other scan launch.
- The close edge resets loading, so the slow-scan effect disarms while
hidden and a reopened dialog waits out a fresh silence window
(regression test added).
- The truncated note's survival through a scan is now asserted in the
slow-scan test; the wait-bound test moved to fake timers with the
200ms bound explicit.
- select()'s exemption from the one-frame rule and the constants' local
calibration premise are recorded in JSDoc and the capability-seam
Agent Note; the themed-scrollbars note's rebinding enumeration is
replaced by a pointer to the mechanical gate (it had drifted twice).
Both pairs re-recorded.
Navigations keep the previous view rendering while scanning: target and
parent legs land as one two-pane frame when the parent leg settles within
a 200ms wait bound (past it the target lands alone and the late leg
upgrades in place; Escape inside the landing window withdraws the
navigation). The loading indicator floats over the content on the card
background and appears only once a scan outlives a 300ms silence window,
so navigation never shifts the columns or flashes an intermediate frame.
The truncated note now describes the on-screen panes instead of hiding
during scans.
fix(web): keep one composer bar DOM across the no-workspace transition
The composer.bar slot moves from session to session-maybe scope: with no
current session the entry still mounts, the machine faces (keyboard, stop,
command) arrive undefined, and the bar renders its normal DOM inert via the
disabled owner prop. DisabledInputBar and its parallel tree are gone, so the
textarea node survives the cold-start workspace pick instead of flashing
through a remount. A blank session whose workspace was deleted takes the
same inert path through owner props.
test(web): add the composer DOM-continuity acceptance probe
Drives a real dsh web server with headless chromium through the cold-start
-> pick-workspace -> type flow and asserts the composer textarea is the
same DOM node throughout (a marker property must survive). Rerun
prerequisites are in the header comment.
docs(web): session-maybe identity is adoption, not hold-forever
fix(web): session-maybe entries adopt the first session, then remount like strict entries
A session-maybe entry used to keep one React instance across every
transition, so component-local state leaked between sessions once the
composer bar moved to that scope (PermissionSelect's optimistic pick, the
IME composition guard). Identity is now adoption: an incarnation born
session-less holds through the arrival of the first session (the blank
shell's DOM survives the workspace pick), and afterwards behaves exactly
like a strict session entry — a switch or a drop to no-session remounts,
clearing local state by construction. The child key is an incarnation
counter kept in the stable outlet wrapper via render-phase setState.
chore: knip knows the root acceptance probe's playwright dependency
scripts/hero-composer-dom-continuity.mjs resolves playwright through
apps/web's devDependency tree (createRequire), which knip cannot follow;
ignore it at the root workspace.