diff --git a/.claude/hooks/issues-surface.sh b/.claude/hooks/issues-surface.sh index f22141372..cac48f0fb 100755 --- a/.claude/hooks/issues-surface.sh +++ b/.claude/hooks/issues-surface.sh @@ -60,8 +60,9 @@ queue_rows="$(awk ' ' "$ledger" 2>/dev/null || true)" total="$(printf '%s' "$rows" | grep -c . || true)" -if [ "${total:-0}" -eq 0 ]; then - echo "[issues] Outstanding-work memory (docs/outstanding-issues.md): no open items. Record one with /issues add …" +queue_total="$(printf '%s' "$queue_rows" | grep -c . || true)" +if [ "${total:-0}" -eq 0 ] && [ "${queue_total:-0}" -eq 0 ]; then + echo "[issues] Outstanding-work memory (docs/outstanding-issues.md): no recommended or open items. Record one with /issues add …" exit 0 fi @@ -72,7 +73,6 @@ c1="$(count "$p1")"; c2="$(count "$p2")"; c3="$(count "$p3")" echo "[issues] Outstanding-work memory — ${total} open (${c1}×P1, ${c2}×P2, ${c3}×P3). Source of truth: docs/outstanding-issues.md · read the full list back with /issues." -queue_total="$(printf '%s' "$queue_rows" | grep -c . || true)" if [ "${queue_total:-0}" -gt 0 ]; then echo "[issues] Recommended execution queue — ${queue_total} retained tasks (first 8):" printf '%s\n' "$queue_rows" | head -n 8 | while IFS=$'\t' read -r ord ids acuity capability timing; do diff --git a/docs/outstanding-issues.md b/docs/outstanding-issues.md index 5ba66d462..e1381d90c 100644 --- a/docs/outstanding-issues.md +++ b/docs/outstanding-issues.md @@ -36,11 +36,11 @@ This queue contains only work that remains recommended. Revalidate a row against before starting. Its position is not authority to call providers, spend money, change production, commit, push, open a PR, or deploy. -Order numbers remain stable within a reconciliation snapshot. A gap means an item was completed or -removed after current-main verification; it is not missing recommended work. +Order numbers are contiguous within a reconciliation snapshot. Reorder or remove rows only after +current-main verification, and keep every queued ID synchronized with its open item. -- **A1 — urgent:** active safety, privacy, data-loss, or release/launch blocker. One operator/legal - item is retained; there is no current A1 code defect. +- **A1 — urgent:** active safety, privacy, data-loss, or release/launch blocker. `#053` and `#059` + are independent current A1 items; start the legal package now while fixing the local privacy defect. - **A2 — important:** confirmed correctness, clinical, privacy, reliability, or evaluation work. - **A3 — planned:** worthwhile work that is safe to defer until its trigger. - **Optional:** start only when measured need, ownership, and cost justify it. @@ -51,33 +51,36 @@ removed after current-main verification; it is not missing recommended work. | Order | ID(s) | Acuity | Capability | When | Estimate | Outcome, gate, verification, and stopping condition | | ----: | ---------------------- | -------- | ------------------------------------------- | ------------------------------------------------------------------ | ---------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | 1 | `#053` | A1 | Operator — legal/privacy | Start now; finish before real patient use/privacy-approved release | 4–8 hours internal; 1–6 weeks elapsed | Execute DPAs; decide ZDR/residency; obtain cache behavior in writing; review subprocessors; obtain APP 8 and APP 5/1 counsel sign-off. Do not change public copy before approval. | -| 2 | `#052` | A2 | High — ingestion concurrency | Ready; first code task | 0.5–1 day | Add red single/bulk tests, then block full/retry reindex during a fresh agent-enrichment lease while keeping stale leases and enrichment mode unchanged. Run focused safety tests and `verify:cheap`; stop if current `main` cannot reproduce it. | -| 3 | `#030` | A2 | High — evaluation semantics | After order 2 | 2–4 hours | Require distinct source identities for distinct comparison slots. Run focused matching tests, typecheck, and `verify:cheap`; stop without changing strict aliases, retrieval, or ranking. | -| 4 | `#019` | A2 | Specialist — RAG answer pipeline | Local reproducer now; behavior change after order 8 | 0.5–1 day reproducer | Reproduce admission-source loss in the fallback layer using PR #1096’s source shape. Any behavior change needs protected review and an approved baseline/post canary; stop if independently non-reproducible. | -| 6 | `#054` | A2 | Standard locally; Operator hosted | Local safety identifier now; hosted next approved window | 15–30 min local; 1–2 hours hosted | Presence-check and fill confirmed secret/config gaps with distinct per-environment values. Never record values. Require clean readiness/secret checks; stop on ambiguous environment or project identity. | -| 7 | `#022` | A2 | Operator — clinical governance + Specialist | Decision-ready | 1–2 hours policy; 0.5–1 day first ten | Decide BMJ attestation policy and review the ten highest-impact local documents. Record reviewer/evidence/time; stop after ten and remeasure warning debt. | -| 8 | `#051`, `#023` | A2 | Specialist — RAG diagnostics | After scheduled 2026-07-26 run | 2–4 hours | With GitHub-read approval, compare structured canary/browser/irrelevant-at-10 artifacts without dispatching a rerun. Record deterministic/provider/latency deltas and disposition residuals; stop without spending. | -| 9 | `#018` | A2 | Specialist — clinical RAG/retrieval | After order 8, one mechanism at a time | 1–2 days diagnosis | Give lithium, ADHD, and metabolic residuals separate current-main reproducers and candidates. Behavior canaries require approval; stop any item without a deterministic reproducer or on regression. | -| 10 | `#029` | A2 | Specialist — answer quality/clinical safety | After orders 8–9 | 0.5–1 day inventory; 1–3 days per fix | Re-enumerate current fallback stubs and fix one causal cluster at a time without weakening grounding/citation gates. Stop if a change merely makes the metric easier to pass. | -| 11 | `#001` | A2 | Specialist — retrieval/ranking | After order 8 and rollout approval | 0.5–1 day plus canary | Keep semantic reranking off unless an approved ambiguity comparison preserves 36/36, recall 1.0, zero per-case regressions, and shows measured gain; otherwise record keep-off and stop. | -| 12 | `#025` | A2 | Operator — Railway/GitHub/chat/Supabase | Next approved observability window | 1–3 hours/channel | Choose owned deployment, CI, ingestion, and SLO alerts; mock first, then one approved controlled provider event/channel. The merged Supabase trigger remains inert until its verified inputs are configured. Stop without an accountable responder. | -| 13 | `#055` | A2 | Specialist release owner + Operator | Before next full-confidence release/handoff | 2–4 hours plus runtime | On one exact SHA, run local/provider gates, Firefox/WebKit, required hosted CI, and close actionable GitHub threads. Stop at first failure and rerun only the repaired smallest gate. | -| 14 | `#056` | A2 | Operator — Supabase/Railway + Specialist | After cost/ownership approval | 0.5–1 day | Provision isolated `Clinical KB Staging` with synthetic data and distinct secrets. Verify identity, schema, indexing, health, and data boundary; never copy production clinical documents. | -| 15 | `#057` | A2 | High — release/SRE + Operator | After order 14 | 2–4 hours plus soak | Run documented staging soak and rollback against an exact candidate. Retain latency/error/rollback evidence; stop on unsafe data, identity mismatch, or unowned rollback. | -| 16 | `#058` | A2 | Operator — production data + Specialist | Next approved production verification window | 30–60 min read-only; 1–2 hours if needed | Verify registry/differentials/medications are non-empty before writing; seed only confirmed gaps idempotently. Stop when healthy or owner/project identity is ambiguous. | -| 17 | `#007` | A3 | Operator decision + Standard frontend | When product chooses canonical Tools route | 15–30 min decision; 0.5 day | Align navigation, redirect, sitemap, and reachability around one entry point. Stop while the standalone page has an unresolved requirement. | -| 18 | `#011` | A3 | Operator — Supabase capacity | Immediately before first compute scale-up | 30–60 min plus observation | Switch Auth to percentage allocation, record before/after, and run approved advisor/health checks. Stop if no scale-up is planned. | -| 19 | `#017` | A3 | High — performance/browser | Before order 23; approved live-site window | 1–2 hours | Capture reproducible mobile/desktop Lighthouse/Web-Vitals evidence and decide whether payload work is justified. Stop if metrics are acceptable or evidence is too noisy. | -| 20 | `#024` | A3 | High — Next.js/Playwright/WebKit | After order 8 or real Safari reproduction | 0.5–1 day | Distinguish test interception from a Safari defect. Apply test-only correction only with a discriminating repro; keep access-control assertions meaningful. | -| 21 | `#033` | A3 | Specialist — prompt/source governance | After orders 7–8 | 1–2 days plus approved eval | Design unknown-vs-adverse metadata wording and prompt tests. Require no supported-grounding drop and zero citation failures; stop on broad over-caveating or degradation. | -| 22 | `#037` | A3 | Operator — clinical/product + Standard | Next trust-policy review | 30–60 min; up to 0.5 day | Decide whether routine claims cap at medium trust. Record policy; if accepted, change only the flag/expectations and run focused tests. | -| 23 | `#012`, `#013`, `#016` | A3 | High — bundling/runtime performance | After order 19 or equivalent evidence | 0.5–2 days/route | Optimize only a production route with measured payload/render/motion harm. Require material gain plus focused, `verify:cheap`, and browser evidence; stop on small gain. | -| 24 | `#027` | Optional | Operator — SRE/provider | When an owned external alert path is wanted | 1–2 hours | Decide vendor/cost/privacy/owner; if accepted, prove one non-PHI outage and recovery alert. Stop when no responder owns it. | -| 25 | `#028` | Optional | Specialist privacy/observability + Operator | After privacy/ownership/cost approval | 1–3 days | Define vendor/region/retention/redaction/sampling/source-map envelope before SDK work. Prove no clinical text, identifiers, or secrets leave; stop if unacceptable. | -| 26 | `#038` | Optional | High — product/design architecture | When a new comparison surface is approved | 0.5–1 day | Define a shared interaction contract without flattening mode-specific content. Stop when no concrete new surface exists. | -| 27 | `#040` | Optional | High — visual QA/accessibility | When baseline owner/update workflow exist | 1–2 days | Establish a small stable desktop/mobile/accessibility baseline set. Do not make it blocking if flake or maintenance cost outweighs detection value. | - - +| 2 | `#059` | A1 | Specialist privacy + clinical frontend | Ready; before real-patient use | 3–5 hours | Align the Safety Plan Generator with the no-patient-data contract. Require an owner decision, then make copy, behavior, print/copy output, and tests agree. Stop before adding persistence or provider transmission. | +| 3 | `#060` | A2 | Specialist clinical safety | Ready; after order 2 | 2–4 hours | Add a red render-policy test, then fail closed when answer relevance metadata is absent while preserving explicit source-backed behavior. Run focused policy/provenance tests, `verify:cheap`, and production-readiness. | +| 4 | `#052` | A2 | High — ingestion concurrency | Ready; first independent ingestion task | 0.5–1 day | Add red single/bulk tests, then block full/retry reindex during a fresh agent-enrichment lease while keeping stale leases and enrichment mode unchanged. Run focused safety tests and `verify:cheap`; stop if current `main` cannot reproduce it. | +| 5 | `#061` | A2 | Specialist queue reliability | Ready; after order 4 | 0.5–1.5 days | Reproduce a queued document with no open job, then add the smallest idempotent owner-scoped recovery path. Require exactly one job under crash/concurrency/repeat; hosted changes require approval. | +| 6 | `#030` | A2 | High — evaluation semantics | After order 3 | 2–4 hours | Require distinct source identities for distinct comparison slots. Run focused matching tests, typecheck, and `verify:cheap`; stop without changing strict aliases, retrieval, or ranking. | +| 7 | `#019` | A2 | Specialist — RAG answer pipeline | Local reproducer now; behavior change after order 11 | 0.5–1 day reproducer | Reproduce admission-source loss in the fallback layer using PR #1096’s source shape. Any behavior change needs protected review and an approved baseline/post canary; stop if independently non-reproducible. | +| 8 | `#054` | A2 | Standard locally; Operator hosted | Local safety identifier now; hosted next approved window | 15–30 min local; 1–2 hours hosted | Presence-check and fill confirmed secret/config gaps with distinct per-environment values. Never record values. Require clean readiness/secret checks; stop on ambiguous environment or project identity. | +| 9 | `#022` | A2 | Operator — clinical governance + Specialist | Decision-ready | 1–2 hours policy; 0.5–1 day first ten | Decide BMJ attestation policy and review the ten highest-impact local documents. Record reviewer/evidence/time; stop after ten and remeasure warning debt. | +| 10 | `#051`, `#023` | A2 | Specialist — RAG diagnostics | After scheduled 2026-07-26 run | 2–4 hours | With GitHub-read approval, compare structured canary/browser/irrelevant-at-10 artifacts without dispatching a rerun. Record deterministic/provider/latency deltas and disposition residuals; stop without spending. | +| 11 | `#018` | A2 | Specialist — clinical RAG/retrieval | After order 10, one mechanism at a time | 1–2 days diagnosis | Give lithium, ADHD, and metabolic residuals separate current-main reproducers and candidates. Behavior canaries require approval; stop any item without a deterministic reproducer or on regression. | +| 12 | `#029` | A2 | Specialist — answer quality/clinical safety | After orders 10–11 | 0.5–1 day inventory; 1–3 days per fix | Re-enumerate current fallback stubs and fix one causal cluster at a time without weakening grounding/citation gates. Stop if a change merely makes the metric easier to pass. | +| 13 | `#001` | A2 | Specialist — retrieval/ranking | After order 10 and rollout approval | 0.5–1 day plus canary | Keep semantic reranking off unless an approved ambiguity comparison preserves 36/36, recall 1.0, zero per-case regressions, and shows measured gain; otherwise record keep-off and stop. | +| 14 | `#025` | A2 | Operator — Railway/GitHub/chat/Supabase | Next approved observability window | 1–3 hours/channel | Choose owned deployment, CI, ingestion, and SLO alerts; mock first, then one approved controlled provider event/channel. The merged Supabase trigger remains inert until its verified inputs are configured. Stop without an accountable responder. | +| 15 | `#055` | A2 | Specialist release owner + Operator | Before next full-confidence release/handoff | 2–4 hours plus runtime | On one exact SHA, run local/provider gates, Firefox/WebKit, required hosted CI, and close actionable GitHub threads. Stop at first failure and rerun only the repaired smallest gate. | +| 16 | `#056` | A2 | Operator — Supabase/Railway + Specialist | After cost/ownership approval | 0.5–1 day | Provision isolated `Clinical KB Staging` with synthetic data and distinct secrets. Verify identity, schema, indexing, health, and data boundary; never copy production clinical documents. | +| 17 | `#057` | A2 | High — release/SRE + Operator | After order 16 | 2–4 hours plus soak | Run documented staging soak and rollback against an exact candidate. Retain latency/error/rollback evidence; stop on unsafe data, identity mismatch, or unowned rollback. | +| 18 | `#058` | A2 | Operator — production data + Specialist | Next approved production verification window | 30–60 min read-only; 1–2 hours if needed | Verify registry/differentials/medications are non-empty before writing; seed only confirmed gaps idempotently. Stop when healthy or owner/project identity is ambiguous. | +| 19 | `#007` | A3 | Operator decision + Standard frontend | When product chooses canonical Tools route | 15–30 min decision; 0.5 day | Align navigation, redirect, sitemap, and reachability around one entry point. Stop while the standalone page has an unresolved requirement. | +| 20 | `#011` | A3 | Operator — Supabase capacity | Immediately before first compute scale-up | 30–60 min plus observation | Switch Auth to percentage allocation, record before/after, and run approved advisor/health checks. Stop if no scale-up is planned. | +| 21 | `#017` | A3 | High — performance/browser | Before order 25; approved live-site window | 1–2 hours | Capture reproducible mobile/desktop Lighthouse/Web-Vitals evidence and decide whether payload work is justified. Stop if metrics are acceptable or evidence is too noisy. | +| 22 | `#024` | A3 | High — Next.js/Playwright/WebKit | After order 10 or real Safari reproduction | 0.5–1 day | Distinguish test interception from a Safari defect. Apply test-only correction only with a discriminating repro; keep access-control assertions meaningful. | +| 23 | `#033` | A3 | Specialist — prompt/source governance | After orders 9–10 | 1–2 days plus approved eval | Design unknown-vs-adverse metadata wording and prompt tests. Require no supported-grounding drop and zero citation failures; stop on broad over-caveating or degradation. | +| 24 | `#037` | A3 | Operator — clinical/product + Standard | Next trust-policy review | 30–60 min; up to 0.5 day | Decide whether routine claims cap at medium trust. Record policy; if accepted, change only the flag/expectations and run focused tests. | +| 25 | `#012`, `#013`, `#016` | A3 | High — bundling/runtime performance | After order 21 or equivalent evidence | 0.5–2 days/route | Optimize only a production route with measured payload/render/motion harm. Require material gain plus focused, `verify:cheap`, and browser evidence; stop on small gain. | +| 26 | `#027` | Optional | Operator — SRE/provider | When an owned external alert path is wanted | 1–2 hours | Decide vendor/cost/privacy/owner; if accepted, prove one non-PHI outage and recovery alert. Stop when no responder owns it. | +| 27 | `#028` | Optional | Specialist privacy/observability + Operator | After privacy/ownership/cost approval | 1–3 days | Define vendor/region/retention/redaction/sampling/source-map envelope before SDK work. Prove no clinical text, identifiers, or secrets leave; stop if unacceptable. | +| 28 | `#038` | Optional | High — product/design architecture | When a new comparison surface is approved | 0.5–1 day | Define a shared interaction contract without flattening mode-specific content. Stop when no concrete new surface exists. | +| 29 | `#040` | Optional | High — visual QA/accessibility | When baseline owner/update workflow exist | 1–2 days | Establish a small stable desktop/mobile/accessibility baseline set. Do not make it blocking if flake or maintenance cost outweighs detection value. | + + ## Open items @@ -96,6 +99,9 @@ removed after current-main verification; it is not missing recommended work. | #056 | P2 | task | Provision isolated staging environment | After explicit cost/ownership approval, provision `Clinical KB Staging` Supabase and Railway tiers with distinct secrets and synthetic/non-clinical data. Verify identity, schema, indexing, health, and the production-data boundary. | `docs/staging-setup.md`; `docs/operator-backlog.md` | 2026-07-24 | | #057 | P2 | task | Complete staging soak and rollback rehearsal | After #056, run the documented soak and rollback against an exact candidate; retain latency/error/rollback evidence. Stop on unsafe data, identity mismatch, or an unowned rollback decision. | `docs/launch-operator-runbook.md`; `docs/capacity-review.md` | 2026-07-24 | | #058 | P2 | task | Verify production content before any seed write | Against `Clinical KB Database`, verify registry, differentials, and medications surfaces are non-empty before writing. Seed only confirmed gaps idempotently with approved owner/project identity and confirmation flags. | `docs/launch-operator-runbook.md`; `docs/operator-backlog.md` | 2026-07-24 | +| #059 | P1 | issue | Safety Plan Generator contradicts the privacy contract | **Outcome:** the tool, privacy notice, PIA, and tests agree on whether patient identifiers may be entered, copied, printed, or saved. **Next:** obtain a privacy/clinical decision, then default to identifier-free behavior unless transient identifier processing is explicitly approved and documented. **Success:** no contradictory copy and no identifier is persisted or transmitted without an approved basis. **Verify:** focused component/privacy/copy/accessibility tests, browser print/copy smoke, `verify:cheap`, and production-readiness. **Stop:** any new storage or provider transmission requires separate review. | `src/components/patient-safety-plan.tsx:649`; `src/app/privacy/page.tsx:28`; `docs/privacy-impact-assessment.md:145` | 2026-07-24 | +| #060 | P2 | issue | Missing answer relevance metadata is treated as source-backed | **Outcome:** absent `relevance` metadata renders conservatively. **Next:** add the red render-policy test, then make the smallest policy-only correction to `relevance?.isSourceBacked !== false`. **Success:** missing and explicit-false relevance fail closed while explicit source-backed behavior is unchanged. **Verify:** focused answer-render-policy, provenance and clinical-safety tests, `verify:cheap`, and production-readiness. **Stop:** do not expand into retrieval, ranking, or generation. | `src/lib/types.ts:947`; `src/lib/answer-render-policy.ts:145` | 2026-07-24 | +| #061 | P2 | issue | Upload crash can strand a queued document without a job | **Outcome:** a crash between document and job creation cannot strand an upload indefinitely. **Next:** add a stranded-row reproducer, then choose the smallest idempotent atomic-enqueue RPC or bounded scheduled sweep consistent with ownership and rollback contracts. **Success:** exactly one recoverable job is created; existing open jobs do not duplicate; owner scope, retry, audit, and rollback remain intact. **Verify:** focused upload/recovery/schema tests, migration guards, disposable replay if needed, `verify:cheap`, and production-readiness. **Stop:** hosted changes require approval, and no at-least-once claim is valid until the crash case passes. | `src/app/api/upload/route.ts`; `docs/webhooks.md:163-192` | 2026-07-24 | | #005 | P3 | rec | `finalScore` saturates at clamp ceiling | Base + ~40 stacked boosts routinely exceed 1.0, so strong matches tie at 1.0 and order by an arbitrary `document_id` tiebreak. If ranking is ever revisited, break ties by the **pre-clamp** score rather than raising the `[0,1]` ceiling (downstream gates assume `[0,1]`). Ordering already sorts by the unbounded pre-clamp `rankScore` (`clinical-search.ts:1735,1927,1950-1955`), so the clamp confines only the reported confidence value, not result order. Not a defect on the current golden set; any change here is a protected RAG surface (canary required). | `docs/rag-hybrid-findings-and-todo.md` P1 item 4; `src/lib/clinical-search.ts:1735` | 2026-07-21 | | #007 | P3 | rec | `/tools` vs `/?mode=tools` parallel Tools entry points | `/tools` (standalone `ApplicationsLauncherPage`) has no inbound in-app link; the sidebar Tools item uses `/?mode=tools`. Decide the canonical entry point and wire nav consistently, or drop the standalone `/tools` page + `/applications` redirect. Currently allowlisted in `tests/route-reachability.test.ts`. | `src/app/tools/page.tsx`; `src/app/applications/route.ts` | 2026-07-21 | | #009 | P3 | rec | Confirm `/api/jobs` is intentionally server/ops-only | No client `fetch()` reaches `/api/jobs` (only tests import it). Confirm it is a deliberate ops/manual surface; if abandoned, remove it. | `src/app/api/jobs/route.ts` | 2026-07-21 |