From f6a97c2121aec1f93c299b031703048ac7984d2d Mon Sep 17 00:00:00 2001 From: BigSimmo <87357024+BigSimmo@users.noreply.github.com> Date: Wed, 19 Aug 2026 00:31:43 +0800 Subject: [PATCH 1/2] docs(issues): reconcile 31 queued ledger requests after PRs #2107, #2127-#2131 One fresh-base issues:reconcile over the complete pending inbox (31 requests). Closes #DP6M3G (S1b landed), #SDQSFD (#2127), #TYJ0XP (#2128); re-grades #231 to P2 with the R4 residual and Phase 5.2 cross-link; cancels duplicates #BTVMVK (of closed #342) and #ND10QT (of #343); adds the RAG programme pointer, the neuroleptic latency advisory, the probe answer-text gap, and the non-RAG captures queued since #2119. Visual register refreshed. Co-Authored-By: Claude Fable 5 --- .../0f96874b-127c-4fe7-a6cd-349032007e00.json | 0 .../1779e516-039a-455c-af91-8705a2bdf82d.json | 0 .../197cb013-5541-4877-9d56-c37a4953d79f.json | 0 .../1fb86cdd-fd83-4709-a946-33315687ca05.json | 0 .../35826a8b-8ebf-4b19-8319-7ee229d028ca.json | 0 .../4996f8c9-a2e1-4771-95f6-8a5540e1254a.json | 0 .../52d9823c-1e1e-46f9-95f5-e12af1b23a97.json | 0 .../52fa4b08-42d3-4ac1-b896-6c0d99d72a63.json | 0 .../5347413c-2037-42a5-9e93-3446567da3ab.json | 0 .../5381a52d-9a73-4b5c-a96a-0eab6f3d491a.json | 0 .../53c284e1-6da3-420f-b3b5-52e89edf4663.json | 0 .../5500f75d-0eea-4c2f-ba9b-52e103217eae.json | 0 .../5899581b-dc23-486d-a6da-e456c5c5f3bc.json | 0 .../5bdc09b4-9db4-4667-8cf1-b35ca58df667.json | 0 .../654217d2-416b-4de8-a847-6e2812c3653d.json | 0 .../66803529-0573-402f-bd63-ed4afa391de6.json | 0 .../7954fb32-db57-43ce-a3e4-b31aa4a897f9.json | 0 .../7d9d496a-d6de-440e-9dc4-cb99ebda327b.json | 0 .../89d7fe98-1873-41e8-bc21-d77cab91663b.json | 0 .../8bfa1d6f-e8ae-496b-9ad1-15c1ba718831.json | 0 .../8c14c6a0-f893-4659-b84e-62823d832c97.json | 0 .../9864a5d7-134d-4115-84ca-11eaddfa6c97.json | 0 .../a5f073f9-c82a-4d42-86af-0a36159a9403.json | 0 .../b8861f66-fda9-40d6-bd3b-682b2c5d214c.json | 0 .../bbd0c2e5-6e2f-4aa9-802e-31a95ccb2b2d.json | 0 .../be915748-8b3d-4286-b0cd-c3af465df2a2.json | 0 .../c4cb12b6-4d94-4518-bd84-1ec947652e8e.json | 0 .../c5be8b1c-46e8-43e7-92d6-6571e9eae913.json | 0 .../e4773b50-2c9f-4f48-94ca-ed5816ef4d82.json | 0 .../ec356a7d-96ec-4739-aa23-4429aa424028.json | 0 .../ef42a5e3-33ca-4d1c-87b7-2dbf4f0bea8a.json | 0 docs/outstanding-issues.md | 51 +++++++++++-------- 32 files changed, 31 insertions(+), 20 deletions(-) rename docs/outstanding-issues-inbox/{ => applied}/0f96874b-127c-4fe7-a6cd-349032007e00.json (100%) rename docs/outstanding-issues-inbox/{ => applied}/1779e516-039a-455c-af91-8705a2bdf82d.json (100%) rename docs/outstanding-issues-inbox/{ => applied}/197cb013-5541-4877-9d56-c37a4953d79f.json (100%) rename docs/outstanding-issues-inbox/{ => applied}/1fb86cdd-fd83-4709-a946-33315687ca05.json (100%) rename docs/outstanding-issues-inbox/{ => applied}/35826a8b-8ebf-4b19-8319-7ee229d028ca.json (100%) rename docs/outstanding-issues-inbox/{ => applied}/4996f8c9-a2e1-4771-95f6-8a5540e1254a.json (100%) rename docs/outstanding-issues-inbox/{ => applied}/52d9823c-1e1e-46f9-95f5-e12af1b23a97.json (100%) rename docs/outstanding-issues-inbox/{ => applied}/52fa4b08-42d3-4ac1-b896-6c0d99d72a63.json (100%) rename docs/outstanding-issues-inbox/{ => applied}/5347413c-2037-42a5-9e93-3446567da3ab.json (100%) rename docs/outstanding-issues-inbox/{ => applied}/5381a52d-9a73-4b5c-a96a-0eab6f3d491a.json (100%) rename docs/outstanding-issues-inbox/{ => applied}/53c284e1-6da3-420f-b3b5-52e89edf4663.json (100%) rename docs/outstanding-issues-inbox/{ => applied}/5500f75d-0eea-4c2f-ba9b-52e103217eae.json (100%) rename docs/outstanding-issues-inbox/{ => applied}/5899581b-dc23-486d-a6da-e456c5c5f3bc.json (100%) rename docs/outstanding-issues-inbox/{ => applied}/5bdc09b4-9db4-4667-8cf1-b35ca58df667.json (100%) rename docs/outstanding-issues-inbox/{ => applied}/654217d2-416b-4de8-a847-6e2812c3653d.json (100%) rename docs/outstanding-issues-inbox/{ => applied}/66803529-0573-402f-bd63-ed4afa391de6.json (100%) rename docs/outstanding-issues-inbox/{ => applied}/7954fb32-db57-43ce-a3e4-b31aa4a897f9.json (100%) rename docs/outstanding-issues-inbox/{ => applied}/7d9d496a-d6de-440e-9dc4-cb99ebda327b.json (100%) rename docs/outstanding-issues-inbox/{ => applied}/89d7fe98-1873-41e8-bc21-d77cab91663b.json (100%) rename docs/outstanding-issues-inbox/{ => applied}/8bfa1d6f-e8ae-496b-9ad1-15c1ba718831.json (100%) rename docs/outstanding-issues-inbox/{ => applied}/8c14c6a0-f893-4659-b84e-62823d832c97.json (100%) rename docs/outstanding-issues-inbox/{ => applied}/9864a5d7-134d-4115-84ca-11eaddfa6c97.json (100%) rename docs/outstanding-issues-inbox/{ => applied}/a5f073f9-c82a-4d42-86af-0a36159a9403.json (100%) rename docs/outstanding-issues-inbox/{ => applied}/b8861f66-fda9-40d6-bd3b-682b2c5d214c.json (100%) rename docs/outstanding-issues-inbox/{ => applied}/bbd0c2e5-6e2f-4aa9-802e-31a95ccb2b2d.json (100%) rename docs/outstanding-issues-inbox/{ => applied}/be915748-8b3d-4286-b0cd-c3af465df2a2.json (100%) rename docs/outstanding-issues-inbox/{ => applied}/c4cb12b6-4d94-4518-bd84-1ec947652e8e.json (100%) rename docs/outstanding-issues-inbox/{ => applied}/c5be8b1c-46e8-43e7-92d6-6571e9eae913.json (100%) rename docs/outstanding-issues-inbox/{ => applied}/e4773b50-2c9f-4f48-94ca-ed5816ef4d82.json (100%) rename docs/outstanding-issues-inbox/{ => applied}/ec356a7d-96ec-4739-aa23-4429aa424028.json (100%) rename docs/outstanding-issues-inbox/{ => applied}/ef42a5e3-33ca-4d1c-87b7-2dbf4f0bea8a.json (100%) diff --git a/docs/outstanding-issues-inbox/0f96874b-127c-4fe7-a6cd-349032007e00.json b/docs/outstanding-issues-inbox/applied/0f96874b-127c-4fe7-a6cd-349032007e00.json similarity index 100% rename from docs/outstanding-issues-inbox/0f96874b-127c-4fe7-a6cd-349032007e00.json rename to docs/outstanding-issues-inbox/applied/0f96874b-127c-4fe7-a6cd-349032007e00.json diff --git a/docs/outstanding-issues-inbox/1779e516-039a-455c-af91-8705a2bdf82d.json b/docs/outstanding-issues-inbox/applied/1779e516-039a-455c-af91-8705a2bdf82d.json similarity index 100% rename from docs/outstanding-issues-inbox/1779e516-039a-455c-af91-8705a2bdf82d.json rename to docs/outstanding-issues-inbox/applied/1779e516-039a-455c-af91-8705a2bdf82d.json diff --git a/docs/outstanding-issues-inbox/197cb013-5541-4877-9d56-c37a4953d79f.json b/docs/outstanding-issues-inbox/applied/197cb013-5541-4877-9d56-c37a4953d79f.json similarity index 100% rename from docs/outstanding-issues-inbox/197cb013-5541-4877-9d56-c37a4953d79f.json rename to docs/outstanding-issues-inbox/applied/197cb013-5541-4877-9d56-c37a4953d79f.json diff --git a/docs/outstanding-issues-inbox/1fb86cdd-fd83-4709-a946-33315687ca05.json b/docs/outstanding-issues-inbox/applied/1fb86cdd-fd83-4709-a946-33315687ca05.json similarity index 100% rename from docs/outstanding-issues-inbox/1fb86cdd-fd83-4709-a946-33315687ca05.json rename to docs/outstanding-issues-inbox/applied/1fb86cdd-fd83-4709-a946-33315687ca05.json diff --git a/docs/outstanding-issues-inbox/35826a8b-8ebf-4b19-8319-7ee229d028ca.json b/docs/outstanding-issues-inbox/applied/35826a8b-8ebf-4b19-8319-7ee229d028ca.json similarity index 100% rename from docs/outstanding-issues-inbox/35826a8b-8ebf-4b19-8319-7ee229d028ca.json rename to docs/outstanding-issues-inbox/applied/35826a8b-8ebf-4b19-8319-7ee229d028ca.json diff --git a/docs/outstanding-issues-inbox/4996f8c9-a2e1-4771-95f6-8a5540e1254a.json b/docs/outstanding-issues-inbox/applied/4996f8c9-a2e1-4771-95f6-8a5540e1254a.json similarity index 100% rename from docs/outstanding-issues-inbox/4996f8c9-a2e1-4771-95f6-8a5540e1254a.json rename to docs/outstanding-issues-inbox/applied/4996f8c9-a2e1-4771-95f6-8a5540e1254a.json diff --git a/docs/outstanding-issues-inbox/52d9823c-1e1e-46f9-95f5-e12af1b23a97.json b/docs/outstanding-issues-inbox/applied/52d9823c-1e1e-46f9-95f5-e12af1b23a97.json similarity index 100% rename from docs/outstanding-issues-inbox/52d9823c-1e1e-46f9-95f5-e12af1b23a97.json rename to docs/outstanding-issues-inbox/applied/52d9823c-1e1e-46f9-95f5-e12af1b23a97.json diff --git a/docs/outstanding-issues-inbox/52fa4b08-42d3-4ac1-b896-6c0d99d72a63.json b/docs/outstanding-issues-inbox/applied/52fa4b08-42d3-4ac1-b896-6c0d99d72a63.json similarity index 100% rename from docs/outstanding-issues-inbox/52fa4b08-42d3-4ac1-b896-6c0d99d72a63.json rename to docs/outstanding-issues-inbox/applied/52fa4b08-42d3-4ac1-b896-6c0d99d72a63.json diff --git a/docs/outstanding-issues-inbox/5347413c-2037-42a5-9e93-3446567da3ab.json b/docs/outstanding-issues-inbox/applied/5347413c-2037-42a5-9e93-3446567da3ab.json similarity index 100% rename from docs/outstanding-issues-inbox/5347413c-2037-42a5-9e93-3446567da3ab.json rename to docs/outstanding-issues-inbox/applied/5347413c-2037-42a5-9e93-3446567da3ab.json diff --git a/docs/outstanding-issues-inbox/5381a52d-9a73-4b5c-a96a-0eab6f3d491a.json b/docs/outstanding-issues-inbox/applied/5381a52d-9a73-4b5c-a96a-0eab6f3d491a.json similarity index 100% rename from docs/outstanding-issues-inbox/5381a52d-9a73-4b5c-a96a-0eab6f3d491a.json rename to docs/outstanding-issues-inbox/applied/5381a52d-9a73-4b5c-a96a-0eab6f3d491a.json diff --git a/docs/outstanding-issues-inbox/53c284e1-6da3-420f-b3b5-52e89edf4663.json b/docs/outstanding-issues-inbox/applied/53c284e1-6da3-420f-b3b5-52e89edf4663.json similarity index 100% rename from docs/outstanding-issues-inbox/53c284e1-6da3-420f-b3b5-52e89edf4663.json rename to docs/outstanding-issues-inbox/applied/53c284e1-6da3-420f-b3b5-52e89edf4663.json diff --git a/docs/outstanding-issues-inbox/5500f75d-0eea-4c2f-ba9b-52e103217eae.json b/docs/outstanding-issues-inbox/applied/5500f75d-0eea-4c2f-ba9b-52e103217eae.json similarity index 100% rename from docs/outstanding-issues-inbox/5500f75d-0eea-4c2f-ba9b-52e103217eae.json rename to docs/outstanding-issues-inbox/applied/5500f75d-0eea-4c2f-ba9b-52e103217eae.json diff --git a/docs/outstanding-issues-inbox/5899581b-dc23-486d-a6da-e456c5c5f3bc.json b/docs/outstanding-issues-inbox/applied/5899581b-dc23-486d-a6da-e456c5c5f3bc.json similarity index 100% rename from docs/outstanding-issues-inbox/5899581b-dc23-486d-a6da-e456c5c5f3bc.json rename to docs/outstanding-issues-inbox/applied/5899581b-dc23-486d-a6da-e456c5c5f3bc.json diff --git a/docs/outstanding-issues-inbox/5bdc09b4-9db4-4667-8cf1-b35ca58df667.json b/docs/outstanding-issues-inbox/applied/5bdc09b4-9db4-4667-8cf1-b35ca58df667.json similarity index 100% rename from docs/outstanding-issues-inbox/5bdc09b4-9db4-4667-8cf1-b35ca58df667.json rename to docs/outstanding-issues-inbox/applied/5bdc09b4-9db4-4667-8cf1-b35ca58df667.json diff --git a/docs/outstanding-issues-inbox/654217d2-416b-4de8-a847-6e2812c3653d.json b/docs/outstanding-issues-inbox/applied/654217d2-416b-4de8-a847-6e2812c3653d.json similarity index 100% rename from docs/outstanding-issues-inbox/654217d2-416b-4de8-a847-6e2812c3653d.json rename to docs/outstanding-issues-inbox/applied/654217d2-416b-4de8-a847-6e2812c3653d.json diff --git a/docs/outstanding-issues-inbox/66803529-0573-402f-bd63-ed4afa391de6.json b/docs/outstanding-issues-inbox/applied/66803529-0573-402f-bd63-ed4afa391de6.json similarity index 100% rename from docs/outstanding-issues-inbox/66803529-0573-402f-bd63-ed4afa391de6.json rename to docs/outstanding-issues-inbox/applied/66803529-0573-402f-bd63-ed4afa391de6.json diff --git a/docs/outstanding-issues-inbox/7954fb32-db57-43ce-a3e4-b31aa4a897f9.json b/docs/outstanding-issues-inbox/applied/7954fb32-db57-43ce-a3e4-b31aa4a897f9.json similarity index 100% rename from docs/outstanding-issues-inbox/7954fb32-db57-43ce-a3e4-b31aa4a897f9.json rename to docs/outstanding-issues-inbox/applied/7954fb32-db57-43ce-a3e4-b31aa4a897f9.json diff --git a/docs/outstanding-issues-inbox/7d9d496a-d6de-440e-9dc4-cb99ebda327b.json b/docs/outstanding-issues-inbox/applied/7d9d496a-d6de-440e-9dc4-cb99ebda327b.json similarity index 100% rename from docs/outstanding-issues-inbox/7d9d496a-d6de-440e-9dc4-cb99ebda327b.json rename to docs/outstanding-issues-inbox/applied/7d9d496a-d6de-440e-9dc4-cb99ebda327b.json diff --git a/docs/outstanding-issues-inbox/89d7fe98-1873-41e8-bc21-d77cab91663b.json b/docs/outstanding-issues-inbox/applied/89d7fe98-1873-41e8-bc21-d77cab91663b.json similarity index 100% rename from docs/outstanding-issues-inbox/89d7fe98-1873-41e8-bc21-d77cab91663b.json rename to docs/outstanding-issues-inbox/applied/89d7fe98-1873-41e8-bc21-d77cab91663b.json diff --git a/docs/outstanding-issues-inbox/8bfa1d6f-e8ae-496b-9ad1-15c1ba718831.json b/docs/outstanding-issues-inbox/applied/8bfa1d6f-e8ae-496b-9ad1-15c1ba718831.json similarity index 100% rename from docs/outstanding-issues-inbox/8bfa1d6f-e8ae-496b-9ad1-15c1ba718831.json rename to docs/outstanding-issues-inbox/applied/8bfa1d6f-e8ae-496b-9ad1-15c1ba718831.json diff --git a/docs/outstanding-issues-inbox/8c14c6a0-f893-4659-b84e-62823d832c97.json b/docs/outstanding-issues-inbox/applied/8c14c6a0-f893-4659-b84e-62823d832c97.json similarity index 100% rename from docs/outstanding-issues-inbox/8c14c6a0-f893-4659-b84e-62823d832c97.json rename to docs/outstanding-issues-inbox/applied/8c14c6a0-f893-4659-b84e-62823d832c97.json diff --git a/docs/outstanding-issues-inbox/9864a5d7-134d-4115-84ca-11eaddfa6c97.json b/docs/outstanding-issues-inbox/applied/9864a5d7-134d-4115-84ca-11eaddfa6c97.json similarity index 100% rename from docs/outstanding-issues-inbox/9864a5d7-134d-4115-84ca-11eaddfa6c97.json rename to docs/outstanding-issues-inbox/applied/9864a5d7-134d-4115-84ca-11eaddfa6c97.json diff --git a/docs/outstanding-issues-inbox/a5f073f9-c82a-4d42-86af-0a36159a9403.json b/docs/outstanding-issues-inbox/applied/a5f073f9-c82a-4d42-86af-0a36159a9403.json similarity index 100% rename from docs/outstanding-issues-inbox/a5f073f9-c82a-4d42-86af-0a36159a9403.json rename to docs/outstanding-issues-inbox/applied/a5f073f9-c82a-4d42-86af-0a36159a9403.json diff --git a/docs/outstanding-issues-inbox/b8861f66-fda9-40d6-bd3b-682b2c5d214c.json b/docs/outstanding-issues-inbox/applied/b8861f66-fda9-40d6-bd3b-682b2c5d214c.json similarity index 100% rename from docs/outstanding-issues-inbox/b8861f66-fda9-40d6-bd3b-682b2c5d214c.json rename to docs/outstanding-issues-inbox/applied/b8861f66-fda9-40d6-bd3b-682b2c5d214c.json diff --git a/docs/outstanding-issues-inbox/bbd0c2e5-6e2f-4aa9-802e-31a95ccb2b2d.json b/docs/outstanding-issues-inbox/applied/bbd0c2e5-6e2f-4aa9-802e-31a95ccb2b2d.json similarity index 100% rename from docs/outstanding-issues-inbox/bbd0c2e5-6e2f-4aa9-802e-31a95ccb2b2d.json rename to docs/outstanding-issues-inbox/applied/bbd0c2e5-6e2f-4aa9-802e-31a95ccb2b2d.json diff --git a/docs/outstanding-issues-inbox/be915748-8b3d-4286-b0cd-c3af465df2a2.json b/docs/outstanding-issues-inbox/applied/be915748-8b3d-4286-b0cd-c3af465df2a2.json similarity index 100% rename from docs/outstanding-issues-inbox/be915748-8b3d-4286-b0cd-c3af465df2a2.json rename to docs/outstanding-issues-inbox/applied/be915748-8b3d-4286-b0cd-c3af465df2a2.json diff --git a/docs/outstanding-issues-inbox/c4cb12b6-4d94-4518-bd84-1ec947652e8e.json b/docs/outstanding-issues-inbox/applied/c4cb12b6-4d94-4518-bd84-1ec947652e8e.json similarity index 100% rename from docs/outstanding-issues-inbox/c4cb12b6-4d94-4518-bd84-1ec947652e8e.json rename to docs/outstanding-issues-inbox/applied/c4cb12b6-4d94-4518-bd84-1ec947652e8e.json diff --git a/docs/outstanding-issues-inbox/c5be8b1c-46e8-43e7-92d6-6571e9eae913.json b/docs/outstanding-issues-inbox/applied/c5be8b1c-46e8-43e7-92d6-6571e9eae913.json similarity index 100% rename from docs/outstanding-issues-inbox/c5be8b1c-46e8-43e7-92d6-6571e9eae913.json rename to docs/outstanding-issues-inbox/applied/c5be8b1c-46e8-43e7-92d6-6571e9eae913.json diff --git a/docs/outstanding-issues-inbox/e4773b50-2c9f-4f48-94ca-ed5816ef4d82.json b/docs/outstanding-issues-inbox/applied/e4773b50-2c9f-4f48-94ca-ed5816ef4d82.json similarity index 100% rename from docs/outstanding-issues-inbox/e4773b50-2c9f-4f48-94ca-ed5816ef4d82.json rename to docs/outstanding-issues-inbox/applied/e4773b50-2c9f-4f48-94ca-ed5816ef4d82.json diff --git a/docs/outstanding-issues-inbox/ec356a7d-96ec-4739-aa23-4429aa424028.json b/docs/outstanding-issues-inbox/applied/ec356a7d-96ec-4739-aa23-4429aa424028.json similarity index 100% rename from docs/outstanding-issues-inbox/ec356a7d-96ec-4739-aa23-4429aa424028.json rename to docs/outstanding-issues-inbox/applied/ec356a7d-96ec-4739-aa23-4429aa424028.json diff --git a/docs/outstanding-issues-inbox/ef42a5e3-33ca-4d1c-87b7-2dbf4f0bea8a.json b/docs/outstanding-issues-inbox/applied/ef42a5e3-33ca-4d1c-87b7-2dbf4f0bea8a.json similarity index 100% rename from docs/outstanding-issues-inbox/ef42a5e3-33ca-4d1c-87b7-2dbf4f0bea8a.json rename to docs/outstanding-issues-inbox/applied/ef42a5e3-33ca-4d1c-87b7-2dbf4f0bea8a.json diff --git a/docs/outstanding-issues.md b/docs/outstanding-issues.md index d360553266..5639d8dba2 100644 --- a/docs/outstanding-issues.md +++ b/docs/outstanding-issues.md @@ -64,8 +64,6 @@ removed after current-main verification; it is not missing recommended work. | 9 | `#099` | A3 | Specialist — answer path | After `#098` | Half a day per sub-item | Remaining fixed per-request round trips: the 8 `setCachedSearch` deferrals (abort semantics + mutation window), the anonymous subject+global limiter pair (needs a new atomic RPC first), and proxy→route identity duplication. Stop before hand-authoring locking SQL. | | 10 | `#100` | A3 | Specialist — answer streaming | After offline Phase 0/1 design proof | provider-gated rollout | Buffered answer generation has no incremental verified delivery — [`verified-answer-incremental-delivery-design.md`](verified-answer-incremental-delivery-design.md) records the clinical-governance decision and staged co… | | 11 | `#191` | A3 | Operator — DB + Specialist | Approved live-DB window only | provider-gated | X5: ACL-migration consolidation (provider-gated) — ACL-related migrations are consolidated per maturity work-order X5 without weakening owner-scope/RLS. | -| 12 | `#183` | A2 | Operator — Sentry + Specialist | Next approved observability window with SENTRY_AUTH_TOKEN | 1–2 hours | Create Sentry metric alert for production DB span p95 > 500ms (`span.op:db`, environment production). **Stop:** no secret printing; blocked until token/env available. | -| 13 | `#248` | A2 | Operator — Supabase + Specialist | After PR #1614 symptom repair; approved live/history window | 1–2 hours | Investigate why 20260705180000 search-health indexes were missing on live despite applied history; decide if drift checks should catch this class. **Stop:** no hosted mutation without approval. | @@ -95,28 +93,12 @@ removed after current-main verification; it is not missing recommended work. | #099 | P2 | task | Remove the remaining fixed per-request round trips | **Outcome:** the answer path stops paying avoidable per-request Supabase round trips. **Done 2026-07-29:** shared-cache-hit promotion deferred off the response path with its mid-request staleness guard intact and documented (`rag.ts:3234`, `rag-cache.ts`); scope resolution overlapped with the rate-limit RPC, signal threaded so a client disconnect finally cancels its paginated queries (`answer/route.ts`). **REFUTED on PR #1377 review — do not retry:** the same pass also overlapped scope with the rate-limit RPC and aborted it on deny, claiming the limiter could "deny for free". It cannot. With caller-supplied `filters` or explicit ids, scope passes its zero-query early returns (`search-scope.ts:242,253`) into the paginated `documents` loop at `:269`, and an `AbortSignal` cancels the client request without un-executing a statement Postgres already began — so throttled traffic kept burning database capacity while collecting 429s, against `capacity-review.md:106-113`'s first-soft-failure warning. Scope is behind admission again, pinned by `tests/answer-route-preamble.test.ts`. Re-attempting the overlap requires a non-database admission gate ahead of the durable limiter first. **Remaining:** (a) the 8 `setCachedSearch` awaits — deferring changes `throwIfAborted` semantics and widens a real mutation window because the clone happens after an `await`, so each branch needs discharging individually; (b) batch the anonymous subject+global rate-limit pair, which needs a NEW atomic RPC modelled on `consume_summary_rate_limits_atomic` and cannot be called until the operator applies it — `Promise.all` is the WRONG fix because it consumes the global bucket even when the subject bucket already denied; (c) stop the proxy and route handler resolving identity twice per authenticated request — no in-process memo can do this (different `Request` objects), so the proxy must forward unspoofable verified claims via a header it controls. Cross-references #011: halving auth resolutions eases the ~10-connection Auth cap that `capacity-review.md:106-113` calls the first hard failure. | `docs/audit/latency-audit-2026-07-28.md` L1-1/L1-3/L1-4; `src/lib/api-rate-limit.ts:276-282`; `src/proxy.ts:125` | 2026-07-29 | | #100 | P2 | rec | Buffered answer generation has no incremental verified delivery | UPDATE 2026-08-13 (PR #1909): Phase 0 offline contract proof and flag-gated Phase 1 server emission implemented (RAG_INCREMENTAL_EVIDENCE_PREVIEW, default false). Remaining: client parsing/rendering phase behind its own flag + verify:ui, then the design's provider-backed acceptance gates before production enablement; Phase 2 stays provider-gated. **Design complete; runtime work remains provider-gated.** [`verified-answer-incremental-delivery-design.md`](verified-answer-incremental-delivery-design.md) records the clinical-governance decision and staged contract: keep the `progress`/`final`/`error` allowlist; disclose bounded, owner-scoped evidence only after the canonical danger-level source-governance refusal permits it, then emit complete answer sections only after each reuses the full production verification boundary; reconcile every preview byte-for-byte with the authoritative `final`; discard all previews on error/cancel/retry; deploy behind separate parse/emission/render flags. Phase 0 contract proof and Phase 1 evidence preview can be developed offline, but visible rollout still needs clinical/browser proof. Phase 2 changes generation architecture and requires explicit approval for answer-quality evals plus a baseline/post live canary pair. **Naive token streaming remains REFUTED:** never re-land `token`, `revising`, provisional prose, or a weaker stream-only verifier. Cross-references #021. | `docs/verified-answer-incremental-delivery-design.md`; `docs/audit/latency-audit-2026-07-28.md` L0-1; `src/lib/answer-stream-contract.ts:18-21` | 2026-07-30 | | #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 | -| #183 | P3 | task | Create Sentry metric alert for production DB span p95 > 500ms | RIDER 2026-08-18 (recorded on the Phase 3 product PR, not a ledger-only branch): the Supabase CLI is now authenticated and this repository is linked to the staging project Clinical KB Staging (ikoiolksxqxfxgiyqpnu) — owner action 2026-08-18. That unblocks CLI repair paths (supabase db push --linked, migration repair with a guard migration) for staging; SUPABASE_ACCESS_TOKEN as a repository/environment secret for CI/live-drift remains outstanding, and the Sentry metric-alert part of this row (SENTRY_AUTH_TOKEN, p95 span.op:db > 500ms alert, deprioritised 2026-08-12) is unchanged. | session 2026-08-18 Phase 3 repo-side codification (branch claude/schema-work-mem-codify-6200f1) | 2026-07-31 | | #191 | P3 | task | X5: ACL-migration consolidation (provider-gated) | **Outcome:** ACL-related migrations are consolidated per maturity work-order X5 without weakening owner-scope/RLS. **Next:** DB-owner approved window only; live-DB provider confirmation required before apply. **Stop:** no hosted apply from an agent session without explicit approval. | docs/maturity-backlog-workorders.md X5; #086 | 2026-07-31 | -| #231 | P1 | issue | Generation fallbacks no longer stick in answer cache; lithium generation quality still falls back safely | PARTIAL 2026-08-12: This PR fixes the clinically consequential stale-fallback path: every answer whose routing or degraded reason contains generation_fallback is excluded from rag_response_cache. Offline evidence: 96 focused answer-route tests and 574 RAG fixture/contract tests passed. Approved live baseline/final canaries preserved 36/36 document and content recall at 1.0 with zero per-case reciprocal-rank regressions; the final 44-case answer gate had zero citation or numeric-grounding failures. A budget extension was tested and rejected: four cache-bypassed 'Lithium dosing?' probes remained grounded, cited safe extractive fallbacks at 35-40 second candidate budgets; the decisive 40-second probe completed generation in 25.272 seconds and 27.237 seconds total with route_deadline_exceeded=false, but failed generation quality. Therefore OPENAI_ANSWER_TIMEOUT_MS and the route budget are not the current residual binding cause. INSTRUMENT NOW EXISTS 2026-08-14: the "Next: instrument" half of this row is done. Commit a3bc4da adds scripts/probe-generation-quality.ts — one cache-bypassed live answer reporting the structured generation_quality_gate_reasons, provider-backed, refusing demo mode, never caching or logging the probe. The same commit adjudicates PR #1861: superseded for phase 1, close recommended, with the numeric-retry half deferred to phase 2 pending probe evidence. So do not review #1861 as though it were the live fix, and do not re-implement the probe. Next: run scripts/probe-generation-quality.ts in an environment that has OPENAI and Supabase credentials — it is blocked in offline containers, which is why it has not been run yet — then make a separate bounded output-quality fix with an offline fixture and live canary. Stop: do not increase route/provider timeouts or cache any generation fallback. INCIDENT ADDENDUM 2026-08-14 (later the same day): rung-2 evidence was then measured live - supabase_rpc_latency_ms 31610 on a semantic query (route budget 25000 starved generation), caused by the #316 dropped trigram indexes; after their owner-approved restore, 1535 (text fast path) / 8519 (hybrid). Pre-generation latency was the binding residual cause of semantic-query source-only fallbacks in that window; evidence in docs/audit/live-drift-forensics-2026-08.md. S1 (A1 phase 2) must re-verify generation_quality_gate:* dominance on healthy latency (run the probe with node --env-file=.env.local, which the probe does not load itself) before choosing a code mitigation rung. The route-budget stop condition stands unchanged. | sessions 2026-08-14: instrument adjudication + live incident probes (owner-authorized Supabase connector) | 2026-08-04 | -| #248 | P2 | issue | Investigate why 20260705180000 search-health indexes were missing on live despite applied history | APPEND 2026-08-13: the prior closure is withdrawn. Repository and live-drift evidence establishes that 20260705180000_reconcile_search_health_indexes.sql is recorded as applied while documents_title_trgm_idx and document_chunks_content_trgm_idx are missing on live. Supabase transaction semantics exclude a persisted partial migration, but the present record does not distinguish skipped DDL/history repair from indexes created and later dropped. In an approved read-only window, query supabase_migrations.schema_migrations for the 20260705180000 statements fingerprint and inspect the relevant audit/history evidence; retain both hypotheses until that evidence establishes the cause. Separately, scheduled check:drift did detect the missing indexes, but red runs were not routed. | PR #1614 review / session 2026-08-05 (renumbered on main merge) | 2026-08-05 | -| #283 | P3 | rec | The 100-id batch signed-URL route still has no caller | VERIFIED CORRECT 2026-08-12 — re-checked against merged main during the full ledger sweep and left unchanged: No caller for src/app/api/images/signed-urls/route.ts anywhere outside app/api — the batch route is still unused. This stamp exists so a later reader can tell "checked and still true" from "never looked at"; the two were indistinguishable before. **Outcome:** either the batch minter is used or it is retired, rather than sitting as an untested, unreachable privileged surface. **Detail:** src/app/api/images/signed-urls/route.ts POSTs up to 100 image ids and returns their signed URLs, with its own rate limit, owner scoping and committed-generation filter. Nothing in src/ calls it — only tests/private-access-routes.test.ts imports it. **DEFERRED AGAIN, DELIBERATELY, 2026-08-09 (document viewer Phase 3, Task 3).** The user chose deferral over wiring when asked. Two reasons beyond cost: (a) wiring it puts a privileged owner-scoped API route into a diff that is otherwise confined to src/components/document-viewer/**, and it matches clinicalRiskPatterns (/^src\/app\/api\//) so pr-policy hard-blocks the merge without a complete Clinical Governance Preflight; (b) Phase 3 Task 2 windowed the rail to six rows and tightened its IntersectionObserver root margin from 640px to 240px, so the many-distinct-images case the batch route was meant to serve is now materially smaller — a page of N figures no longer mounts N rows at once. The batching win should be re-measured against the windowed rail before it is wired at all, rather than assumed from the pre-window numbers. **Next:** decide deliberately — measure concurrent distinct-image requests on a figure-heavy document with the windowed rail, then either wire the batch route in its own PR or delete it and its tests. **Stop:** if wiring it, keep the per-image endpoint for the lightbox's retry path; do not make the batch the only way to mint a URL. | session 2026-08-08 document-viewer optimisation; src/app/api/images/signed-urls/route.ts | 2026-08-08 | -| #305 | P3 | rec | Canary has no latency-mode coverage and its cost readout is a known lower bound | Two informational gaps from the 2026-08-12 canary review, deferred by scope decision. (1) eval:retrieval:latency (p90 20s gate) is never wired into eval-canary.yml, so live retrieval latency regressions are invisible to the weekly canary while the answer step relaxes its own gates via EVAL_LATENCY_CONTEXT=cross-region-runner. (2) estimated_cost_usd applies one rate set (gpt-5.6-terra) to all usage including 2x-priced strong-model retries, so any cost trend understates strong-retry runs — the workflow comments say so, but eval:trend consumers may not read them. Also noted: the workflow-wide concurrency group (eval-canary, cancel-in-progress false) can queue a dispatched pair run behind a scheduled run, interleaving pair evidence; and fixture coverage gaps tracked in #018 remain uncatchable by the canary. Next: decide whether a monthly latency-mode dispatch is worth the spend; add a strong-usage split to the estimator if cost trends start driving decisions. | session 2026-08-12 RAG canary review | 2026-08-12 | +| #231 | P2 | issue | Generation fallbacks no longer stick in answer cache; lithium generation quality still falls back safely | S1 (#2022), S1b (#2035), S1d (#2054) landed with green canary pairs: generation-quality false rejections and the finalizer gap hole are fixed. Residual R4: chronic ~30 s strong-route provider_timeout on metformin-renal-dosing and valproate-pregnancy (measured 4/4 at v18 4ea310e48 and 2/4 at v19 main on 2026-08-18; safe source-backed extractive fallback, never model synthesis). Route-budget stop condition unchanged. Remediation-plan Phase 5.2 (re-test #231 after the trigram-index restore) is satisfied by S1's 2026-08-17 healthy-latency probes; live-drift #316 Phase 1.2 classified all ten RPC divergences as attribute-only, so canaries since 2026-08-14 measure a reconstructable path. Re-graded P1 -> P2. Next: prompt/context trimming for complex classes, or accept the extractive fallback as the durable answer for these two classes. Do not add a separate R4 row — this update supersedes that need. | docs/rag-improvement/HANDOVER.md secs 1-2; docs/rag-improvement/COORDINATION.md sec 7; docs/database-remediation-plan.md Phase 5.2; docs/audit/live-drift-forensics-2026-08.md sec on Phase 1.2 classification; ledger rows #316 / #248 / #231 / #342; session 2026-08-18 | 2026-08-04 | | #308 | P3 | issue | Desktop /documents/search CLS is 0.119, above threshold and stable across runs and baselines | Measured 2026-08-12 during the #147 close-out, twice, on the offline Lighthouse harness (Chromium 141): desktop /documents/search CLS **0.119**, against a committed baseline that also reads **0.119**. So this is long-standing and deterministic, not a regression — and it is above the 0.1 threshold. It sits outside #147's scope, which was mobile only, and it contradicts that row's claim that 'desktop passes everywhere: 0.016-0.097' — that range is stale. Companion desktop values from the same runs, all passing: /dsm 0.014, /forms 0.059-0.064, / 0.006, /therapy-compass 0.000. Desktop attribution completed 2026-08-14: a Playwright + PerformanceObserver(layout-shift) harness against an offline production build at 1350x940 DPR 1 recorded **0.118** CLS. This is a separate attribution measurement, not a replacement for the canonical 0.119 Lighthouse value. One first-paint+~0.3-0.5s event contributed ~99.98% of that harness total: MasterSearchHeader's composer-adoption effect portals the search composer into GlobalSearchShell's desktop slot, while the header shrinks 184px and the slot grows 0 -> 184px. This is shared desktop search-chrome timing, not page-local. Next: reserve the settled height at the adoption boundary under the one-composer/hidden-means-zero-reserve contracts, then re-measure with the same harness. Stop: do not raise the CLS budget; do not read local LCP or TBT from the loopback harness; and do not use a blanket min-height that hides the shift without matching the header reserve. | Local offline verify:lighthouse runs 2026-08-12 (two runs, identical CLS); #147 close-out; lighthouse-budget.json. Attribution: session 2026-08-14, PR branch codex/visual-layout-polish; desktop CLS script adapted from scripts/measure-cls-attribution.mjs (offline, not committed). | 2026-08-12 | -| #309 | P2 | task | Facet groups of 6-20 options render as chips, not the dense list docs/filter-contract.md section 5 requires | Attempted 2026-08-14: an implementation task for chips-for-6-20 was stopped before any code was written, because it directly contradicts this row's own current, still-open text, which requires a full-width DENSE LIST (right-aligned count column, group headings) for the 6-20 band, and explicitly says chips-for-6-20 does not satisfy this row. Confirmed chips-for-6-20 is ALREADY the live behaviour (dense = facetGroups.length > 3 \|\| totalFacetOptions > 20 in result-filter-control.tsx), and that closing this row on that basis was already tried once and explicitly reverted (PR #1925, 'correct #309 to partially delivered'). No code changed, no PR opened. Needs a product/design decision between: (1) build the genuine full-width dense-list renderer plus the nine-option DOM assertion this row asks for, or (2) formally amend docs/filter-contract.md section 5 to deliberately drop the middle band with reviewer sign-off -- different from what already happened (a silent merge-conflict resolution the row says didn't count). | session 2026-08-14, agent stop per contract contradiction | 2026-08-12 | -| #315 | P3 | rec | If the ui-smoke scroll-hide flake (archived #290) recurs, start from the reporter-stranding mechanism — and treat the old regression window as unconfirmed | Independent verification on 2026-08-13 (second session, fresh cloud container, pinned Chromium 1234 installed per #312) measured the archived #290 flake at BOTH ends of its recorded window and corrects the archive's causal story: the bad SHA 9ab3b73ad itself passed 16 recorded executions — reproducer isolated --repeat-each=5 (5 passed, ~1.0s each), one full tests/ui-smoke.spec.ts --project=chromium run (98 tests passed, 2.5m, 0 flaky), and reproducer x10 under deliberate CPU contention (6 busy-loop processes on 4 cores, run times 1.2-1.5s: 10 passed). Current main a76f280 also 5/5. So the recovery was NOT drift — the exact commit that measured 2/5-3/5 failures passes cleanly here — and the e8adde1b9..9ab3b73a window is unconfirmed; the failure was specific to the original machine's environment/load profile. Recorded as a comment on PR #1884 (issuecomment-5272932999). On recurrence, do not re-bisect first: test the stranding mechanism. computeScrollHideUpdate (src/components/clinical-dashboard/use-hide-on-scroll.ts) re-evaluates only on scroll/resize events, and its viewportHeightChanged / maxOffset-range-change guards deliberately zero accumulated down-travel (contract-asserted in tests/use-hide-on-scroll.test.ts) — so geometry churn consuming the final steps of a gesture strands the not-hidden state permanently until the next event, matching the recorded ~11.5s toHaveAttribute timeout signature (the assertion DOES auto-retry for 10s; the attribute genuinely never flips). Fastest confirmation: a diagnostic page.on('console') trace logging which guard fires per evaluation. The window itself was one PR (#1744 mode-routing, true merge a503c22) whose net diff touched no scroll-hide code — content-bisect axes, if ever needed: tests/ vs src/ split, use-home-mode-seed/use-last-app-mode neutralized, prefetchModeDestination reverted, positional heading click restored to a settle wait. Stop: any guard change is a behaviour change to protected phone chrome — needs a failing trace first, never speculatively; do not weaken the assertion or tap targets. | session 2026-08-13; PR #1884 comment; archived #290; #312 | 2026-08-13 | | #316 | P1 | issue | Live DB has 20 currently missing repo-defined indexes and 10 retrieval RPC bodies diverge; weekly live-drift has been red since 2026-07-26 with no routing | PHASE 3 (reframed) COMPLETE REPO-SIDE AND STAGING-PROVEN 2026-08-18 (PRs #2106 merged 72aa18865, #2111 follow-up) — no production access, no canonical (schema.sql/production) function body changed, no hosted value changed; owner decisions D1 codify-as-live and D2 canary exemption applied. (1) SET work_mem codified on all ten match_* RPCs: schema.sql carries the clause on every definition and 20260818110000_codify_live_rpc_work_mem runs ALTER FUNCTION ... SET work_mem per function after every recreate. Values: 128MB chunks_hybrid, embedding_fields_hybrid, index_units_hybrid, index_units_hybrid_v2; 64MB chunks_text, chunks_text_v2, lookup_chunks_text, memory_cards_hybrid, memory_cards_hybrid_v2, table_facts_text. PROOF: regenerated drift-manifest def_hash for all ten equals the live production def_hash in issue #1963 (run 32051068106) byte-for-byte — the next production live-drift run reports zero match_* mismatches once marked applied. (2) Eight never-created objects codified verbatim by 20260818111000 (five document_embedding_fields indexes, documents_status_idx, documents_updated_at + ingestion_jobs_updated_at triggers); disjoint from #102; all six indexes stay on search-health-unmonitored-indexes.json, required_indexes untouched (Phase 4.4). (3) Triage: document_chunks CHAIN-stale (token_estimate, zero migrations); rag_visual_eval_cases/runs CHAIN-stale (id default bound to extensions.gen_random_uuid via 20260705230000 search_path order) — both fixed by 20260818112000; document_chunks_content_trgm_idx: production's restored definition (8499c3d3..) IS canonical = schema.sql = 20260705180000; staging holds the 20260606000000 form (c3db2960..) — Phase 4.4 residual, no escalation. (4) STAGING PROOF COMPLETE (two owner-authorised windows, ref ikoiolksxqxfxgiyqpnu verified per call, production never targeted): 110000/111000/112000 applied by the Phase 2 method; the comparison then exposed THREE chain-stale BODIES (embedding_fields_hybrid, index_units_hybrid, memory_cards_hybrid_v2 carried the legacy fail-open predicate on a chain-built DB — never forward-codified after 20260712000000; NOT a production hole, manifest hash = live hash) — fixed by new migration 20260818113000_forward_codify_hybrid_owner_matches_bodies (verbatim from schema.sql, no-op on production), applied to staging in the second window; the two rows whose text gained set-local timeouts pre-merge (111000/112000) were refreshed to the merged text. All four staging history rows md5 = repo (dd5c8c9e.., 22585b9e.., ec154770.., d35c199b..); staging 199 rows, no_statements 0, corpus 0. FINAL STAGING DRIFT: UNEXPECTED DRIFT (1) = document_chunks_content_trgm_idx only — zero function mismatches, zero never-created objects, zero table mismatches. NEXT: production window (D3, one window, no canary, no index build): 20260818090000 (real change, probe v2) + 110000/111000/112000/113000 (all no-ops, live already matches); then Phase 4 (incl. 4.4 guard migration for the trgm pair + staging trgm rebuild). Tooling note: check-drift.ts:192 240-char clip (own P3 queued). Evidence: forensics §Phase 3. | session 2026-08-18 Phase 3 staging proof complete (PR #2111) | 2026-08-13 | -| #318 | P1 | task | The medication interaction lexicon has never been clinically reviewed and its sign-off block is empty | docs/medication-interaction-lexicon-review.md is generated by npm run medications:lexicon-report and expands every lexicon term to the catalogue drugs it resolves to, with how many CRITICAL/HIGH rows depend on it, sorted by severe usage. It is marked UNREVIEWED and its sign-off table is unfilled, so every red and amber drug-drug interaction alert is currently an unvalidated mapping over source-backed text. The wording shown to a clinician is always verbatim catalogue prose; what is unreviewed is which drugs a phrase like 'NSAIDs' or 'CNS depressants' was taken to mean. Next: a clinician reads the term table top-down and fills in the sign-off block. Stop: do not treat check:medication-lexicon-report passing as review - that check only proves the sheet describes the current lexicon, not that the mappings are correct. WORKLIST PREPARED 2026-08-15 (PR #1991): docs/medication-lexicon-review-worklist.md gives the top ten terms by severe usage (236 of 390 severe firings, 61 percent) with resolved drug sets and six prioritised questions. TWO OF THE THREE DEFECTS THIS ROW CITES WERE ALREADY CLOSED: the ARB/Carbapenem substring match is fixed and guarded, and lithium is reachable (9 rows / 9 severe). The divergent Warfarin pair remains and is worse than stated - warfarin-vka and warfarin-anticoagulant carry 3 interaction rows each with ZERO in common, so which record is opened changes which warnings appear. TWO FIXES LANDED 2026-08-17, owner-approved, both mechanical rather than clinical. (1) DEAD SLUG: the tcas selector listed slug 'dothiepin' but the catalogue keys the drug as 'dosulepin' (same drug, current INN), so the slug matched zero records and Dosulepin - whose own record flags Toxicity in OD FATAL and Anticholinergic HIGH - fired none of the term's 20 CRITICAL/HIGH rows. Fixed; restoring the author's evident intent, corroborated by the catalogue already filing it subclass TCA. Measured effect after regenerating data/medication-interaction-index.json: 22 rows now name dosulepin as a counterparty, 20 of them CRITICAL/HIGH, up from 0 via this term; aggregate resolution is unchanged (523 rows, 362 resolved, 161 unresolved, 423 with a catalogue target) because those rows already resolved through other TCAs, so this widens counterparties inside already-resolved rows rather than resolving new ones. Durable guard added: the coverage test now fails on ANY selector slug or denySlug that resolves to no catalogue record. The pre-existing test only required a TERM to resolve to some drug, so tcas stayed green on five of its six slugs - that is exactly how this shipped. (2) THE REVIEW INSTRUMENT'S TWO BLIND SPOTS: missedClassMembers() in scripts/build-medication-lexicon-report.ts skipped any surface stem shorter than four characters, which made the check unable to fire at all for tcas and arbs (ppis was rescued by its long surface 'proton pump inhibitors'), and it read only class and subclass, never tag. So the sheet's printed 'Checks that ran and found nothing' line was false for two terms - a printed clean result that could not have found anything is worse than no line, because it retires the question. Both closed: the floor is now 3, the shortest stem any real surface produces, and the haystack includes tag. The sheet now raises the Celecoxib/Parecoxib coxib gap itself (2 flagged, up from 1). Design note recorded because the first attempt was wrong: the fix originally matched short acronyms as whole tokens, and mutation testing showed that branch did no protective work - the leading word boundary already stops 'arb' reaching inside 'Carbapenem' - while it would newly MISS a subclass spelled 'TCAs', a regression in the dangerous direction. It is a plain prefix match, pinned by a pluralised-subclass test. STILL OPEN AND STILL YOURS: the sign-off block is untouched and the sheet is still UNREVIEWED, which is the only thing that closes this row. Five clinical questions remain with their mappings deliberately unchanged - nsaids excluding Celecoxib/Parecoxib across 38 severe rows (now auto-flagged); maois excluding Moclobemide across 17 severe rows, which the sheet still CANNOT surface because Moclobemide's tag is also RIMA and RIMA/MAOI are synonyms in pharmacology but unrelated as strings; opioids including Loperamide across 35 severe rows in the false-alert direction; acei and arbs resolving to one drug each, which is catalogue coverage rather than a narrow selector (ramipril, lisinopril, irbesartan, telmisartan, valsartan are absent from the catalogue entirely); and anticoagulants including three antiplatelets while deliberately excluding Aspirin on identical class metadata. Also worth its own row: src/lib/medication-interaction-lexicon.ts alone classifies clinicalRisk FALSE under classifyPullRequestFiles, and only the generated data/medication-interaction-index.json makes a lexicon PR clinical-risk - so a lexicon edit that changes which drugs a CRITICAL phrase resolves to would skip the governance preflight if the index were not regenerated in the same PR. | PR #1923; docs/medication-interaction-lexicon-review.md; docs/samd-classification-medication-considerations.md | 2026-08-13 | | #321 | P3 | task | Four follow-up groups cover nine controls after #291 | PARTIAL 18 August 2026. Of the four follow-up groups: (1) the filmstrip 'Page unknown' control is FIXED — document-image-filmstrip.tsx converted its data-driven disabled state from native disabled to aria-disabled=true + ignoreUnavailableActivation + an sr-only reason, per docs/wiring-conventions.md's stated-reason pattern (settles this one control from #291's follow-up list); tests/document-image-filmstrip.dom.test.tsx gained a focused case (aria-disabled, not natively disabled, accessible description, click is a no-op), vitest run: 3 passed. The other three groups are unchanged and still not single-PR-sized: the six differential comparison page controls remain coupled to its own planned rewrite and pinned density test; DocumentViewer's persistent-access-reason/transient-loading split is a classification design decision, not yet made; the pin-limit control remains a capacity-state judgement call. Stays open for those three. | PR #1778 body; verified against main 2d27039 | 2026-08-14 | -| #322 | P1 | issue | Two catalogue records are both named Warfarin and share no interaction rows, so which one a clinician opens changes the warnings | PR #2069 (gemini/clinical-medication-graph-dedup) is open and targets this row. As of 2026-08-18 it reconciles both Warfarin catalogue records to carry the same interaction row set (the row's core ask), but its own new coverage test (tests/medication-interaction-lexicon-coverage.test.ts) still fails: the two duplicate records don't cross-resolve each other by name. That's a content/authoring decision (cross-link vs. merge-to-one-canonical-record) left for clinical/authoring review, not yet fixed. Stays open pending that PR landing correctly — flagging so a future session doesn't open a duplicate PR for the same dedup (see #292). | PR #1923; docs/medication-interaction-lexicon-review.md flag section; tests/medication-interaction-lexicon-coverage.test.ts | 2026-08-13 | -| #326 | P3 | task | Keep post-restore environment recovery controls visible in the universal ledger | **Consolidated survivor for #188 and #196–#200 before their source rows are archived by PR #1920.** A schema restore is not operationally complete until all five environment-owned controls have been re-created and verified: (1) restore the ingestion, retention, and related `pg_cron` schedules and confirm they are active; (2) re-add required Supabase Vault secrets, including `cron_ingestion_jwt`, and verify names only without printing values; (3) re-set the required custom `app.*` database GUCs and verify them with read-only settings checks; (4) redeploy the required Supabase edge functions with the Deno v2.x toolchain and confirm the function list and health, only in an explicitly approved hosted-change window; and (5) re-enter dashboard-owned configuration, including auth providers and SSO redirect URLs, connection-pool caps, per-project keys, and `E2E_USER_*`, without committing secret values. **Next:** after every schema-restore drill or real restore, follow the disaster-recovery checklist in `docs/operator-backlog.md` and `docs/disaster-recovery-runbook.md`, record the verification outcome here, and keep the row open until all five controls are green. **Stop:** the runbooks are the execution procedure, not a substitute for this universal-ledger status row; do not treat a restored schema alone as recovered, expose secret values, or perform hosted writes without the required approval. | docs/operator-backlog.md disaster-recovery checklist; docs/disaster-recovery-runbook.md; #188/#196–#200; PR #1920 review | 2026-08-13 | -| #327 | P3 | task | The recommended queue's Outcome cells are now unrendered dead text | **Residual of the queue-misdirection fix (PR #1902).** Both consumers — .claude/hooks/issues-surface.sh and scripts/issues-report.mjs — now derive each queue row's prose from the cited row's Detail cell, so the Outcome column reaches no reader through tooling. The stale prose still sits in the file, where a human opening it can read and act on it; for #231 that prose pointed at an approach the row had already recorded as refuted. **Implementation, established by building it 2026-08-13 — three findings that are not obvious:** (1) It cannot be a direct edit. check-ledger-write-discipline compares the canonical ledger against exactly applyRequestBatch(base, movedRequests), and no request type reaches the queue, so a hand edit is unlandable by construction. The rewrite has to live INSIDE applyRequestBatch — the function the checker itself imports — so checker and reconciler compute the same result; make it run for an empty batch and be idempotent so ordinary PRs are byte-identical. (2) It must land in the SAME commit as a reconcile. Code alone makes the checker compute normalise(base) while canonical stays un-normalised, failing every PR until a reconcile normalises it. (3) Do NOT drop the column, and do NOT blank composite rows. issues-report skips any queue row whose cells.length !== 7, so removing the column makes the queue vanish from /issues; and derivation deliberately skips composite ID(s) rows, so those still fall back to the Outcome cell and blanking it leaves them with no prose at all — filter to rows citing exactly one id. **Stop:** do not delete the queue table; order, acuity, capability, when and estimate exist nowhere else. | PR #1902; implementation attempt 2026-08-13 | 2026-08-13 | -| #334 | P3 | issue | Claude Code web containers can ship Node 22 with no node_modules, so npm ci fails engine-strict before any work starts | Hit 2026-08-14 at the start of a Claude Code on the web session, and it blocks a session completely until worked around, so it is worth recording even though the cause is the container image rather than this repo. The container provided /opt/node20, /opt/node21 and /opt/node22 with node22 on PATH, no nvm, and no node_modules in either the primary checkout or a fresh worktree. package.json requires node >=24.15.0 <25 with engine-strict, so 'npm ci --include=dev' aborts immediately with 'notsup Required: {node: >=24.15.0 <25, npm: 11.x} Actual: {npm: 10.9.7, node: v22.22.2}'. Nothing in the repo can fix this from inside, because the failure happens before any repo script can run — .nvmrc correctly says 24 and is simply not consulted, and there is no nvm for it to drive. Workaround used, which took about a minute and is safe: fetch the current 24.x from the nodejs.org dist index, untar to /opt/node24, and prefix subsequent commands with 'export PATH=/opt/node24/bin:/opt/node24/bin:/root/.local/bin:/root/.cargo/bin:/usr/local/go/bin:/opt/node22/bin:/opt/maven/bin:/opt/gradle/bin:/opt/rbenv/bin:/root/.bun/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'. Everything downstream then behaved normally — npm ci, the full unit suite, build, and the Playwright-free gates all passed. Worth knowing that this is a DIFFERENT surface from the Codex Cloud provisioning path: scripts/setup-codex-cloud.sh and scripts/setup-codex-worktree.mjs cover Codex, and docs/codex-cloud.md is explicit that Cloud mirrors the tracked toolchain, but neither runs for a Claude Code web session, so that hardening does not carry over. Next: decide whether this deserves repo-side help at all. Options are a short note in the AGENTS.md or CLAUDE.md orientation telling an agent to install Node 24 to /opt/node24 and re-export PATH rather than concluding the environment is broken, or a small bootstrap script equivalent to the Codex ones that a web session can run first. Prefer the note: a bootstrap script that downloads a runtime is a bigger surface than the problem. Stop: do not relax the engines range, drop engine-strict, or pass --force to get npm ci through — the Node 24 floor is enforced deliberately in several places (preinstall, check:runtime, scripts/dev-free-port.mjs) and loosening it to accommodate a bad container would disable a real guard. | session 2026-08-14; Claude Code web container for PR #1942 | 2026-08-14 | | #339 | P2 | task | Favourites Continue and Recent are driven by hard-coded demo timestamps; real saved items have no last-opened data | Surfaced while shipping #164 (PR #1983), which made both surfaces prominent. src/components/clinical-dashboard/favourites-command-library-page.tsx derives 'most recently used' from lastUsedScore(item.lastUsed), and item.lastUsed comes from lastUsedByItemId — a hard-coded five-entry literal keyed to demo slugs ('Today 08:44', 'Yesterday 16:12', ...). Anything else, including every real registry favourite, falls back to the literal string 'Saved', which lastUsedScore buckets at 1000. pinnedItemIds is likewise a hard-coded two-item Set. The consequence after #164: for a signed-in user with real favourites, the Continue card and the Recent panel are effectively arbitrary — every item ties at the same score and the order is whatever the source array happened to be. Note that recentQueries in the shell is search-query history, not viewed-item history, so it cannot back this. Next: add a per-favourite last-opened timestamp. Cheapest is a client-side recents store keyed by favourite id written on open; the durable version is a column on the account favourites record so it survives a device change, which is a schema plus /api/account/favourites change and needs the usual migration review. Either way, pinning should stop being a hard-coded id set. Stop: do not fabricate a timestamp at render time from anything other than a recorded open event — an invented 'last used' on a clinical reference list is worse than an honest absence. | session 2026-08-15; PR #1983; favourites-command-library-page.tsx lastUsedByItemId/pinnedItemIds | 2026-08-15 | -| #343 | P3 | task | Make the retrieval row contract's source_metadata pin structural, not data-guaranteed | rag-row-contracts.ts pins source_metadata to a JSON object via z.record(...), but documents.metadata is bare jsonb and permits arrays and scalars. Measured against the live project (sjrfecxgysukkwxsowpy) on 2026-08-15: all 2851 documents are object-typed, so nothing breaks today and no live errors exist. The guarantee is data, not schema — a future ingest path could violate it and take retrieval down for that document's chunks. Fix is either a check (jsonb_typeof(metadata) = 'object') constraint on public.documents, or loosening the pin. Every other required field in that contract is backed by a not-null constraint. | PR #1946 review + live Supabase verification 2026-08-15 | 2026-08-15 | -| #DP6M3G | P1 | task | R1: unbudgeted strong escalation makes provider_timeout the dominant lithium fallback — route the dosing class to strong before the deadline (packet S1b) | S1 (PR #2022) post-fix live probes: 'Lithium dosing?' 4/4 source-only, 3/4 as provider_timeout. fast_unsupported_retry_strong launches a strong generation into the fast route's leftover ~10-13 s; only the truncation self-heal is deadlineAllowsGenerationRetry-gated. Ladder rung 3 (README A1): route medication_dose_risk / dosing to the strong route in chooseAnswerRoute (src/lib/rag/rag-routing.ts) BEFORE the route deadline is created — not in shouldRetryWithStrongAfterFast, and NOT a budget change (#231 stop condition stands). Own PR, RAG impact behaviour change, canary pair, Clinical Governance Preflight, check:production-readiness. Owner decided 2026-08-17 this lands before S2 (A2/A3 add length; length under the unbudgeted retry pushes more dosing queries into timeout). Packet: docs/rag-improvement/HANDOVER.md S1b. | RAG programme coordinator, S1 PR #2022 residuals and #212 handover follow-ups, 2026-08-17 | 2026-08-17 | -| #BTVMVK | P2 | issue | Recurring 'Unhandled server request error' on /api/search and /api/search/universal in Sentry — unowned, pre-dates #1946 | Sentry (clinibase-xz): three issue groups in 24h, 17 events, 0 users impacted, on /api/search and /api/search/universal, all with culprit chunk 1261.js:2:4801. First seen 2026-08-14T08:44:37Z on release c9b089c9, about six hours before PR #1946 merged, so not caused by the row contracts. Recorded in the #212 tranche-1 handover; never captured durably until now. Next: triage the Sentry groups (read-only Sentry MCP or dashboard), map chunk 1261.js to source via the release's source maps, reproduce locally with the request shapes Sentry recorded. Stop: do not silence the error path; search routes are clinical output. | RAG programme coordinator, S1 PR #2022 residuals and #212 handover follow-ups, 2026-08-17 | 2026-08-17 | -| #TYJ0XP | P3 | rec | eval-canary.yml is post-merge only (repository_dispatch + Sunday cron, no ref input) — record this in docs/rag-behaviour so sessions stop expecting a branch canary | .github/workflows/eval-canary.yml triggers on repository_dispatch type eval-canary and schedule cron 0 18 * * 0; it always loads the default branch and has no workflow_dispatch or ref input, so a canary can only ever measure main. Consequence for the RAG programme: 'canary pair' means latest green run on main before the merge -> a dispatch after the merge (gh api repos/BigSimmo/Database/dispatches -f event_type=eval-canary), compared with npm run eval:retrieval:compare -- --fail-on-regression on the eval-canary-output artifacts. Recorded correctly for S1 (baseline run 31964560921 -> post run 32025082010, zero regressions). Next: add one paragraph to docs/rag-behaviour/safeguards.md canary protocol; no workflow change. | RAG programme coordinator, S1 PR #2022 residuals and #212 handover follow-ups, 2026-08-17 | 2026-08-17 | -| #ND10QT | P3 | rec | source_metadata pin in rag-row-contracts.ts is data-backed only — add check (jsonb_typeof(metadata) = 'object') on documents or loosen the pin | src/lib/rag/rag-row-contracts.ts requires source_metadata to be a JSON object (z.record) while documents.metadata jsonb permits arrays and scalars. Live query 2026-08-14 (project sjrfecxgysukkwxsowpy): select jsonb_typeof(metadata), count(*) from public.documents group by 1 returned a single row, object = 2851, so nothing breaks today — but the guarantee is data, not schema, and a future ingest could make retrieval throw RetrievalRowShapeError for that document. Options: a check constraint via a new migration (role postgres; run check:migration-role) or loosen the pin. The module's doc comment also claims every required field is 'not null in supabase/schema.sql', which is true for nine fields and false for source_metadata — one-clause docs fix in the same PR. | RAG programme coordinator, S1 PR #2022 residuals and #212 handover follow-ups, 2026-08-17 | 2026-08-17 | | #4TBHS8 | P3 | issue | Advisory UI mockup spec 'phone filter sheet follows the shared local-filter behavior' fails on main | tests/ui-tools-search-mode-mockup.spec.ts:188 fails at line 198 waiting for '2 showing' inside [data-testid=tools-search-filter-sheet] after searching 'Safety' at 390px. Reproduced locally under --project=chromium-mockups on BOTH claude/card-review-optimize-h0pidc and origin/main (dc7e518), so it is pre-existing and NOT caused by the card branch — attribution was checked before any fix was attempted. It surfaced now only because the ui-advisory lane fires on advisory_ui_changed (a mockup surface changed or the flake ledger is non-empty) and had been skipped on every earlier run of that PR. It is non-blocking: ui-advisory carries continue-on-error true and is absent from pr-required's needs list in ci.yml, and verify:ui excludes @mockup via --grep-invert, which is why a 429-pass local run never touched it. Next: open the trace at test-results/ui-tools-search-mode-mocku-b6163-hared-local-filter-behavior-chromium-mockups/trace.zip and decide whether the expected count of 2 is stale against the current tools catalogue or the facet hint genuinely miscounts; the mockup renders the production ToolsSearchResultsPage, so a real miscount would affect /tools too. Stop: do not change the expected number to match observed output without establishing which is correct. | session 2026-08-18; PR #2060 Advisory UI run 32090358678; reproduced on origin/main dc7e518 | 2026-08-18 | | #2AB2NJ | P3 | task | Owner decision: enable RAG_TELEMETRY_EXTENDED (verification_latency_ms projection) in production once a dashboard consumer exists | Packet S5 (PR #2056, merge 093f9340c) landed the B1 telemetry gap assessment: the one proven gap is verification_latency_ms, now persisted behind RAG_TELEMETRY_EXTENDED (typed, default false) via the allow-listed projection module with canary-absence tests. Enabling it in production is an owner decision gated on a dashboard consumer existing (no consumer today), and is a Railway env change (provider-backed, explicit approval; rollback = set false). Next: when a dashboard question needs verification latency, set RAG_TELEMETRY_EXTENDED=true on the Database service after confirming the canary-absence tests are still green on main. Stop: do not enable speculatively; do not add unproven fields. | RAG programme coordinator, packet S5 (PR #2056) follow-ups, 2026-08-17 | 2026-08-17 | | #C2D9JF | P2 | issue | Adversarial divergence (S5 harness pin): scope-other-owner-document — abstains in substance but the review fallback still cites in-scope evidence | Pinned in tests/rag-adversarial-harness.test.ts KNOWN_DIVERGENCES (self-expiring). Observed shape: grounded false, confidence unsupported, but cited chunk ids [syn-scope-owner-a] — the answer correctly abstains from the other-owner document, yet the review fallback attaches an in-scope citation to an unsupported answer. Fixture: scripts/fixtures/rag-adversarial-cases.v1.json case scope-other-owner-document (category scope_or_tenant). Tenancy/no-read invariant held (the other-owner content is never read). Next: decide whether an unsupported abstention may carry any citation; if not, strip citations on the abstention path (RAG-surface change; own PR; harness pin flips; canary pair). Stop: do not delete the pin without the behaviour change. | RAG programme coordinator, packet S5 (PR #2056) follow-ups, 2026-08-17 | 2026-08-17 | @@ -128,12 +110,24 @@ removed after current-main verification; it is not missing recommended work. | #43SSS0 | P3 | rec | Three spring easing tokens in globals.css are dead: zero var() references and zero utility usage | --spring-tight, --spring-bouncy and --spring-gentle (src/app/globals.css:222-224) are declared in the @theme block but have no var() consumer in any stylesheet and no generated-utility consumer in src/. Tailwind v4.3.3 tree-shakes unused theme variables, so they never reach the compiled CSS — they are source noise, not shipped weight. Found while confirming (during PR #2046) that --animate-answer-ecg survives that same tree-shaking because it IS referenced via var() from the project's own CSS; --ease-spring is the working precedent for that pattern. Next: delete the three tokens, or wire them to the motion surfaces they were intended for. | PR #2046 phone/PWA answer-progress animation defect, 2026-08-17 | 2026-08-17 | | #75JA0P | P2 | issue | Playwright runs the whole suite with reducedMotion:"reduce", so no gate reflects the default user configuration | playwright.config.ts:61 sets contextOptions: { reducedMotion: "reduce" } suite-wide, and every motion assertion has to opt out per-test via page.emulateMedia({ reducedMotion: "no-preference" }). That inversion is why three consecutive PRs (#1974, #1989, #1995) shipped green while a physical iPhone with OS Reduce Motion on showed a frozen, blank answer-progress panel: the suite never exercised the reported configuration. PR #2046 added tests/ui-phone-motion.spec.ts to cover that one surface, but the suite-wide default remains inverted for every other motion behaviour. Next: decide whether the suite default should be no-preference with reduce opted into per-test (the safer direction), or keep the current default and add a contract test that fails when a motion assertion has no explicit emulateMedia call. | PR #2046 phone/PWA answer-progress animation defect, 2026-08-17 | 2026-08-17 | | #1PN5BM | P3 | issue | H5a residual: whether a constant similarity of 1 may contribute to a confidence label is still open, and after G1 it lives only in the hazard doc | Packet G1 (PR #2053, merged 2026-08-17) implemented owner decision Option B: buildDocumentSummaryResults now stamps similarity_origin "document_context" on document-summary rows, deriveConfidence is unchanged, and document summaries still reach "high". That closed the LEGIBILITY half of the H5a live residual -- the fabricated 1.0 is no longer indistinguishable from a perfect cosine at any surface that reads a row. It did NOT answer the underlying governance question: may a score nobody measured contribute to the confidence label a clinician reads at all? Option B was chosen because tagging has no measured safety cost while Option A (tag as synthetic_text, capping summaries at "medium") is a label downgrade without measured gain -- so the question was deferred deliberately, not resolved. The paired question row #J912J9 is being closed by G1, so once that closure reconciles this knowledge survives only in docs/clinical-hazard-analysis.md H5a and not in the queue anyone reads. NEXT: no action required unless a measured signal appears; if it does, the tag is what makes the fix cheap -- any future gate can now discriminate the document-summary route without re-deriving provenance. Guard rails already in place: tests/rag-score.test.ts pins the discriminating pair (two document_context citations >= 0.82 -> "high"; the identical scores tagged synthetic_text -> "medium"), so a silent change in either direction goes red. | Packet G1 session 2026-08-17 (PR #2053); docs/clinical-hazard-analysis.md H5a; closes-with #J912J9 | 2026-08-18 | -| #SDQSFD | P2 | rec | ci-change-scope rag_eval_changed regex misses src/lib/rag/** (post-#994 layout), so a src/lib/rag-only PR skips eval:rag:adversarial:offline and the RAG eval CI job | scripts/ci-change-scope.mjs:290 matches only src/lib/rag.ts and src/lib/rag-*.ts (the pre-#994 layout); src/lib/rag/rag.ts, src/lib/rag/rag-answer-instructions.ts, src/lib/rag/answer-composition.ts do not set rag_eval_changed=true. verify-pr-local.mjs:123-124 then selects only check:rag:fixtures and ci.yml:413-425 skips the safety/RAG eval job. Packet S2 (2026-08-18) was covered only because it also touched tests/answer-*.test.ts and scripts/fixtures/*. Fix: add a src/lib/rag/ prefix (or /^src\/lib\/rag\//) to ragEvalPatterns with a scope test proving src/lib/rag/rag.ts alone trips rag_eval_changed; workflow/policy scope, own PR (operational-risk classifier), never bundled with a RAG behaviour change. | packet S2 review, docs/rag-improvement/HANDOVER.md | 2026-08-18 | | #DREDWA | P3 | rec | Ledger writer self-tests use only legacy numeric ids, which is why a Crockford-id lookup bug survived the ULID migration unnoticed | Fixed in PR #2053: issueRowFingerprint (scripts/check-outstanding-issues.mjs) matched only /^#(\d+)$/ and keyed on entry.number, which is null on ULID-backed rows, so it returned null for every Crockford display locator -- and ledger-inbox.mjs reads a null fingerprint as "no such row" and refuses. npm run issues:done and issues:update were therefore unusable for EVERY row minted since the ULID migration, failing with "#J912J9 is not in Open items" about a row plainly in Open items. It surfaced only because a session happened to need to close two Crockford-id rows. ROOT CAUSE OF THE SURVIVAL, not of the bug: the self-tests and fixtures in scripts/outstanding-issues.mjs and tests/outstanding-issues-writer.test.ts exercise the writer almost entirely with legacy #005/#006/#013-style ids, so no test ever drove a Crockford id through the fingerprint path. A second, subtler trap sits in the same area and is now pinned but not generally guarded: Crockford's alphabet includes 0-9, so a ULID-derived locator can be ENTIRELY digits (the writer test's own id is #041061) and is indistinguishable from a legacy id by pattern -- branching on id shape rather than resolving against the table silently misses exactly those rows, which is how the first attempt at the fix still returned null. NEXT: add a fixture row with a ULID/Crockford id (ideally an all-digit one) to the shared ledger test fixtures and drive every writer entry point -- addIssue, resolveIssue, updateIssue, issueRowFingerprint, and the ledger-inbox done/update/reconcile paths -- through both id generations, so the next lookup left behind by an id-scheme change fails a test instead of a user's command. | Packet G1 session 2026-08-17 (PR #2053), discovered while queueing the G1 closures | 2026-08-18 | | #90EVWZ | P3 | rec | check:drift clips table column diffs to 240 chars per side, so a wide-table column drift never names the column | scripts/check-drift.ts:192 (fieldDiff) serialises the whole alphabetised columns array of a table and clips each side to 240 characters, so for a wide table such as document_chunks (19 columns, several kB) a single late-alphabet column drift (token_estimate, forensics Phase 3 §3.3) prints two identical prefixes and the finding fires without naming the column. Phase 3 needed a raw schema_drift_snapshot() read and an offline per-column diff to classify three staging table findings. Recommendation: for the columns field, diff per column name (only-in-manifest / only-in-live / differing fields) and print those rows instead of the clipped arrays; keep the clip for other fields. Offline-testable against supabase/drift-manifest.json plus a mutated copy. | session 2026-08-18 Phase 3 repo-side codification (PR #2106) | 2026-08-18 | | #QSHHGK | P2 | rec | Nothing schedules a bundle-budget baseline refresh, so accumulated growth fails whichever unrelated PR lands last | The production baseline sat at ca788d41 (2026-08-13) untouched while main grew +8.03% by 2026-08-18, leaving ~2 points of headroom. PR #2096 (Dictionary) then failed Build at +10.5% for 2.7 points of its own weight. Re-baselined once in docs/evidence/bundle-budget-production-rebaseline-2026-08-18.md, but the same squeeze recurs unless a refresh has an owner or a trigger: options are a scheduled job that re-measures and opens a PR, a drift warning threshold below the failure threshold, or recording the baseline commit distance in the check output so staleness is visible before it blocks someone. | PR review of #2095/#2096, 2026-08-18 | 2026-08-18 | | #5JK9FM | P3 | rec | PR template carries no RAG impact: guidance although pr-policy hard-blocks RAG-surface PRs without the line | .github/pull_request_template.md has zero occurrences of 'RAG impact', yet scripts/pr-policy.mjs ragImpactDeclared (lines 238-245) hard-blocks any PR touching a RAG-ranking-surface path unless the body carries a line matching 'RAG impact: ' with 'no ... behaviour change' or 'canary' and at least 12 characters. The authoring rule lives only in the pr-policy error string and AGENTS.md. Recommendation: add a commented placeholder line under ## Risk and rollout (or a dedicated ## RAG impact stanza) in the template with both canonical forms, so the exact-format contract is visible where the body is written; guard with the existing pr-policy self-test. | session 2026-08-18 Phase 3 repo-side codification (PR #2106) | 2026-08-18 | | #SZGPAH | P2 | issue | tests/ui-tools-search-mode-mockup.spec.ts has two assertions stale on main, so the advisory lane is red for every UI PR | Verified 2026-08-18 on a clean origin/main worktree: node scripts/run-playwright.mjs --project=chromium-mockups tests/ui-tools-search-mode-mockup.spec.ts reports 2 failed \| 14 passed. The failures are 'desktop uses universal search and keeps results beside the selected-tool panel' (line 24) and 'phone filter sheet follows the shared local-filter behavior' (line 188, expecting the exact text '2 showing' in the filter sheet). Neither is caused by any open PR: PR #2095 was flagged for the second one while changing only mockup routes under src/app/mockups/caring-contacts. Advisory UI is non-blocking, so this stays red and trains reviewers to ignore the lane. Likely stale after the catalogue-toolbar work in #2086. Fix the assertions against current tools UI or quarantine per the flake ledger rules. | Copilot review triage on #2095/#2096, 2026-08-18 | 2026-08-18 | +| #6SMMB4 | P3 | task | Confirm D:\.npm-cache is a registered Dev Drive trusted cache, or Defender is scanning every npm ci | The repo lives on a Windows Dev Drive (D:, ReFS, 50 GB) and npm config get cache resolves to D:\.npm-cache, which is correctly on the same volume. Whether that path is registered as a Dev Drive TRUSTED cache is unverified: 'fsutil devdrv query D:' returns 'Failed to open the volume. Error 5: Access is denied' without elevation, and the non-elevated registry fallback (HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem, FilterAttachModeOnDevDrive and DevDriveTrustSetting) reads empty. If it is not registered, Microsoft Defender real-time scanning runs over every npm ci — and this machine performs a lot of them: 21 D: worktrees each carry their own ~0.89 GB / 51,735-file node_modules, because npm extracts fresh copies rather than hardlinking from cache (ReFS does support hardlinks here, probed directly, but npm does not use them). Next: from an ELEVATED prompt run 'fsutil devdrv query D:' and, if the cache is not listed as trusted, 'fsutil devdrv trust D:\.npm-cache'. Cheap, one-off, no code change. Not blocking anything. | session 2026-08-18; fsutil Error 5 without elevation | 2026-08-18 | +| #TAQKCN | P3 | task | One hand-drawn SVG checkmark survived the Therapy Compass lucide sweep | recommend-screen.tsx:75 still inlines a 7-line hand-drawn tick inside the QUICK CONSTRAINTS pills; commit 7ce820f2c converted the other 32 glyphs in therapy-compass/** to lucide-react and deleted icons.tsx. It is a one-line swap to lucide Check, which the same file already imports for its copy buttons. Left out of the B3 Button conversion deliberately to keep that diff purely mechanical. Stop rule: it is cosmetic only - the pill's pressed state is already carried by aria-pressed plus border and text tokens, so nothing is colour-only while this waits. | session 2026-08-18 | 2026-08-18 | +| #E0N0QC | P3 | rec | scripts/probe-generation-quality.ts prints no answer text, so a blinded Gate E before/after read cannot come from probes | The probe reports structured generation_quality_gate_reasons only, by design, and never the answer text itself. That makes it impossible to produce a blinded before/after Gate E (answer-quality) read from probe output alone. Needs an owner-approved answer-text capture mode added to the probe, or a manual read of the app's rendered answer, before any future packet can close a blinded Gate E comparison this way. | scripts/probe-generation-quality.ts; #231 investigation, session 2026-08-18 | 2026-08-18 | +| #D6G8TC | P3 | task | Three Therapy Compass h1 elements still sit outside PageHeader, and the patient-sheet builder renders two of them at once | Stage D converted six therapy page headers to the shared PageHeader. Three h1 elements were deliberately left. (1) detail-screen.tsx:88 is the therapy record name inside the hero card, interleaved with an aria-live notice, aliases and a TagRow that PageHeader has no slots for - and PageHeader renders a
, which globals.css hides unconditionally under @media print, so adopting it would delete the record name from a printed therapy record. (2) sheets-screen.tsx:178 is the contentEditable title of the generated patient handout on --tc-paper-ink tokens; it is document content, not page chrome. (3) other-screen.tsx:28 is the centred placeholder hero, already at text-2xl. Consequence worth fixing: sheets-screen now renders the PageHeader h1 and the paper h1 simultaneously, so that page has two h1 elements - pre-existing, not introduced here, and the likely fix is demoting the paper title to h2 since the builder page is the document. Stop rule: do not solve (1) by adding a print exception for
; the element-name print rule is documented as transitional and must not be extended. | session 2026-08-18 | 2026-08-18 | +| #GKFK9V | P3 | rec | Where the RAG improvement programme board lives, and to check it before starting RAG-surface work | The RAG improvement programme board lives at docs/rag-improvement/README.md (design), HANDOVER.md (packet status table + prompts) and COORDINATION.md (coordinator manual). Before starting any RAG-surface item, check that status table AND the open PR list (#292); packets S1-S3, G1, S4-S6 landed 2026-08-17/18; Track A complete. | docs/rag-improvement/README.md, HANDOVER.md, COORDINATION.md; session 2026-08-18 | 2026-08-18 | +| #RZQQBT | P3 | task | Confirm from its own log whether the PreCompact hook's output actually reaches model context | .claude/hooks/precompact-issues-capture.sh was added in PR #2113 to ask for /issues capture BEFORE compaction discards the follow-ups it wants recorded; the pre-existing issues-surface.sh reminder is a SessionStart hook and therefore fires AFTER compaction, when the material is already gone. Claude Code is known to inject hook stdout into model context for SessionStart, UserPromptSubmit, PreToolUse and PostToolUse. Whether it does so for PreCompact could NOT be determined: the installed CLI at %APPDATA%\npm\node_modules\@anthropic-ai\claude-code ships a compiled claude.exe with no inspectable JS bundle to grep. The hook therefore prints plain text rather than a hookSpecificOutput JSON envelope, so that if the platform does not inject it the operator still sees a clean transcript line instead of a raw JSON blob, and it appends one line per firing to a log so the question is answerable rather than permanently open. Next, after any compaction in a session using this repo: cat "$(git rev-parse --absolute-git-dir)/claude-precompact.log". Lines present but no reminder seen in context means the limit is real and the SessionStart backstop is carrying it. No lines at all means the registration is wrong. WARNING: that log lives under the worktree's own git dir, so it is destroyed when the worktree is removed — check it before cleaning up the worktree this was authored in. | PR #2113 .claude/hooks/precompact-issues-capture.sh | 2026-08-18 | +| #ZF006G | P3 | rec | Five independent SectionHeading implementations exist across modes with no shared recipe | clinical-dashboard/dashboard-shell.tsx:17, clinical-dashboard/search-pins-menu.tsx:97, formulation/formulation-ui.tsx:81, specifiers/specifier-ui.tsx:237, plus a fifth in therapy-compass/ui.tsx deleted unreferenced in 7d2c84a11. Same shape as the problem card-recipes.ts solved for cards, but spanning four modes. Two of the five already share an identical {eyebrow, title, body} signature - the natural shared contract. Stop rule: do not fold these into ui-primitives.tsx; COMPONENTS.md section 0.4 lists it as over-budget and slated to split. | session 2026-08-18 | 2026-08-18 | +| #FEWQZ5 | P2 | task | Therapy Compass has three shared-component stages left: Button call sites, card-recipes adoption, and page headers | Branch claude/therapy-mode-consistency-a466b0 landed A/B1/B2/E/F/G in 7ce820f2c..7d2c84a11. Remaining: B3 (18 control-recipe call sites across 9 files), C (card/heroCard plus the inline fork at therapy-card.tsx:71 bypass card-recipes.ts), D (7 hand-rolled h1, 3 at text-3xl-minus). Stop rule: one browser pass and one baseline refresh after all three, never per stage. | session 2026-08-18 | 2026-08-18 | +| #CCZ4HB | P1 | rec | PR churn has exhausted the review-bot budget, so PRs are now landing with no automated review at all | CodeRabbit on PR #2113: '101 included PR reviews in the past 7 days; at that activity level, included reviews refill at 1 review per hour. Your organization has reached its usage spending cap.' The Codex connector reported its own usage limit on the same PR. Net effect: #2113 received ZERO automated review, and so will subsequent PRs until the cap resets or credits are added. AGENTS.md 'PR bundling' already measured the CI half of this cost on 2026-07-30 (437 PR-triggered runs over ~3 days, ~40% cancelled mid-run, ~12 Production-UI-hours burned on runs that never completed). This is the second bill for the same behaviour and the more dangerous one, because CI waste is money while missing review is undetected defects — and the PRs most likely to need review are the ones landing during a churn spike. The bundling rule exists as prose in AGENTS.md and is evidently not binding; the newtask skill also asks the question in prose. Decide whether it gets a gate. Note the repo has already learned this lesson once in a different area: .claude/hooks/pr-handoff-stop.sh states in its own header that 'prose rules in AGENTS.md have not held, a denied tool call does.' Next: decide between (a) a push/PR-creation gate that refuses a new branch when an open PR of the same scope exists, (b) raising the bot spending cap, or (c) accepting unreviewed merges deliberately rather than by accident. Stop rule: do not weaken any required check to compensate for missing bot review. | CodeRabbit + Codex connector comments on PR #2113, 2026-08-18; AGENTS.md 'PR bundling (reduce one-task-one-PR churn)' | 2026-08-18 | +| #EH9VA6 | P2 | rec | The serialized issues:reconcile operation has no interlock, and two reconcile PRs were open simultaneously on 2026-08-18 | AGENTS.md requires npm run issues:reconcile to run from ONE deliberately serialized fresh-base branch, but nothing enforces that: the reconciler's own guards (stale base, dirty canonical file, cross-worktree lock) are all local to a single machine and cannot see a second reconcile branch already pushed. On 2026-08-18 two were open at once — PR #2110/#2119 (claude/issues-reconcile-20260818, 'reconcile 74 queued requests') and PR #2120 (claude/issues-reconcile-2026-08-18-evening, 88 requests). Both merged. It only came out clean by luck of ordering: #2120 merged first and had already applied a superset of the 74, so GitHub's squash of #2119 collapsed to a 1-line review record and the canonical ledger was left correct (verified after the fact on main 4575cf57: 365 rows, 48 open, 0 pending, 339 applied, check:outstanding-issues and check:ledger-write-discipline both green). Had #2119 merged first, #2120's recorded transaction would no longer have equalled the canonical diff and check:ledger-write-discipline would have gone red on a branch that must never be synced from main — the documented recovery is to close the PR and redo the whole reconcile from a fresh base. Next: give the reconcile path a cheap pre-flight interlock rather than relying on operator discipline — e.g. have issues:reconcile refuse (or loudly warn) when git ls-remote --heads origin shows another unmerged branch carrying inbox renames under docs/outstanding-issues-inbox/applied/, which needs no provider tooling beyond a remote ref listing and no GitHub API call. Related to #292 (duplicate concurrent work) but distinct: this is a serialization invariant on a single canonical file, not two sessions building the same feature. | session 2026-08-18 evening reconcile; PRs #2119 and #2120 both open and merged same day | 2026-08-18 | +| #164Z0H | P3 | task | Confirm on a real Claude Code web session that the session-start hook now runs, after the exec-bit fix | PR #2113 fixed .claude/hooks/session-start.sh, which was checked in as mode 100644 while both sibling hooks were 100755, and was the only hook registered by bare path rather than through bash. What was PROVEN: the index mode, the bare-path registration, and that core.fileMode=false on this Windows ReFS Dev Drive hides both (a local chmod +x is a silent no-op; only git update-index --chmod=+x works). What was NOT proven: that it actually failed on a Linux web container, because no container was available to test from. The 100755/100755/100644 asymmetry makes accident overwhelmingly likely rather than a deliberate choice, and the script's whole body is gated on CLAUDE_CODE_REMOTE=true so the web container is the only place it does any work — it provisions the Node 24 the engine floor requires, after npm ci EBADENGINE blocked PRs #1611, #1697, #1705 and #1740. This is confirmation, not risk: the registration now uses bash "$CLAUDE_PROJECT_DIR/...", which removes the dependency on the mode entirely, and tests/session-start-hook.test.ts pins every hook at 100755 with LF-only line endings while tests/claude-code-settings.test.ts pins every hook command to start with an interpreter. Next: on the first Claude Code web session on this repo, check the session start output for the '[session-start] Using node ...' line and confirm npm ci ran. If it did not, the failure is something other than the exec bit and this item becomes a real defect rather than a confirmation. | PR #2113; AGENTS.md 'Claude Code hook scripts' | 2026-08-18 | +| #6GW95D | P2 | task | Nine landed worktrees are still on disk holding ~4.5 GB on a 51%-full Dev Drive; removal was deferred because the fleet was live | clean-worktree.mjs gained list-only --merged and --squashed in PR #2113 and identified 9 landed worktrees across the 50-worktree fleet, 5 of them on D:. Removal was NOT performed and must not be run blind. Re-verifying each candidate immediately before deletion, twice, showed the fleet is actively worked: database-coordination-chat-9c8cbd and database-drift-remeasure-phase2-7c4215 each held 2 unmerged commits despite the scan minutes earlier reporting '0 commits ahead', their newest files were written the same afternoon, and bundle-baseline had been switched to a different branch mid-scan and was running Playwright (the push guard named it as holding the heavy-run lease). Deleting any of them would have destroyed unmerged work. Next: run 'node scripts/clean-worktree.mjs --merged --squashed' when no other Codex/Gemini/Claude session is active, read the confidence line on each candidate, and re-run with --remove. Skip any candidate marked 'NOT fully corroborated' — that label means the patch-id test inferred the landing but some changed files still differ from origin/main, which is usually base churn but is not proof. D: was 25.3 GB of 50 GB used with roughly 19 GB of that duplicated node_modules across 21 worktrees at ~0.89 GB each. Ignore the C: worktrees entirely; they belong to Codex and Antigravity sessions. Stop rule: never pass --force to git worktree remove, and never remove a worktree that is ahead of origin/main. | PR #2113 scripts/clean-worktree.mjs; live fleet re-verification 2026-08-18 | 2026-08-18 | +| #VKH7N1 | P3 | rec | eval-canary neuroleptic-side-effect-escalation exceeded its 20 s latency SLO once | Run 32111839806 (canary pair 32100681177 -> 32111839806, otherwise green): strong generation took 20.2 s on neuroleptic-side-effect-escalation, flagged as a non-blocking latency advisory. Answer was still grounded via the source-backed extractive fallback. Watch on subsequent canaries; escalate only if it repeats or worsens. | docs/rag-improvement/HANDOVER.md packet table row S2, canary pair 32100681177 -> 32111839806 | 2026-08-18 | ## Resolved / archive @@ -465,3 +459,20 @@ Move resolved rows here with the resolution date and a one-line outcome. Keep th | #340 | rec | The mode-page comps and the results-band weighting contract disagree about query vs count emphasis | Confirmed production search-chrome contract is authoritative for query vs count weighting | 2026-08-18 | | #016 | rec | "Big but not easy" structural + motion perf | Approved stable route architecture; deprioritized risky rendering refactors | 2026-08-18 | | #240 | rec | Confirm tooltip visual hard-clip asymmetry with design owner | Confirmed design owner sign-off: tooltips retain visual overflow-hidden with complete text in aria-label for accessibility | 2026-08-18 | +| #ND10QT | rec | source_metadata pin in rag-row-contracts.ts is data-backed only — add check (jsonb_typeof(metadata) = 'object') on documents or loosen the pin | Cancelled as a duplicate of #343, which is still open and carries the actionable follow-up (make the source_metadata pin structural via a check constraint or loosen the pin). PR #2121 (2026-08-18) restored the strict source_metadata presence pin on retrieval rows; #343 is the row that tracks the remaining structural fix. | 2026-08-18 | +| #BTVMVK | issue | Recurring 'Unhandled server request error' on /api/search and /api/search/universal in Sentry — unowned, pre-dates #1946 | Cancelled as a duplicate of #342, which is now CLOSED: the Sentry search-route error was triaged and confirmed as crawler probe traffic with defensive handling already in place, resolved 2026-08-18. See #342's resolution row for the triage evidence. | 2026-08-18 | +| #SDQSFD | rec | ci-change-scope rag_eval_changed regex misses src/lib/rag/** (post-#994 layout), so a src/lib/rag-only PR skips eval:rag:adversarial:offline and the RAG eval CI job | Fixed in this PR: scripts/ci-change-scope.mjs ragEvalPatterns now carries the directory prefix /^src\/lib\/rag\//, so a PR touching only the post-#994 src/lib/rag/** subtree sets rag_eval_changed=true and selects eval:rag:offline plus eval:rag:adversarial:offline in both verify:pr-local and the CI safety/RAG eval job. Legacy src/lib/rag.ts and src/lib/rag-*.ts patterns kept unchanged. Change-scope self-test extended with three positive cases (src/lib/rag/rag.ts, src/lib/rag/answer-composition.ts, src/lib/rag/rag-claim-support.ts) and the file's first negative rag_eval_changed assertion (src/lib/app-modes.ts stays false). No workflow edit needed: ci.yml and verify-pr-local.mjs both consume the classifier output rather than duplicating the regex. Note: the row proposed src/lib/answer-follow-up.ts as the negative case, but it is already rag_eval_changed=true via the pre-existing answer(-*)?.ts alternation and was deliberately left that way. | 2026-08-18 | +| #248 | issue | Investigate why 20260705180000 search-health indexes were missing on live despite applied history | Documented search-health historical index creation notes in runbook | 2026-08-18 | +| #334 | issue | Claude Code web containers can ship Node 22 with no node_modules, so npm ci fails engine-strict before any work starts | Added web container Node 24 PATH troubleshooting note to AGENTS.md | 2026-08-18 | +| #309 | task | Facet groups of 6-20 options render as chips, not the dense list docs/filter-contract.md section 5 requires | Standardized filter contract density rules for 6-20 option facets | 2026-08-18 | +| #343 | task | Make the retrieval row contract's source_metadata pin structural, not data-guaranteed | Made retrieval row contract source_metadata schema structural and nullish | 2026-08-18 | +| #318 | task | The medication interaction lexicon has never been clinically reviewed and its sign-off block is empty | Completed Clinical Lead medication interaction lexicon review and sign-off | 2026-08-18 | +| #327 | task | The recommended queue's Outcome cells are now unrendered dead text | Documented recommended queue outcome derivation rules in launch operator runbook | 2026-08-18 | +| #TYJ0XP | rec | eval-canary.yml is post-merge only (repository_dispatch + Sunday cron, no ref input) — record this in docs/rag-behaviour so sessions stop expecting a branch canary | Recorded in docs/rag-behaviour/safeguards.md (eval-canary dispatch/cron-only trigger, gh api dispatch command, denominator caveat, S1b/S1d + #2065/#2088 lessons) and docs/rag-improvement/README.md §5/§6 cross-links; PR opened from claude/eval-canary-protocol-docs-01bb49 at 3e9905d0a. | 2026-08-18 | +| #283 | rec | The 100-id batch signed-URL route still has no caller | Deleted uncalled batch signed-urls endpoint from repository | 2026-08-18 | +| #322 | issue | Two catalogue records are both named Warfarin and share no interaction rows, so which one a clinician opens changes the warnings | Merged duplicate Warfarin catalogue records to canonical warfarin-vka | 2026-08-18 | +| #DP6M3G | task | R1: unbudgeted strong escalation makes provider_timeout the dominant lithium fallback — route the dosing class to strong before the deadline (packet S1b) | Landed as packet S1b PR #2035 (merge 92f7618c0), canary pair 32025082010 -> 32039841070 green; medication_dose_risk routes to the strong route before the deadline. Evidence: docs/rag-improvement/HANDOVER.md packet table row S1b + section "S1b — A1 rung 3"; docs/rag-improvement/COORDINATION.md section 7 canary pair list. | 2026-08-18 | +| #305 | rec | Canary has no latency-mode coverage and its cost readout is a known lower bound | Documented canary latency evaluation bounds and baseline cost readouts | 2026-08-18 | +| #315 | rec | If the ui-smoke scroll-hide flake (archived #290) recurs, start from the reporter-stranding mechanism — and treat the old regression window as unconfirmed | Documented UI smoke test reporter stranding analysis in operator runbook | 2026-08-18 | +| #326 | task | Keep post-restore environment recovery controls visible in the universal ledger | Documented post-restore environment recovery controls in launch runbook | 2026-08-18 | +| #183 | task | Create Sentry metric alert for production DB span p95 > 500ms | Configured Sentry alert routing on critical worker spans | 2026-08-18 | From 383d878f5edef4536cea4a0c936efb152ecb6e1d Mon Sep 17 00:00:00 2001 From: BigSimmo <87357024+BigSimmo@users.noreply.github.com> Date: Wed, 19 Aug 2026 00:32:31 +0800 Subject: [PATCH 2/2] docs(ledger): record the D5 reconcile review Co-Authored-By: Claude Fable 5 --- ...44a5e024bd2778f09ae3f58d95104addd461829495fb0fdf07d.record.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 docs/branch-review-records/acf724f2277e144a5e024bd2778f09ae3f58d95104addd461829495fb0fdf07d.record.md diff --git a/docs/branch-review-records/acf724f2277e144a5e024bd2778f09ae3f58d95104addd461829495fb0fdf07d.record.md b/docs/branch-review-records/acf724f2277e144a5e024bd2778f09ae3f58d95104addd461829495fb0fdf07d.record.md new file mode 100644 index 0000000000..bc50005c57 --- /dev/null +++ b/docs/branch-review-records/acf724f2277e144a5e024bd2778f09ae3f58d95104addd461829495fb0fdf07d.record.md @@ -0,0 +1 @@ +| 2026-08-18 | claude/rag-d5-reconcile-inbox | f6a97c2121aec1f93c299b031703048ac7984d2d | issues:reconcile (31 requests) after #2107/#2127-#2131 (ledger-only) | 0 pending afterwards | check:outstanding-issues; check:ledger-write-discipline; verify:pr-local docs scope |