diff --git a/docs/branch-review-ledger.md b/docs/branch-review-ledger.md index 77760bc02d..f67efb8a1e 100644 --- a/docs/branch-review-ledger.md +++ b/docs/branch-review-ledger.md @@ -672,27 +672,29 @@ Records before 2026-07-28 were written by hand and had drifted: 146 lines carrie | 2026-08-06 | a24f74fdf0134487a03dce37dd9f1e9bd18502f5 | a24f74fdf0134487a03dce37dd9f1e9bd18502f5 | PR #1614 post-merge RAG index restoration audit | Pass - guard-only migration, no DDL, no ranking/RPC change; pr-policy ragRanking=false so no eval-canary required; 1 P3 doc nit (#248 renumber note says 237->246, row is #248) | check:migration-role; npx vitest run tests/supabase-schema.test.ts (74 passed); check:outstanding-issues | | 2026-08-06 | PR #1614 / codex/restore-rag-indexes-20260804 | a24f74fdf0134487a03dce37dd9f1e9bd18502f5 | PR #1614 post-merge RAG index restoration audit | Pass - guard-only migration, no DDL, no ranking/RPC change; pr-policy ragRanking=false so no eval-canary required; 1 P3 doc nit (#248 renumber note says 237->246, row is #248); supersedes 2026-08-06 row (ref column mistakenly held commit SHA instead of PR ref, breaking ledger:lookup per Devin/Sentry review on PR #1636) | check:migration-role; npx vitest run tests/supabase-schema.test.ts (74 passed); check:outstanding-issues | | 2026-08-06 | claude/implement-97vpz7 | 00ab7bfd34684bc854d15a3f28987674098a7130 | PR #1646 soft-tail answer-cache skip + soft-tail test hardening | fixed — answer-path soft-tail skip via rag-query-guard helpers; soft-tail fixture pins; duplicate memo test removed; in-corpus assert narrowed; budget 4362 | test:rag-query-guard+unsupported-cache+classifier-memo 22/22,check:maintainability-budgets 4362/4362 | +| 2026-08-06 | cursor/grok-quick-wins-a2c0 (PR #1651) | 49f82b831342e4666f76e307d5c61cba8db2a029 | Run PR sweep: CI fix + threads + drift | before: Sentry+Devin threads (double-zoom, issues:done, TOKENS px) + stale queue renumber after deletes; after: fixed+pushed; 5 threads resolved; CI queued awaiting runners; merge-tree clean; no provider-backed checks | vitest gestures+hide-on-scroll 35 passed; outstanding-issues gate+writer self-test (incl. multi-queue prune) passed; no provider-backed checks run | +| 2026-08-06 | cursor/grok-quick-wins-a2c0 (PR #1651) | 5d625d3e64752df0655c071b061642cfbbe4ea5f | Run PR sweep: CI fix + threads + drift | before: Sentry+Devin threads (double-zoom, issues:done, TOKENS px) + stale queue renumber; after: fixed in 38b7f8e4+5d625d3e; 5 threads resolved; CI queued on runners; merge-tree clean | vitest gestures+hide-on-scroll 35 passed; outstanding-issues gate+writer self-test passed; no provider-backed checks run | +| 2026-08-06 | temp-rebase | 868a8a2800351ce85a2ad13e14d80550cbc3e668 | Merge conflict resolution and CI fixes | Verified and ready for PR | verify:pr-local | | 2026-08-06 | claude/pr-handoff-stop-hook (PR #1649) | fff524d73ebfafeef7bdc50752a6d14f253ebc2e | Run PR sweep: CI fix + threads + drift | before: 5 unresolved threads (Devin create-from-output + 4 CodeRabbit), mergeable/BLOCKED, Actions major outage leaving CI pending; after: hardened jq-less input/output separation + session fail-open + prefix unlock + tests (9 passed) in fff524d73ebfafeef7bdc50752a6d14f253ebc2e, threads replied+resolved, branch current with main, CI re-triggered (Actions outage — not babysat) | npx vitest run tests/pr-handoff-stop.test.ts (9 passed); bash -n hook OK; no provider-backed checks run | | 2026-08-06 | claude/pr-handoff-stop-hook (PR #1649) | f67e5c9103c3e1483ad8e034fe7a6757c2362d74 | Run PR sweep: CI fix + threads + drift | before: 5 unresolved threads (Devin create-from-output + 4 CodeRabbit), mergeable/BLOCKED, Actions major outage leaving CI pending; after: hardened jq-less input/output separation + session fail-open + prefix unlock + tests (9 passed) in f67e5c9103c3e1483ad8e034fe7a6757c2362d74, threads replied+resolved, branch current with main, CI re-triggered (Actions outage — not babysat) | npx vitest run tests/pr-handoff-stop.test.ts (9 passed); bash -n hook OK; no provider-backed checks run | | 2026-08-06 | claude/pr-handoff-stop-hook (PR #1649) | 36c1bccd89f976bcae3dabf8f5787198db5df078 | Run PR sweep: CI fix + threads + drift | before: 5 unresolved threads (Devin create-from-output + 4 CodeRabbit), mergeable/BLOCKED, Actions major outage leaving CI pending; after: hardened jq-less input/output separation + session fail-open + prefix unlock + tests (9 passed) in 36c1bccd89f976bcae3dabf8f5787198db5df078, threads replied+resolved, branch current with main, CI re-triggered (Actions outage — not babysat) | npx vitest run tests/pr-handoff-stop.test.ts (9 passed); bash -n hook OK; no provider-backed checks run | | 2026-08-06 | claude/pr-handoff-stop-hook (PR #1649) | 3403126bc6cd86145d6921a3fe4d081181e8a113 | Run PR sweep: CI fix + threads + drift | before: 5 unresolved threads (Devin create-from-output + 4 CodeRabbit), mergeable/BLOCKED, Actions major outage leaving CI pending; after: hardened jq-less input/output separation + session fail-open + prefix unlock + tests (9 passed) in 3403126bc6cd86145d6921a3fe4d081181e8a113, threads replied+resolved, branch current with main, CI re-triggered (Actions outage — not babysat) | npx vitest run tests/pr-handoff-stop.test.ts (9 passed); bash -n hook OK; no provider-backed checks run | | 2026-08-06 | claude/pr-handoff-stop-hook (PR #1649) | 057a5579e538fcacc15feb8a0ac7fa580b3decb4 | PR #1649 review-and-fix | fixed: Bugbot cross-session prune disarm + marker-write fail-open context + deny gh pr comment/review; superseded dead Run PR ledger HEADs; merge-tree clean vs main; threads cleared; CI re-trigger on push | vitest:pr-handoff-stop 11/11; verify:cheap 516 files/5457 tests; verify:pr-local pass (format+lint+typecheck+test+rag-fixtures); bash -n hook OK; security-review: no P0/P1; no provider gates | | 2026-08-06 | claude/pr-handoff-stop-hook (PR #1649) | 057a5579e538fcacc15feb8a0ac7fa580b3decb4 | Run PR sweep: CI fix + threads + drift | supersede: prior stacked Run PR rows used unresolvable HEADs (fff524d7/f67e5c91/3403126b); reviewed product tip is this SHA (ledger bookkeeping may sit one commit above); Bugbot prune+context+comment/review fixes landed | vitest:pr-handoff-stop 11/11; verify:cheap pass; verify:pr-local pass | -| 2026-08-06 | temp-rebase | 868a8a2800351ce85a2ad13e14d80550cbc3e668 | Merge conflict resolution and CI fixes | Verified and ready for PR | verify:pr-local | -| 2026-08-07 | codex/docker-delivery-hardening (PR #1656) | fe339678ca23fc794238f458f0537a33f1b76c2c | prlanded | MERGED; tip tree empty vs squash fe339678; remote branch deleted | prlanded content verify; no provider-backed checks | | 2026-08-06 | claude/settings-nav-freeze-desktop-tdzh7z (PR #1641) | d4ecd2b5fc48a8d8f37f081cac2d80beb749df01 | Run PR sweep: CI fix + threads + drift | before: mergeable/BLOCKED, 0 unresolved threads, 0 behind main; prior CI reds were infra (npm ECONNRESET on Unit coverage; e7f380f3 cancelled at Set up job). after: pushed d4ecd2b5 ResizeObserver pin-clamp distance reset; all review threads remain resolved; CI re-triggered but GitHub Actions major_outage — runs pending/queued, no product failure to fix; merge tree clean | local typecheck PASS; local lint (settings-dialog) PASS; format unchanged; no provider-backed checks run; hosted CI awaiting Actions recovery (run 31120931239) | | 2026-08-06 | claude/settings-nav-freeze-desktop-tdzh7z (PR #1641) | c31827e63c20788c5dabb22b96ddbf239c65f893 | Run PR sweep: CI fix + threads + drift | before: mergeable/BLOCKED, 0 unresolved threads, 0 behind main; prior CI reds were infra (npm ECONNRESET; cancelled Set up job). after: product fix d4ecd2b5 (ResizeObserver pin-clamp distance reset) + ledger row; all review threads resolved; merge tree clean; hosted CI pending on GitHub Actions major_outage (no product failure) | local typecheck PASS; local lint (settings-dialog) PASS; no provider-backed checks run; hosted CI awaiting Actions recovery | +| 2026-08-06 | cursor/mode-nav-pr-1647-a5eb | 4c8d70612f3be4a1267ed16b81e926a9f2e1ef50 | PR #1647 mode-nav | no high-confidence defects; medium: record pages lose mode destinations after Subnav removal (section-nav early return); addon-slot guard still coincidence-tested not runtime; includes() activeId fragile for future slugs | read mode-nav/*, page-secondary-navigation, mode-secondary-navigation, specifier/formulation record anchors + tests; catalog slug collision scan (0 hits); test:focused blocked (test paths changed) | +| 2026-08-06 | claude/ds-truth-fixes | 7a9c41a971aa9111f050cd39d4429ada1b3f4409 | PR #1655 heavy review-and-fix | fixed DownloadLink tone DOM leak + stale ToggleSwitch/Links §9 docs; merge-tree clean; verify:cheap+verify:pr-local green; CI re-queued after push | bugbot+deep-review; vitest ui-primitives+ui-v2 60p; verify:cheap 5448p; verify:pr-local format+lint+typecheck+test+build+rag-fixtures; no provider gates | +| 2026-08-07 | claude/pr-handoff-stop-hook (PR #1649) | 76169ebcea48ca5efd9859b9a1f8c579dcc8b834 | PR #1649 pr-handoff-stop hook + AGENTS.md/handoff docs | shipped and squash-merged as 76169eb; hook denies post-handoff PR/CI polling (shell gh, GitHub MCP pull_request/workflow/check/job_log/update_branch, Monitor/ScheduleWakeup/CronCreate) while leaving commit, push, ledger:append and PR create/merge allowed; anchored exemption keeps create_pull_request_review denied; known limit: .claude/settings.json binds Claude Code only, Codex/Cursor get AGENTS.md prose with no enforcement (captured as an outstanding issue). Row recorded late and against the merged squash commit because the branch tip 2ad32de9b is unreachable after branch deletion | named #1649 gates: check-docs-links PASS (1629 refs); ci-change-scope --self-test PASS; check-gate-manifest PASS; check-codex-cloud-setup PASS (static); check-branch-review-ledger PASS; check-outstanding-issues PASS; Prettier clean on AGENTS.md/.claude/settings.json/handoff SKILL; bash -n hook clean; classifyPullRequestFiles all risk flags false; ~20 hook payloads exercised; incomplete vs full handoff: verify:pr-local NOT run (no node_modules); verify:ui NOT run (no UI delta); no provider-backed checks run | +| 2026-08-07 | codex/docker-delivery-hardening (PR #1656) | fe339678ca23fc794238f458f0537a33f1b76c2c | prlanded | MERGED; tip tree empty vs squash fe339678; remote branch deleted | prlanded content verify; no provider-backed checks | | 2026-08-07 | claude/settings-nav-freeze-desktop-tdzh7z (PR #1641) | 7d3e62677ae178952aeca82048b492c4b84eaf05 | prlanded | MERGED; tip tree empty vs squash 7d3e6267; remote branch deleted | prlanded content verify; no provider-backed checks | | 2026-08-07 | cursor/viewer-phase1-shell-extract-1db8 (PR #1665) | bd46a39ac02e604eb45178b5ed38d39f06cc6830 | prlanded | MERGED; remote branch deleted; squash tip on main | prlanded; no provider-backed checks | -| 2026-08-06 | cursor/mode-nav-pr-1647-a5eb | 4c8d70612f3be4a1267ed16b81e926a9f2e1ef50 | PR #1647 mode-nav | no high-confidence defects; medium: record pages lose mode destinations after Subnav removal (section-nav early return); addon-slot guard still coincidence-tested not runtime; includes() activeId fragile for future slugs | read mode-nav/*, page-secondary-navigation, mode-secondary-navigation, specifier/formulation record anchors + tests; catalog slug collision scan (0 hits); test:focused blocked (test paths changed) | | 2026-08-07 | claude/new-session-6fz57i (PR #1647) | 47cffe5f65d9e1d74e4b97b8bb13fecd6b73aebc | prlanded | MERGED: mode-nav roll-out to DSM/Specifiers/Formulation/Differentials; tip 71edf468 empty vs squash 47cffe5f; remote branch deleted | content tree empty vs squash; no provider-backed checks run | | 2026-08-07 | claude/ds-token-tracking-scale (PR #1663) | 82b6f5a4c02c163aba4391e7ca5a1ab77780e7ae | prlanded | MERGED: name letterspacing scale and ratio tokens; tip ec0b03c3 empty vs squash 82b6f5a4; remote branch deleted | content tree empty vs squash; no provider-backed checks run | | 2026-08-07 | claude/sidebar-closed-default-i6n2fk (PR #1637) | 2f881abf8524742984ece90cb631f78658c87a19 | prlanded | MERGED: desktop sidebar defaults collapsed; tip empty vs squash; remote branch deleted | content tree empty vs squash; no provider-backed checks run | | 2026-08-07 | claude/answer-shell-ds-adoption (PR #1658) | d9221389c5b11123e7d7bc882bda342a6fd9e11d | prlanded | MERGED: AnswerCard on live answer shell; tip empty vs squash; remote branch deleted | content tree empty vs squash; no provider-backed checks run | -| 2026-08-06 | claude/ds-truth-fixes | 7a9c41a971aa9111f050cd39d4429ada1b3f4409 | PR #1655 heavy review-and-fix | fixed DownloadLink tone DOM leak + stale ToggleSwitch/Links §9 docs; merge-tree clean; verify:cheap+verify:pr-local green; CI re-queued after push | bugbot+deep-review; vitest ui-primitives+ui-v2 60p; verify:cheap 5448p; verify:pr-local format+lint+typecheck+test+build+rag-fixtures; no provider gates | | 2026-08-07 | claude/ds-truth-fixes (PR #1655) | cc349d1305df7cc0619d73a9487d8eb04d65acff | prlanded | MERGED; squash tip empty vs branch tip 1ffa4be19ea91e4da686082aec832cba5eddb47f; design-system truth fixes + retire left/right knob | content tree empty vs squash; no provider-backed checks run | | 2026-08-07 | cursor/document-cover-thumbnails-b74c (PR #1661) | 096ba3138fe4dda182d98cc2f9c4e0fe9a09132b | prlanded | MERGED; squash tip empty vs branch tip 04934971711f2f7d346bbe6e0b9c0c8cd9776e43; first-page PDF cover thumbnails on document search cards | content tree empty vs squash; no provider-backed checks run | -| 2026-08-06 | cursor/grok-quick-wins-a2c0 (PR #1651) | 49f82b831342e4666f76e307d5c61cba8db2a029 | Run PR sweep: CI fix + threads + drift | before: Sentry+Devin threads (double-zoom, issues:done, TOKENS px) + stale queue renumber after deletes; after: fixed+pushed; 5 threads resolved; CI queued awaiting runners; merge-tree clean; no provider-backed checks | vitest gestures+hide-on-scroll 35 passed; outstanding-issues gate+writer self-test (incl. multi-queue prune) passed; no provider-backed checks run | -| 2026-08-06 | cursor/grok-quick-wins-a2c0 (PR #1651) | 5d625d3e64752df0655c071b061642cfbbe4ea5f | Run PR sweep: CI fix + threads + drift | before: Sentry+Devin threads (double-zoom, issues:done, TOKENS px) + stale queue renumber; after: fixed in 38b7f8e4+5d625d3e; 5 threads resolved; CI queued on runners; merge-tree clean | vitest gestures+hide-on-scroll 35 passed; outstanding-issues gate+writer self-test passed; no provider-backed checks run | | 2026-08-07 | cursor/grok-quick-wins-a2c0 (PR #1651) | 2563b4adf4f0c0580ca371acfee94f9ae1ca3d0f | prlanded | MERGED; squash tip empty vs branch tip 4655643770dba7ca4078f1586c0461fd91657bf9; Grok-safe quick wins (tokens, a11y, perf, gates) | content tree empty vs squash; no provider-backed checks run | | 2026-08-07 | cursor/viewer-phase0-gesture-a11y-1db8 (PR #1660) | 097dfd245f798f8105eeb6c1cf4fc077f969496f | prlanded | MERGED; squash tip empty vs branch tip 810cfc9b4a1c476a0dcc995bffb00d7329a85686; Phase 0 gesture INP, preview a11y, image decode | content tree empty vs squash; no provider-backed checks run | +| 2026-08-07 | claude/pr-handoff-loop-prevention-54y5zr (PR #1670) | dfe2946110e0ff93bd4acc571ae79c26b79a7a85 | PR #1670 heavy review-and-fix | synced origin/main (behind-but-clean DIRTY cleared); fixed CodeRabbit checks-cell to name exact #1649 gates + incomplete verify:pr-local/ui + no provider checks; Bugbot none; no P0/P1; #258/#ledger delta accurate; merge-tree clean; threads cleared | verify:cheap 519 files/5493 passed; verify:pr-local docs scope (format+docs+ledger+outstanding-issues); check:branch-review-ledger; check:outstanding-issues; no provider gates | diff --git a/docs/outstanding-issues.md b/docs/outstanding-issues.md index f73d9a53dc..970e19cbcb 100644 --- a/docs/outstanding-issues.md +++ b/docs/outstanding-issues.md @@ -166,7 +166,7 @@ removed after current-main verification; it is not missing recommended work. | 113 | `#257` | Optional | High — formulation/specifiers flake | Standing until second reproduction | 15–30 min | Single unreproduced ui-formulation flake when run with ui-specifiers — record a second sighting only; do not quarantine until three on the same SHA. **Stop:** do not weaken assertions. | - + ## Open items > **Merged-main canary update (2026-07-23, run `30018289898`):** the new structured report correctly recorded evaluated tree `c24f2e8f2d30d0c59fc1eba025d3dcd63478137e`, run/attempt identity and `cross-region-runner` latency context. Golden retrieval remained 36/36 with document/content recall 1.0 and no failed cases. The 44-case answer gate had grounded-supported and unsupported-correct rates of 1.0, but failed because `neuroleptic-side-effect-escalation` again returned one citation where two are required (citation-failure rate 0.0227). `admission-discharge-comparison` again omitted the specific AKG admission document after `comparison_source_extractive_fallback`; `admission-discharge-coverage-paraphrase` was advisory-only at 24,870 ms. Answer cost was reported as `$0.234736`. Do not retry immediately: retain this as the first structured datapoint, compare it with the scheduled 2026-07-26 report, and keep retrieval/ranking unchanged. @@ -296,9 +296,11 @@ removed after current-main verification; it is not missing recommended work. | #252 | P2 | issue | check:bundle-budget counts mockup chunks, contradicting #013's initial-bundle position | The budget's totalGzipBytes comes from measureChunkPaths(walkJsFiles(CHUNKS_DIR)) — EVERY built client chunk, including routes that 404 in production. The manifest-scoped initialDashboardChunks set is used only for the fixture-payload assertion, not the budget. So two repo positions disagree about mockups and nothing says so: #013 records that mockup chunks 'are not an initial production bundle' and must not be restructured without deploy-artifact evidence, while the gate charges them against a repo-wide ceiling. PR #1580 is the live cost — a mockups-only PR blocked on 'FAIL +10.1% vs baseline (tolerance 10%)' for chunks no user can load; it has sat red and unmerged since 2026-08-02. Docs now state the mechanism (AGENTS.md gate bullet, CLAUDE.md mockups bullet) so it stops being a surprise, but the metric decision is unmade. Next action: pick one and make the script say so — (a) exclude mockup-only chunks from totalGzipBytes so the number means production weight, which matches #013 but removes all back-pressure on mockup growth (59 routes on main today, 4 more in open PRs); or (b) keep counting them, rename the reported metric so it does not read as production bundle weight, and treat the tolerance as a deliberate hygiene ceiling. Option (b) additionally wants the mockup share reported separately, which is the measurement #013 asks for before any prune. Stop: do not raise the tolerance or run --update to clear #1580 — that discards the only back-pressure without deciding anything. Renumbered from this PR's original #249 → #252 because main claimed #249–#251 via PR #1624. | session 2026-08-05 open-PR review; PR #1580 Build log; scripts/check-bundle-budget.mjs; ledger #013 | 2026-08-05 | | #253 | P3 | task | #1606 needs a hand-merge against merged PR #1615, not a rebase | MobileResultFilterControl's native — its change is the iOS 16px anti-zoom rule — so #1606's blue-highlight fix does not exist on main today. #1606 is still open (verified 2026-08-05, not closed) and reports mergeable_state 'dirty' against main because both PRs rewrote the same function with different designs; resolving it needs a hand-merge of the two implementations, not a rebase and not a close-and-redo. Two things to re-verify on the current head before merging: (1) the P2 from Codex review — ArrowDown/ArrowUp previously focused the current placeholder option even when disabled (Services' 'current', Formulation's 'Current search'), stranding keyboard users since every option was tabIndex=-1; the branch is reported to have since fixed this, but confirm on the exact head being merged. (2) its prior lint error, react-hooks/set-state-in-effect at search-results-header-band.tsx:670 (setMenuBox(null) synchronously inside useLayoutEffect), which PR #1620's new pre-push guard now catches before push. Also re-check the 3 Playwright failures previously seen on ui-stress and ui-tools single-line badge assertions against the current implementation. Stop: do not close #1606 to route around the conflict — it is the only open PR carrying this accessibility fix. Renumbered from this PR's original #250 → #253 because main claimed #249–#251 via PR #1624. | session 2026-08-05 open-PR review sweep; PR #1606 (open, dirty, verified live); Codex review thread on search-results-header-band.tsx:696 | 2026-08-05 | | #254 | P2 | issue | PR #1617's Codex Cloud acceptance evidence is pinned to a head the branch has moved past | PR #1617 is the surviving side of the Codex Cloud MCP dispute (PR #1613 was closed against it on 2026-08-05), and its whole case rests on one first-hand measurement: a fresh Codex Cloud task reporting 'no Railway tool exposed', 'no Supabase tool exposed', 'no GitHub tool exposed' — zero provider tools from repo-written MCP config — while the hosted OAuth path passed in ChatGPT. That evidence is recorded in docs/audit/cloud-connection-acceptance-2026-08-05.md against task head 76dfe85fa93787b3845d0bd460aa18ff753ca2ca, and the PR body states 'The final branch head is 7d485f88db391cc7e8e73c57ddbde61f532375fc'. The branch head is now bf7684a77ef5fa5d53a1e7891cb7f446d4741e4a, so both pins are stale and the acceptance no longer describes what would merge. This matters more than usual because the acceptance IS the argument: #1613 was closed on the strength of it, and its own merge gate is the kind of exact-head check that a moved head invalidates. Next action: before #1617 leaves draft, re-run the fresh Codex Cloud acceptance at the exact current head and update both the report and the body pin, or state explicitly which parts of the evidence are head-independent (the connector-page absence of Railway/Supabase is a product-surface fact and does not depend on the head; the zero-tool discovery result does). Stop: do not treat the 76dfe85f/7d485f88 evidence as covering the current head, and do not reopen #1613 on the basis that #1617's evidence is stale — staleness is not refutation. Renumbered from this PR's original #251 → #254 because main claimed #249–#251 via PR #1624. | session 2026-08-05 open-PR review sweep; PR #1617 body and docs/audit/cloud-connection-acceptance-2026-08-05.md | 2026-08-05 | -| #255 | P2 | issue | Remote/Cloud containers cannot run any browser gate: Playwright lock drift plus a missing Chromium build | In the 2026-08-05 remote container, npm run verify:pr-local failed closed at its first precondition — 'check:installed-lock-parity ... playwright: installed 1.62.0 does not match locked 1.62.1' — and Chromium could not launch at all: 'Executable doesn't exist at /opt/pw-browsers/chromium_headless_shell-1234/...' while the image only ships chromium-1194 and chromium_headless_shell-1194. So verify:ui, verify:phone-chrome and verify:release are all unrunnable in a remote session regardless of the diff, and verify:pr-local cannot even reach its selected gates. This is not a one-off 'run npm ci': the installed Playwright disagrees with the lockfile, and installing the locked 1.62.1 would request a browser revision the image also does not carry, so the fix is an image/pin alignment rather than an install. Consequence worth writing down: PRs authored from remote sessions can only produce static and unit evidence locally and must delegate browser proof to CI's Production UI jobs, which is what #1620/#1621/#1622 did — #1621's Chromium evidence came entirely from CI (0 failed of 17, all three Production UI shards). Next action: align the container image's Playwright browser builds with the lockfile pin, or document the delegation explicitly in docs/testing.md so a remote session does not read a fail-closed parity error as a defect in its own change. Related but distinct from #149, which is about the parity checker only comparing seven top-level packages rather than about an actual blocking drift. Stop: do not work around it by setting PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD or pointing executablePath at the mismatched 1194 build to force a green browser run — a browser gate run against the wrong revision is not evidence. Renumbered from this PR's original #252 → #255 because main claimed #249–#251 via PR #1624. | session 2026-08-05 open-PR review sweep; verify:pr-local and verify:phone-chrome attempts on PRs #1620/#1621 | 2026-08-05 | +| #255 | P2 | issue | Remote/Cloud containers cannot run any browser gate: Playwright lock drift plus a missing Chromium build | In the 2026-08-05 remote container, npm run verify:pr-local failed closed at its first precondition — 'check:installed-lock-parity ... playwright: installed 1.62.0 does not match locked 1.62.1' — and Chromium could not launch at all: 'Executable doesn't exist at /opt/pw-browsers/chromium_headless_shell-1234/...' while the image only ships chromium-1194 and chromium_headless_shell-1194. So verify:ui, verify:phone-chrome and verify:release are all unrunnable in a remote session regardless of the diff, and verify:pr-local cannot even reach its selected gates. This is not a one-off 'run npm ci': the installed Playwright disagrees with the lockfile, and installing the locked 1.62.1 would request a browser revision the image also does not carry, so the fix is an image/pin alignment rather than an install. Consequence worth writing down: PRs authored from remote sessions can only produce static and unit evidence locally and must delegate browser proof to CI's Production UI jobs, which is what #1620/#1621/#1622 did — #1621's Chromium evidence came entirely from CI (0 failed of 17, all three Production UI shards). Next action: align the container image's Playwright browser builds with the lockfile pin, or document the delegation explicitly in docs/testing.md so a remote session does not read a fail-closed parity error as a defect in its own change. Related but distinct from #149, which is about the parity checker only comparing seven top-level packages rather than about an actual blocking drift. Stop: do not work around it by setting PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD or pointing executablePath at the mismatched 1194 build to force a green browser run — a browser gate run against the wrong revision is not evidence. Renumbered from this PR's original #252 → #255 because main claimed #249–#251 via PR #1624. **Second reproduction 2026-08-07 (remote container, PR #1670):** identical parity failure, same versions — 'playwright: installed 1.62.0 does not match locked 1.62.1' — two days later on a different image instance, so this is a standing property of the remote image rather than one bad container. New detail: the diff was docs-only (two append-only ledger files), and parity still halted `verify:pr-local` at step 2 of a 10-step plan that contained no browser gate at all. So the blast radius is wider than browser proof: a remote session cannot complete the PR-local gate for ANY scope, and has to re-run the selected steps by hand to get evidence (done there: the remaining eight all passed). That strengthens the documentation half of the next action — docs/testing.md should say a remote session may see this on a diff that never touches a browser. | session 2026-08-05 open-PR review sweep; verify:pr-local and verify:phone-chrome attempts on PRs #1620/#1621 | 2026-08-05 | | #256 | P2 | issue | Declared information-page section sets whose target ids nothing renders | A set in informationPageSectionDefinitions claims its route before the mode branch, then AvailableInformationPageNavigation drops every item whose targetIds are absent from the DOM and returns null, so the page shows no navigation at all. Proven live on PR #1647: specifierSections/formulationSections declared ten ids (specifier-overview, formulation-five-ps, and eight more) that no component rendered; invisible while those pages carried their own subnav, a dead end the moment it moved to the shared bar. Fixed for those two by wiring the anchors in. Suspected remaining: form-overview and the differential-presentation-* set returned no literal id= match. Next: verify each declared set at route level and either render the anchors or delete the set. Do NOT audit by grepping for id=: several live sections are rendered through a sectionId prop instead (source-evidence), so a source scan reports them dead and would have to be muzzled to pass — assert against the rendered DOM per route. | session 2026-08-06; PR #1647; Devin review finding | 2026-08-06 | | #257 | P3 | issue | Single unreproduced ui-formulation flake: keeps specifier and formulation route families clinically separate | Observed once on 2026-08-06 at PR #1647 head f5833acc, running tests/ui-formulation.spec.ts + tests/ui-specifiers.spec.ts together against local Chromium (1 failed, 11 passed). Did NOT reproduce: passed in isolation with --grep, and passed again on a full-file re-run (7/7). Recorded only so a second sighting is recognisable as a second rather than looking like a first. Per docs/testing.md this is one reproduction of three — do NOT quarantine, and do not weaken the assertion. Next: no action unless it recurs; if a second reproduction lands on the same SHA, note it here, and only on a third open a tests/flake-ledger.json entry with @quarantine and a <=30-day expiry. | session 2026-08-06; PR #1647 | 2026-08-06 | +| #258 | P2 | rec | The PR-handoff stop rule is enforced for Claude Code only; Codex and Cursor get prose with no gate | **Outcome:** a session that opens a PR stops following it in every agent this repo supports, not just Claude Code. **Detail:** PR #1649 added `.claude/hooks/pr-handoff-stop.sh` plus the AGENTS.md "Stop when the pull request is open" section. The hook is registered in `.claude/settings.json`, which only Claude Code reads, so the PostToolUse marker and the PreToolUse denials (shell `gh pr checks/status/view/run watch`, GitHub MCP tools named pull_request/workflow_run/workflow_job/check_run/check_suite/job_log/update_branch, and Monitor/ScheduleWakeup/CronCreate) simply do not exist for Codex or Cursor sessions. Those agents get the AGENTS.md prose and nothing else — and prose alone is exactly what was already in force, and already insufficient, before #1649. Cost is the same long tail of post-handoff CI polling the hook was built to cut, just relocated to whichever agent lacks the gate; a cloud Codex session is the worst case because nothing naturally ends it. **Next:** cheapest first — check whether Codex and Cursor expose any pre-tool interception this repo can register (Codex plugin hooks under `plugins/clinical-kb/`, Cursor rules under `.cursor/`); if neither offers a deny path, the fallback is a shared marker file plus a wrapper the agent is told to route `gh` through, which is weaker but still detectable. If no mechanism exists at all, record that explicitly here so the gap is a known limit rather than an open task. **Stop:** do not weaken the Claude Code hook to make the tools symmetric, and do not add a second copy of the deny list — one script, multiple registrations. | PR #1649; .claude/hooks/pr-handoff-stop.sh; .claude/settings.json; AGENTS.md "Stop when the pull request is open"; session 2026-08-07 | 2026-08-07 | +| #260 | P2 | task | Two unpushed Sentry commits are stranded on a Windows-only branch and will be lost with that machine | **Outcome:** the Sentry setup/logging-hardening work is either shipped or consciously discarded, not left sitting in one machine's reflog. **Detail:** `claude/cloud-pr-loop-prevention-bc052b` carries two commits — `c3c9d6a31` and `abbcdc8e9`, ~389 lines across `src/sentry.*.config.ts`, `src/lib/env.ts`, `src/lib/supabase/client.tsx`, `src/components/ui-primitives.tsx` — that were never pushed and are not the authoring session's own work. The branch does not exist on the remote, so the commits are unreachable from any cloud or remote container; a 2026-08-07 remote session could not inspect, verify, or ship them and could only record their existence. The same worktree (`.claude/worktrees/pensive-borg-6be2f0`) still holds the same four files uncommitted. Two Sentry branches DO exist on origin — `claude/sentry-nextjs-sdk-setup-2v24q5` and `cursor/sentry-nextjs-sdk-7cee` — but whether either already carries this change is unconfirmed: a three-dot diff against `origin/main` from the remote container returned empty for both, which is not trustworthy as proof either way and was not pursued further. Note this touches `src/lib/env.ts` and `src/lib/supabase/client.tsx`, so it is not a docs-class change and needs a real gate whenever it does ship. **Next:** from the Windows machine, diff those two commits against the two remote Sentry branches to decide whether the work is already represented. If it is, delete the branch; if it is not, push it and open a PR rather than leaving it local. **Stop:** do not discard the commits blind, and do not assume the remote Sentry branches supersede them without a content diff — nothing has yet compared them. | session 2026-08-07 remote container; handoff notes from the PR #1649 session; origin branches claude/sentry-nextjs-sdk-setup-2v24q5 and cursor/sentry-nextjs-sdk-7cee | 2026-08-07 | ## Resolved / archive @@ -453,5 +455,6 @@ Move resolved rows here with the resolution date and a one-line outcome. Keep th | #223 | issue | MatchExplanationChips is exported with zero call sites anywhere in the repo | Resolved 2026-08-06: MatchExplanationChips already absent from source on main; confirmed no call sites. | 2026-08-06 | | #225 | issue | Favourites renders up to three EmptyState live regions at once | Resolved 2026-08-06: FavouritesEmptyMatches already rendered once outside breakpoint containers on main. | 2026-08-06 | | #246 | issue | `refetching` claims a CSS dimming that globals.css does not define | Resolved 2026-08-06: false CSS dimming claim already removed from search-results-header-band; pulsing dot is the intentional refetch signal. | 2026-08-06 | +| #259 | task | Ledger row for claude/pr-handoff-loop-prevention-54y5zr (PR #1670) is still owed | Resolved 2026-08-07, and not by this session: a Cursor review-and-fix sweep on PR #1670 appended the row for claude/pr-handoff-loop-prevention-54y5zr at dfe2946110e0ff93bd4acc571ae79c26b79a7a85 (scope 'PR #1670 heavy review-and-fix'), and refined the #1649 row's checks cell to name the exact gates after a CodeRabbit finding. The structural observation this row was opened for still holds and is worth keeping: a handoff whose deliverable IS a ledger append cannot append its own row without a second commit to that head cancelling its in-flight CI. What resolved it here was a DIFFERENT session picking the row up in a sweep that was already touching the branch — which is the practical answer to the pattern, and cheaper than either paying for a CI restart or writing the row post-merge against the squash commit. | 2026-08-07 |