Repository navigation
test(ui-react): split navigation reach pointer case families - #2434
schlessera wants to merge 2 commits into
Conversation
|
2026-10-19 — #2417 continuation r2, under the parent's existing claim The nine relevant unit failures are repaired in Focused evidence: the original three files reproduce exactly 24 pass / 9 fail. Repaired tests pass 38/38, 181 assertions, with all original assertions retained. Bypassing the document config check fails all four current-document negatives; bypassing worker enforcement fails the real current-config negative even after recomputing the manifest; bypassing the command digest fails its drift guard, and admitting just the actual changed config fails Source equivalence is rechecked: all 62 direct top-level statements / 42 assertion sites and all 43 imported durable-suite statements / 138 assertion sites remain exact. Fresh private empty-cache frozen copyfile dependencies match qualified identity Initial hosted measurement: run 39217736277 attempt 1 failed overall. Its three browser jobs succeeded. Their actual checkout logs, case/resource artifacts and immutable Git API agree on synthetic Downloaded immutable browser artifacts have verified ZIP SHA-256:
All 330 discovered browser file/project instances reconcile exactly once across the three shards. All 24 navigation instances and 2,151 cases pass, with case names matching the prior complete local receipt, zero navigation skips/failures and zero unhandled errors. The complete browser domain reports 9,056 passed and 10 skipped cases outside navigation; those skips are not hidden in the navigation count. Every navigation file/project is below 250 seconds, maximum 186.961 seconds. The table records logged file elapsed time, not summed case-body time; every entry has passed status.
Browser job IDs are 117945823735, 117945823953 and 117945823662. All used the unchanged pinned image Historical scheduling evidence at main The established PR #2434 stays draft and uses |
Draft continuation at
86457357cc94d5917c98aa49f6941f3c2158eab8: the nine audit-fixture failures are repaired locally without changing production qualification. Initial hosted run 39217736277 failed overall; all three browser jobs passed and their 24 navigation measurements are below 250 seconds. Native blocker #2350, successful-run weights and final complete candidate confirmation remain open. No new ready event or expensive retry is requested.Refs #2417; part of #1849.
What changed
The navigation reach proof now schedules its seven existing case families as separate files. An eighth wrapper preserves the formerly side-effect-imported durable Actions cases exactly once in each rail pointer project. The shared fixture retains its original hooks, scene ownership, abort checks and resource disposal.
Why this shape
This follows the existing declaration boundaries. All width, start, target, theme and pointer variants remain; no assertions, deadlines, capture paths, project defaults or concurrency bounds change. The rail discovery entry is a glob over the new leaves. Each leaf owns a fresh isolated Vitest module/fixture. The durable wrapper imports its existing suite before the reach fixture, preserving hook registration order and both cleanup layers.
The current timing table remains historical evidence. Every new leaf is explicitly unmeasured and receives the sequencer’s existing positive default; these weights are not an allowlist. The configuration/source change invalidates prior retained proof. A successful hosted run must supply the refresh before qualification. No product code or shipped package surface changes, so no changeset or contract update is needed.
Proof
17766e9a065e1e8dfb58c33c36af7f27991ed77e, base90a95123cfceb169bd2ecf7c213544db742eaed7.getText(), including complete parameter loops, helpers and hooks. All 42 assertion expressions have an exact original-to-new mapping below. These are static source counts, not executed assertion counts.Undiscovered browser scenario: packages/ui-react/tests/browser/navigation-reach.desktop.pointer.tsx; deletingSessions oncefails source-statement equivalence. Both mutations were restored.bun run check:pr --base origin/mainpasses: 235 fast tests / 2,315 assertions; import-graph feedback finds no affected Bun tests, which is not browser proof.07874b2132e08cde15e0e0b8d743f483a1f59fba. Runtime: Bun 1.4.2, Vitest 4.1.11, Playwright 1.63.0, pinned imagemcr.microsoft.com/playwright@sha256:eff16c30e6f3f4af0a03fa4b706120d5e9b0891c344a27d64559aff5900a4a27(image Node 24.20.0; host Node 24.21.0). Native invocation usedscripts/visual.mjs --inside --project=rail-fine --project=rail-coarse --project=rail-mixed --filter=navigation-reach. --proof-reportinside that image with ordinary UID 1000, dropped capability sets, no new privileges, network none, and no outward IPv4/IPv6 routes; repository guards and default per-project scheduling remain intact.Case-family mapping
All paths below are under
packages/ui-react/tests/browser/; original line numbers refer to the base’snavigation-reach.pointer.tsx. Each family runs in all three unchanged pointer projects.navigation-reach.counts.pointer.tsxnavigation-reach.inventory.pointer.tsxnavigation-reach.desktop.pointer.tsxnavigation-reach.parity.pointer.tsxnavigation-reach.handoff.pointer.tsxnavigation-reach.targets.pointer.tsxnavigation-reach.keyboard.pointer.tsxnavigation-reach.durable-actions.pointer.tsximports the samedurable-actions.layout.tsxThe seven direct declarations expand to 605 cases per pointer / 1,815 across three pointers. The existing durable Actions suite is additional and preserved as a whole, including its capture identifiers. Fixtures at original 40–420 and 509–582 move to
navigation-reach-fixture.tsx; the parity-onlyPHONE_PATHSstays beside its loop. No current code citation moved in docs; historical wait-evidence records retain their original SHA and locations.Exact assertion mapping
Each row names one original
expectorexpect.pollsite and its unchanged complete matcher expression. Repeated dynamic executions retain the original loops.navigation-reach-fixture.tsxexpect(matchMedia("(any-pointer: coarse)").matches, "coarse media premise").toBe(mode !== "fine")expect(matchMedia("(any-pointer: fine)").matches, "fine media premise").toBe(mode !== "coarse")expect(matchMedia("(prefers-reduced-motion: reduce)").matches, "reduced motion premise").toBe(true)expect(name, `a named control: ${el.outerHTML.slice(0, 80)}`).not.toBe("")expect(r.height, `44px target height: ${name}`).toBeGreaterThanOrEqual(43.5)expect(r.width, `44px target width: ${name}`).toBeGreaterThanOrEqual(43.5)expect(el.contains(hit), `nothing covers ${name} at ${point.x},${point.y}: ${hit?.outerHTML.slice(0, 120)}`).toBe(true)expect.poll(() => (el = step.find(s)) !== null && !moving(el), { interval: 16, message: `${step.name} on screen and at rest, toward ${toward}` }).toBe(true)navigation-reach.counts.pointer.tsxexpect(Number.isInteger(allowed(name, start, width)), `${name} from ${start} at ${width}`).toBe(true)expect(new Set(PALETTE_ROWS).size, "one target per palette row").toBe(PALETTE_ROWS.length)navigation-reach.inventory.pointer.tsxexpect(ui$(s).paletteOpen, "phone guard clears programmatic opening").toBe(false)expect(s.host.querySelector('[data-palette]'), "no hidden modal below 480").toBeNull()expect([...rows].sort(), `the palette at ${width} lists the routed commands`).toEqual([...PALETTE_ROWS].sort())expect(rows.filter((r) => r === "Sessions"), "Sessions once").toHaveLength(1)navigation-reach.desktop.pointer.tsxexpect.poll(() => target.reached(s), { message: `${name} from ${start} at ${width} (${mode}) after ${steps.length}` }).toBe(true)expect.poll(() => SURFACE[name]!(s), { message: `${name} is drawn, not only flagged, from ${start} at ${width}` }).toBe(true)expect(steps.length, `activations to ${name} from ${start} at ${width} (D52 §2)`).toBe(allowed(name, start, width))expect.poll(() => s.writes, { message: `${name} from ${start}: requests that write` }).toEqual(job)expect(document.documentElement.scrollWidth, "no horizontal overflow").toBeLessThanOrEqual(width)navigation-reach.parity.pointer.tsxexpect.poll(() => target.reached(s), { message: `${name} by the palette row` }).toBe(true)expect.poll(() => target.reached(s), { message: `${name} by its route` }).toBe(true)expect({ ...routed, paneFocused: name === "Sessions" ? routed.paneFocused : null }, `${name}: route and palette agree`) .toEqual({ ...reference, paneFocused: name === "Sessions" ? reference.paneFocused : null })navigation-reach.handoff.pointer.tsxexpect([...paletteRows(s)].sort(), "the palette lists the routed commands and the handoff").toEqual([...PALETTE_ROWS, HANDOFF].sort())expect.poll(() => handoffOpen(s), { message: `${HANDOFF} by the palette row` }).toBe(ITHACA.id)expect(reference.review, "the palette row opened a review").toBe(ITHACA.id)expect.poll(() => handoffOpen(s), { message: `${HANDOFF} by the row's overflow` }).toBe(ITHACA.id)expect({ ...routed, panels: routed.panels.filter((p) => p !== "sessionPanelOpen"), paneFocused: null }, `${HANDOFF}: the overflow and the palette agree`).toEqual({ ...reference, panels: reference.panels.filter((p) => p !== "sessionPanelOpen"), paneFocused: null })navigation-reach.targets.pointer.tsxexpect(rows.length, "the palette lists its rows").toBe(PALETTE_ROWS.length)expect(row.contains(hit), `the row's own box takes a press at ${x},${y}: ${name} hit ${hit?.outerHTML.slice(0, 120)}`).toBe(true)expect(Math.round(r.height * 10) / 10, `fine-pointer density: ${name}`).toBe(/sync|spends/.test(name) ? 35.7 : 34)expect(r.height, `44px target height: ${name}`).toBeGreaterThanOrEqual(43.5)expect(r.width, `44px target width: ${name}`).toBeGreaterThanOrEqual(43.5)navigation-reach.keyboard.pointer.tsxexpect(document.activeElement, "Tab reaches All commands").toBe(all)expect(dialog(), "Enter opens the palette").not.toBeNull()expect(document.activeElement, "focus enters the query").toBe(dialog()!.querySelector("input"))expect(dialog()).toBeNull()expect(document.activeElement, "Esc returns focus to All commands").toBe(all)expect(index, `${target.palette} is listed`).toBeGreaterThanOrEqual(0)expect((document.activeElement?.textContent ?? "").startsWith(target.palette!), `arrows reach ${target.palette}`).toBe(true)expect.poll(() => target.reached(s), { message: `${name} by keyboard` }).toBe(true)expect.poll(() => SURFACE[name]!(s), { message: `${name} is drawn after the keyboard route` }).toBe(true)expect(dialog(), "running a row closes the palette").toBeNull()Local measurements (qualification cost, not a hosted speedup)
Fresh private frozen-lockfile install used copyfile and an empty private Bun cache. No mutable dependency/build outputs were shared with another checkout. GNU time receipts are command-local; CPU is user + system charged to that process and waited descendants, not VM-wide or sampled container CPU. Build and typecheck overlapped, so their summed wall cost is not elapsed critical path.
Vitest reports 328.70 seconds elapsed, 0.238 seconds setup, 17.03 seconds imports and 930.89 summed test seconds across parallel projects. These framework phases are not complete lifecycle setup costs; fresh installation, build and font setup are separate above. Additional discovery/omission/equivalence/receipt commands and both failed bootstrap launches are retained in the handoff’s measurement ledger. One diagnostic Docker sample observed 6.011 GiB used; it is not peak memory or a resource comparison. The largest file is 160.354 seconds locally. This does not establish the hosted per-file threshold or replace the required weight refresh.
counts.pointer.tsxdesktop.pointer.tsxdurable-actions.pointer.tsxhandoff.pointer.tsxinventory.pointer.tsxkeyboard.pointer.tsxparity.pointer.tsxtargets.pointer.tsxChecklist
Anything left open
The initial hosted measurement is complete and failed overall. Every new navigation file/project is measured below 250 seconds, and all shard job costs are recorded below. The existing tool refuses failed overall runs, so successful-run weights remain pending. After #2350 is resolved, a worker must reclaim #2417 and complete successful proof, the admitted weight refresh and final updated-candidate confirmation before merge. #2417 stays open; no whole-CI improvement is claimed.
Audit fixture repair and initial hosted measurements
2026-10-19 — #2417 continuation r2, under the parent's existing claim
e1849-2417-20261019-r1.The nine relevant unit failures are repaired in
86457357cc94d5917c98aa49f6941f3c2158eab8. Positive browser-document, inactive-command and worker-boundary fixtures now read independently owned raw Git blobs from delivered base90a95123cfceb169bd2ecf7c213544db742eaed7; document directory membership and binary fonts are frozen too. Actual current config/caller/producer bytes are tested separately. Production qualification hashes, audit implementations, offline guards, images, deadlines and navigation cases are unchanged. This follows delivered #2374/#2388 rather than granting qualification to changed source.Focused evidence: the original three files reproduce exactly 24 pass / 9 fail. Repaired tests pass 38/38, 181 assertions, with all original assertions retained. Bypassing the document config check fails all four current-document negatives; bypassing worker enforcement fails the real current-config negative even after recomputing the manifest; bypassing the command digest fails its drift guard, and admitting just the actual changed config fails
CURRENT_COMMAND_SOURCE_DRIFT_REQUIRES_FRESH_PROOF. Changing the positive fixture owner to the PR's unreviewed config fails the original and added positive assertions. Every mutation is restored byte-for-byte. Initial strict types caught a readonlytest.eachinput; copying that list resolves it. Final strict types pass (31.79 s wall, 49.54 s accounted CPU); requiredbun run check:pr --base origin/mainpasses 719 fast tests / 4,622 assertions plus 38 affected import-feedback tests / 181 assertions (64.69 s wall, 91.17 s accounted CPU); focused execution is explicit because the initial split preflight did not select these tests. No failing setup is represented as behavioral evidence.Source equivalence is rechecked: all 62 direct top-level statements / 42 assertion sites and all 43 imported durable-suite statements / 138 assertion sites remain exact. Fresh private empty-cache frozen copyfile dependencies match qualified identity
0c2758c046f2b69d5f33b66521baf3098db5f44256b73ec96961c98d381e6245(843 packages, 59,516 files, 1,833,832,361 bytes).Initial hosted measurement: run 39217736277 attempt 1 failed overall. Its three browser jobs succeeded. Their actual checkout logs, case/resource artifacts and immutable Git API agree on synthetic
4e2448ea8ab6402f64413e1080738eb09fd27b8e, tree07874b2132e08cde15e0e0b8d743f483a1f59fba, parents base90a95123cfceb169bd2ecf7c213544db742eaed7and original split head17766e9a065e1e8dfb58c33c36af7f27991ed77e. This is evidence for the original split, not new hosted proof of the repair head.Downloaded immutable browser artifacts have verified ZIP SHA-256:
d58a6fb9fca83c3463ef48423c62eed58006df62e92f0fa04c252b2cd8c91ff2.270dfb93281cd7e9554ee66a0eea9a9a44ebadf5215f5e5b8d29c991432173e7.71fc6b0aae80f40024cd7eaff0c482322b1836bde4b072cd9405a17a6d21eeea.All 330 discovered browser file/project instances reconcile exactly once across the three shards. All 24 navigation instances and 2,151 cases pass, with case names matching the prior complete local receipt, zero navigation skips/failures and zero unhandled errors. The complete browser domain reports 9,056 passed and 10 skipped cases outside navigation; those skips are not hidden in the navigation count. Every navigation file/project is below 250 seconds, maximum 186.961 seconds. The table records logged file elapsed time, not summed case-body time; every entry has passed status.
counts.pointer.tsxdesktop.pointer.tsxdurable-actions.pointer.tsxhandoff.pointer.tsxinventory.pointer.tsxkeyboard.pointer.tsxparity.pointer.tsxtargets.pointer.tsxBrowser job IDs are 117945823735, 117945823953 and 117945823662. All used the unchanged pinned image
mcr.microsoft.com/playwright@sha256:eff16c30e6f3f4af0a03fa4b706120d5e9b0891c344a27d64559aff5900a4a27, with four logical CPUs and approximately 16.77 GB VM memory. VM active CPU and sampled used memory cover proof commands including containers; they are not process CPU or exact peak memory. Whole-job times include setup/finalization; build/browser phases overlap that wall interval and are not extra costs.Historical scheduling evidence at main
7f22bb6ac2892360f3a5c4d3a1f93d9997af43e8, run 39109891338, recorded the original single navigation file at approximately 481/411/428 seconds (fine/coarse/mixed). The split's largest files are 163.335/182.984/186.961 seconds respectively; summed navigation file time is 1,060.943 seconds versus about 1,320 historical seconds. These different-source observations establish smaller measured scheduling units, not a controlled speedup. Historical browser job walls were 808/887 seconds across two shards (1,695 total); this initial three-shard run is 881/416/898 (2,195 total). No whole-browser job-wall improvement is observed or claimed; the unmeasured new files still use positive default weights.The established
scripts/refresh-browser-costs.tsadmission requires a successful overall CI run, not merely successful browser jobs. Executing it against this run refuses withA successful attributed CI run/attempt is required. Its checks and the existing weights remain unchanged. The issue's successful-run weight criterion remains pending even though this initial measurement meets the numeric per-file threshold.PR #2434 stays draft and uses
Refs #2417. Native mount-inspector blocker #2350 remains unresolved; no native code was changed, no expensive confirmation/ready event was requested, and no merge is claimed. Remaining: resolve that blocker, obtain successful complete candidate proof, refresh weights through the established tool, then qualify the final refreshed source. The initial base remains unchanged; no rebase or main integration was performed. Coordinating review is now complete. Claime1849-2417-20261019-r1and its assignment are released; see the final handoff below.Coordinating handoff
2026-10-19 — coordinating review and blocked handoff.
Reviewed repair
86457357cc94d5917c98aa49f6941f3c2158eab8(tree67bc17bd4f246677483d4b27baffbe031f3abfc8) against the original split. The five-file correction supplies independently frozen positive browser fixtures, including directory membership and binary font blobs, and explicitly tests current-source drift. Production pins and runtime guards are unchanged. No navigation assertions, scenarios or deadlines changed. Independent review found no actionable defect; receipt hashes match, named causal mutations fail on the intended assertions, restoration passes 38 tests / 181 assertions, and strict types plus required preflight pass. Current-head draft gates and contract checks pass; their intentionally skipped product jobs are not complete candidate proof.The preceding head's hosted browser measurements retain their original identity: run 39217736277 attempt 1, head
17766e9a065e1e8dfb58c33c36af7f27991ed77e, base90a95123cfceb169bd2ecf7c213544db742eaed7, checkout4e2448ea8ab6402f64413e1080738eb09fd27b8e. All 2,151 navigation cases in 24 file/project instances pass without navigation skips/errors; the largest instance is 186.961 seconds, below the 250-second criterion. Browser shard job walls are 881 / 416 / 898 seconds. This provides smaller scheduling units, not a controlled whole-CI speedup: current summed browser job walls are 2,195 seconds versus 1,695 in the differently sourced historical two-shard comparison. Weight refresh correctly refuses this failed overall run, so its successful-run prerequisite and final confirmation remain outstanding. These browser receipts are not executions on the repaired head.#2350 remains open with needs: repro. PR #2434 stays draft and #2417 stays blocked/open, both retaining milestone 0.44.0. Implementation is preserved on
as/split-navigation-browser-tests; clean implementation checkouts are retained. Claime1849-2417-20261019-r1is released with this invocation's assignment. Continuation r2 is complete; no child work remains.Resume after #2350 is resolved and qualified: explicitly reclaim #2417, assess live base/source changes, run required preflight, verify requested and actual synthetic identities, obtain complete passing hosted confirmation, refresh browser weights through the existing admitted-run tool, and confirm the resulting final candidate before merge and actual-main reconciliation. No unchanged retry, pin relaxation, skipped runtime or increased timeout is accepted as proof.