diff --git a/docs/branch-review-ledger.md b/docs/branch-review-ledger.md index fe5bf79f39..a34c4f65f7 100644 --- a/docs/branch-review-ledger.md +++ b/docs/branch-review-ledger.md @@ -837,26 +837,33 @@ Records before 2026-07-28 were written by hand and had drifted: 146 lines carrie | 2026-08-09 | cursor/differentials-diagnosis-links-9f18 | 0e77e7bc0842bef4ffc045c6dbea4626152490d1 | differentials diagnosis term links | implemented exact+alias termLinks chips on diagnosis+presentation pages; vitest 58/58; verify:pr-local green | vitest differential-diagnosis-links+detail+section-nav+route; verify:pr-local; ensure spot-check | | 2026-08-09 | cursor/differentials-diagnosis-links-9f18 | 0daa9e2f9fc84e879fd661da94203568309234a6 | PR #1768 Autopilot+Bugbot review-and-fix | Merged origin/main (DIRTY was ledger+detail-page staleness; merge-tree clean). Fixed SEGMENT_SPLIT to spaced-slash only so Delirium / medical psychosis links while alcohol/benzo, DVT/PE, food/fluid stay intact. Dispositioned: Copilot termLinks ??{} + Fragment key already fixed; CodeRabbit clean-keys moot (visibleSectionItems already cleans); CodeRabbit bare-slash split rejected (clinical harm). No Bugbot findings. Threads cleared on push. Merge left to user. | vitest differential-diagnosis-links+detail+route 49/49; verify:cheap exit 0 (543 files, 5828 passed/4 skipped); verify:pr-local exit 0 (lint/typecheck/test/build/rag-fixtures); merge-tree clean vs origin/main; no provider gates | | 2026-08-09 | cursor/differentials-diagnosis-links-9f18 | f784e81bcc0b53ef76b3da07a8e81f96d9bf0c71 | pr-1768 unblock | merged origin/main onto ba590f9; merge-tree clean; DIRTY mergeability cleared; push tip follows amend with this ledger | merge-tree clean; threads resolved; auto-merge was armed | -| 2026-08-09 | claude/documentviewer-nav-convergence-oddhjx | 1395d533cb13eadc705e47f76aa9f39a7a11c058 | DocumentViewer / in-page-nav convergence (#288): non-adoption decision recorded in docs/search-chrome-behaviour.md; merged duplicated visible-element predicate into resolveVisibleElement; new convergence guard test | Converged what was duplicated; DocumentReviewer header adoption declined on the merits with four blocking reasons recorded. No contract test edited. | verify:pr-local (546/547 files, 5883 tests pass; sole failure tests/pr-handoff-stop.test.ts reproduced on pristine origin/main), verify:phone-chrome (contracts 123 pass; focused Chromium 7 pass), contract set 12 files/151 tests pass, lint, typecheck, format | +| 2026-08-09 | claude/document-viewer-phase-3-bj5k5v | 156db63f1b60f09791e426b043ea90d427b789ab | post-#1772 test simplification: replace the viewer perf source-text grep with behavioural coverage; de-literalise rail window and keyboard label assertions | PR #1777 opened. Self-review of #1772's own tests against an excessive-strictness challenge. Finding: the client-performance-boundaries grep for resolveLiveCanvasWindow / resolveRenderAheadPages / liveCanvasLimit / requestIdleCallback was not merely brittle, it was INEFFECTIVE - replacing the budget call with a hardcoded 3 leaves every identifier in the file, so it stayed green while the viewer retained three full-zoom canvases (measured both ways). Replaced by a DOM case that binds the budget (VIEWER_MAX_ZOOM at dpr 3 gives ~16.8M backing px against the 24M budget, window collapses to 1) and fails on exactly that substitution. Also exported RAIL_IMAGE_WINDOW so the rail test derives its counts (verified by tuning 6->8: all 7 still pass), and relaxed the keyboard aria-label assertions from exact prose to the key names. Pre-existing greps for disableAutoFetch / canvas.width = 0 / pageToCleanup left alone deliberately - two are now redundant but they are another author's guard. | verify:pr-local (1 pre-existing root-only failure: pr-handoff-stop #291; 5872 passed), build OK 80s + client bundle secret check, eval:rag:offline 36 golden cases / 574 tests, lint + typecheck clean. Sabotage-verified in both directions. Browser gates unrunnable here (#279) - unchanged by this diff. | | 2026-08-09 | claude/planning-build-intelligence-9ot0nm | 3df3cb3993f73cda4dbbc4ac7549f84b3c6ea7ed | Node 24.15 engine floor: engines.node, preinstall hook, check:runtime, session-start provisioning, codex-cloud assertion | Authored and handed off as PR #1771; closes #285; operationalRisk true, clinicalRisk/ragRanking false | test 5800 passed/1 pre-existing root-uid failure (pr-handoff-stop, confirmed on stashed clean tree); lint 0; typecheck 0; prettier --check . pass; check:runtime pass; check:codex-cloud pass; check:outstanding-issues pass; preinstall boundary proof 24.13/24.14.9 reject, 24.15/24.19 accept, 25.0.0 reject; contract test mutation-checked red | | 2026-08-09 | pull/1771 | 466ec4216272c31c5f754db213dbdc529583b167 | PR 1771 runtime floor enforcement | P2: Cloud and Desktop setup paths remain major-only; do not merge until range-aware | static review; check:runtime PASS; check:codex-cloud PASS; ledger PASS; outstanding issues PASS; focused Vitest blocked by active Playwright lease | -| 2026-08-09 | claude/document-viewer-phase-3-bj5k5v | 156db63f1b60f09791e426b043ea90d427b789ab | post-#1772 test simplification: replace the viewer perf source-text grep with behavioural coverage; de-literalise rail window and keyboard label assertions | PR #1777 opened. Self-review of #1772's own tests against an excessive-strictness challenge. Finding: the client-performance-boundaries grep for resolveLiveCanvasWindow / resolveRenderAheadPages / liveCanvasLimit / requestIdleCallback was not merely brittle, it was INEFFECTIVE - replacing the budget call with a hardcoded 3 leaves every identifier in the file, so it stayed green while the viewer retained three full-zoom canvases (measured both ways). Replaced by a DOM case that binds the budget (VIEWER_MAX_ZOOM at dpr 3 gives ~16.8M backing px against the 24M budget, window collapses to 1) and fails on exactly that substitution. Also exported RAIL_IMAGE_WINDOW so the rail test derives its counts (verified by tuning 6->8: all 7 still pass), and relaxed the keyboard aria-label assertions from exact prose to the key names. Pre-existing greps for disableAutoFetch / canvas.width = 0 / pageToCleanup left alone deliberately - two are now redundant but they are another author's guard. | verify:pr-local (1 pre-existing root-only failure: pr-handoff-stop #291; 5872 passed), build OK 80s + client bundle secret check, eval:rag:offline 36 golden cases / 574 tests, lint + typecheck clean. Sabotage-verified in both directions. Browser gates unrunnable here (#279) - unchanged by this diff. | -| 2026-08-09 | claude/disabled-button-accessibility-piclvr | 722abdb780c715c0a89df268ed48f6c741ffd569 | disabled-placeholder buttons -> aria-disabled + inert handler (25 sites, 13 components); controlDisabled/therapy recipe aria-disabled styling; require-button-wiring redundantDisabledPair gate; wiring-conventions contract rewrite (settles #291) | authored — PR #1778 opened | lint (uncached, exit 0); typecheck; test 5878 passed/1 pre-existing root-env failure in pr-handoff-stop; build; check:rag:fixtures 36 golden cases; prettier --check clean; verify:ui not run (no browser in container) | -| 2026-08-09 | claude/in-page-nav-pr-3-i6gi8n | 6651feef4fab63f1181fba57908cb22e2932df3c | in-page-nav PR 3: convert /medications/[slug] (panel-swap) and /factsheets/[slug] (anchors) onto InPageNavHeader; record the differentials-presentations exception; delete orphaned SecondaryNavigation (#271) | converted 2 of 3 routes, 3rd recorded as a reasoned lasting exception; tocFor and SecondaryNavigation deleted; route-sections contract 7 -> 12 routes plus a panel-swap suite | verify:pr-local (1 pre-existing root-permission failure in pr-handoff-stop.test.ts, all else green); test 5932 passed; in-page-nav-route-sections 29 passed; verify:phone-chrome 3/4 stages (focused-browser blocked by #255 Chromium 1194 vs 1234); build + bundle-budget + rag:fixtures green; verify:ui not run (#255, delegated to CI) | +| 2026-08-09 | cursor/therapy-card-densify-e975 | 3db839a6bb1f5b45fc55bb732d21b30551a506b0 | therapy search ResultCard densify (gap, tags, favourite, actions, match cells) | pass — denser cards; band gap fixed; single-row prioritized tags; heart top-right; 3-col actions; summarised cells | unit 35/35; verify:pr-local pass; ensure visual phone+desktop pass | | 2026-08-09 | claude/m3-token-debt-262-261 | c6e1fe7fc42ec6f286eb5a3d8f7ddad7dfad2724 | design-system contract: raw padding/radius/line-height ratchets + type-step selection gate (#262 parts 2/3); closed #218/#270 | Authored and self-verified; PR #1780 open, auto-merge deliberately not armed (gate change). Baseline additive: all 15 pre-existing metrics and every debtByPath entry byte-identical; 94/94 new findings verified present at their cited line. Mutation-tested both halves of part 3 and three failure modes of part 2. | check:design-system-contract, check:icon-scale, check:type-scale, check:outstanding-issues, vitest design-system-contract-utils (31 passed), format:check whole-tree, verify:cheap (exit 1 from 5 pre-existing failures, none in this diff; 3 cleared by merging main, remaining 2 byte-identical to origin/main) | +| 2026-08-09 | claude/documentviewer-nav-convergence-oddhjx | 1395d533cb13eadc705e47f76aa9f39a7a11c058 | DocumentViewer / in-page-nav convergence (#288): non-adoption decision recorded in docs/search-chrome-behaviour.md; merged duplicated visible-element predicate into resolveVisibleElement; new convergence guard test | Converged what was duplicated; DocumentReviewer header adoption declined on the merits with four blocking reasons recorded. No contract test edited. | verify:pr-local (546/547 files, 5883 tests pass; sole failure tests/pr-handoff-stop.test.ts reproduced on pristine origin/main), verify:phone-chrome (contracts 123 pass; focused Chromium 7 pass), contract set 12 files/151 tests pass, lint, typecheck, format | +| 2026-08-09 | claude/disabled-button-accessibility-piclvr | 722abdb780c715c0a89df268ed48f6c741ffd569 | disabled-placeholder buttons -> aria-disabled + inert handler (25 sites, 13 components); controlDisabled/therapy recipe aria-disabled styling; require-button-wiring redundantDisabledPair gate; wiring-conventions contract rewrite (settles #291) | authored — PR #1778 opened | lint (uncached, exit 0); typecheck; test 5878 passed/1 pre-existing root-env failure in pr-handoff-stop; build; check:rag:fixtures 36 golden cases; prettier --check clean; verify:ui not run (no browser in container) | | 2026-08-09 | cursor/differentials-four-page-nav-5ebf | 93ea437610c1f1b681c3a5cbdc72fe8b9b178710 | differentials four-page nav | implemented Search/Diagnoses/Presentations/Compare equal pages; compare queue; kind labels; Search q+run restore | vitest nav+differentials-navigation; typecheck; lint; full unit 5814 passed | | 2026-08-09 | cursor/differentials-four-page-nav-5ebf | 384a1bedd8dd1064fb2fcf26ac845224e2cafdc4 | PR #1774 differentials four-page nav heavy review-and-fix | fixed P1 ids+Playwright; ModeNav route gate; RSC queue clears bundle+shadow; Copilot ModeNav-on-detail dispositioned (info page); ledger reorder dispositioned (merge=ledger) | vitest nav 47p; design-system-contract; typecheck; lint; test 5897p; build+bundle-budget 1543.7 within tol; focused pw compare queue 1p | | 2026-08-09 | claude/m3-token-debt-262-261 | 95221ef4235abd9544158b07b8b8569f00c9ec78 | PR #1780 review-and-fix | fixed P2 ratchet bypasses (arbitrary-property classes, CSS-consumer exemption anti-rot, modern CSS zero units); Bugbot clean; merge-tree clean; required CI was green on prior tip | vitest design-system-contract-utils 32/32; check:design-system-contract; mutation CSS-exemption fail→restore; verify:cheap PASS (549 files / 5933 tests); verify:pr-local stages PASS (test flake in design-system-adoption timed out once then 51/51 + full test 549/549 + check:rag:fixtures PASS); no provider gates | | 2026-08-09 | claude/m3-token-debt-262-261 | 7bac3bd762b381cb25c9b2a15ef3bb7223d15b16 | PR #1780 review-and-fix | fixed P2 ratchet bypasses (arbitrary-property classes, CSS-consumer exemption anti-rot, modern CSS zero units); Bugbot clean; merge-tree clean; required CI was green on prior tip | vitest design-system-contract-utils 32/32; check:design-system-contract; mutation CSS-exemption fail→restore; verify:cheap PASS (549 files / 5933 tests); verify:pr-local stages PASS (test flake in design-system-adoption timed out once then 51/51 + full test 549/549 + check:rag:fixtures PASS); no provider gates | | 2026-08-09 | cursor/dsm-search-header-fix-15d6 | df088c766f1761496189ec09146aa54c23b1c012 | dsm-search-header | pass: removed catalogue page strip; ribbon + category filter match target | vitest dsm-search-empty-state; npm test 5857 passed; lint; typecheck; ensure phone /dsm/search?q=Delirium | | 2026-08-09 | claude/m3-token-debt-262-261 | fe75e6acade008e68f953e235cc035f2e5d9d216 | PR #1780 review-and-fix | fixed P2 ratchet bypasses; synced origin/main (#1775); Bugbot clean; merge-tree clean | vitest design-system-contract-utils 32/32; check:design-system-contract; mutation CSS-exemption; verify:cheap PASS 549/5933; verify:pr-local stages PASS after adoption flake retest; check:rag:fixtures PASS; no provider gates | -| 2026-08-09 | origin/pr/1686 | a5cce760d73bd174dba200b53852568dcdb9be0d | PR #1686 CI testing perfection and merged rollout reconciliation | Merged required CI was green, but hosted evidence confirmed P2 shard imbalance, duplicated critical coverage, net-negative 1.09 GB cache transport, inactive container revision enforcement, duplicated workflow/build/browser work, and missing local npm-ci selection. Fixed locally on current main; no P0/P1. | Hosted run 31285952061 inspected; focused Vitest 55 passed plus browser-preflight 12 passed; CI workflow suite 256 passed; typecheck passed; CI scope, verification plan, shard parity, gate manifest, action pins, npm-ci dry-run, docs and outstanding-issues guards passed; no Playwright/browser run or provider mutation. | -| 2026-08-09 | cursor/therapy-card-densify-e975 | 3db839a6bb1f5b45fc55bb732d21b30551a506b0 | therapy search ResultCard densify (gap, tags, favourite, actions, match cells) | pass — denser cards; band gap fixed; single-row prioritized tags; heart top-right; 3-col actions; summarised cells | unit 35/35; verify:pr-local pass; ensure visual phone+desktop pass | | 2026-08-09 | cursor/therapy-card-densify-e975 | 52f07d49f89e6c786c624ccbd38ae552818a2071 | PR 1783 babysit | fixed review threads: TagRow +N clip, title/alias preview exclusion, preview field fallbacks; Copilot md grid kept; CI re-triggered after Copilot tip | npm test: 5958 passed / 4 skipped | +| 2026-08-09 | claude/in-page-nav-pr-3-i6gi8n | 6651feef4fab63f1181fba57908cb22e2932df3c | in-page-nav PR 3: convert /medications/[slug] (panel-swap) and /factsheets/[slug] (anchors) onto InPageNavHeader; record the differentials-presentations exception; delete orphaned SecondaryNavigation (#271) | converted 2 of 3 routes, 3rd recorded as a reasoned lasting exception; tocFor and SecondaryNavigation deleted; route-sections contract 7 -> 12 routes plus a panel-swap suite | verify:pr-local (1 pre-existing root-permission failure in pr-handoff-stop.test.ts, all else green); test 5932 passed; in-page-nav-route-sections 29 passed; verify:phone-chrome 3/4 stages (focused-browser blocked by #255 Chromium 1194 vs 1234); build + bundle-budget + rag:fixtures green; verify:ui not run (#255, delegated to CI) | | 2026-08-09 | PR #1782 / cursor/fix-document-open-scroll-e5bf | 5709f2cc7a954197e02107c96d7896d8d13445c3 | document-viewer open-at-top | ship: remove chunk mount scrollIntoView so document opens stay at overview top | document-viewer-shell.dom 7 pass; document-section-summary.dom 8 pass; verify:pr-local dry-run | | 2026-08-09 | cursor/fix-document-open-scroll-e5bf (PR #1782) | 98029875db7d640d3e699829249bb33892296bff | PR #1782 unblock | before: static-pr+coverage failed on stale adoption-manifest (document-viewer-shell testFiles drift), merge-tree clean 0 behind, auto-merge armed, 1 advisory CodeRabbit waitFor thread; after: regenerated adoption-manifest, hardened scroll negative assertion, pre-commit+handoff adoption sync to prevent recurrence; CodeRabbit dispositioned as fixed by sync assert | check:design-system-adoption PASS; vitest design-system-adoption+document-viewer-shell+docs-inventory 63/63 PASS; format; no provider-backed checks | | 2026-08-09 | cursor/fix-document-open-scroll-e5bf (PR #1782) | 86698228533ebe10452c10c1bd7a3e1610d891ae | PR #1782 unblock | merged origin/main (behind-but-clean); fixed static-pr TS2322 on document-viewer-shell chunk fixture; fixed Production UI DSM compare remove stall via location.assign + DOM proof; prior adoption-manifest drift already fixed | tsc clean for changed files; vitest document-viewer-shell+dsm-compare-remove+design-system-adoption 59/59 PASS; check:design-system-adoption PASS; format; no provider-backed checks | -| 2026-08-10 | codex/ci-perfected-rollout-20260809 (PR #1789) | accbc7c6324b839112ff8df8f9b66d3557f2b98e | PR babysit | unblocked; merged origin/main (false-DIRTY behind-but-clean); fixed Codex P2 ui_changed for Playwright runner helpers; thread replied+resolved | ci-change-scope --self-test pass; merge-tree clean; no provider gates | -| 2026-08-10 | codex/ci-perfected-rollout-20260809 (PR #1789) | bf437370441c43a35ec63353642b0180ba5beba6 | PR babysit | late sync: merged origin/main (#1793/#1794); behind-but-clean; prior tip CI green; no code fixes | merge-tree clean; format clean; prior tip PR required pass; no provider gates | +| 2026-08-09 | codex/chat-mode-home-copy-9d76 | 1d32ce6f0a9f580eef55363de17e15723ae8d898 | PR #1790 babysit | MERGED via squash auto-merge as d812c769; same-mode focus fixed; Copilot aria dispositioned (drawer still Clinical Guide); CodeRabbit focus-steal follow-up in cursor/same-mode-focus-no-steal-6df8; reply API unavailable | PR required PASS; Production UI shards PASS; unit mode-menu-prefetch PASS | +| 2026-08-10 | cursor/same-mode-focus-no-steal-6df8 (PR #1792) | 905caf2d8eeb5d74af4d8d90fef7e50f4cb78f13 | PR #1792 babysit | before: Production UI critical FAILED (TS5101 baseUrl in isolated Playwright tsconfig after Next 16.3 main sync); Lighthouse advisory ignored; merge-tree clean 0 behind. after: removed deprecated baseUrl from run-playwright + run-lighthouse-budget; root-relative @/* paths; regression guards in unit tests; no threads acted on | tsc isolated tsconfig: old baseUrl TS5101 exit 2, fixed exit 0; vitest test-runner-safety+check-lighthouse-budget 84/84 PASS; format; no provider-backed checks | | 2026-08-10 | PR #1797 / claude/codex-m4a-retire-dead-type-8wq9ta | 6bf3c7b2a0600021290e165302fd07d721af6592 | retire the dead --text-2xl-compact type step (ledger #297): globals.css @theme, twMerge config, two test lists, the design-system-contract exemption, TOKENS.md/GATES.md | Executed the recorded next action on outstanding-issues #297. The step had zero class-utility and zero var(--text-*) consumers, so the deletion renders identically; UNUSED_TYPE_STEP_EXEMPTIONS is now empty and the declared-but-unconsumed gate holds the line with no carve-out. One test fixture using the token as a synthetic var() consumer was repointed at --text-2xl-minus. GATES.md corrected to eight non-standard steps; the 705-consumer total is unchanged because this step contributed 0. No clinical, RAG-ranking or operational risk paths touched (classifyPullRequestFiles: all false). | check:design-system-contract PASS (705 production files); check:type-scale --strict PASS; lint exit 0; typecheck exit 0; npm run build after rm -rf .next exit 0 (Compiled successfully in 63s); check:outstanding-issues PASS; verify:pr-local completed through typecheck then failed at test on a PRE-EXISTING root-permission failure in tests/pr-handoff-stop.test.ts that reproduces on clean d812c76 (5993 passed, 1 failed); build and check:rag:fixtures run/assessed separately. No UI gate: no rendered output can change. No provider-backed check run. | | 2026-08-10 | codex/visual-baseline-advisory-pr | 6bc57714c36bc6d027561bb8f5f8b00bb92524b2 | PR #1791 babysit unblock | fixed Production UI formulation Clear→Draft flake settle; classified visual drift vs non-drift failures | test:ci-workflows 263; classify-visual-baseline-outcome+ci-cache-safety 40 | +| 2026-08-10 | cursor/same-mode-focus-no-steal-6df8 | b82ae6fe80cfc5e4dac139383230d5a8fcb62b68 | Run PR sweep | fix: Unit coverage tsconfig contract aligned to #1798 ignoreDeprecations; merged origin/main | vitest test-runner-safety+check-lighthouse-budget 84 passed; Unit coverage was FAIL on 3f2aae3a | +| 2026-08-10 | cursor/same-mode-focus-no-steal-6df8 | f0dc8e922d0cf05ff3d9f7c2c5f4d203c8449794 | Run PR sweep | fix: Unit coverage tsconfig contract aligned to #1798 ignoreDeprecations; merged origin/main | vitest test-runner-safety+check-lighthouse-budget 84 passed; Unit coverage was FAIL on 3f2aae3a | +| 2026-08-10 | cursor/same-mode-focus-no-steal-6df8 | a6a5e4cd59352244163a5d6d5439c2bc40a7ff95 | Run PR sweep | fix: Unit coverage tsconfig contract aligned to #1798 ignoreDeprecations; merged origin/main | vitest test-runner-safety+check-lighthouse-budget 84 passed; Unit coverage was FAIL on 3f2aae3a | +| 2026-08-10 | cursor/same-mode-focus-no-steal-6df8 | f8d7ef3faa397de7c9aecc61a66ec5428a3eeed3 | Run PR sweep | fix: Unit coverage tsconfig contract aligned to #1798 ignoreDeprecations; merged origin/main | vitest test-runner-safety+check-lighthouse-budget 84 passed; Unit coverage was FAIL on 3f2aae3a | +| 2026-08-10 | cursor/same-mode-focus-no-steal-6df8 | e6eea4d9b677de6919165753b9ceae059bac1190 | Run PR sweep | fix: Unit coverage tsconfig contract aligned to #1798 ignoreDeprecations; merged origin/main | vitest test-runner-safety+check-lighthouse-budget 84 passed; Unit coverage was FAIL on 3f2aae3a | +| 2026-08-09 | origin/pr/1686 | a5cce760d73bd174dba200b53852568dcdb9be0d | PR #1686 CI testing perfection and merged rollout reconciliation | Merged required CI was green, but hosted evidence confirmed P2 shard imbalance, duplicated critical coverage, net-negative 1.09 GB cache transport, inactive container revision enforcement, duplicated workflow/build/browser work, and missing local npm-ci selection. Fixed locally on current main; no P0/P1. | Hosted run 31285952061 inspected; focused Vitest 55 passed plus browser-preflight 12 passed; CI workflow suite 256 passed; typecheck passed; CI scope, verification plan, shard parity, gate manifest, action pins, npm-ci dry-run, docs and outstanding-issues guards passed; no Playwright/browser run or provider mutation. | +| 2026-08-10 | codex/ci-perfected-rollout-20260809 (PR #1789) | accbc7c6324b839112ff8df8f9b66d3557f2b98e | PR babysit | unblocked; merged origin/main (false-DIRTY behind-but-clean); fixed Codex P2 ui_changed for Playwright runner helpers; thread replied+resolved | ci-change-scope --self-test pass; merge-tree clean; no provider gates | +| 2026-08-10 | codex/ci-perfected-rollout-20260809 (PR #1789) | bf437370441c43a35ec63353642b0180ba5beba6 | PR babysit | late sync: merged origin/main (#1793/#1794); behind-but-clean; prior tip CI green; no code fixes | merge-tree clean; format clean; prior tip PR required pass; no provider gates | diff --git a/src/components/clinical-dashboard/master-search-header.tsx b/src/components/clinical-dashboard/master-search-header.tsx index d76266e2d2..4921bf8ab8 100644 --- a/src/components/clinical-dashboard/master-search-header.tsx +++ b/src/components/clinical-dashboard/master-search-header.tsx @@ -866,9 +866,7 @@ export function MasterSearchHeader({ window.setTimeout(restoreSameModeFocus, 50); return; } - if (!restoreFocusUnlessMoved(modeButtonRef.current)) { - modeButtonRef.current?.focus({ preventScroll: true }); - } + restoreFocusUnlessMoved(modeButtonRef.current); pendingModeSelectionFocusRef.current = null; }; window.requestAnimationFrame(() => { diff --git a/tests/check-lighthouse-budget.test.ts b/tests/check-lighthouse-budget.test.ts index e8c99ba2d8..00d58d3f06 100644 --- a/tests/check-lighthouse-budget.test.ts +++ b/tests/check-lighthouse-budget.test.ts @@ -415,6 +415,15 @@ describe("committed lighthouse-budget.json", () => { expect(committed.routes.filter((route) => route.includes("?"))).toEqual([]); }); + it("writes an isolated tsconfig that silences TS5101 baseUrl deprecation", () => { + const runner = readFileSync(path.join(process.cwd(), "scripts", "run-lighthouse-budget.mjs"), "utf8"); + + // Same Next 16.3 + TS 6 TS5101 trap as the Playwright runner (#1798). + expect(runner).toContain('ignoreDeprecations: "6.0"'); + expect(runner).toContain('baseUrl: "../.."'); + expect(runner).toContain('paths: { "@/*": ["src/*"] }'); + }); + it("invokes npm's JavaScript npx CLI through Node when available", () => { const runner = readFileSync(path.join(process.cwd(), "scripts", "run-lighthouse-budget.mjs"), "utf8"); diff --git a/tests/mode-menu-prefetch.dom.test.tsx b/tests/mode-menu-prefetch.dom.test.tsx index 242b243347..44cd923e53 100644 --- a/tests/mode-menu-prefetch.dom.test.tsx +++ b/tests/mode-menu-prefetch.dom.test.tsx @@ -167,4 +167,33 @@ describe("mode menu destination prefetch", () => { expect(trigger).toHaveFocus(); }); }); + + it("does not steal focus when the user moves elsewhere during same-mode restore", async () => { + const user = userEvent.setup(); + render( + <> + + + , + ); + + const trigger = screen.getByRole("button", { name: /Mode Answer/i }); + await user.click(trigger); + const answerOption = within(await screen.findByRole("menu", { name: "Choose app mode" })).getByRole( + "menuitemradio", + { name: /Answer/i }, + ); + await user.click(answerOption); + + const outside = screen.getByRole("button", { name: "Outside control" }); + outside.focus(); + await vi.waitFor(() => { + expect(outside).toHaveFocus(); + }); + // Deferred same-mode restore must honor restoreFocusUnlessMoved and leave + // deliberately moved focus alone. + await new Promise((resolve) => setTimeout(resolve, 120)); + expect(outside).toHaveFocus(); + expect(trigger).not.toHaveFocus(); + }); }); diff --git a/tests/test-runner-safety.test.ts b/tests/test-runner-safety.test.ts index 793938069b..3b7d07b079 100644 --- a/tests/test-runner-safety.test.ts +++ b/tests/test-runner-safety.test.ts @@ -733,6 +733,11 @@ describe("provider-safe test environment", () => { expect(runner).toContain('["--max-old-space-size=8192", nextBin, "build", "--webpack"]'); expect(runner).toContain('[nextBin, "start", "--hostname"'); expect(runner).not.toContain('[nextBin, "dev", "--hostname"'); + // Next 16.3 typechecks the run-root tsconfig; TS 6 deprecates baseUrl (TS5101). + // Keep baseUrl + src-relative paths and silence via ignoreDeprecations (#1798). + expect(runner).toContain('ignoreDeprecations: "6.0"'); + expect(runner).toContain('baseUrl: "../.."'); + expect(runner).toContain('paths: { "@/*": ["src/*"] }'); expect(runner).toContain('NODE_ENV: "production"'); expect(runner).toContain('PLAYWRIGHT_OFFLINE_MODE: "true"'); expect(runner).toContain('NEXT_PUBLIC_MOCKUPS_ENABLED: mockupProjectRequested ? "true" : "false"');