diff --git a/docs/branch-review-ledger.md b/docs/branch-review-ledger.md index 11e467882..132dd0905 100644 --- a/docs/branch-review-ledger.md +++ b/docs/branch-review-ledger.md @@ -171,15 +171,17 @@ Records before 2026-07-28 were written by hand and had drifted: 146 lines carrie | 2026-07-30 | claude/outstanding-issues-triage-24c8ow | 8d2710fd6cbdc84e8c50a6c9bc0a1e1a0cd612c8 | open PR changed-scope review | APPROVE: completed items 095, 096, 104, 109, and 115 move to archive with no deletion, duplicate ID, or stale next-id. | check:outstanding-issues PASS; check:branch-review-ledger PASS; diff review; no unresolved threads | | 2026-07-30 | claude/latency-findings-impl-s8g01v | e7ff5e933ba1f34d5adbd46dd77c38aced11ed44 | open PR changed-scope review | APPROVE: ordering-risk documentation is accurate and the near-bottom refusal guard now proves its geometry is non-vacuous before asserting no hide. | diff check PASS; focused test review; no unresolved threads; exact-head Production UI required | | 2026-07-30 | claude/ci-testing-review-2l8klp | 2e2160bc8b9d2d824209c217c67cb9cac1be3a8d | open PR changed-scope review | APPROVE: three-way UI sharding, critical-first gating, measured drag travel, and gate-manifest updates preserve required-check aggregation and deterministic Playwright settings. | check:github-actions PASS; check:ci-scope PASS; check:gate-manifest PASS; ledger guards PASS; exact-head sharded Production UI required | +| 2026-07-30 | codex/docs-sync-automation | 76d7372d8aa886008e2fb637e5911e9c00bb33e3 | documentation synchronization automation review | APPROVE after deletion-path fix; no remaining P0-P2 findings | docs/update and static gates pass; focused Vitest admission blocked | | 2026-07-30 | PR #1430 | a9ae22ac4915e86d51ee05787059382a39bd8ba8 | phone chrome diagnostics and merge repair | fixed and ready for CI | issues guard; ledger guard; 37 focused tests; phone-chrome dry-run | -| 2026-07-30 | PR-1433 | e7a8102620b5b4847894b3df21f438304ea581bd | PR #1433 document result cards and action menu final review | fixed clipped menu, clipboard fallback focus loss, and inherited action typography; no remaining findings | DOM Vitest 4/4; focused Chromium 1/1; typecheck, Prettier, and diff checks pass | +| 2026-07-30 | PR-1442 | 35fc11a2665ecd0464a23949babbbddba8055dcd | PR #1442 documentation synchronization automation | hook is fail-closed for mixed staged inputs and does not auto-stage; generated inventories remain deterministic; no findings | docs update/checks pass; focused Vitest 4 passed; issue and ledger guards pass | | 2026-07-30 | PR-1440 | f7260cc6a0da87cb4df1ac95ef962967e667c3f0 | PR #1440 issue #102 ordering correction | accurately restores the two canary-gated retrieval ordering constraints; no findings | outstanding-issues and ledger guards pass; documentation-only diff | +| 2026-07-30 | PR-1445 | 07933e08cff6c7d81345e02c03727032ccf522b6 | PR #1445 close duplicate issue | correctly archives duplicate #140 while preserving #133 as the surviving open conflict-frequency record; no findings | outstanding-issues and docs-link guards pass; docs-only diff | +| 2026-07-30 | PR-1434 | f6bebf2a8c658df8b3840c1b1133be5c94a977b0 | PR #1434 Codex Cloud setup consolidation and prompt perfector | fixed Cloud runtime verification gaps and reconciled duplicate implementation after #1438; no remaining findings | check:codex-cloud pass; codex-cloud-setup Vitest 4/4; outstanding-issues and ledger guards pass | | 2026-07-30 | PR #1432 | a2b53c815b3c060dec2619af2855a63f9f496858 | Playwright browser preflight review and repair | fixed; focused tests pending coordinator | Prettier PASS; issues guard PASS; focused Vitest blocked by active Playwright lease | | 2026-07-30 | PR #1432 | f85995ade3a19513a531713724813adc742c360d | Playwright browser preflight verification | focused tests pass; typecheck lease-blocked | 16 focused tests PASS; Prettier PASS; typecheck admission blocked | | 2026-07-30 | PR-1432 | 7c7b63cf40d59652954e539ce1b3027005916bf1 | PR #1432 Playwright browser preflight final exact-head review | fixed existing project-isolation contract after preflight refactor; no remaining findings | preflight and isolation Vitest 9/9; typecheck pass; Prettier and diff checks pass | | 2026-07-30 | PR-1432 | a5d234302b57be6f7ce5d1957c9ec00bc7f191f0 | PR #1432 Playwright preflight and phone-scroll reliability | cross-platform preflight fails closed and production focus-restore race is removed from the phone-scroll proof; no remaining findings | preflight tests 9 passed; focused Chromium journey 2 passed; formatting and ledger guards pass | | 2026-07-30 | PR-1432 | 330086eff76f704ce6b9cf5405aeecfdd375027c | PR #1432 visual-config preflight follow-up | visual runs now preflight chromium-artifacts instead of the unrelated main browser matrix; unknown configs fail closed | config-selection tests added; formatting passes; exact-head CI pending | -| 2026-07-30 | PR-1445 | 07933e08cff6c7d81345e02c03727032ccf522b6 | PR #1445 close duplicate issue | correctly archives duplicate #140 while preserving #133 as the surviving open conflict-frequency record; no findings | outstanding-issues and docs-link guards pass; docs-only diff | | 2026-07-30 | claude/organize-local-worktree-d22bc3 | 2f26a53b5aeb3df451cf7b1d04f80b07edf0d6fe | docs organisation: dated-record filing, docs index gaps, orientation maps | PR #1436 opened — 5 dated docs filed into docs/audit and docs/archive, root codex-cloud-review moved under docs/prompts, 17 docs README index gaps closed, root data/ documented in CLAUDE.md + codebase-index; no product code, schema or RAG surface touched | docs:check-links 1368 refs pass; docs:check-scripts 378 pass; docs:check-index OK; format:check whole-tree clean; verify:cheap 26 static gates + lint + typecheck pass, unit 4562 pass / 1 pre-existing Windows path-separator failure in tests/repo-hygiene.test.ts | | 2026-07-30 | PR-1436 | 9d8e081f3e7003d4f2210b00a7b7e54bf7ca2f0b | PR #1436 documentation organization and link repair | fixed stale no-driver wording and renumbered three union-collided issue records; no remaining findings | docs index, links, scripts, outstanding-issues, and ledger guards pass | | 2026-07-30 | cursor/ci-hygiene-gates-1bf5 | b660dbc5a10d7ca3da03541028017f0abc6b5bd3 | ci-hygiene-gates-merge-readiness | NOT READY: cancel-to-green behavior still allowed required PR CI to pass incorrectly; fixed at subsequent head 8f3283d00da274dee507a1b8e9b611321d1f35be | check:ci-scope; check:gitleaks-pinned; scope-classify PR files ui_changed=false; cancelled-as-neutral simulation exposed #095 | @@ -188,12 +190,7 @@ Records before 2026-07-28 were written by hand and had drifted: 146 lines carrie | 2026-07-30 | PR #1446 / claude/ci-testing-review-2l8klp | 8be4f703d5729b4aa10e73ee8fbc77e03f400b8b | ci-testing-review-capture | Withdraws an invalid inference from the earlier records for this PR, on a correct Codex finding. Those rows argued that because the sibling documentScrollTop assertion did not fail, the scroll position held and scroll-restoration causes were ruled out. Playwright aborts a test at the first failing expect, so once anchorTop threw, documentScrollTop NEVER EXECUTED - its absence from the output shows nothing. The #142 row now says so and the class is not ruled out. The capture itself stands: the Services viewport-anchor failure is real, intermittent on byte-identical code (pass/pass/fail/pass-on-rerun), and distinct from #127. Separately CodeRabbit flagged :973 vs :1133 as inconsistent and then withdrew it: :973 is the test declaration and :1133 the thrown assertion, both reported by Playwright, and declaration lines drift (898 / 973 / 1041 across three tree states) which is why the exact title is the durable identity. | check:outstanding-issues PASS (140 rows, unique ids, next-id=143). Lesson: reasoning from an assertion that never ran is the same verified-vs-assumed error this session already hit twice in the other direction. | | 2026-07-30 | claude/x3-rag-coverage-gate-qx9j7d (PR #1454, squashed as 102bb1f) | 102bb1f5edf09e666d1be5934ff5dfb2aa5abcf0 | X3/#086 evidence coverage gate extraction from rag.ts into rag-coverage-gate.ts | clean and landed — byte-identical move verified against pre-merge main, rag.ts 5030->4780, budget ratcheted to 4780, no back-edge, public re-export preserved; squash captured 100% of branch content, nothing orphaned | workflow:rag-lab, focused vitest 81/81, check:maintainability-budgets 4780/4780, check:rag:fixtures 36 golden, eval:rag:offline 567/567, typecheck, lint, check:knip, format:check, verify:cheap 4569 passed, npm test 4569 passed, verify:pr-local build+bundle-scan, post-merge npm test on main 4574 passed | | 2026-07-30 | PR #1432 | 74adc5aa3f8a4dad659c7a40490288ef8efcb82e | Playwright browser preflight and phone-sheet focus repair | APPROVE after current-main sync: browser-project resolution fails closed, phone-sheet focus is stable, and no stale issue-ledger state remains. | 3 focused files 45 passed; phone-chrome dry-run; installed-lock parity; docs and ledger guards; formatting | -| 2026-07-30 | codex/outstanding-local-batch-final | 330d964a04406a9e123c674409f167746f7b9a28 | outstanding local task batch merge readiness | Reviewed changed scope; fixed the env-file bypass in the upload-limit parity guard. No unresolved findings. | Focused Vitest: 7 files, 125 tests passed; exact-head verify:cheap static gates and lint passed; typecheck/full unit pending coordinator availability. | -| 2026-07-30 | codex/outstanding-local-batch-final | 46ebd3f13a3e8b843026dd7d3d4024440970d7ae | upload-limit env regression type correction | Reviewed the test-only ProcessEnv annotation; no unresolved finding. | Focused test and typecheck awaiting repository coordinator; prior exact-head static gates and lint passed. | -| 2026-07-30 | codex/outstanding-local-batch-final | 7b63c28ca6ff9ab2f3599197ee6811292958e2c2 | final upload env fixture correction | Reviewed the contextual ProcessEnv construction after hosted readonly-property failure; no unresolved finding. | Prior hosted Build, Unit coverage, Production UI critical, containers and lint passed; exact-head typecheck rerun pending. | | 2026-07-30 | PR-1470 | 1932e81ece9361c08607d2ef01ad653a7df0ac8d | PR #1470 full diff vs origin/main | PASS after repair: #013 remains open and measurement-gated | check:outstanding-issues passed; docs:check-links 1408 passed; Prettier passed; git diff --check | -| 2026-07-30 | codex/outstanding-local-batch-final | 112ac9ba71f78df6e8d05d0e3fa2e3adf6ba4705 | PR #1480 Docker upload-limit review finding | FIXED P1: the Docker build now receives both server and browser limits, and container CI proves a matched lowered 50 MB pair. | check:upload-limits and check:github-actions passed; focused/typecheck/container rerun pending exact head. | -| 2026-07-30 | PR-1434 | f6bebf2a8c658df8b3840c1b1133be5c94a977b0 | PR #1434 Codex Cloud setup consolidation and prompt perfector | fixed Cloud runtime verification gaps and reconciled duplicate implementation after #1438; no remaining findings | check:codex-cloud pass; codex-cloud-setup Vitest 4/4; outstanding-issues and ledger guards pass | | 2026-07-30 | PR-1441 | c298432cffd2a1aee1b96edda9d32deb31be7f00 | PR #1441 upload-limit parity and issue-ledger closures | upload limit guard is fail-closed and safely wired; archived rows retain their dispositions; no findings | upload parity self-test/runtime pass; issue, ledger, gate-manifest, and docs-script guards pass | | 2026-07-30 | PR #1441 | d8bd22192ce974d4d2340ff26959ee41480218e9 | PR readiness: issue ledger, upload parity, CircleCI cleanup | FIXED: review found the Docker build lacked MAX_UPLOAD_MB input and open issue #119 still requested obsolete CircleCI investigation; both are repaired, with no remaining P0-P2 findings in scope. | upload parity default and 50/50 pass; 50/40 mismatch fails; outstanding-issues, branch-review-ledger, and gate-manifest guards pass | | 2026-07-30 | PR #1441 | 0b17e849406a03b87af20e627da6500a7cd03c2e | PR readiness: issue ledger, upload parity, CircleCI cleanup | FIXED: review repaired Docker build-time server parity, archived stale CircleCI row #119, and made the #095 aggregate harness portable; no remaining P0-P2 findings in scope. | verify:pr-local PASS on parent code tree 727ed55a7: 435 files, 4570 passed, build 1694 pages, client scan pass, RAG 36 cases/21 suites; latest-main docs, issue, review-ledger, and upload guards pass | @@ -205,19 +202,19 @@ Records before 2026-07-28 were written by hand and had drifted: 146 lines carrie | 2026-07-30 | codex/issue-ledger-upload-parity | f35a4ca178724ff59e7a876c4d819bed0b786662 | PR #1441 final current-main sync | approved after merging #1457 without overlap; upload parity and repository guards remain green | upload self-test pass; issues 141; ledger 141+1206; actions pin, format, diff pass | | 2026-07-30 | codex/issue-ledger-upload-parity | dc8068590d5be469ff30789b8b345896a3f1cdb9 | PR #1441 sync after PR #1470 | approved; catalogue payload disposition and upload-limit closures both preserved | upload self-test, issues, ledger, diff pass | | 2026-07-30 | codex/cloud-readiness-consolidation-20260730 | 8ff0a7ec309c80379bd8a9a76ab107a65ac7b837 | PR #1434 Codex Cloud setup and isolation tooling | approved after current-main sync, helper typing repair, static Cloud contracts, and isolation review | codex-cloud, skills, docs, maintainability, issues, ledger, format, isolation 14/14 pass; focused Vitest coordinator-blocked; shell runtime acceptance deferred to hosted Linux | -| 2026-07-30 | codex/outstanding-local-batch-final | 43de3c910ea1a361458586cfb0e5861e8e2d5ee6 | post-main reconciliation merge readiness | APPROVE: retained main's stronger #1441 upload guard, removed the duplicate checker/test, and preserved the six non-overlapping fixes; no unresolved findings. | Upload parity self-test/runtime, GitHub Actions, docs scripts, review ledger, outstanding issues, and diff checks pass; parent exact-head hosted suite fully green; final hosted rerun pending. | -| 2026-07-30 | codex/docs-sync-automation | 76d7372d8aa886008e2fb637e5911e9c00bb33e3 | documentation synchronization automation review | APPROVE after deletion-path fix; no remaining P0-P2 findings | docs/update and static gates pass; focused Vitest admission blocked | -| 2026-07-30 | PR-1442 | 35fc11a2665ecd0464a23949babbbddba8055dcd | PR #1442 documentation synchronization automation | hook is fail-closed for mixed staged inputs and does not auto-stage; generated inventories remain deterministic; no findings | docs update/checks pass; focused Vitest 4 passed; issue and ledger guards pass | | 2026-07-30 | codex/docs-sync-automation | fba8ab4af465c96b8aa318f25d792fefd10e9ada | PR #1442 documentation synchronization automation | approved after current-main conflict resolution, generated inventory refresh, and dirty-output preservation review | docs inventory 194/209; focused 5/5; index, links 1417, scripts 405, issues, ledger, format, diff pass; pre-commit executed successfully | | 2026-07-30 | codex/docs-sync-automation | 1c80a938f27af80df323fb1d6063ef9077f55fdf | PR #1442 hosted gate-count follow-up | approved after static CI exposed and corrected verify:cheap count drift | gate manifest, docs inventory, format, diff pass | | 2026-07-30 | claude/latency-findings-impl-s8g01v | fd3753b4c8cc041889c39f74a0f763edc358c183 | PR #1459 final docs issue review | PASS - no P0-P2 findings; restores open issue 105 and records deletion-guard gap | outstanding-issues, ledger guard, docs links, diff-check | | 2026-07-30 | codex/docs-sync-automation | e1c514f289a864bc741841accae5352a419fbb59 | PR #1442 sync after PR #1459 | approved; issue-evidence correction and docs automation closures preserved | issues, ledger, inventory, gate manifest, diff pass | +| 2026-07-30 | pr/1467 | 6b84090a7c4a57a19521a820bf4c488090fb6062 | docs: close rejected Playwright cache proposal | approved; measured rejection archived on current main | check:outstanding-issues; check:branch-review-ledger; docs inventory/links/scripts; Prettier; diff-check | | 2026-07-30 | codex/issue-ledger-upload-parity-v3 | 95b0e289f03afc46d45def9ed1a165cd614684fd | Replacement PR: issue closures, upload-limit parity, production env precedence | No findings; intended replacement scope preserved on current main | verify:pr-local PASS pre-rebase; exact-head runtime/install/format/lint PASS; focused guards PASS; typecheck rerun blocked by unrelated Playwright lease | | 2026-07-30 | codex/issue-ledger-upload-parity-v3 | 9dff07f85bcce7822eb2b2701b82a80d1e0a145e | PR #1482 Docker-context CI repair | No findings; hosted ENOENT fixed without weakening effective parity | hosted app-image log inspected; normal 150/150 PASS; Docker-context 50/50 PASS; Docker-context 50/40 rejected | | 2026-07-30 | codex/issue-ledger-upload-parity-v3 | 9867f72eddf51e25322028af6ff232dba3560871 | PR #1482 post-#1441 ledger-only salvage | No findings; duplicate implementation dropped and only four resolved issue records remain | diff vs origin/main two docs files; outstanding-issues PASS; branch-review-ledger PASS; main implementation byte-identical | | 2026-07-30 | codex/issue-ledger-upload-parity-v3 | 0a074d9b2572ee06f663d8bbee3b50fb6d4fbd9a | PR #1482 final current-main ledger-only review | No findings; current main preserved and PR diff is ledger-only | three-dot diff two docs files; issue and review ledger guards PASS; four resolutions verified against merged main | | 2026-07-30 | codex/issue-ledger-upload-parity-v3 | fc116cfa0cf06d359548c1bc00d383b872fb1a48 | PR #1482 upload-parity deployment-input repair | No findings; checker changes now trigger build, container, and Railway app paths | check:ci-scope PASS with single-file assertion; upload parity PASS; Railway config test queued behind primary live-provider lease | | 2026-07-30 | codex/issue-ledger-upload-parity-v3 | b4e68aa9e4892d4031479240f7783b7c22bd4bbb | PR #1482 final current-main review | PASS - no P0-P2 findings; ledger archives preserved and deployment inputs repaired | issues, ledger, docs links/scripts, ci-scope self-test, diff-check; hosted full unit pending | +| 2026-07-30 | pr/1467 | fc7abe7f7e7ecb97dc7896c16b5553256da3ad80 | docs: close rejected Playwright cache proposal | approved after current-main reconciliation; archive entry preserved | issue/ledger guards; docs inventory/links/scripts; Prettier; diff-check | +| 2026-07-30 | codex/ledger-next-20260730 | 268b201a1dbaed7cca6dff4a146b0319a5275216 | issue ledger closures, favourites partial-source status, CI and ledger guards | FIXED. No remaining P0-P2 findings. Reconciled current main row by row, retained current-main #105 and #136 dispositions, rejected the unsafe Playwright cache, and fixed favourites partial-source masking plus the indexed-search hydration race. | format PASS; static gates, lint, typecheck PASS; unit 4597 PASS, 3 SKIP, 1 stale donor failure repaired by exact-lock dependency; brace cap direct PASS; focused Chromium 1 PASS; production build PASS; ledger guards PASS | | 2026-07-30 | 0b01c56fe539598279b9393db5e207bc78fa41c9 | 0b01c56fe539598279b9393db5e207bc78fa41c9 | branch-cleanup-deletion-pending | redundant clean detached head already on origin/main; removal deferred by primary-dirty lease | clean status; merge-base ancestor of origin/main; no open PR | | 2026-07-30 | 018673ff5cadadbd799815cea8d742de28922754 | 018673ff5cadadbd799815cea8d742de28922754 | branch-cleanup-deletion-pending | redundant clean detached review base already on origin/main; removal deferred by primary-dirty lease | clean status; merge-base ancestor of origin/main; no open PR | | 2026-07-30 | codex/review-pr1438 | f13c261ee96405dc338db184ec74009bcd3699a3 | branch-cleanup-deletion-pending | redundant exact head merged in PR 1438; removal deferred by primary-dirty lease | clean status; GitHub merged exact head; zero cherry-pick-unique commits | @@ -240,42 +237,67 @@ Records before 2026-07-28 were written by hand and had drifted: 146 lines carrie | 2026-07-30 | codex/review-pr1445 | 483a1c6190dfbd1a5895ef2c419a73f0f2162f05 | branch-cleanup-deletion-pending | redundant exact head merged in PR 1445; removal deferred by primary-dirty lease | clean status; GitHub merged exact head; no active process | | 2026-07-30 | PR #1462 | 5146ae94e226a6e55968d80ecefa53c7cd5df9c3 | bounded inactive-work cleanup documentation | APPROVE after fix: both cleanup batches remain deferred behind the primary-checkout lease, and the resume instruction now names the executable repository command. | outstanding-issues guard; ledger guard; diff review; one review finding fixed | | 2026-07-30 | codex/organize-inactive-20260730 | e7b248e215714fbf823c784857f521f89d86fa3d | PR #1462 changed-scope review | PASS - no P0-P2 findings; exact-lock formatter resolution fails closed | guard-push self-test and focused contracts previously green; issues, ledger, docs, diff-check; hosted full unit pending | -| 2026-07-30 | pr/1467 | 6b84090a7c4a57a19521a820bf4c488090fb6062 | docs: close rejected Playwright cache proposal | approved; measured rejection archived on current main | check:outstanding-issues; check:branch-review-ledger; docs inventory/links/scripts; Prettier; diff-check | -| 2026-07-30 | pr/1467 | fc7abe7f7e7ecb97dc7896c16b5553256da3ad80 | docs: close rejected Playwright cache proposal | approved after current-main reconciliation; archive entry preserved | issue/ledger guards; docs inventory/links/scripts; Prettier; diff-check | +| 2026-07-30 | codex/ledger-next-20260730 | 1ee749bd71da45be2d6b9d3eb4913331696996a6 | issue ledger closures, favourites partial-source status, CI and ledger guards | FIXED. Supersedes the prior review after cleanly merging current main. No remaining P0-P2 findings; current-main #079 was retained, verified closures remained archived, and no product behavior changed during sync. | merge reconciliation + ledger:dedupe PASS; outstanding and branch ledger guards PASS; whole-tree format PASS; prior static, lint, typecheck, unit, build, RAG fixture, and focused Chromium evidence retained | | 2026-07-30 | PR-1473 | a2b2820c13a47425cfc0ea751e57ee35e9bd1105 | PR #1473 full diff vs origin/main | PASS after review repair: governance refusal and error-state contracts are consistent | outstanding-issues guard passed; docs links 1412 passed; docs index passed; Prettier passed; git diff --check | +| 2026-07-30 | codex/ledger-next-20260730 | ee66a39b63fd7e39448ab13a5a5b72441f5321be | issue ledger closures, favourites partial-source status, CI and ledger guards | FIXED. Supersedes prior reviews after merging current main answer-delivery design. No remaining P0-P2 findings; current-main #100 governance text was retained exactly, verified closures remained archived, and the sync added documentation only. | merge reconciliation + ledger:dedupe PASS; outstanding and branch ledger guards PASS; prior format, static, lint, typecheck, unit, build, RAG fixture, and focused Chromium evidence retained | +| 2026-07-30 | pr/1476 | 79822031e696cd3906ce01284ec9736938c40a74 | docs: record ESLint 10 ecosystem blocker | approved; blocker matches installed peer ranges and current main | runtime/install parity; issue/ledger; docs inventory/links/scripts; Prettier; diff-check | | 2026-07-30 | codex/reopen-issue-105 | b94a8f5a693cc44e8aaa0fe3ec5bb65a7c313a3b | Correct #105 status after PR #1482 | No findings; restores the withdrawn verification evidence and leaves the task open | outstanding issues PASS 146 rows 69 open 77 archived next-id 149; docs links and scripts PASS | | 2026-07-30 | codex/reopen-issue-105 | 65635235c91527c57d33dd8311d062d28ccff6d9 | PR #1483 current-main reconciliation | No findings; #105 remains open and main's #136 archival is preserved | issues PASS 146 rows 68 open 78 archived next-id 149; ledger PASS 161 live 1206 archived | | 2026-07-30 | pr/1483 | 76393b9a0c6603e2551898c89a33396f52949da3 | docs: reopen issue 105 after withdrawn verification | approved; restores pending LoadingPanel verification without disturbing PR 1462 | runtime/install parity; issue/ledger; docs inventory/links/scripts; Prettier; diff-check | | 2026-07-30 | pr/1483 | a84fa60eebdbe7a00193c268b401f7abd3cc554e | docs: reopen issue 105 after withdrawn verification | approved after PR 1473 sync; issue 105 remains correctly open | issue/ledger; docs inventory/links/scripts; Prettier; diff-check | -| 2026-07-30 | pr/1476 | 79822031e696cd3906ce01284ec9736938c40a74 | docs: record ESLint 10 ecosystem blocker | approved; blocker matches installed peer ranges and current main | runtime/install parity; issue/ledger; docs inventory/links/scripts; Prettier; diff-check | | 2026-07-30 | pr/1476 | 0fd5a3cdba612d30cfd75ea997177f6e29c34bd3 | docs: record ESLint 10 ecosystem blocker | approved after PR 1483 sync; ESLint blocker and issue 105 correction preserved | issue/ledger; docs inventory/links/scripts; Prettier; diff-check | +| 2026-07-30 | codex/ledger-next-20260730 | 23572a4ad4a6f1520d86715c647ad9d40ff6bb01 | issue ledger closures, favourites partial-source status, CI and ledger guards | FIXED. Supersedes prior reviews after merging current main. No remaining P0-P2 findings; #105 was correctly reopened on withdrawn evidence, current-main #090 and #125 were retained, and verified closures remained archived. | post-CI main reconciliation + ledger:dedupe PASS; outstanding and branch ledger guards PASS; prior hosted exact-head CI all green before base moved; fresh CI required for this head | | 2026-07-30 | pr/1465 | 4e34d97bb9eb5122b9d8f8e54c42793c727f5085 | issues: record fresh #133 evidence | approved; duplicate-ID race and Prettier prerequisite accurately recorded | issue/ledger; docs inventory/links; Prettier; diff-check | +| 2026-07-30 | codex/ledger-next-20260730 | b43817f6243faac8ba22de85a461324b1612ad72 | issue ledger closures, favourites partial-source status, CI and ledger guards | FIXED. Supersedes prior reviews after merging current-main #133 evidence. No remaining P0-P2 findings; PR #1451 and the concurrent #141 race are incorporated into the resolved compact-table outcome, with scoped Prettier protection verified. | main reconciliation + ledger:dedupe PASS; outstanding and branch ledger guards PASS; prior hosted CI green before base moved; fresh CI required for this head | | 2026-07-30 | PR #1477 | 26d713922006c1af8187994edfa76669dc14cd46 | PR #1477 fork-safe Codex autofix routing | Fixed fork routing to the PR head repository, added fail-closed metadata handling, reconciled current main, and found no remaining actionable defects. | check:codex-autofix-workflow; check:github-actions; check:pr-policy; check:outstanding-issues; check:branch-review-ledger; docs:check-inventory; docs:check-links; docs:check-scripts; typecheck; focused Vitest 53 passed; Prettier | | 2026-07-30 | PR #1477 | 20f795da2d9d0adafa6cb3117429ab3665129c0d | PR #1477 fork-safe Codex autofix routing | Refreshed onto current main after #1465; issue and ledger reconciliation remained clean and no new actionable defects were introduced. | check:outstanding-issues; check:branch-review-ledger; check:codex-autofix-workflow; focused Vitest 53 passed | +| 2026-07-30 | codex/ledger-next-20260730 | 072051eb83e0b8317880d6167d06b3865b4a6ff7 | issue ledger closures, favourites partial-source status, CI and ledger guards | FIXED. Supersedes prior reviews after merging current-main PR #1477. No remaining P0-P2 findings; the implemented #131 fail-closed Codex delivery contract replaces the earlier accepted-limitation wording, and all other resolved/open dispositions remain intact. | main reconciliation + ledger:dedupe PASS; outstanding, branch-review, and Codex autofix guards PASS; prior exact-head hosted CI all green before base moved; fresh CI required for this head | +| 2026-07-30 | codex/outstanding-local-batch-final | 330d964a04406a9e123c674409f167746f7b9a28 | outstanding local task batch merge readiness | Reviewed changed scope; fixed the env-file bypass in the upload-limit parity guard. No unresolved findings. | Focused Vitest: 7 files, 125 tests passed; exact-head verify:cheap static gates and lint passed; typecheck/full unit pending coordinator availability. | +| 2026-07-30 | codex/outstanding-local-batch-final | 46ebd3f13a3e8b843026dd7d3d4024440970d7ae | upload-limit env regression type correction | Reviewed the test-only ProcessEnv annotation; no unresolved finding. | Focused test and typecheck awaiting repository coordinator; prior exact-head static gates and lint passed. | +| 2026-07-30 | codex/outstanding-local-batch-final | 7b63c28ca6ff9ab2f3599197ee6811292958e2c2 | final upload env fixture correction | Reviewed the contextual ProcessEnv construction after hosted readonly-property failure; no unresolved finding. | Prior hosted Build, Unit coverage, Production UI critical, containers and lint passed; exact-head typecheck rerun pending. | +| 2026-07-30 | codex/outstanding-local-batch-final | 112ac9ba71f78df6e8d05d0e3fa2e3adf6ba4705 | PR #1480 Docker upload-limit review finding | FIXED P1: the Docker build now receives both server and browser limits, and container CI proves a matched lowered 50 MB pair. | check:upload-limits and check:github-actions passed; focused/typecheck/container rerun pending exact head. | +| 2026-07-30 | codex/outstanding-local-batch-final | 43de3c910ea1a361458586cfb0e5861e8e2d5ee6 | post-main reconciliation merge readiness | APPROVE: retained main's stronger #1441 upload guard, removed the duplicate checker/test, and preserved the six non-overlapping fixes; no unresolved findings. | Upload parity self-test/runtime, GitHub Actions, docs scripts, review ledger, outstanding issues, and diff checks pass; parent exact-head hosted suite fully green; final hosted rerun pending. | | 2026-07-30 | PR #1480 | 6c1e76f53aee87be8408cebc295744fbdce05367 | PR #1480 bounded outstanding reliability fixes | Fixed both review findings: documented the dark accent role and added partial favourites retry without hiding valid counts; no other actionable defects found. | focused Vitest 119 passed; docs index; issue and ledger guards; Actions and Codex workflow guards; Prettier; diff check; typecheck coordinator-blocked | +| 2026-07-30 | codex/ledger-next-20260730 | 2a590d8c56b04ce6202fa1c7814e9858363151c0 | issue ledger closures, favourites partial-source status, CI and ledger guards | FIXED. Supersedes prior reviews after merging current-main PR #1480. No remaining P0-P2 findings; current main's canonical partial-favourites implementation replaces the branch's duplicate notice helper, while the branch's ledger, CI, and indexed-source hydration changes remain intact. | focused overlap suite 7 files / 130 tests PASS; verify:cheap 32 gates PASS; unit 439 files / 4612 PASS / 3 SKIP; ledger guards and merge reconciliation PASS | | 2026-07-30 | codex/close-pr1480-issues | bf8ac88b024642eb45d1fead86f4ee30fce3f98d | archive PR 1480 issue resolutions | approved: five resolved rows moved intact to archive | check:outstanding-issues; prettier check; diff check | +| 2026-07-30 | codex/ledger-next-20260730 | 7d6a341b1ac0efdf001bf06146a297bd2cb2cb4c | issue ledger closures, favourites partial-source status, CI and ledger guards | FIXED. Supersedes prior reviews after merging current-main PR #1486. No remaining P0-P2 findings; #141 and #144 are archived from the implemented PR #1480 evidence, and current-main outcomes for #091, #128, and #134 are retained without changing source behavior. | docs-only main reconciliation + ledger:dedupe PASS; outstanding ledger 146 rows / 50 open / 96 archived PASS; branch-review ledger PASS; prior combined-tree verify:cheap 32 gates PASS | +| 2026-07-30 | PR-1469 | 02108d5424f8a3ab50f45808a6cc3cbd872e7555 | PR #1469 component state matrix coverage | PASS after current-main sync; tests execute enabled and disabled popup transitions plus document search loading, empty, and fault states | focused Vitest 2 files, 10 tests passed; outstanding-issues and branch-review-ledger guards passed; no unresolved review threads | +| 2026-07-30 | codex/ledger-next-20260730 | 85a6bdf74629096fba1b476e52b76e241665fd15 | issue ledger closures, favourites partial-source status, CI and ledger guards | FIXED. Supersedes prior reviews after merging current-main PR #1469. No remaining P0-P2 findings; #107 is archived with executing jsdom state-matrix coverage, and the branch's existing changes remain intact. | focused current-main state-matrix suite 2 files / 10 tests PASS; outstanding ledger 146 rows / 49 open / 97 archived PASS; branch-review ledger PASS; prior combined-tree verify:cheap 32 gates PASS | | 2026-07-30 | codex/close-issue-127 | 9bbb8486d399ed31b9bf43364579f466a4e66c67 | archive issue 127 after post-fix runs | approved: close condition satisfied with no post-fix recurrence | check:outstanding-issues; prettier check; diff check | | 2026-07-30 | codex/close-issue-127 | d5fd28f75b404046f13507aa3705d55898d7669c | review finding wording correction | approved: causal wording now matches PR 1427 implementation | check:outstanding-issues; prettier check; diff check | -| 2026-07-30 | PR-1469 | 02108d5424f8a3ab50f45808a6cc3cbd872e7555 | PR #1469 component state matrix coverage | PASS after current-main sync; tests execute enabled and disabled popup transitions plus document search loading, empty, and fault states | focused Vitest 2 files, 10 tests passed; outstanding-issues and branch-review-ledger guards passed; no unresolved review threads | | 2026-07-30 | claude/global-search-mockups-mrgmzl | e79e499839e56bff66aecc37d1c915ac3127e995 | prlanded | merged and verified by content | verify:cheap exit 0 (437 files, 4576 passed); verify:pr-local exit 0; CI pr-required green on a6f2281; squash e79e499 content diff vs branch tip empty; late aria-live/role=alert commit confirmed present on main | -| 2026-07-30 | codex/close-issue-105 | 09950abc8cf2d23455a6cbab3521bdec921ef272 | archive issue 105 after driven browser proof | approved: specific lazy fallback observed in driven desktop and phone Chromium | browser chunk-delay proof; check:outstanding-issues; prettier check; diff check | -| 2026-07-30 | PR-1475 | 6de5c321beac55860cc4b6fc7d26ef5a7e088f38 | PR #1475 ingestion behavioral extraction | PASS after current-main reconciliation; extracted decisions preserve entrypoint behavior and replace the matching source-grep assertion with executable coverage | focused Vitest 3 files, 27 tests passed; typecheck passed; outstanding-issues and branch-review-ledger guards passed; provider-backed ingestion not run | +| 2026-07-30 | codex/ledger-next-20260730 | 14508ca0406c29f3f7a31dc72db1e1d1d626c595 | issue ledger closures, favourites partial-source status, CI and ledger guards | FIXED. Supersedes prior reviews after merging current-main PRs #1481 and #1487. No remaining P0-P2 findings; #127 remains archived with the later exact-head evidence and #146 retains both new shard-1 flake data points. | docs-only main reconciliation + ledger:dedupe PASS; outstanding ledger 146 rows / 49 open / 97 archived PASS; branch-review ledger PASS; prior exact-head hosted CI all green before base moved | | 2026-07-30 | PR-1458 | 8c1975b178c67e4c54acffc395d85e38c43d39f5 | PR #1458 superseded root-gate reconciliation | PASS: retained only unique documentation corrections after PR #1480 landed the stronger tracked-root gate; archived resolved shared-hook issue #143 | docs index and links passed; outstanding-issues and branch-review-ledger guards passed; diff check passed | +| 2026-07-30 | PR-1475 | 6de5c321beac55860cc4b6fc7d26ef5a7e088f38 | PR #1475 ingestion behavioral extraction | PASS after current-main reconciliation; extracted decisions preserve entrypoint behavior and replace the matching source-grep assertion with executable coverage | focused Vitest 3 files, 27 tests passed; typecheck passed; outstanding-issues and branch-review-ledger guards passed; provider-backed ingestion not run | +| 2026-07-30 | codex/ledger-next-20260730 | 226ab1508e4a4eecd42fb473b9e19fb190fe5f0d | issue ledger closures, favourites partial-source status, CI and ledger guards | FIXED. Supersedes prior reviews after merging current-main PRs #1475 and #1458. No remaining P0-P2 findings; #106 and #143 are archived from implemented executable worker/indexing coverage and durable hook tracking. | focused worker/indexing suite 3 files / 27 tests PASS; CI-safe production-readiness READY; outstanding ledger 146 rows / 47 open / 99 archived PASS; branch-review ledger PASS | +| 2026-07-30 | codex/close-issue-105 | 09950abc8cf2d23455a6cbab3521bdec921ef272 | archive issue 105 after driven browser proof | approved: specific lazy fallback observed in driven desktop and phone Chromium | browser chunk-delay proof; check:outstanding-issues; prettier check; diff check | | 2026-07-30 | PR-1448 | 8ece7f345e93170c6bd242701eaff05f5504d98b | PR #1448 authenticated live workflow | PASS after review repair: protected-main-only checkout, explicit bounded mutations, scoped secrets, and static dispatch confirmation; no live provider workflow dispatched | GitHub Actions and PR-policy guards passed; focused Vitest 3 passed; docs links and scripts, issue and ledger guards, Prettier and diff checks passed | +| 2026-07-30 | codex/ledger-next-20260730 | 039b43a5e163c0f622a327ef50c36cf5249296cc | issue ledger closures, favourites partial-source status, CI and ledger guards | FIXED. Supersedes prior reviews after merging current-main PRs #1448 and #1488. No remaining P0-P2 findings; #105 is archived from driven Chromium evidence and the authenticated-live workflow remains explicitly provider-gated. | GitHub Actions pin guard PASS; outstanding ledger 146 rows / 46 open / 100 archived PASS; branch-review ledger PASS; focused authenticated-live test deferred by repository coordinator; fresh hosted Unit coverage required | +| 2026-07-30 | codex/ledger-next-20260730 | 9511c615bf94adf8c7ceee5cb1630c9a168b71c0 | issue ledger closures, favourites partial-source status, CI and ledger guards | FIXED. Supersedes prior reviews after merging current-main PR #1479. No remaining P0-P2 findings; all 146 IDs and 100 resolved dispositions are retained while main's file-wide Prettier exclusion and measured #133 evidence are incorporated. | main reconciliation + ledger:dedupe PASS; outstanding ledger 146 rows / 46 open / 100 archived PASS; branch-review ledger PASS; authenticated-live workflow test 1 file / 3 tests PASS | | 2026-07-30 | codex/outstanding-deletion-guard | da1bed4bcb05f2b975823c76bab0913278cfaea6 | issue 148 deletion guard | approved: no P0-P2 findings; base comparison is fail-closed in CI and preserves archive moves | verify:cheap; deletion self-test; unreadable-base proof; CI scope; GitHub Actions pin guard | -| 2026-07-30 | codex/sync-ci-anti-churn | 4f99c6d6dbcd4d2c16d5ec58183003c64d989ac8 | issue 145 anti-churn guidance | approved: guidance now covers both pushes and sync mutations without weakening cancellation | check:outstanding-issues; prettier AGENTS; diff check | -| 2026-07-30 | PR-1492 | a50640970a4e4197c64fba7239aeae073445fed9 | PR #1492 branch-sync churn review | FIXED P2: exact-head queued or in-progress workflows now block automated branch updates; Run PR guidance matches the executable guard | focused Vitest 1 file, 8 tests passed; Prettier passed; sync dry-run passed on 19 open PRs; diff check passed; no provider-backed application checks run | +| 2026-07-30 | codex/ledger-next-20260730 | a278acad1ca88c28e45619b6a28e3f245c49d786 | PR #1484 post-main reconciliation | Ready: merged ee34b4d2a row-by-row; preserved all 146 issue IDs and archived #148 | verify:cheap PASS (442 files, 4626 passed, 3 skipped); ledger guards and ci-scope PASS | | 2026-07-30 | codex/ingestion-fixes-current-main-20260731 | fe68a0a817213ef33ddeee35b45034656986d089 | ingestion fixes replacement release readiness | ready after fixing unreachable partial-batch handling and invalid recovery owner lookup | 4 focused files 183 tests passed; typecheck passed; production-readiness READY; git diff --check passed | -| 2026-07-30 | codex/archive-advisory-ui-scope | c8d50c7ac275212cbebf5c53fe859d863e800bbf | archive issue 137 after current-main verification | approved: implementation and fail-open self-tests remain green on current main | check:ci-scope; check:gate-manifest; check:outstanding-issues; diff check | +| 2026-07-30 | codex/ledger-next-20260730 | 41956467ae96c64058d7c391fcbbc6803a3f8012 | PR #1484 post-main RAG and ingestion sync | Ready: merged current main cleanly; protected RAG files identical to origin/main and no retrieval behavior delta | focused 7 files/201 tests PASS; production-readiness READY; ledger guards and ci-scope PASS | +| 2026-07-30 | codex/ledger-next-20260730 | 71d5ad7376167ff6f81f1e1f69dedb658c1db3ac | PR #1484 post-main offline-budget sync | Ready: preserved branch ledger and current-main #098/#121 corrections row-by-row; no ranking behavior change | search budget/contract 2 files/4 tests PASS; outstanding-issues 146 rows PASS | | 2026-07-30 | PR-1494 | 807a3a09f5afc12e8db4f9158abe09d9c7b336c9 | PR #1494 pre-commit fail-open review | FIXED P2: legacy worktrees may skip a genuinely absent generator, while a staged deletion or rename now fails closed | docs-inventory Vitest 5 passed; shell syntax passed; Prettier test check passed; diff check passed | +| 2026-07-30 | codex/sync-ci-anti-churn | 4f99c6d6dbcd4d2c16d5ec58183003c64d989ac8 | issue 145 anti-churn guidance | approved: guidance now covers both pushes and sync mutations without weakening cancellation | check:outstanding-issues; prettier AGENTS; diff check | +| 2026-07-30 | PR-1492 | a50640970a4e4197c64fba7239aeae073445fed9 | PR #1492 branch-sync churn review | FIXED P2: exact-head queued or in-progress workflows now block automated branch updates; Run PR guidance matches the executable guard | focused Vitest 1 file, 8 tests passed; Prettier passed; sync dry-run passed on 19 open PRs; diff check passed; no provider-backed application checks run | +| 2026-07-30 | PR-1484 | 9583b7fdc3d2908874c39654dadce0ec7401640a | PR #1484 final current-main review | approved after fixing P2 file-wide Prettier-ignore false rejection; composite actions retain coverage, workflow-only changes skip coverage, ledger canonicalization and ready-for-review/action-pin guards match repository contracts | GitHub Actions pin, CI scope, outstanding-issues, branch-review-ledger, Prettier and diff checks passed; final merge-tree audit clean; hosted exact-head CI pending push | | 2026-07-30 | claude/x3-rag-coverage-gate-qx9j7d (PR #1463, squashed as dba7356f) | dba7356fc8dc926d951d6de6f019d5b8e000be21 | X3/#101 per-request hydration extraction from rag.ts into rag-hydration.ts | clean and landed — byte-identical move verified against pre-merge main, rag.ts 4780->4543, budget ratcheted to 4543, no back-edge (cluster referenced zero rag.ts-local symbols), both public re-exports preserved; squash captured 100% of branch content | typecheck, lint, check:knip, check:maintainability-budgets 4543/4543, focused vitest 83/83 incl rag-query-concurrency, eval:rag:offline 572/572 36 golden, format:check, verify:cheap, verify:pr-local build+bundle-scan, post-merge content verification on main | | 2026-07-30 | dba7356fc8dc926d951d6de6f019d5b8e000be21 | dba7356fc8dc926d951d6de6f019d5b8e000be21 | X3 hydration unit: per-request hydration extraction from rag.ts into rag-hydration.ts (PR #1463) | clean and landed — byte-identical move verified against pre-merge main, rag.ts 4780->4543, budget ratcheted to 4543, no back-edge, both public re-exports preserved. Supersedes the earlier row for this HEAD, which was keyed only to the slash-form branch token and so returned NOT REVIEWED on a landed-SHA lookup; it also mislabelled the unit as #101, which is the unrelated open canary-gated retrieval-parallelisation recommendation | typecheck, lint, check:knip, check:maintainability-budgets 4543/4543, focused vitest 83/83, eval:rag:offline 572/572 36 golden, format:check, verify:cheap 442 files 4625 passed, verify:pr-local, post-merge content verification on main | -| 2026-07-30 | PR #1474 | 098186866932394d2cc17983e566ae6c44b063b4 | PR #1474 full diff vs origin/main | approved | verify:cheap; eval:rag:offline; live canary 30578169116 -> 30579534353 | +| 2026-07-30 | PR-1484 | dfb23bb48a16a4da5fd54a34205d8df9796ecc66 | PR #1484 final merge readiness after main sync | approved; no new P0-P2 findings after current-main sync | outstanding-issues, branch-review-ledger, GitHub Actions pin, CI scope, diff check and final merge audit passed | +| 2026-07-30 | codex/ledger-next-20260730 | 011a3713fb2dde1900260f2c8ebd2b0d7c540efc | PR #1484 closure-preservation repair | Ready: restored eleven verified archive dispositions lost during concurrent main sync; preserved #145 archive transition | outstanding-issues 146 rows, 44 open/102 archived PASS; only #145 state changed from prior verified candidate; focused offline 2 files/4 tests PASS | +| 2026-07-30 | codex/archive-advisory-ui-scope | c8d50c7ac275212cbebf5c53fe859d863e800bbf | archive issue 137 after current-main verification | approved: implementation and fail-open self-tests remain green on current main | check:ci-scope; check:gate-manifest; check:outstanding-issues; diff check | +| 2026-07-30 | codex/ledger-next-20260730 | bfbfe2cab8ae28e38e5b1090b5c83f8e024ac0f0 | PR #1484 final main decision sync | Ready: current main contained; #130 archived by owner decision; #149/#150 added open; all prior closures preserved | outstanding-issues 148 rows, 45 open/103 archived PASS; branch ledger PASS; whole-tree format PASS; diff check PASS | | 2026-07-30 | codex/coverage-scope-policy | 94f97cdb1d0543724de408f19e79d64e61c8b31a | issue 139 coverage scope policy | approved: workflow coverage breadth is deliberate and test-pinned; docs-like skills remain static-only | check:ci-scope; check:gate-manifest; check:outstanding-issues; prettier; diff check | | 2026-07-30 | codex/coverage-scope-policy | 4da2a003bc2254507662d1b8b6e9768e94371abd | issue 139 coverage scope policy post-sync | approved: late main sync preserves deliberate workflow coverage and static-only skill policy | check:ci-scope; check:outstanding-issues; check:branch-review-ledger; diff check | | 2026-07-30 | codex/archive-completed-ci-tasks | 5c902f422ceee78ef68132900fda734c1d5bc1f8 | archive issues 133 and 135 | approved: both rows were already resolved on current main and focused guards prove their contracts | check:ci-scope; check:outstanding-issues; check:branch-review-ledger; diff check | +| 2026-07-30 | codex/ledger-next-20260730 | 7238475c16576928a251c7a3d6de6134e6a72a4e | close verified ledger and CI follow-ups | No remaining findings after current-main sync; retained richer canonical #133/#135 dispositions from merged #1500. | check:ci-scope; check:gate-manifest; check:outstanding-issues; check:branch-review-ledger; git diff --check | | 2026-07-30 | codex/next-local-task | 3e6d6d69c15fc056773657e15879ba2283fa2899 | archive issues 129 and 132 | approved: documented constraints satisfy both explicit outcomes without overstating client-side enforcement | guard:push:self-test; focused vitest 24/24; check:github-actions; check:outstanding-issues; diff check | +| 2026-07-30 | codex/ledger-next-20260730 | ade61bab0ef8d2d35e0fec7e81c08e0a850cf58e | close verified ledger and CI follow-ups | No remaining findings after #1501 sync; retained canonical #133/#135 rows and added non-overlapping #129/#132 dispositions from main. | check:ci-scope; check:gate-manifest; check:outstanding-issues; check:branch-review-ledger; git diff --check | +| 2026-07-30 | PR #1474 | 098186866932394d2cc17983e566ae6c44b063b4 | PR #1474 full diff vs origin/main | approved | verify:cheap; eval:rag:offline; live canary 30578169116 -> 30579534353 | | 2026-07-30 | claude/design-visual-baselines | b57432facb7ded1e9605d1076e0d8c9d661efa2c | open PR changed-scope review | APPROVE after fix: platform-scoped baseline guidance matches the candidate-path and AWAITING_BASELINE adoption contract. | Prettier PASS; docs:check-links PASS; check:ci-scope PASS; review thread resolved; exact-head visual CI required | | 2026-07-30 | pr/1431 | 74e10087eb20a81279fb56d18f28a2475d895fab | docs: visual baseline platform layout | approved; candidate adoption and Linux baseline guidance match implementation | runtime/install parity; ledger; CI scope; docs inventory/links; Prettier; diff-check | | 2026-07-30 | pr/1431 | b4848aa92e890193a4a41744b611746673f3b058 | docs: visual baseline platform layout | approved after remote-head reconciliation; guidance unchanged | ledger; CI scope; docs inventory/links; Prettier; diff-check | | 2026-07-30 | pr/1431 | 897de9b1b7fc243006c1a71e67a6333681272ac6 | docs: visual baseline platform layout | approved after PR 1462 base sync; visual guidance unchanged | ledger; CI scope; docs inventory; Prettier; diff-check | +| 2026-07-30 | PR-1433 | e7a8102620b5b4847894b3df21f438304ea581bd | PR #1433 document result cards and action menu final review | fixed clipped menu, clipboard fallback focus loss, and inherited action typography; no remaining findings | DOM Vitest 4/4; focused Chromium 1/1; typecheck, Prettier, and diff checks pass | diff --git a/docs/codex-review-protocol.md b/docs/codex-review-protocol.md index c77259029..a97741c65 100644 --- a/docs/codex-review-protocol.md +++ b/docs/codex-review-protocol.md @@ -32,6 +32,10 @@ Use this protocol for every Codex review, audit, bug hunt, PR review, release-re - Ask before any OpenAI, Supabase, GitHub/GitLab, hosted CI, or provider-backed workflow. - After any completed branch/PR review, append to `docs/branch-review-ledger.md` with `npm run ledger:append -- --ref --head --scope --outcome --checks `. Record the full 40-character SHA; `see PR head` and abbreviations make the record unmatchable and cause the review to run again. The ledger is append-only: never edit or delete an existing record; append a correction or superseding record (`--supersede`) instead. This ledger append is allowed even during a pure review. Do not hand-write the markdown row — hand-written rows are what produced the mojibake, wrong-width, and duplicate records the 2026-07-28 hygiene pass had to repair. Do not push a tip whose sole delta is a babysit ledger append; after merging `origin/main` into a branch that touched the ledger, run `npm run ledger:dedupe` when exact twins appear. +## Ledger Rotation + +At the start of each UTC calendar quarter, or earlier when the live table becomes unwieldy, run `npm run ledger:rotate -- --dry-run`. If the preview contains only the intended completed records, run `npm run ledger:rotate` and commit the live ledger and generated archive together. Lookup, sweep, and integrity checks read both locations. Never hand-move rows or delete unique review content; stop if the dry-run shows unexpected mass movement or an archive-path collision. + ## Severity Guide - P0: Data loss, security breach, production outage, or clinical safety issue likely to harm users immediately. diff --git a/docs/outstanding-issues.md b/docs/outstanding-issues.md index af446e8d1..4a06ea19c 100644 --- a/docs/outstanding-issues.md +++ b/docs/outstanding-issues.md @@ -106,13 +106,11 @@ removed after current-main verification; it is not missing recommended work. | #055 | P2 | task | Run one exact-SHA full release and PR gate | Before the next full-confidence release/handoff, record the candidate/PR SHA and run the local/provider release gates, Firefox/WebKit, required hosted CI, and actionable GitHub review-thread closure once. Stop at the first actionable failure and rerun only the repaired smallest gate. | `docs/launch-operator-runbook.md`; `docs/codex-review-protocol.md` | 2026-07-24 | | #056 | P2 | task | Reconcile the existing staging migration history | `Clinical KB Staging` already exists as a healthy, empty Supabase/Railway tier with distinct secrets and no production clinical data, but it is 23 repository migrations behind. In the next approved staging schema window, apply the exact missing migration chain, then re-run indexing, health, identity and data-boundary proof. Do not recreate the environment or copy production clinical documents. | current-main staging verification; `docs/staging-setup.md`; `docs/operator-backlog.md` | 2026-07-27 | | #057 | P2 | task | Complete staging soak and rollback rehearsal | After #056, run the documented soak and rollback against an exact candidate; retain latency/error/rollback evidence. Stop on unsafe data, identity mismatch, or an unowned rollback decision. | `docs/launch-operator-runbook.md`; `docs/capacity-review.md` | 2026-07-24 | -| #005 | P3 | rec | `finalScore` saturates at clamp ceiling | Base + ~40 stacked boosts routinely exceed 1.0, so strong matches tie at 1.0 and order by an arbitrary `document_id` tiebreak. If ranking is ever revisited, break ties by the **pre-clamp** score rather than raising the `[0,1]` ceiling (downstream gates assume `[0,1]`). Ordering already sorts by the unbounded pre-clamp `rankScore` (`clinical-search.ts:1735,1927,1950-1955`), so the clamp confines only the reported confidence value, not result order. Not a defect on the current golden set; any change here is a protected RAG surface (canary required). | `docs/rag-hybrid-findings-and-todo.md` P1 item 4; `src/lib/clinical-search.ts:1735` | 2026-07-21 | | #011 | P3 | task | Auth DB-connection allocation is operator-only | Supabase Auth (GoTrue) is capped at ~10 absolute DB connections (Supabase perf advisor). Switch to **percentage-based** allocation in the Supabase **dashboard** before the first compute scale-up — **not settable via SQL/MCP** (operator-owned). Verify via a staging soak + an approval-gated read-only advisor re-check. | `docs/auth-connection-cap-runbook.md`; `docs/process-hardening.md` (Known follow-up debts) | 2026-07-21 | | #013 | P3 | rec | Route-chunk + mockup catalogue JSON weight | Keep this recommendation open and measurement-gated. `build:analyze` still finds route-scoped catalogue modules: `/specifiers` ships `specifiers-search-index.json` (~180 KB parsed), `/forms` ships `forms-catalog.json` (~132 KB), and `/formulation` ships `formulation-content.json` (~52 KB; client-side local search needs an index/full split or a search endpoint). The approved Lighthouse sample covered `/forms`, but `/specifiers` and `/formulation` remain unmeasured, so the precommitted `#017` rule does not permit archiving their payload work. Development-only `*-mockups.tsx` chunks are not an initial production bundle and production returns 404 for `/mockups/*`; do not restructure them without deploy-artifact or cold-start evidence. **Next:** collect route-specific LCP/CLS and CrUX INP evidence for `/specifiers` and `/formulation`, then close only the routes that meet every `#017` threshold. | session 2026-07-21 (`build:analyze`); PR #1470 review | 2026-07-21 | | #016 | P3 | rec | "Big but not easy" structural + motion perf | Deferred larger levers: (a) nonce-CSP forces every product route to `╞Æ Dynamic` (zero static generation) — evaluate Partial Prerendering / static shells for the static clinical catalogues (DSM/differentials/therapy/specifiers/formulation); (b) sidebar expand/collapse animates `grid-template-columns` (biggest smoothness cost, motion-gated — needs a transform-overlay rethink); (c) Therapy Compass fetches 692 KB / 2.5 MB JSON client-side (defer until interaction + confirm brotli); (d) settings/setup/admin dialogs static-imported into the home chunk (`next/dynamic` them); (e) `src/app/(search-app)/layout.tsx:4` imports 71.6 KB of Therapy-Compass-only CSS in the ROUTE-GROUP layout, making it render-blocking on `/`, `/documents`, `/forms`, `/dsm` and every mode home; (f) `shared-search-app-shell.tsx:8` statically imports the `therapy-compass` barrel, pulling `workspace.tsx` + `bindings.tsx` + `nav.tsx` into every `(search-app)` route; (g) three client waterfalls (`use-app-preferences.ts:156-182`, `ClinicalDashboard.tsx:977-1069`, `signed-image.tsx:60-84` + `use-signed-image-url.ts:39`) and the paint offenders in `globals.css` beyond the sidebar grid — three stacked `backdrop-filter` passes on an always-mounted translating element (`:709-748`), `box-shadow` inside a `transition` list (`:677-684`), and `@keyframes shimmer` animating `background-position` on the shared `Skeleton` (`:2289-2296`). **CORRECTED 2026-07-29 on (c):** the Therapy Compass filenames are unversioned and Next serves `/public` with an ETag, so only the FIRST visit pays 690.6 KB / 2,470 KB — repeat visits pay ~4 revalidation round trips. The fix is content-hashed filenames + `immutable` (touching `scripts/build-therapies-index.mjs` and `check:therapy-data-index`), NOT a bare `Cache-Control` line. See `docs/audit/latency-audit-2026-07-28.md` L3-1/L3-2/L3-3/L3-6/L3-7. | session 2026-07-21 (build route table + design audit) | 2026-07-21 | | #017 | P3 | task | Field Web-Vitals baseline via live Lighthouse | In-sandbox runtime vitals were blocked (prod server hard-requires Supabase secrets; dev-mode CLS measured excellent at 0.00–0.04, content-first pages 0.000). Run Lighthouse against `psychiatry.tools` for real LCP/INP/CLS to prioritize #012–#016 by measured impact rather than reasoning. **Instrument landed (PR #1385):** `live-web-vitals.yml` is dispatch-only, takes no secrets and runs nothing until someone dispatches it — which is itself a live production action needing explicit approval. `scripts/summarise-web-vitals.mjs` holds the decision rule, committed before any numbers were read: mobile LCP < 2500 ms AND CLS < 0.1 on every route (plus INP < 200 ms from CrUX) closes this row and makes only the explicitly measured **payload** findings gated by #017 WONTFIX — e.g. the route-chunk/catalogue weight in #013. It does **not** close #016 wholesale: #016's motion, CSS, client-waterfall, caching, and dynamic-import items stay open unless they have separate evidence, because Lighthouse LCP/CLS do not validate those. Any breach makes only that route's findings actionable. It fails closed — a missing run, a null metric, a route-slug collision, and a measurement that landed on a different URL than requested (redirect, dropped or reordered query) are all breaches. **Sampled since PR for #114:** each route/strategy cell is measured `SAMPLES` times (default 3), the MEDIAN is graded, and a cell whose samples land on both sides of a threshold is reported as incomplete evidence rather than resolved either way — so the "evidence is too noisy" stop rule can finally fire. A mid-run Chrome change also disqualifies the verdict. **Read the first dispatch as a measurement to be sanity-checked, not as an oracle:** the grading logic took eight rounds of review corrections to reach this shape, each fix locally right and globally incomplete, so cross-check the emitted table against the raw Lighthouse JSON artifact before recording a verdict — most of all a PASS, which would close #017 and the explicitly measured payload findings. Lighthouse cannot measure INP in lab conditions, so that clause of the rule is confirmed from CrUX field data and any pass is provisional on it. **DISPATCHED + GRADED 2026-07-30 (run 30548662649): BREACH on all five mobile routes — #017 does NOT close.** Mobile medians vs LCP<2500ms / CLS<0.1: root 4308ms/0.023, therapy-compass 4716ms/0.142, documents-search 3676ms/0.220, dsm 3639ms/0.363, forms 3786ms/0.212. Desktop passes everywhere (LCP 625-694ms, CLS 0.016-0.097). Every LCP sample range sits wholly above 2500ms, so the straddle/noise stop rule does NOT fire — this is gradeable, not an artefact. Per the pre-written rule only the breaching routes' findings become actionable; nothing becomes WONTFIX, which is the opposite of what a favourable sample would have done. CLS 0.363 on /dsm is the worst single number and is visible shift, not a byte-count issue. **Caveat:** recorded from the summariser's emitted table; the raw Lighthouse JSON artifact (id 8762211043, 30-day retention) has NOT been cross-checked, and INP is absent because Lighthouse cannot measure it in lab conditions. **RANKED 2026-07-30 — see `#147`.** The ranking this row asked for is done, and it changed what the row costs to work on: the mobile CLS numbers reproduce EXACTLY in the local offline production Lighthouse harness (all four measurable routes to three decimals; desktop range identical at both endpoints). So the CLS half needs no live dispatch and no Supabase credentials, and this row's own "prod server hard-requires Supabase secrets" premise is stale — `scripts/run-lighthouse-budget.mjs` exists to sidestep it. LCP does not reproduce locally (no network latency) though its ranking does, which corroborates `#117`. **Next:** `#147` owns the CLS work and `#117` the LCP outlier; this row stays open only for the raw-JSON cross-check of artifact 8762211043 and the CrUX INP clause, neither of which blocks either. **Stop:** do not re-dispatch the live workflow to re-measure CLS. | session 2026-07-21 (measurement pass) | 2026-07-21 | | #018 | P2 | task | Split the lithium, ADHD and metabolic residuals by mechanism | Current evidence keeps the mechanisms separate. **Lithium — closed within this item:** the row/atom-aware subject guard, foreign-parameter rejection and query-specific range promotion returned `0.5–1.0 mmol/L` with correct targeting/citation; the full retrieval canary remained 36/36 with recall 1.0 and zero per-case RR regressions, and the full answer canary passed every blocking gate. **ADHD — open corpus debt:** `CG.MHSP.ADHD.pdf` is absent from the hosted corpus and the retrieved chart exposes `accessible_table_count=0`; repair corpus/fixture or ingestion evidence rather than weakening extractive budgets. **Metabolic — open structured-evidence debt:** the standalone plural classifier worsened the live answer and was reverted; obtain auditable schedule text/table evidence before another candidate. | targeted live lithium/ADHD/metabolic evidence 2026-07-27; `docs/evidence/rag-reliability-evidence-2026-07-27.md`; refuted approaches | 2026-07-21 | -| #021 | P3 | rec | E-3d H2 residual: strong/comparison generation discards | approx. 6 generation attempts per full 44-case run still fail the final quality gate and fall to extractive on strong-route comparison/complex shapes (the designed-conservative outcome). PARKED: weakest cost/benefit on the queue — a wave (approx. $2-4 pair + reviewer cycle) to shave seconds off a few hard cases. Revisit only if latency/waste complaints or a cheaper lever appears. | E-3c design record; runs #59-#61 diagnostics | 2026-07-21 | | #022 | P2 | task | Source-governance metadata refresh (operator) | The selected policy is now encoded locally as auditable `third_party_reference_attested` evidence with policy version, reviewer qualification, evidence references and append-only review history. It deliberately preserves `clinical_validation_status=unverified`; malformed, stale or non-BMJ evidence remains review debt. Migration `20260727010000_bmj_third_party_source_attestation.sql` is prepared but was **not applied**. The ten most visible local-document candidates are captured in `docs/evidence/rag-top-local-review-manifest-2026-07-26.json` with `attestation_applied=false`; qualified human review, deliberate hosted apply/attestation, and warning-rate remeasurement remain operator work. | governance worklist; local policy/migration tests; top-ten evidence manifest | 2026-07-21 | | #023 | P2 | task | Complete scheduled browser and labeling disposition | **Partial 2026-07-30:** `release-browser-matrix` no longer depends on `pr-required`, so a blocking scheduled dependency audit cannot skip Firefox/WebKit. Still need one green matrix datapoint + human irrelevant-at-10 disposition. The 2026-07-26 retrieval and answer artifacts are read and compared under resolved #051. Scheduled CI run `30216361999` failed its existing production dependency audit before Firefox/WebKit, while production Chromium passed. After that audit is green, capture one scheduled/manual browser-matrix datapoint; separately record the human decision for the stable irrelevant-at-10 set. #084 now makes each top-10 grade and matched signal reproducible, but it does not substitute for the human disposition. Do not rerun or spend on RAG for this item. | runs `30216191889`/`30216361999`; per-rank diagnostics #084; session 2026-07-27 | 2026-07-21 | | #024 | P2 | issue | WebKit e2e `_rsc` prefetch access-control errors | PR #1205 narrowed catch-all interception and duplicate navigation, but Next 16.2.11 still raises `_rsc` access-control `pageerror`s after document-source fallbacks: `/documents/source?id=&page=2&chunk=safety%20plan` → `/documents/?page=2&chunk=safety+plan`; `/documents/source/evidence?id=not-a-uuid&page=2` → `/documents/search`. The invalid-id failure survived removing every Playwright route; Chromium passed both. **Next:** on a provider-free macOS host, run both URLs in stable Safari and Safari Technology Preview without interception, capture console text plus `_rsc` status/access-control headers, and compare Playwright WebKit with routing on/off. Treat as an app defect only if native Safari reproduces; otherwise return to the harness. Never suppress `pageerror` or change CORS without native evidence. | PRs #1179/#1205; current-main local WebKit evidence; session 2026-07-28 | 2026-07-28 | @@ -122,14 +120,11 @@ removed after current-main verification; it is not missing recommended work. | #033 | P3 | rec | Source governance metadata absent from the LLM prompt | `buildRagSourceBlock` omits `document_status`, `clinical_validation_status`, and `extraction_quality`, so the model cannot self-caveat during generation and governance is enforced only post-hoc. Generation-surface change: needs `eval:rag` plus `eval:quality --rag-only` (grounded-supported must not drop, citation-failure 0) and explicit approval. Carries the same "unknown Γëá bad" hazard as #032 — on a partially-enriched corpus the model would likely over-caveat correct sources, so design the prompt wording before spending an eval. | `src/lib/rag/rag-source-block.ts:126-198`; PR #1051 audit item 8 | 2026-07-22 | | #035 | P3 | rec | Threshold-conflict detection covers only 3 params | `detectThresholdDisagreements` checks only ANC, WBC, and platelets paired with withholding verbs, so cross-source conflicts on medication doses, lithium/thyroid levels, or vital signs go undetected. Deliberately narrow (see the comment at `:469-474`). Broadening changes when an answer is classified `conflicting` and adds warnings — real false-positive risk. Needs new fixtures plus a behaviour review before any change. | `src/lib/evidence.ts:469-574`; PR #1051 audit item 7 | 2026-07-22 | | #036 | P3 | rec | No explicit `is_public` visibility flag on documents | Public-corpus visibility is implicit: `owner_id IS NULL` on an `indexed` document (`resolveSearchScope`). The `metadata.public_corpus` marker is written by the promotion migrations but never used as a retrieval filter. Promotion is unconditional on `clinical_validation_status`, so unverified documents are publicly searchable — compensated by keeping `unverified_source` in the frontend-visible warning set. A hard schema flag touches RLS and the clinical-risk-gated retrieval RPCs; weigh against the existing compensating control before acting. | `supabase/schema.sql:61-108`; `src/lib/search-scope.ts:181-236`; PR #1051 audit item 3 | 2026-07-22 | -| #037 | P3 | rec | D5 trust-cap-all-claims flag parked OFF | `NEXT_PUBLIC_RAG_TRUST_CAP_ALL_CLAIMS` extends authority gating from high-risk claims to **all** supported claims (`deriveTrust`). Ships OFF by design; flipping it caps trust to `medium` for routine claims across the board — a product/clinical-UX decision, not a defect. Both states are test-pinned. Next action: product decision, then flip and re-baseline the UI expectations. | `src/lib/answer-render-policy.ts:159-177`; PR #1051 audit item 11 | 2026-07-22 | -| #038 | P3 | rec | Consolidate shared comparison behavior | Several clinical modes expose comparison workflows with similar selection, empty-state and mobile-dock needs. Define one shared behavioral contract before another comparison surface is added; keep mode-specific clinical content separate. This is a design-system recommendation, not a current defect. | design audit reconciliation; session 2026-07-22 | 2026-07-22 | | #039 | P3 | rec | Consolidate catalogue toolbar patterns | Catalogue/search pages have independently evolved filter, sort, result-count and mobile toolbar behavior. Inventory the existing implementations and converge only the repeated interaction contract; do not flatten mode-specific search semantics. | design audit reconciliation; session 2026-07-22 | 2026-07-22 | | #040 | P3 | rec | Add targeted visual-regression baselines | Keep a small approved baseline set for high-value desktop/mobile surfaces and accessibility modes instead of screenshotting every route. Start with account/settings, document viewer, mode homes and bottom-composer interactions; define an intentional-update workflow before enabling blocking comparisons. | design audit reconciliation; session 2026-07-22 | 2026-07-22 | | #079 | P3 | task | Disposition retained worktrees in bounded cleanup batches | **Outcome:** the retained reconciliation tail is gradually classified without another disruptive all-worktree sweep. **Next:** after the primary checkout is clean and `npm run check:primary-checkout-lease` allows writes, revalidate and remove the twenty clean redundant candidates recorded on 2026-07-30 with `branch-cleanup-deletion-pending`; then process no more than ten further worktrees per explicitly scheduled pass using current owner/process metadata, open-PR state, exact review-ledger coverage, ancestry, and cherry-pick-aware content proof. **Success:** remove only clean, inactive, bundled worktrees whose content is merged or explicitly rejected; record every disposition and retain recovery evidence. **Stop:** preserve dirty, active, secret-bearing, post-freeze, paused, or ambiguous work and never use reset, force deletion, broad clean, or process killing. | final reconciliation inventory retained 104 independent worktrees; session 2026-07-24; 2026-07-30 bounded review found 20 redundant candidates across two bounded batches but the primary-dirty write lease blocked removal | 2026-07-30 | | #086 | P3 | task | Repository maturity backlog — remaining structural work | **Outcome:** the deferred repository-maturity backlog ships as verified draft PRs, one per structural change. **Canonical runbook:** [`docs/maturity-backlog-workorders.md`](maturity-backlog-workorders.md). **Remaining:** X3 `rag.ts` decomposition (in progress); X7 finish the `src/lib` domain reorg; X6 clinical/retrieval/answer coverage floors; X5 ACL-migration consolidation (provider-gated); L1 archive the retired `backfill:*` one-shots + the dead `ci-change-scope` token; M1 repo-host hardening (maintainer, audit §8). **Shipped:** L4 ledger rotation (#1418 — `ledger:rotate`, live/archive corpus, `merge=ledger`). **X3 progress:** the evidence coverage gate shipped as `src/lib/rag/rag-coverage-gate.ts` (PR #1454, squashed `102bb1f`) — `evaluateEvidenceCoverageGate` + `applyCoverageGateTelemetry` moved byte-identically, `rag.ts` 5,030 → 4,780, budget ratcheted to 4,780, no back-edge, `evaluateEvidenceCoverageGate` still re-exported from `@/lib/rag/rag`. **Hydration unit SHIPPED (X3 hydration; PR #1463, squashed as `dba7356f`):** `src/lib/rag/rag-hydration.ts` now owns the hydration cluster is `createDocumentRankingMetadataCache` / `attachDocumentRankingMetadata` / `withCachedIndexQuality` / `attachIndexQualityMetadata` / `attachPageVisualEvidence` plus the `DocumentRankingMetadataCache` type (byte-identical move; `rag.ts` 4,780 → 4,543, budget ratcheted to 4,543). **It did NOT on its own unblock `prepareCoverageGateResults`**, exactly as the 2026-07-30 Codex finding on PR #1461 predicted (the original claim that it re-homed all five dependencies was wrong, and shipping it confirmed that). That function needs five `rag.ts`-only runtime symbols, and hydration accounts for only two of them (`attachDocumentRankingMetadata`, `attachPageVisualEvidence`). The other three sit outside the cluster and are a separate seam: `selectRankedRetrievalResults` (`rag.ts:1825`, retrieval selection), `applySecondStageRerankIfNeeded` (`rag.ts:679`, second-stage ranking), and `measureSearchPhase` (`rag.ts:1975`, the shared pipeline timing wrapper — 21 references across the file, of which only `metadata_hydration` and `visual_hydration` are hydration phases, so it belongs with the search orchestrator/telemetry, not with hydration). So `prepareCoverageGateResults` can only move after BOTH hydration and that ranking/timing seam are re-homed; it stayed in `rag.ts` for #086 because a back-edge and a signature change were both refused. Verify with a symbol-location plus call-site search before planning the boundary — do not treat hydration alone as sufficient. **Next:** remaining X3 units on user go-ahead. **Stop:** RAG/retrieval items need the flag + go-ahead; X5 is live-DB provider-gated. | `docs/maturity-backlog-workorders.md`; audit §8/§10; session 2026-07-28 | 2026-07-28 | | #090 | P2 | task | Upgrade the eslint ecosystem to clear remaining dev-scoped high advisories | **Outcome:** full `npm audit` reports zero high advisories from the eslint toolchain. **Blocked 2026-07-30:** the stable ecosystem still has no compatible ESLint 10 set. `eslint-config-next@16.2.12` permits ESLint 10 but bundles `eslint-plugin-react@7.37.5`, `eslint-plugin-import@2.32.0`, and `eslint-plugin-jsx-a11y@6.10.2`; each plugin's published peer range still ends at ESLint 9, and the React plugin retains the previously reproduced removed-context-API crash. Keep the Dependabot major hold and ESLint `9.39.5`; do not force an invalid peer graph merely to make the audit report green. **Next:** recheck after those three plugins publish stable ESLint 10 support, then upgrade eslint and the complete plugin/config set together. Residual highs (`@eslint/config-array`, `@eslint/eslintrc`, `eslint`, `eslint-config-next`, `eslint-plugin-import`, `eslint-plugin-jsx-a11y`, plus the advisory's numeric `<=5.0.7` hit on the unused `brace-expansion@1.1.16` / `2.1.2` maintenance lines that still ship an unpatched `main`) cascade from this dev-only toolchain. **Success:** peer-valid install, `npm run lint` clean, `verify:cheap` green, full-audit highs cleared, no rule-config regressions. **Stop:** do not use `npm audit fix --force` or override plugin peer ranges. Production `npm audit --omit=dev` is already clean after the exceljs `archiver@8` / `unzipper@0.12.5` overrides on PR #1314. | stable npm metadata recheck 2026-07-30; session 2026-07-28 brace-expansion triage (PR #1314) | 2026-07-30 | -| #092 | P3 | task | Refetch pulse deferred on auth-backed registries (privacy invariant) | **Outcome:** a background refresh keeps the prior count visible instead of a skeleton, without weakening identity clearing. **Detail:** the `refetching` status is built in the band and adopted only on `formulation-home-page.tsx`, where the lag is `useDeferredValue` over static data. It is deliberately NOT adopted on `use-registry-records.ts:85`, `use-medication-catalog.ts:76` or `use-differential-catalog.ts:133`, which all clear data on entering loading. `use-differential-catalog.ts:122` states why: "Auth must clear prior identity's matches immediately", and `:164` that "a later retype of any prior query cannot resurrect authorized matches." **Next:** if adopted, guard preservation on identity AND query equality, and pin with a test that an identity change still clears immediately. **Stop:** never hold records across an auth transition. | PR #1316 plan phase 6; session 2026-07-28 | 2026-07-28 | | #093 | P2 | issue | Next streaming `S:` clone causes Playwright strict-mode violations under CI load | **Outcome:** duplicate-element strict-mode failures stop appearing on loaded CI runs. **Detail:** under full-suite CI load Next.js leaves a hidden duplicate page root in the stream, so a `getByTestId` that is unique locally resolves to 2 elements in CI (seen as `differentials-search-results` on PR #1316, and previously noted on PR #1294 against main). It does not reproduce in isolation, on a single spec, or locally. The documented workaround is to scope the locator to the visible root. **Reproduced locally 2026-07-28** (isolated _production_ build via `run-playwright.mjs`, full `verify:ui`): `ui-tools.spec.ts:563` duplicated `forms-home` and `ui-smoke.spec.ts:3001` duplicated `favourite-row-lithium-monitoring-guideline`; in both, copy 1 is nested under `mobile-composer-reserve-pad`. Both pass when run alone, so it is load/order-dependent, not build-mode dependent — this also corrects an earlier note that CI uses `next dev`; it does not. **Strongest evidence (CI run `30345484316`, 2026-07-28): `ui-overlap.spec.ts:199` on `/` asserted `toHaveCount(1)` successfully and then the same `header#search` locator resolved to 2 a statement later, one of them hidden.** A duplicate that appears _after_ a passing count assertion is a stream/hydration artifact by construction, not a static double mount and not something a CSS or component change can cause. That makes four distinct testids across four specs with the identical shape. **Mitigated, not fixed, on `main` (2026-07-28):** `3a8edb93` rewrapped `gotoHome` in `tests/ui-overlap.spec.ts` to retry count-and-visibility together via `toPass`, so a transient second header no longer trips strict mode there — its own note says "checking count then immediately calling waitFor races that flicker into a strict-mode violation". That hardens one helper; the duplicate root itself is unchanged and other specs remain exposed. **Confirmed pre-existing:** at `631d90d2`, the commit before PR #1316's first commit, that spec already documented "two `header#search` nodes" and "a second transient `header#search` can exist briefly" — so this predates that branch. **Next:** with a full-suite repro now available, bisect the preceding specs to find the state that triggers the second mount, then either scope the shared helpers to the visible root once or fix the mount. **Stop:** do not paper over new occurrences with `.first()` before the duplicate itself is explained. | PR #1316 CI runs; PR #1294 note on main; session 2026-07-28 | 2026-07-28 | | #094 | P2 | rec | Design-system gates assert structure, not rendered effect | **Outcome:** a style contract cannot pass while the style is inert. **Detail:** PR #1316's accent rail shipped inert because `.search-band` sat in `@layer components`, which loses to Tailwind's utilities layer regardless of specificity — and the test asserted `toHaveClass("search-band")`, i.e. class presence, not effect. Computed style showed `1px rgb(229,231,235)` where `2px rgb(11,111,134)` was intended. The same shape of gap let a rail-colour assertion compare a colour against a width and pass unconditionally. **Next:** for contracts where the visual IS the requirement (rails, forced-colors thickness, tap targets), assert `getComputedStyle` in a Playwright case rather than class names in a DOM test, and add the unlayered-component convention to the design-system contract check. **Stop:** do not convert existing passing DOM tests wholesale; add computed-style proof only where the effect carries the meaning. | PR #1316 Codex P2 finding; session 2026-07-28 | 2026-07-28 | | #098 | P2 | task | Offline round-trip budget harness for the hot routes | **Outcome:** per-scenario Supabase round-trip counts are pinned by a test, so an extra round trip on a hot path is a red gate rather than an inference. **Done 2026-07-29:** the measurement gap is closed — `Server-Timing` now covers `auth`/`ratelimit`/`scope` on `/api/answer`, `auth`/`ratelimit`/`search`/`total` on `/api/search`, and `auth`/`ratelimit` on `/api/answer/stream` (previously the route the UI actually calls emitted no header at all). Headers flush before the first SSE frame, so in-stream stages cannot reach a header and must NOT be routed through the governed `progress`/`final` contract. `tests/answer-route-preamble.test.ts` pins admission-before-scope (no scope call while the limiter is pending or after a deny) and the client-disconnect abort signal. **Done 2026-07-30 (PR #1450, `1bff4c78`):** the counting proxy exists and the answer path is budgeted. `tests/helpers/supabase-round-trip-counter.ts` counts on **execution, not construction** — a builder that is never awaited costs zero, one awaited twice costs two — which is the distinction that makes the count mean "requests issued". `tests/rag-round-trip-budget.test.ts` pins two offline answer-path scenarios (a single-source source-only answer, and that trips do not scale with the number of retrieved sources) plus three self-tests of the counter, and is registered in `scripts/fixtures/rag-offline-contract-tests.json` so it runs inside the offline contract rather than only on demand. Verified locally, provider-free: `Test Files 1 passed (1)`, `Tests 5 passed (5)`. Its documented blind spot is worth repeating before anyone cites a budget as total cost: it sees only traffic through the wrapped client, so a trip issued via another client instance, a direct `fetch`, or a provider SDK is invisible to it. **Done 2026-07-30 (PR #1450, `1bff4c78`):** the counting proxy exists and the answer path is budgeted. `tests/helpers/supabase-round-trip-counter.ts` counts on **execution, not construction** — a builder that is never awaited costs zero, one awaited twice costs two. `tests/rag-round-trip-budget.test.ts` pins two offline answer-path scenarios plus three self-tests of the counter, registered in `scripts/fixtures/rag-offline-contract-tests.json`. Its documented blind spot: it sees only traffic through the wrapped client, so a trip via another client instance, a direct `fetch`, or a provider SDK is invisible to it. **Done 2026-07-30 (search *retrieval core*, not the endpoint):** `tests/search-round-trip-budget.test.ts` pins `searchChunksWithTelemetry` — what `/api/search` calls to retrieve — registered in both the contract fixture and `scripts/rag-offline-contract.mjs`. **Corrected after Codex review on PR #1464:** an earlier version of this row and the test itself claimed to pin `/api/search`. They do not. The route's auth, rate limiting, scope resolution, related-document enrichment and telemetry write are all invisible to this suite, so a round trip added to any of them leaves it green — and the refusal budget below is about *retrieval*, not about an adversarial HTTP request, which still pays the route preamble. **The measured shape is itself the finding:** one search costs **11 round trips** — `rag_aliases` 1, `match_document_chunks_text_v2` **3**, `match_document_table_facts_text_v2` **3**, `get_related_document_metadata_v2` 1, `document_index_quality` 1, `document_images` 2 — so the two text RPCs are each issued three times per search. Pinned by total *and* breakdown, because a refactor swapping one probe for an unrelated query would keep the total at 11 while changing the traffic. Deterministic across three consecutive runs. The refusal budget asserts **zero** Supabase traffic, matching `rag.ts`'s claim that prompt-injection intent is refused before any query issues, and was proven against the broken shape: with a non-refused query it fails on the round-trip assertion (`expected 11 to be +0`), which is why that assertion is ordered ahead of the results assertion. **Next:** (a) add the route-level budget this suite does not provide — drive `POST` from `src/app/api/search/route.ts` with counted clients, following the `tests/answer-route-preamble.test.ts` pattern, so a round trip added to the route preamble or post-processing is a red gate; (b) decide whether `match_document_chunks_text_v2` ×3 and `match_document_table_facts_text_v2` ×3 per search are intended or a probe that should be collapsed — a latency question this budget surfaced but does not answer, and one that touches retrieval, so any change needs the usual RAG gate. (c) `scripts/eval-rag-offline.mjs` and `scripts/test-rag-offline.mjs` remain unwired; the offline contract runner is now the de-facto single home for budgets, so either adopt that explicitly here or wire them. | `docs/audit/latency-audit-2026-07-28.md` measurement plan; `src/lib/server-timing.ts`; `src/lib/answer-stream-contract.ts:18-21` | 2026-07-29 | @@ -138,9 +133,7 @@ removed after current-main verification; it is not missing recommended work. | #101 | P3 | rec | Canary-gated retrieval parallelisation candidates | **Outcome:** independent retrieval stages stop running serially, proven by a live canary pair. Candidates: metadata/memory/visual hydration triples repeated on four branches (`rag.ts:2460,2493,2521` and three more) while `rag.ts:2751-2804` already parallelises three RPCs in one `Promise.all`, so the omission is inconsistency rather than intent; the nested `await`-in-loop scope enumeration (`search-scope.ts:202,328`); typeahead results never cached (`rag.ts:2698-2711`); universal-search coalescing (`/api/search` has it, `/api/search/universal` does not). Each changes candidate assembly, truncation, or what the next keystroke returns, so each needs 36/36 retrieval plus recall 1.0 and zero per-case rr regressions. Distinct from #001 (semantic rerank). Resolved #075 and #083 are the precedents for why these are gated rather than free. **Stop:** needs the #098 harness and explicit canary approval first. | `docs/audit/latency-audit-2026-07-28.md` L2-1/L2-2/L2-8/L1-5 | 2026-07-29 | | #102 | P3 | task | Apply the additive `documents` index debt (operator) | **Outcome:** bare-column `ILIKE` and the paged status scan on `documents` are index-served on hosted. `documents_title_trgm_idx` indexes a CONCATENATED expression, so the bare-column predicates in `api/documents/route.ts:193` and `rag-candidate-sources.ts:477` (RAG path) cannot use it and fall back to scanning; `search-scope.ts:271-277` sorts per page against the single-column `documents_status_idx`. **Runbook prepared 2026-07-29 — NOT applied, item stays open:** three `CREATE INDEX CONCURRENTLY` statements authored and reviewed in `docs/operator-apply-performance-latency-remediation.md` — additive, though **the "recall is byte-identical" claim was RETRACTED on 2026-07-29 review**: `fetchDocumentTitleAliasRows` (`rag-candidate-sources.ts:482`) applies `.limit(12)` with no `ORDER BY`, so a new index can change which title-alias documents feed candidate assembly. Only the documents-list use stays ordering-safe; `(status,id)` is canary-gated too — see runbook, and making that `.limit(12)` deterministic first does **not** lift the gate — an unordered `LIMIT` has no stable selection to preserve, so imposing an order can pick a different twelve and is itself an ordering behaviour change on a retrieval surface, which AGENTS.md requires a canary pair for. Sequencing the ordering fix first is worthwhile (unordered `LIMIT` on a retrieval input is latent nondeterminism regardless) but yields two canary-gated changes, not one (PR #1377 review). **Deliberately NO migration file:** an additive-index migration without a synchronized `schema.sql` mirror and regenerated drift manifest is exactly what closed PR #1312, and the mirror cannot come first because `required_indexes` in `search_schema_health()` (`schema.sql:3178`) runs against live. **Next (operator):** **author the migration first** — `supabase/migrations/` is the source of truth and `schema.sql` only a mirror, so hand-run operator SQL never reaches staging, disaster-recovery replay, or a local `supabase db reset`, and a `required_indexes` registration would fail there (PR #1377 review); follow the `20260717170000_registry_projection_cleanup.sql` idempotent pattern. **That migration must also carry the health-function change** — `required_indexes` lives inside `search_schema_health()`, which is redefined by `create or replace function` in eleven migrations (copy `20260705180000_reconcile_search_health_indexes.sql:62`); editing `schema.sql:3177` alone moves only the mirror and leaves the indexes unmonitored on hosted (PR #1377 review). Then apply concurrently, confirm `indisvalid`, mirror both the index statements and the identical function body into `schema.sql`, run `npm run drift:manifest` (Docker), and deploy the migration LAST — in that order, in one change. Expect `check:drift` to report them as unexpected between steps 1 and 2. **Rollback is three deployed phases, not the reverse of one:** retract `required_indexes` via its own `create or replace function` migration and deploy → drop concurrently live → only then deploy the `schema.sql` removal plus an idempotent forward `drop index if exists` migration, because Supabase wraps migrations in a transaction and a plain `DROP INDEX` there takes the lock the concurrent procedure exists to avoid (PR #1377 review). | `docs/audit/latency-audit-2026-07-28.md` L2-3/L2-5; `docs/operator-apply-performance-latency-remediation.md` | 2026-07-29 | | #103 | P2 | issue | Wide table-facts trigram index missing from `schema.sql` | **Outcome:** the migration chain and `schema.sql` agree on `document_table_facts` trigram indexes. `supabase/migrations/20260714190000_document_table_facts_trgm_idx.sql` creates a wide 5-column trigram index that is **absent from `supabase/schema.sql`**, so local replay and the live database can diverge. Distinct from #102: different owner and verification path. **Next:** confirm whether the wide index exists live, then take one of exactly two routes — **retained:** mirror `document_table_facts_text_trgm_idx` into `supabase/schema.sql` beside the narrow one and regenerate `drift-manifest.json`; **redundant:** drop it through a new forward migration, never by deleting `20260714190000`. **`drift-allowlist.json` is NOT a third option** (PR #1377 review): its own header scopes it to _"Known live-vs-`schema.sql` divergence"_, so it can silence a live drift finding but cannot reconcile the migration chain with the mirror — a fresh `supabase db reset` still runs `20260714190000` and creates the index while `schema.sql` still omits it, leaving this row's stated outcome unmet. **No offline gate catches this today:** the migration↔`schema.sql` parity test (`tests/drift-detection.test.ts:59-68`) only asserts one migration's `schema_drift_snapshot` function definition, not an index inventory — which is why this sits open rather than red in CI, and why a replay-to-schema inventory comparison is the check that would have caught it. Note the narrow `document_table_facts_title_row_param_trgm_idx` (`schema.sql:6425`) is the one the effective RPC expression (`:6726`) actually matches, so the wide index may be genuinely redundant — do not drop it without live scan evidence, per the monitored-not-auto-fixed index policy. | `docs/audit/latency-audit-2026-07-28.md` limitations; `npm run check:drift` | 2026-07-29 | -| #110 | P3 | task | Design-system project token manifest lags its stylesheet | **Outcome:** the claude.ai/design token panel matches the shipped stylesheet. **Detail:** PR #1375 pushed a recompiled `_ds_bundle.css` (Clinical Sky, `--e0`–`--e4`, 4px radius grid, `--tracking-eyebrow`/`--leading-display`/`--leading-prose`) plus the four changed guideline docs to project `08d6f126`, but `_ds_manifest.json` is converter-generated and still advertises `--text-4xs: 0.5rem`, the old `--radius-lg/xl/2xl` values, and `--tw-leading`/`--tw-tracking` entries scoped to the retired `.leading-[…]` / `.tracking-[0.08em]` utilities. Rendering is correct; only the token inventory lags. Hand-editing was rejected — `kind`/`scope`/`annotation` are converter heuristics and a wrong panel is worse than a stale one. **Next:** in a session with the `/design-sync` skill, `npm ci`, then `npm install --prefix .ds-sync --no-save --package-lock=false esbuild ts-morph @types/react @tailwindcss/cli geist`, read `.design-sync/NOTES.md`, and run `resync.mjs --remote` so bundle and manifest regenerate together. **Stop:** do not hand-author `_ds_manifest.json`; the converter is not a published npm package and ships with the skill. | PR #1375; `.design-sync/NOTES.md`; project `08d6f126` (`_ds_needs_recompile` marker present) | 2026-07-29 | | #121 | P3 | issue | Container Playwright browser build lags the pinned client | **Outcome:** browser gates run in remote sessions without hand-patching. **Evidence 2026-07-30:** the repo's Playwright client resolves headless-shell build `1234`; the container image provides `1194` at `/opt/pw-browsers`, so every browser test fails at launch. Worked around in-session by symlinking `chromium_headless_shell-1234/chrome-headless-shell-linux64/chrome-headless-shell` to the `1194` `headless_shell` binary plus its sibling resources — container-local, nothing committed, and it disappears with the session. `PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1` means the mismatch cannot self-heal. **Next:** decide whether the image pins the browser build or the repo pins a client matching the image; until then any remote session claiming browser proof must state which it used. **Added 2026-07-30 (session closing `#120`):** the mismatch reproduced unchanged on `main` at `c5c1a86` — `npx playwright install --dry-run chromium` reports `chromium v1234` while `/opt/pw-browsers` holds only `chromium-1194` and `chromium_headless_shell-1194`, and one `verify:phone-chrome` run lost all 13 browser tests at launch. It has now been misread twice: the 2026-07-30 handoff records 13 launch failures taken as "my change is wrong", and `#120` was filed as a gate defect from a reading taken under this condition (closed as not reproducible; the gate exits 1 correctly). **Detection, before trusting or filing anything from a browser gate:** compare `npx playwright install --dry-run chromium` against `ls /opt/pw-browsers`. **Stop:** do not file a gate defect from a run whose tests never launched — zero assertions executed, so the output describes the environment, not the diff. **Correction 2026-07-30 — the symlink workaround is not always available, so this row's own evidence overstates the escape hatch.** In a Claude Code remote session the sandbox **refused** `mkdir`/`ln -s` under `/opt/pw-browsers` (permission denied by the auto-mode classifier, not by file permissions — the directory itself is writable). So a sandboxed session has no way to bridge the builds, and the honest options reduce to two: request the write permission explicitly, or state that no browser evidence is available and leave the browser claim unmade. **Retracted the same day, by me:** the sentence above claiming the options "reduce to two" was wrong, and it is left standing rather than deleted because the retraction is the useful part. There is a third route that needs no filesystem write at all: **`PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH`**, read by `playwright.config.ts:11` and honoured by the preflight (`scripts/playwright-browser-preflight.mjs:101`), pointed at the container's existing `1194` binary. Verified by launching it, not by reading the flag: `chromium.launch({ executablePath: "/opt/pw-browsers/chromium_headless_shell-1194/chrome-linux/headless_shell" })` under the repo's Playwright 1.62 client reported `version 141.0.7390.37`, rendered a page and measured a `boundingBox` of the expected height. So a sandboxed remote session **can** produce browser evidence, and the earlier claim that it cannot was an over-generalisation from one blocked `mkdir`. The mismatch itself is unchanged and this row stays open — the point is that its consequence is a one-env-var workaround, not a hard stop. **Related, landed 2026-07-30 (PR #1432, `3054d685`):** `assertPlaywrightBrowsersReady` now runs inside `scripts/run-playwright.mjs`, so a missing binary exits `1` with one explicit message naming the override, instead of surfacing as N tests "failing" at launch — the misdiagnosis that produced `#120`. | `docs/testing.md`; container `/opt/pw-browsers` | 2026-07-30 | -| #126 | P3 | task | Quarterly branch-review ledger rotation reminder | **Outcome:** live ledger stays navigable after #1418 L4 bootstrap. **Next:** each UTC calendar-quarter start (or when the live table feels unwieldy), run `npm run ledger:rotate -- --dry-run`, then `npm run ledger:rotate` and commit live+archive. Lookup/sweep/check already read archives. **Stop:** do not hand-move rows; do not delete unique review content. | session 2026-07-30; follow-up to #1418 / L4 | 2026-07-30 | | #117 | P2 | rec | Therapy Compass catalogue payload is the mobile LCP outlier | **Outcome:** `/therapy-compass` mobile LCP lands near the other mobile routes instead of double them. **Measured 2026-07-30** by the new pre-merge Lighthouse budget: mobile LCP 5229 ms, TBT 612 ms, CLS 0.142, against 2123-2460 ms on every other mobile route and 826 ms on desktop — so it is client-side work under mobile CPU/network throttling, not server latency. **Cause:** `useTherapyData` fetches `public/therapy-compass-data/therapies-index.json` (690 KB raw, 139 KB gzipped, 205 records x 16 fields) for the home/search/pathways screens, so the download plus JSON parse sits on the critical path before content paints. 90% of that weight is long-form clinical prose — indications 159 KB (26%), contraindicationsOrCautions 139 KB (23%), bestUsedFor 73 KB (12%), clinicalSummary 67 KB (11%), patientPopulation 59 KB (10%), targetSymptoms 48 KB (8%) — while name, slug, category, tags and setting together are 54 KB (7%). **Blocked on one decision per field group: rendered on the card, matched by search, or neither.** `therapy-card.tsx` references five of those prose fields and the same index feeds the search screen, so stripping fields could silently change clinical display or search recall. **Next:** settle that per-field question, then either pre-truncate prose that only feeds card display, or move search matching server-side / load prose on first keystroke. **Gate:** `check:therapy-data-index` plus the therapy Playwright journeys; re-measure with `npm run verify:lighthouse`. **Stop:** do not drop a field from the catalogue payload without confirming no card renders it and no search path matches on it. Same class as #013 (route-chunk / catalogue JSON weight), different route and now measured. | session 2026-07-30 Lighthouse budget first run; PR #1404 | 2026-07-30 | | #118 | P2 | task | Adopt the visual and Lighthouse baselines so the two new gates actually gate | **Outcome:** `visual-baseline` and `lighthouse-budget` stop reporting and start blocking. **Detail:** PR #1404 added both as `continue-on-error` jobs outside `pr-required`, deliberately. `tests/ui-visual-baseline.spec.ts` has no committed baselines, so all six targets fail with a missing-snapshot error by design; the job uploads them on every run (run 30513537912, artifact 8748062487, 31 files). `lighthouse-budget.json` ships `enforce: false` with `baseline: null`, so the grader warns rather than grades. **Next:** (1) download that artifact, review the six PNGs and commit them under the platform-scoped screenshots directory that `playwright.visual.config.ts` names in its `snapshotPathTemplate` — from CI, never a developer machine, because font hinting differs between them; (2) run `npm run check:lighthouse-budget -- --update` against a known-good CI build and flip `enforce`, but not before #117 or the baseline pins a known-slow route; (3) then add each job to `pr-required` and drop `continue-on-error` in the same edit. **Also:** PR #1404 added the first rendered-effect contract for #094, but 37 of the 38 unlayered visual classes still carry exemptions in `tests/helpers/style-contracts.ts` rather than contracts; and `scripts/run-lighthouse-budget.mjs` duplicates about 50 lines of the isolated-server boot in `scripts/run-playwright.mjs`, deferred to avoid destabilising the required UI gate in the same change. **Stop:** do not make a missing baseline skip instead of fail — that is the soft-skip-green pattern `AGENTS.md` forbids. | session 2026-07-30; PR #1404 | 2026-07-30 | | #142 | P3 | task | Four loose dated docs need source and migration edits before they can be filed | **Outcome:** every dated point-in-time doc lives in `docs/audit/` or `docs/archive/` as `docs/README.md` requires, not loose at the `docs/` top level. **Detail:** PR #1436 filed the five that were docs-only moves. These four are referenced from outside `docs/`, so relocating them means editing source, tests and migration SQL comments — a different risk class than a docs tidy, and not worth bundling into one: `capacity-review.md` (`scripts/soak-test.ts`), `tenancy-defense-in-depth-review.md` (`src/lib/owner-scope.ts`, `tests/owner-scope-guard.test.ts`, two migrations, `SECURITY.md`, `.claude/agents/clinical-governance-reviewer.md`), `operator-apply-july8-batch.md` (three migrations plus `supabase/schema.sql`), `scale-readiness-review.md` (one migration). Also note `forward-codify-retrieval-rpcs-workorder.md` is indexed as a completed workorder but live is still ahead of the repo on those RPCs, so archiving it would misrepresent open operator work. **Next:** treat as low priority — the docs are correctly indexed and reachable where they are; only file them if a pass is already editing those migrations. Editing applied migration SQL is subject to `npm run check:migration-role`'s immutability pin. | PR #1436; session 2026-07-30 | 2026-07-30 | @@ -171,8 +164,6 @@ Move resolved rows here with the resolution date and a one-line outcome. Keep th | #145 | issue | Branch syncs could repeatedly cancel healthy in-flight CI | Resolved 2026-07-30. The operator helper now queries Actions for the current head and skips `update-branch` when the required CI workflow is queued or in progress; focused tests cover queued, running, completed, and unrelated workflows. The open-PR sync, CI-speed, and canonical Run PR procedures all require one late sync after review/fix work is assembled. `cancel-in-progress` remains enabled. | 2026-07-30 | | #137 | rec | Advisory UI ran mockup tests for unrelated UI changes | Resolved 2026-07-30. `advisory_ui_changed` now runs the lane only for mockup-surface changes or when the flake ledger contains a quarantine. The scope self-test covers both directions, unreadable-ledger fail-open behavior, and parity for all five advisory specs; current-main `check:ci-scope` and `check:gate-manifest` pass. | 2026-07-30 | | #139 | rec | Change scope exposed dead outputs and appeared to over-trigger coverage | Resolved 2026-07-30. Unconsumed `source_changed`, `workflow_changed`, and `changed_files` job outputs were removed. The remaining coverage breadth is now an explicit fail-safe policy: every non-documentation change, including workflow-only edits, runs unit coverage because those files can alter test setup or the gate itself. Self-tests pin both cases; narrower signals still scope build, UI, database, and container work. | 2026-07-30 | -| #133 | rec | Outstanding-ledger edits conflicted through union merging and Prettier padding | Resolved 2026-07-30. PR #1444 removed `merge=union` and added regression coverage requiring an ordinary, conflict-visible merge attribute; PR #1479 excluded the ledger from Prettier so a maximum-width row no longer rewrites the whole table. The current-main outstanding-issues and branch-review-ledger guards pass. | 2026-07-30 | -| #135 | rec | API-only App Router changes unnecessarily selected full UI verification | Resolved 2026-07-30. `isUiChangedPath` excludes `src/app/api/**`, while the CI scope self-test pins API-only changes as `ui_changed: false` and preserves the non-UI static/unit safety gates. Current-main `check:ci-scope` passes. | 2026-07-30 | | #129 | issue | GitHub update-branch ignored the custom ledger merge driver | Resolved 2026-07-30 by constraining the operation rather than trusting it as a conflict oracle. The branch-sync procedure requires `git merge-tree --write-tree` first, permits only a human-authenticated update, and directs clean custom-driver false conflicts to a local `git merge origin/main` plus ordinary push. | 2026-07-30 | | #132 | issue | Client-side push guards could be bypassed in agent environments | Resolved 2026-07-30 under the row's explicit-limitation outcome. AGENTS.md names the missing-hook and missing-`gh` fail-open paths as load-bearing operator rules; ordinary PR CI enforces formatting server-side, while the tested local sentinel remains an early auto-merge race guard where `gh` is available. No privileged `pull_request_target` execution of PR code was added. | 2026-07-30 | @@ -243,6 +234,15 @@ Move resolved rows here with the resolution date and a one-line outcome. Keep th | #031 | issue | Populate canary Source Governance table | The answer-quality step now consumes the preceding `golden-retrieval.json` only for source-governance reporting. Offline replay of run `30018289898` populated 338 top results, including 202 review-required entries, while retaining zero retrieval cases and no additional threshold failures. Retrieval and ranking behavior are unchanged. | 2026-07-24 | | #020 | task | Validate eval:quality cost readout post-fix | Confirmed on merged-main canary run `30018289898`: Answer Metrics reported 9 nonzero-cost cases and an estimated answer cost of `$0.234736`; the structured report retained the same value. The PR #1050 estimator fix is operationally proven. | 2026-07-23 | | #003 | task | Staging tenancy release evidence outstanding | Ran GitHub Action and validated isolation | 2026-07-21 | +| #135 | rec | UI scope overfires: `ui_changed` matches every `src/app` path | RESOLVED 2026-07-30 on current main. PR #1413 added an explicit `src/app/api/**` exclusion, moved the full-run UI sentinel outside that subtree, and self-tests pin API-only changes to `ui_changed=false` while retaining source, coverage, build and RAG gates where applicable. | 2026-07-30 | +| #133 | rec | Conflict-resistant outstanding-issues ledger tables | RESOLVED 2026-07-30. The stock union driver is removed, all three tables use compact canonical rows, and current main now excludes this file from whole-tree Prettier so a max-width row cannot re-pad 144 unrelated lines. The measured mechanism is narrower than the original report: an edit within existing column maxima changes two lines either way, while an append that raises a maximum changes 144 padded lines versus two compact lines—and appends are the common operation. This branch also retains scoped `prettier-ignore` markers and a guard that rejects padded or unprotected tables. The file deliberately has no merge driver, so genuinely overlapping edits conflict instead of silently concatenating duplicates. Source: PRs #1444, #1451, #1479; concurrent #141 allocation evidence. | 2026-07-30 | +| #126 | task | Quarterly branch-review ledger rotation reminder | RESOLVED 2026-07-30. The recurring UTC-quarter rotation procedure now lives in `docs/codex-review-protocol.md`: dry-run first, rotate only the intended completed records, commit live and archive together, and stop on unexpected movement or archive collision. A perpetual open reminder is no longer needed. | 2026-07-30 | +| #110 | task | Design-system project token manifest lags its stylesheet | RESOLVED 2026-07-30. The full `/design-sync` re-sync ran in a session that had the skill, so `_ds_manifest.json` regenerates server-side instead of being hand-authored: `resync.mjs --remote` rebuilt the bundle from the current `src/app/globals.css`, `package-validate.mjs` exited 0 (`render check: 10/10 previews render cleanly`), and the upload re-armed the `_ds_needs_recompile` sentinel that makes the app rebuild the manifest and `_adherence.oxlintrc.json` from the uploaded source on next open. 66 files written, 0 deletes, design-side `templates/**` preserved; `_ds_sync.json` written last. Also corrected two stale claims in the conventions header the port had invalidated (PR #1443). | 2026-07-30 | +| #092 | task | Refetch pulse deferred on auth-backed registries (privacy invariant) | CLOSED 2026-07-30 as deliberately deferred to preserve the identity-clearing privacy invariant. Auth-backed registries continue clearing prior records on loading rather than retaining a refetch count across a possible identity transition. Reopen only with identity-and-query equality guards plus a test proving an identity change clears immediately. | 2026-07-30 | +| #038 | rec | Consolidate shared comparison behavior | CLOSED 2026-07-30 as a future design principle rather than current outstanding implementation. No approved new comparison surface presently needs a shared contract, and existing mode-specific behavior remains unchanged. Reopen when a concrete new comparison surface is approved. | 2026-07-30 | +| #037 | rec | D5 trust-cap-all-claims flag parked OFF | CLOSED 2026-07-30 by product disposition: retain `NEXT_PUBLIC_RAG_TRUST_CAP_ALL_CLAIMS` OFF as the accepted policy. Routine supported claims are not globally capped to medium trust; both flag states remain test-pinned. No code, environment, clinical-output, or provider change was made. Reopen only after an explicit clinical/product trust-policy decision. | 2026-07-30 | +| #021 | rec | E-3d H2 residual strong/comparison generation discards | CLOSED 2026-07-30 as deliberately parked. The conservative quality gate continues to fall back to extractive output for the residual hard cases; no generation or provider behaviour changed. Reopen only if measured latency or generation-waste complaints justify an approved evaluation wave, or a materially cheaper lever appears. | 2026-07-30 | +| #005 | rec | `finalScore` saturates at clamp ceiling | CLOSED 2026-07-30 as not a current defect. Result ordering already uses the unbounded pre-clamp `rankScore`; the `[0,1]` clamp applies only to reported confidence, and the current golden set has no defect. RAG impact: no retrieval behaviour change — ledger disposition only. Reopen only within an approved ranking initiative with the required canary. | 2026-07-30 | | #002 | task | Process-ownership fix not yet isolated on `main` | Fixed process isolation using child.pid termination | 2026-07-21 | | #008 | rec | Dead href builders in `document-flow-routes.ts` | Not dead code (false positive): `documentReaderHref`/`documentEvidenceHref` are live via the mock wrappers in `src/components/document-search-mockups.tsx` + `src/components/master-document-flow-mockups.tsx` (rendered under `src/app/mockups/document-search/`) and covered by `tests/document-flow-routes.test.ts`; removing breaks the build. Only the production non-mock hrefs are unlinked from prod UI — a wiring gap, not dead code. | 2026-07-22 | | #015 | task | Content-first fallback regression tests | Added `tests/registry-record-loader.dom.test.tsx` (8) + `tests/medication-record-page.dom.test.tsx` (6) covering content-first fallback paint, live swap-in, spinner/skeleton, error + not-found/unauthorized states, and the invariant that no authoritative verification badge shows before live governance reconciles (registry fixture-flag neutralization + medication governance-drop-on-error). | 2026-07-22 | diff --git a/scripts/check-github-action-pins.mjs b/scripts/check-github-action-pins.mjs index ff364aed1..3fa355699 100644 --- a/scripts/check-github-action-pins.mjs +++ b/scripts/check-github-action-pins.mjs @@ -124,10 +124,16 @@ failures.push(...collectPinFailures(process.cwd())); const ciWorkflowPath = path.join(workflowDir, "ci.yml"); const ciWorkflow = readFileSync(ciWorkflowPath, "utf8"); +const ciPullRequestTrigger = yamlBlock(ciWorkflow, "pull_request:", 2); const migrationJob = yamlBlock(ciWorkflow, "db-reset-verify:", 2); const setupSupabaseStep = yamlBlock(migrationJob, "- name: Setup Supabase CLI", 6); const restoreSupabaseStep = yamlBlock(migrationJob, "- name: Restore Supabase Docker image cache", 6); const saveSupabaseStep = yamlBlock(migrationJob, "- name: Save Supabase Docker images", 6); +if (!/^ types: \[opened, synchronize, reopened, ready_for_review\]$/m.test(ciPullRequestTrigger)) { + failures.push( + "ci.yml: pull_request events must retain opened/synchronize/reopened and include ready_for_review so undrafting starts required CI.", + ); +} if (!new RegExp(`^ SUPABASE_CLI_VERSION: ${expectedSupabaseCliVersionPattern}$`, "m").test(ciWorkflow)) { failures.push(`ci.yml: global SUPABASE_CLI_VERSION must remain pinned to ${expectedSupabaseCliVersion}.`); } diff --git a/scripts/check-outstanding-issues.mjs b/scripts/check-outstanding-issues.mjs index cbee9982b..e484649dd 100644 --- a/scripts/check-outstanding-issues.mjs +++ b/scripts/check-outstanding-issues.mjs @@ -33,6 +33,7 @@ export const ISSUES_PATH = "docs/outstanding-issues.md"; const OPEN_HEADING = "## Open items"; const ARCHIVE_HEADING = "## Resolved / archive"; const MARKER = //; +const PRETTIER_IGNORE = ""; /** * An id cell's shape, e.g. `#042`. Used to READ the number, never to decide * whether a line is a row. @@ -72,6 +73,10 @@ function cells(line) { .map((cell) => cell.trim()); } +function canonicalTableRow(line) { + return `| ${cells(line).join(" | ")} |`; +} + /** * The lines that make up one table's BODY, and the width its separator declares. * @@ -224,9 +229,33 @@ export function parseIssues(markdown) { }; } -export function checkIssues(markdown) { +export function checkIssues(markdown, { prettierIgnored = false } = {}) { const problems = []; const { openStart, archiveStart, nextId, markerCount, rows, orphans, bodyCount } = parseIssues(markdown); + const lines = markdown.split("\n"); + + // Prettier pads every Markdown table cell to the widest value in its column. + // In this long-lived ledger, changing one cell would then rewrite hundreds + // of unrelated rows and make concurrent merges needlessly conflict. + for (let index = 0; index < lines.length; index += 1) { + const line = lines[index]; + if (/^\|.*\|\s*$/.test(line) && line !== canonicalTableRow(line)) { + problems.push( + `line ${index + 1} is not a compact canonical table row — use one space around each cell delimiter`, + ); + } + if ( + !prettierIgnored && + /^\|/.test(line) && + SEPARATOR.test(lines[index + 1] ?? "") && + lines[index - 1]?.trim() !== PRETTIER_IGNORE + ) { + problems.push( + `line ${index + 1} starts a table without ${PRETTIER_IGNORE} immediately above it — ` + + "formatting would re-pad every row and amplify merge conflicts", + ); + } + } if (openStart < 0) problems.push(`missing the "${OPEN_HEADING}" heading`); if (archiveStart < 0) problems.push(`missing the "${ARCHIVE_HEADING}" heading`); @@ -338,6 +367,10 @@ export function checkIssues(markdown) { return problems; } +export function prettierIgnoreCoversIssues(prettierIgnore) { + return prettierIgnore.split(/\r?\n/).some((line) => line.trim() === ISSUES_PATH); +} + /** * IDs that existed at the comparison base but disappeared from the current * ledger entirely. Moving a row from open to archive keeps its allocation and @@ -396,17 +429,26 @@ function readIssuesAtRevision(ref) { function selfTest() { const good = [ "", + "## Recommended execution queue", + PRETTIER_IGNORE, + "| Rank | ID |", + "| --- | --- |", + "| 1 | #001 |", "## Open items", + PRETTIER_IGNORE, "| ID | Pri | Summary |", "| --- | --- | --- |", "| #001 | P2 | a |", "## Resolved / archive", + PRETTIER_IGNORE, "| ID | Summary |", "| --- | --- |", "| #002 | b |", ].join("\n"); const cases = [ ["a well-formed file", good, 0], + ["a table without a scoped prettier ignore", good.replace(`${PRETTIER_IGNORE}\n| Rank | ID |`, "| Rank | ID |"), 1], + ["a padded table row", good.replace("| #001 | P2 | a |", "| #001 | P2 | a |"), 1], ["a duplicated id", good.replace("| #002 | b |", "| #001 | b |"), 2], // duplicate + both-tables ["an id at the marker", good.replace("next-id=3", "next-id=2"), 1], ["a row with a stray pipe", good.replace("| #001 | P2 | a |", "| #001 | P2 | a | b |"), 1], @@ -459,6 +501,19 @@ function selfTest() { for (const problem of problems) console.error(` - ${problem}`); } } + const fileWideIgnoreProblems = checkIssues(good.replaceAll(`${PRETTIER_IGNORE}\n`, ""), { + prettierIgnored: true, + }); + if (fileWideIgnoreProblems.length !== 0) { + failures += 1; + console.error( + `self-test FAILED: a file-wide prettier ignore replaces scoped table comments — expected 0 problems, got ${fileWideIgnoreProblems.length}`, + ); + } + if (!prettierIgnoreCoversIssues(`# ledger files\n${ISSUES_PATH}\n`) || prettierIgnoreCoversIssues("docs/*.md\n")) { + failures += 1; + console.error("self-test FAILED: file-wide prettier-ignore detection must require the exact ledger path"); + } if (failures > 0) process.exit(1); const deletionCases = [ @@ -526,7 +581,13 @@ function main() { return; } const markdown = readFileSync(ISSUES_PATH, "utf8"); - const problems = checkIssues(markdown); + let prettierIgnored = false; + try { + prettierIgnored = prettierIgnoreCoversIssues(readFileSync(".prettierignore", "utf8")); + } catch { + // Without a file-wide ignore, each table must carry its own scoped comment. + } + const problems = checkIssues(markdown, { prettierIgnored }); const base = issueBaseRevision(); let checkedBase = null; if (base) { diff --git a/scripts/ci-change-scope.mjs b/scripts/ci-change-scope.mjs index 741c6d922..c5c162f60 100644 --- a/scripts/ci-change-scope.mjs +++ b/scripts/ci-change-scope.mjs @@ -542,6 +542,18 @@ function selfTest() { }, ); + assertScope("workflow-only-keeps-coverage", [".github/workflows/ci.yml"], { + coverage_changed: true, + workflow_changed: true, + }); + assertScope("composite-action-only-keeps-coverage", [".github/actions/setup-ui-e2e/action.yml"], { + coverage_changed: true, + workflow_changed: true, + }); + assertScope("runtime-config-keeps-coverage", ["lighthouse-budget.json"], { + coverage_changed: true, + }); + assertScope("unstaged-status", parseStatusPorcelain(" M scripts/ci-change-scope.mjs\0"), { source_changed: true, workflow_changed: true, diff --git a/tests/ui-smoke.spec.ts b/tests/ui-smoke.spec.ts index c48ec1c3f..2c0091cce 100644 --- a/tests/ui-smoke.spec.ts +++ b/tests/ui-smoke.spec.ts @@ -972,6 +972,17 @@ test.beforeEach(stubZeroTouchPoints); test.describe("Clinical KB UI smoke coverage", () => { test.describe.configure({ timeout: 60000 }); + test("Supabase connection hints reach the document head without provider traffic", async ({ page }) => { + await page.goto("/", { waitUntil: "domcontentloaded" }); + + const preconnect = page.locator('head link[rel="preconnect"][href="http://127.0.0.1:1"]'); + const dnsPrefetch = page.locator('head link[rel="dns-prefetch"][href="http://127.0.0.1:1"]'); + + await expect(preconnect).toHaveCount(1); + await expect(preconnect).toHaveAttribute("crossorigin", "anonymous"); + await expect(dnsPrefetch).toHaveCount(1); + }); + for (const viewport of dashboardViewports) { test(`dashboard loads without page overflow at ${viewport.name}`, async ({ page }) => { await page.setViewportSize({ width: viewport.width, height: viewport.height }); @@ -3584,6 +3595,7 @@ test.describe("Clinical KB UI smoke coverage", () => { ).toBeVisible(); const sourceSearch = page.getByLabel("Search within indexed source text").last(); + await waitForReactEventHandler(sourceSearch, "onChange"); await sourceSearch.fill("safety plan include"); const desktopTextPanel = page.getByTestId("source-chunk-indexed-text-panel"); await expect(desktopTextPanel.getByText("Hit 1 of 2").first()).toBeVisible();