diff --git a/.claude/hooks/issues-surface.sh b/.claude/hooks/issues-surface.sh index dab08f83d..6ef078f54 100755 --- a/.claude/hooks/issues-surface.sh +++ b/.claude/hooks/issues-surface.sh @@ -26,22 +26,26 @@ source_val="$(printf '%s' "$payload" \ | head -n1 | sed -E 's/.*"([^"]*)"$/\1/')" # --- parse the "Open items" table only --------------------------------------- -# Emit "PRIIDTYPESUMMARY" per open row. Scoped between the +# Emit ordered universal-ledger fields per active row. Scoped between the # "## Open items" heading and the next "## " heading so the Resolved/archive -# table (different columns) is never counted. +# and superseded historical tables are never counted. rows="$(awk ' /^## Open items/ { inopen=1; next } /^## / { if (inopen) inopen=0 } inopen && /^\| #[0-9]/ { n=split($0, c, "|") - id=c[2]; pri=c[3]; typ=c[4]; sum=c[5] + id=c[2]; pri=c[3]; typ=c[4]; sum=c[5]; order=c[9]; class=c[10]; when=c[12]; estimate=c[13] gsub(/^[ \t]+|[ \t]+$/, "", id) gsub(/^[ \t]+|[ \t]+$/, "", pri) gsub(/^[ \t]+|[ \t]+$/, "", typ) gsub(/^[ \t]+|[ \t]+$/, "", sum) - printf "%s\t%s\t%s\t%s\n", pri, id, typ, sum + gsub(/^[ \t]+|[ \t]+$/, "", order) + gsub(/^[ \t]+|[ \t]+$/, "", class) + gsub(/^[ \t]+|[ \t]+$/, "", when) + gsub(/^[ \t]+|[ \t]+$/, "", estimate) + printf "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n", order, pri, id, typ, sum, class, when, estimate } -' "$ledger" 2>/dev/null || true)" +' "$ledger" 2>/dev/null | sort -n -k1,1 || true)" total="$(printf '%s' "$rows" | grep -c . || true)" if [ "${total:-0}" -eq 0 ]; then @@ -49,20 +53,20 @@ if [ "${total:-0}" -eq 0 ]; then exit 0 fi -group() { printf '%s\n' "$rows" | awk -F'\t' -v p="$1" '$1==p'; } +group() { printf '%s\n' "$rows" | awk -F'\t' -v p="$1" '$2==p'; } count() { printf '%s' "$1" | grep -c . || true; } p1="$(group P1)"; p2="$(group P2)"; p3="$(group P3)" 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." +echo "[issues] Universal task ledger — ${total} recommended open (${c1}×P1, ${c2}×P2, ${c3}×P3). Source of truth: docs/outstanding-issues.md · read the full ordered list with /issues." -print_group() { # $1=rows $2=max-to-list - local data="$1" limit="$2" shown=0 more=0 pri id typ sum +print_ordered() { # $1=rows $2=max-to-list + local data="$1" limit="$2" shown=0 more=0 order pri id typ sum class when estimate [ -z "$data" ] && return 0 - while IFS=$'\t' read -r pri id typ sum; do - [ -z "$pri" ] && continue + while IFS=$'\t' read -r order pri id typ sum class when estimate; do + [ -z "$order" ] && continue if [ "$shown" -lt "$limit" ]; then - echo " ${pri} ${id} ${typ} — ${sum}" + echo " ${order}. ${pri} ${id} ${typ} [${class}] — ${sum}; when: ${when}; estimate: ${estimate}" shown=$((shown + 1)) else more=$((more + 1)) @@ -70,22 +74,20 @@ print_group() { # $1=rows $2=max-to-list done <`** — append a row to **Open items**. Infer `Pri`/`Type` from the text - (ask only if genuinely ambiguous; default `P2`/`task`). Allocate the ID from the - `` marker, then bump that marker. Fill `Source` with - `session ` unless the user names one; `Added` is today's date. +- **`/issues add `** — verify that the candidate is current, evidence-supported, deduplicated + and worth its cost/risk before adding it. Append a fully populated **Open items** row, allocate the + ID from ``, bump the marker, and place it at the smallest sensible + **Order** while renumbering later rows. Do not add speculative, completed, stale, duplicate, + superseded or no-longer-recommended work. - **`/issues done [outcome]`** — move that row from **Open items** to **Resolved / archive** with today's date and a one-line outcome. Archive, never delete. - **`/issues update `** — edit an open row's summary or next action in place. -- **`/issues capture`** — scan the current session for recommendations, follow-ups, deferrals, and - unfixed problems that surfaced but were not recorded. Propose them as a numbered list and add the - confirmed ones (dedupe against existing rows first — do not re-add something already tracked). +- **`/issues capture`** — scan the current session and repository evidence for genuinely retained + work. Reclassify or omit completed, stale, duplicate, superseded, speculative and uneconomic claims; + add only confirmed recommended items after deduplication. ## Capture discipline (proactive memory) -When a task in _any_ session ends with unresolved follow-ups — a deferred fix, a "revisit when X" -recommendation, a known risk, a TODO you had to leave — offer to record them here before the context -is lost. That is what makes this a memory rather than a static list. Prefer one crisp row over a -paragraph; put the smallest next action in **Detail / next action**. +When a task ends with a supported follow-up, offer to reconcile it here before context is lost. Do not +capture every suggestion: verify current source evidence, impact, existing safeguards, cost, risk, +dependencies and provider requirements first. Prefer the smallest actionable outcome. ## Writing rules - Keep the table format and column order exactly as in `docs/outstanding-issues.md`. One row per item. - IDs are monotonic and never reused — always allocate from the `issues:next-id` marker and bump it. +- Keep **Order** contiguous and unique. Skip blocked rows during execution; do not reorder them merely + because a dependency is temporarily unavailable. +- Use exactly one allowed **Final classification** from the ledger conventions. +- Fill every retained row's next action, executor, when, estimate, dependencies/approvals, success + criteria, local/hosted verification and stopping condition. - Escape `|` inside cell text (write `\|`) so the markdown table stays intact. - Respect the repo's RAG/clinical/privacy flagging rules if an item _itself_ touches a protected surface — recording it here is fine, but acting on it later still needs the usual gate. -## Persist the memory (commit) +## Persist the ledger -After any mutation, stage and commit **only** `docs/outstanding-issues.md` so the memory survives the -ephemeral container and other worktrees: - -``` -git add docs/outstanding-issues.md -git commit -m "issues: " -``` - -Do not stage or commit anything else, and do not push unless the user asks (or you are already in a -handoff/upload flow). A plain read-only `/issues` commits nothing. +Edit the ledger when requested. A ledger mutation does not authorize a commit, push or pull request; +follow the repository Git instructions and the user's explicit publishing scope. A plain `/issues` +mutates nothing. diff --git a/AGENTS.md b/AGENTS.md index 32d9bc6c0..968798da6 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -448,23 +448,24 @@ Run the matching planner command in `docs/productivity-workflows.md` without sid -## Outstanding-work memory (`/issues`) - -`docs/outstanding-issues.md` is the durable, cross-session memory of every outstanding **task**, -**recommendation**, and **issue** for this repo. Chat context resets between sessions; that file does -not, so anything worth remembering after a session ends belongs there. - -- When the user types `/issues`, invoke the `issues` skill (`.claude/skills/issues/SKILL.md`): read - `docs/outstanding-issues.md` and state the open items back, grouped by priority. A plain `/issues` - is read-only — it mutates and commits nothing. -- `/issues add|done|update|capture …` mutate the ledger; each mutation commits **only** - `docs/outstanding-issues.md` (no push unless the user asks or you are already handing off). -- Proactively offer to `capture` unresolved follow-ups, deferrals, and known risks into the ledger - before a session's context is lost — that is what keeps it a memory rather than a stale list. -- A `SessionStart` hook (`.claude/hooks/issues-surface.sh`, wired in `.claude/settings.json`) - auto-surfaces the open items into context at the start of every session and, on a context reset - (`compact`/`resume`/`clear`), nudges a `/issues capture`. It is read-only — it never writes the - ledger. `/issues` is still the way to read the full list or mutate it. +## Universal repository task ledger (`/issues`) + +`docs/outstanding-issues.md` is the single durable, cross-session ledger for all agents and +worktrees. Its ordered **Open items** table contains only current, evidence-supported work still +worth doing, with priority, classification, executor capability, timing, effort, dependencies, +approvals, success criteria, verification and stopping conditions. Other backlog and runbook files +are supporting evidence, not competing queues. + +- Before starting or recommending repository work, read `docs/outstanding-issues.md` and revalidate + the relevant row against current `main`. +- When the user types `/issues`, invoke the `issues` skill (`.claude/skills/issues/SKILL.md`) and + state active rows in numeric **Order**. A plain `/issues` is read-only. +- `/issues add|done|update|capture …` may mutate the ledger only after removing completed, stale, + duplicate, superseded, speculative or no-longer-recommended claims. A ledger mutation does not + itself authorise a commit, push, pull request, provider call, deployment or production change. +- The read-only `SessionStart` hook (`.claude/hooks/issues-surface.sh`, wired in + `.claude/settings.json`) surfaces the ordered active work and prompts evidence-based capture after + context resets. ## Codex GitHub review behavior diff --git a/docs/README.md b/docs/README.md index 0b743e80c..f49960a49 100644 --- a/docs/README.md +++ b/docs/README.md @@ -71,7 +71,8 @@ npm run docs:check-links ## Plans and workstreams (living) -- [maturity-backlog-workorders.md](maturity-backlog-workorders.md) — actionable work orders tracking the repository-maturity audit backlog +- [outstanding-issues.md](outstanding-issues.md) — single universal task ledger and recommended execution order +- [maturity-backlog-workorders.md](maturity-backlog-workorders.md) — historical maturity workorders; only entries promoted to the universal ledger are active tasks - [framework-dependency-modernization-checklist.md](framework-dependency-modernization-checklist.md) — ordered Next.js 16, runtime, dependency, Turbopack, and verification migration program - [search-rag-master-plan.md](search-rag-master-plan.md) / [search-rag-master-context.md](search-rag-master-context.md) — search/RAG roadmap and shared context - [rag-hybrid-findings-and-todo.md](rag-hybrid-findings-and-todo.md) — hybrid retrieval findings backlog diff --git a/docs/branch-review-ledger.md b/docs/branch-review-ledger.md index b9b2a8b96..f8f2edb72 100644 --- a/docs/branch-review-ledger.md +++ b/docs/branch-review-ledger.md @@ -20,7 +20,7 @@ Use this ledger to prevent repeated branch and PR reviews when the reviewed HEAD | Date | Branch or ref | Reviewed HEAD | Scope | Outcome | Checks | | ---------- | -------------------------------------------------------- | ---------------------------------------- | ---------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| 2026-07-24 | `codex/supabase-document-change-trigger` | `9c7d9edf509a51478f5bebbabcca64e3926dc877` + reviewed working diff | Document-change ingestion trigger migration, schema mirror, grants, privacy and fail-safe delivery | APPROVE. No P0-P2 finding. The trigger is update-only, acts solely on a strict JSON boolean false/absent-to-true transition, sends only the receiver's allowlisted owner-scoped fields, fails open for document writes when Vault/GUC/pg_net is unavailable, and revokes execution from public/anon/authenticated. No production URL fallback exists. Highest residual risk is deliberate pg_net at-most-once delivery; the clear-then-flip recovery and data-preserving rollback are documented, and the trigger remains inert until both the Vault secret and environment base-URL GUC are configured. | Disposable `supabase/postgres:17.6.1.127` schema replay and drift-manifest regeneration passed (16s; scratch container removed); focused schema/drift/receiver Vitest 89/89; migration-role, function-grant (30 SECURITY DEFINER functions) and owner-scope guards; production-readiness CI mode READY with expected secretless-worktree warnings; offline RAG 21 suites/307 tests; `verify:cheap` 365 files, 3,241 passed/1 skipped; static trace of receiver payload, authoritative owner-scoped reload and idempotent enqueue path. No live provider mutation or migration apply. | +| 2026-07-24 | `codex/supabase-document-change-trigger` | `9c7d9edf509a51478f5bebbabcca64e3926dc877` + reviewed working diff | Document-change ingestion trigger migration, schema mirror, grants, privacy and fail-safe delivery | APPROVE. No P0-P2 finding. The trigger is update-only, acts solely on a strict JSON boolean false/absent-to-true transition, sends only the receiver's allowlisted owner-scoped fields, fails open for document writes when Vault/GUC/pg_net is unavailable, and revokes execution from public/anon/authenticated. No production URL fallback exists. Highest residual risk is deliberate pg_net at-most-once delivery; the clear-then-flip recovery and data-preserving rollback are documented, and the trigger remains inert until both the Vault secret and environment base-URL GUC are configured. | Disposable Supabase Postgres 17.6.1.127 image replay and drift-manifest regeneration passed (16s; scratch container removed); focused schema/drift/receiver Vitest 89/89; migration-role, function-grant (30 SECURITY DEFINER functions) and owner-scope guards; production-readiness CI mode READY with expected secretless-worktree warnings; offline RAG 21 suites/307 tests; `verify:cheap` 365 files, 3,241 passed/1 skipped; static trace of receiver payload, authoritative owner-scoped reload and idempotent enqueue path. No live provider mutation or migration apply. | | 2026-07-23 | PR #1090 / `cursor/fix-phone-dock-edge-1b1d` | `761de7e9ad623b6bd8d634d849a9eb465d622e48` (merged as `09028ef217209fceb53f1122ac7738b509bce323`) | Phone safe-area and edge-to-edge search-dock UI review | MERGED. No P0-P2 finding. The branch was three commits behind, so current `origin/main` was merged before landing; the actual merge tree matched the reviewed synthetic tree. The dock remains flush to the viewport with safe-area padding inside the form, and the phone shell no longer retains the `dvh` clamp that created the Safari toolbar band. Zero actionable review threads. | `npm run ensure`; focused `ui-tools.spec.ts` phone-home and edge-to-edge scenarios: Chromium 2/2 and WebKit 2/2; refreshed hosted policy, security, unit, build, advisory UI, Production UI and required aggregate checks green; exact-head ancestry and local-main tree equality proved after merge. | | 2026-07-22 | PR #1087 / `codex/reconcile-product-truth` | `edbc2260fef59ca2fa7c6973dffb85e32354bce1` (merged as `05dc52fd8408a65117e22a6236e43252203bea92`) | Product-truth copy, account persistence and unavailable-SSO presentation | MERGED. Cross-device claims now match favourites/preferences persistence; recent searches are identified as browser-session data; the contradictory “never shared” statement is removed. All unavailable setup providers and Apple elsewhere use the connected accessible “coming soon” placeholder pattern. The single review finding was fixed, replied to and resolved. | Red DOM proof; focused 19/19; `verify:cheap` 3,220 passed / 1 skipped; `verify:ui` 265/265; PR-local build/secret scan/offline RAG; final hosted required, Production UI, policy and security checks green. No provider calls or RAG spend. | | 2026-07-22 | PR #1086 / `codex/reconcile-xlsx-budgets` | `5376880a40749b6526fd7e4603a7be9d04bc9624` (merged as `2963fba46eacd644618a588fa283f7597faa2644`) | XLSX resource-boundary review | MERGED. Enforces worksheet, non-empty-row, rendered-cell and UTF-8 output ceilings before result fragments are appended; sparse-column output is preserved. No actionable review threads. | Red 257-sheet reproducer; focused 4/4; `verify:cheap` 3,218 passed / 1 skipped; PR-local build/scan/offline RAG; hosted required/security/policy green. | diff --git a/docs/maturity-backlog-workorders.md b/docs/maturity-backlog-workorders.md index 2c3a945c9..1d9567b81 100644 --- a/docs/maturity-backlog-workorders.md +++ b/docs/maturity-backlog-workorders.md @@ -1,12 +1,15 @@ -# Maturity backlog — work orders +# Maturity backlog — historical work orders -Living tracker that turns the deferred backlog from +Historical tracker that records work orders derived from [`docs/audit/2026-07-20-repository-maturity.md`](audit/2026-07-20-repository-maturity.md) §10 -into actionable, sequenced work orders. Each item states its **outcome**, **approach**, **key +and their implementation status. Each item states its **outcome**, **approach**, **key files**, **risk**, **verification**, and **status**. High-risk items are deliberately kept as their own work order — the audit's rule is one dedicated PR + full-suite verification per structural change, not a single mixed PR. +This file is not an active queue. [`docs/outstanding-issues.md`](outstanding-issues.md) is the +repository's single universal task ledger; only work promoted there is currently recommended. + **Status legend:** `DONE` (landed) · `IN PROGRESS` (partially landed; more PRs remain) · `READY` (scoped, safe to start) · `OPEN` (needs a decision or a dedicated PR) · `PROVIDER-GATED` (touches live DB/CI/provider — needs explicit confirmation) · `SATISFIED` diff --git a/docs/operator-backlog.md b/docs/operator-backlog.md index eb749675b..90344d1ad 100644 --- a/docs/operator-backlog.md +++ b/docs/operator-backlog.md @@ -1,10 +1,12 @@ -# Operator backlog +# Operator runbook index -Single source of truth for **human-only / provider-gated actions** that cannot be done from a coding -session (they touch Supabase, Railway, OpenAI, or GitHub settings, per the AGENTS.md provider boundary). -This exists so that launch-blocking state lives in the repo instead of chat memory. +Reference index for **human-only / provider-gated actions** that cannot be done from a coding session +(they touch Supabase, Railway, OpenAI, or GitHub settings, per the AGENTS.md provider boundary). +This is not a second task queue: [`docs/outstanding-issues.md`](outstanding-issues.md) is the single +universal ledger and decides which operator actions are currently recommended. -**How to use:** work top to bottom; each row links to the detailed runbook. `Status` values are +**How to use:** start from the ordered universal ledger, then use the matching row here for detailed +operator procedure and historical status. Do not work this table top to bottom independently. `Status` values are `⏳ pending`, `🔎 verify` (may already be done — confirm before repeating), `✅ done`, `—` (n/a). Update the row (and its runbook) when an action lands. The sequenced flow with exact commands and approval gates is [launch-operator-runbook.md](launch-operator-runbook.md); this table is the index. diff --git a/docs/outstanding-issues.md b/docs/outstanding-issues.md index e31b22152..2a40c617c 100644 --- a/docs/outstanding-issues.md +++ b/docs/outstanding-issues.md @@ -1,19 +1,23 @@ # Outstanding Issues, Recommendations & Tasks -Durable, cross-session memory of everything still outstanding for this repo: open **tasks**, -**recommendations** not yet acted on, and **issues** not yet resolved. Chat context is ephemeral -(sessions summarise and reset); this file is not — it is the single source of truth the +This is the repository's single universal task ledger. Its **Open items** table contains only work +that current evidence still supports doing; order, acuity, classification, executor capability, +timing, effort, dependencies, approvals, success criteria, verification and stopping conditions live +on each row. Chat context is ephemeral; this file is the source of truth the [`/issues` skill](../.claude/skills/issues/SKILL.md) reads back and updates. -**Rule of thumb:** if it is worth remembering after this session ends, it belongs here. +Completed, stale, duplicate, superseded, speculative or uneconomic suggestions do not belong in the +active table. Preserve useful provenance in **Resolved / archive** or Git history; do not create +another repository task ledger. ## How this is used -- Say `/issues` in Claude Code → the skill reads this file and states the open items back, - grouped by priority with a one-line summary count. Nothing is mutated on a plain read. +- Say `/issues` in Claude Code → the skill reads this file and states the active rows back in + recommended order with a one-line summary count. Nothing is mutated on a plain read. - `/issues add …`, `/issues done `, `/issues capture`, and friends mutate the tables below. The full command surface lives in the skill file. -- Every mutation keeps this file committed so the memory survives across sessions and worktrees. +- Repository publication is a separate, explicitly authorised Git workflow; editing the ledger does + not itself authorise a commit, push or pull request. ## Conventions @@ -23,53 +27,57 @@ Durable, cross-session memory of everything still outstanding for this repo: ope - **Type**: `task` (a concrete unit of work), `rec` (a recommendation to weigh), or `issue` (a defect / risk / gap). - **Detail / next action** is the smallest thing that would move the item forward. +- **Order** is the recommended sequence. Skip a blocked row and take the next independent ready row. +- **Final classification** must be one of: `Required now`, `Recommended`, `Optional`, + `Defer until dependency is resolved`, `Requires user/operator decision`, or + `Requires provider approval`. +- **Executor** expresses the minimum judgment/authority needed, not a named assignee. +- **Estimate** is active effort. Approval, scheduled-run, legal-review and soak waits are stated + separately in **When**. - **Source** points at where it came from: a doc, a PR (`#123`), a file:line, or `session YYYY-MM-DD`. - Resolving an item moves its row to **Resolved / archive** with the date and a one-line outcome — rows are archived, not deleted, so the history stays auditable. - + ## Open items -> **Merged-main canary update (2026-07-23, run `30018289898`):** the new structured report correctly recorded evaluated tree `c24f2e8f2d30d0c59fc1eba025d3dcd63478137e`, run/attempt identity and `cross-region-runner` latency context. Golden retrieval remained 36/36 with document/content recall 1.0 and no failed cases. The 44-case answer gate had grounded-supported and unsupported-correct rates of 1.0, but failed because `neuroleptic-side-effect-escalation` again returned one citation where two are required (citation-failure rate 0.0227). `admission-discharge-comparison` again omitted the specific AKG admission document after `comparison_source_extractive_fallback`; `admission-discharge-coverage-paraphrase` was advisory-only at 24,870 ms. Answer cost was reported as `$0.234736`. Do not retry immediately: retain this as the first structured datapoint, compare it with the scheduled 2026-07-26 report, and keep retrieval/ranking unchanged. +Only these rows are active. Work from the lowest ready **Order**; skip a blocked row and take the next +independent ready task. Revalidate the cited evidence against current `main` when starting. Inclusion +does not authorise provider access, paid checks, production changes, legal/clinical decisions, commits, +pushes, deployments or pull requests. -> **RAG reconciliation correction (2026-07-23):** fresh current-main live evidence supersedes the broad diagnosis in #018. The three named misses are not one composer defect. Lithium reproduced an unrelated-table retrieval fast-path defect; ADHD still retrieves a relevant chart-heavy CAMHS source but exhausts the extractive route budget; metabolic retrieves the correct AKG source but selects schedule-free prose; #019 remains post-retrieval comparison source selection. A narrow lithium subject-evidence guard improved its targeting result from 0 to 1 with golden recall 1.0 and no reciprocal-rank regressions, but was reverted and rejected because the required full canary failed. Keep #029 open for the remaining fallback-stub cases. Do not combine these residuals or change ranking scores, comparator ordering, aliases, clamps, or semantic reranking without a separate reproducer and passing canary pair. +| ID | Pri | Type | Summary | Detail / next action | Source | Added | Order | Final classification | Executor | When | Estimate | Dependencies / approvals | Success criteria | Verification | Stop condition | +| ---- | --- | ----- | -------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | ---------- | ----: | ---------------------------------- | ----------------------------------------------------------------- | ------------------------------------------------------------------------------ | --------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| #059 | P1 | task | Verify containment of previously exposed credentials | In approved provider dashboards, revoke or rotate any still-valid OpenAI, Supabase service-role/database and E2E credentials previously exposed outside authorised stores; update only the intended secret stores and record status without values. | session 2026-07-24 security reconciliation | 2026-07-24 | 1 | Requires provider approval | Credentialed security/operator owner plus independent reviewer | Immediately in an approved operator window | 1–3 h | Provider owners; correct project/environment identity; secret-store mutation approval | Provider-side evidence shows every old credential is rejected or retired, replacements exist only in intended stores, and affected readiness checks pass. | Approved provider audit/rotation evidence, presence-only local/hosted checks, and secret scanning that never prints values. | Stop before any provider or secret-store action without approval; never paste credentials into Git, logs, issues or chat and do not rewrite history without separate evidence. | +| #052 | P1 | task | Close the APP 8, DPA and ZDR governance position | Have the accountable privacy/legal owners complete the existing OpenAI and Railway checklist, record contract versions, ZDR/project scope, prompt-cache answer, APP 8 basis, dates and owners. | `docs/openai-cross-border-basis.md`; `docs/privacy-impact-assessment.md` PIA-1/PIA-6 | 2026-07-24 | 2 | Requires user/operator decision | Privacy/legal authority plus provider account owner | Now; before processing sensitive production data under an unapproved basis | 2–4 h active; 1–10 business days elapsed | Legal authority; OpenAI/Railway account access; provider contact approval | Signed, dated repository record covers both processors and the chosen controls. | Document review plus approved provider evidence; no API or account action by an agent. | Stop at recorded approval or explicit risk-acceptance; do not invent legal conclusions or change product copy before sign-off. | +| #053 | P1 | task | Verify the publication reviewed-state migration in production | With explicit Supabase approval, prove whether `20260722190000_bind_publication_approval_to_reviewed_state.sql` is present and schema-equivalent; propose a separate forward apply only if absent. | PR #1081; `docs/branch-review-ledger.md`; `supabase/migrations/20260722190000_bind_publication_approval_to_reviewed_state.sql` | 2026-07-24 | 3 | Requires provider approval | Advanced database agent plus credentialed operator/reviewer | As soon as approved; before relying on the publication approval control | 1–2 h | Correct Supabase project identity; read-only provider approval; separate mutation approval if absent | Live migration history and relevant functions, trigger and constraints match the reviewed source. | Approved read-only drift/project checks and captured sanitized evidence; local migration/schema tests remain green. | Stop on wrong project, ambiguous history or unexpected drift; do not repair or apply raw SQL in this task. | +| #030 | P2 | issue | Require distinct evidence for both comparison slots | Add a red unit case proving one wide-tier alias document cannot satisfy both expected files, then make the smallest matcher change so two distinct correct documents pass. | `src/lib/eval-document-matching.ts`; session 2026-07-22 | 2026-07-22 | 4 | Required now | Advanced agent plus independent RAG reviewer | Next local code task | 2–4 h | None; local/offline only | One-document false positive fails; two-document coverage passes; other matcher fixtures are unchanged. | Focused matching/eval tests, then the smallest relevant offline quality gate and `verify:cheap`. | Stop before changing production aliases, retrieval scores, ranking or provider-backed behaviour. | +| #051 | P2 | task | Compare the next structured answer-quality canary | After the scheduled run, compare its content, provider-route, latency and cost classifications with run `30018289898`; record one disposition per difference. | PRs #1095/#1097; run `30018289898` | 2026-07-23 | 5 | Defer until dependency is resolved | Advanced RAG agent plus reviewer | After the 2026-07-26 18:00 UTC scheduled run completes | 1–2 h | Scheduled artifact; explicit GitHub/provider access approval | The second report is classified against the first and either establishes stability or names a narrow follow-up. | Offline report/trend tooling first; approved hosted artifact inspection only after permission. | Stop without an early paid retry; one additional datapoint is not authority for broad tuning. | +| #023 | P3 | task | Disposition the scheduled browser and labelling artifacts | Read the scheduled Firefox/WebKit and irrelevant-at-10 artefacts, then classify each as defect, flake, human decision or no action with evidence. | sessions 2026-07-20/21; `docs/branch-review-ledger.md` convergence notes | 2026-07-21 | 6 | Defer until dependency is resolved | Advanced QA agent plus human reviewer for labels | After the 2026-07-26 scheduled workflows complete | 1–2 h | Scheduled artifacts; explicit GitHub/provider access approval | Every artifact has one evidence-backed disposition and only reproducible defects become new work. | Reproduce locally/offline where possible; inspect hosted artifacts only when approved. | Stop after disposition; do not create work from a single unexplained flake or unapproved clinical label. | +| #019 | P2 | issue | Pin and fix comparison evidence loss in the fallback layer | Build a red fallback-layer unit reproducer from the live admission/discharge source shape; fix only the proven post-generation loss if the canary comparison permits. | run `30018289898`; PR #1096 | 2026-07-21 | 7 | Recommended | Advanced RAG agent plus independent reviewer | After #030 and the #051 comparison | 4–8 h local; hosted validation later | #030; #051; provider approval for behaviour validation | The red reproducer turns green while deterministic ranking/packing and unrelated fallback cases remain unchanged. | Focused fallback tests, offline retrieval/answer gates, `check:production-readiness`; approved post-change canary. | Stop if the loss cannot be reproduced below retrieval, or if benefit requires ranking/alias changes. | +| #018 | P2 | task | Resolve lithium, ADHD and metabolic residuals independently | Create a current-main reproducer for one mechanism at a time; assess a bounded retrieval-fast-path, extractive-budget or schedule-selection change in separate work. | runs `30007833352`/`30009207429`; PR #1093 | 2026-07-21 | 8 | Defer until dependency is resolved | Advanced RAG agent plus clinical/RAG reviewer | After #051 and #019 | 0.5–1 day per mechanism | Stable canary; current reproducer; provider approval for behaviour checks | Each accepted slice improves its named case without golden recall/MRR or per-case regression. | Focused local tests and offline gates; approved baseline/post canary pair per behaviour slice. | Stop a slice without measured benefit; never combine the three mechanisms or revive the archived guard wholesale. | +| #029 | P2 | issue | Rebaseline remaining fallback-stub cases on current main | Re-run the existing dump only after canary stability, count current fallback-stub outputs, separate already-covered mechanisms, and retain only reproducible actionable cases. | run #61 artifact; session 2026-07-22 | 2026-07-22 | 9 | Defer until dependency is resolved | Advanced RAG agent plus clinical reviewer | After #051, #019 and the first #018 slice | 2–4 h analysis; fixes estimated separately | Stable canary; explicit provider/spend approval for a fresh dump | A current baseline replaces the stale `12/30` claim and every retained case maps to a named mechanism/test. | Offline artifact analysis first; approved answer-eval dump only when necessary. | Stop if the current baseline no longer reproduces the claim; do not start a broad composer rewrite. | +| #022 | P2 | task | Complete the source-governance decision and highest-value reviews | Decide the BMJ published-reference attestation policy, then review the 21 genuine local WA sources by visibility, beginning with the current highest-impact tranche. | `docs/source-governance-refresh-worklist-2026-07-22.md`; runs #61/#57 | 2026-07-21 | 10 | Requires user/operator decision | Clinical governance authority plus credentialed database operator | After #052 policy alignment; may run independently of code | 1–2 h decision; 1–3 days review | Clinical authority; approved database access; defined tranche | BMJ policy is recorded and the agreed local tranche has dated reviewer/status evidence. | Worklist burn-down and approved read-only governance report; mutation verification only under separate approval. | Stop at the agreed tranche; do not infer 38 individual BMJ reviews or add blanket ranking weights. | +| #025 | P2 | task | Activate the retained webhook paths safely | Follow `docs/webhooks.md` one path at a time: configure only approved secrets and endpoints, verify fail-closed behaviour first, then send one controlled non-sensitive event per retained path. | PRs #968/#1100/#1101; `docs/webhooks.md` | 2026-07-22 | 11 | Requires provider approval | Credentialed operator plus security/reliability reviewer | In an explicitly approved provider window | 1–3 h | Correct Railway/GitHub/Supabase targets; provider and secret-store approval | Each retained path is configured in the intended environments, delivers one sanitized event, rejects invalid authentication, and has an owned destination. | Local configuration/readiness checks first; approved provider-state inspection and one controlled non-PHI delivery per path. | Stop before reading or changing secret values without approval; stop on target ambiguity, duplicate destinations or unsafe payloads. | +| #054 | P2 | task | Verify environment secret and configuration parity safely | Compare required variable presence and non-secret fingerprints across production, staging and CI; record missing/mismatched names without printing values. | `docs/operator-backlog.md`; `docs/deployment-architecture.md`; `docs/privacy-impact-assessment.md` PIA-2 | 2026-07-24 | 12 | Requires provider approval | Credentialed operator plus security reviewer | Before the next release or provider/config change | 1–2 h | Railway/GitHub/Supabase approval as applicable; correct environment identity | Required names are present in intended environments, intentionally environment-specific values are documented, and true parity gaps have owners. | Local env-name/parity checks plus approved provider-side presence/fingerprint evidence and boot/readiness proof. | Stop before reading, rotating, copying or replacing secret values; verification is not mutation authority. | +| #007 | P3 | rec | Establish one canonical Tools entry point | Obtain the product choice, route navigation consistently to it, and keep or remove aliases only with explicit redirect/reachability coverage. | `src/app/tools/page.tsx`; `src/app/applications/route.ts`; `tests/route-reachability.test.ts` | 2026-07-21 | 13 | Recommended | Product owner plus standard agent | After higher-impact local work, or as a small isolated task | 1–3 h after decision | Product choice; Next.js route guide before code change | One canonical in-app destination exists and retained aliases have intentional tested behaviour. | Focused route/reachability tests, sitemap update/check, `ensure`, browser QA and `verify:ui` as appropriate. | Stop at Tools routing; do not fold the unrelated `/api/jobs` question or redesign the launcher. | +| #055 | P3 | task | Choose and wire one owned alert destination | Choose a single channel and connect only the retained deploy, CI, SLO and deep-health sources, with ownership and escalation expectations. | `docs/operator-backlog.md`; `docs/observability-slos.md`; `.github/workflows/ops-digest.yml` | 2026-07-24 | 14 | Requires user/operator decision | Operations owner plus standard agent/credentialed operator | After an operator selects the destination | 2–4 h | Product/operations decision; provider and secret-placement approval | Each retained source produces one sanitized test alert and one expected rejection/negative proof in the owned destination. | Local workflow/config checks plus separately approved hosted dispatch/integration proof. | Stop before enabling duplicate channels, exposing payloads or contacting providers without approval. | +| #056 | P3 | task | Prove staging soak, rollback and bounded release readiness | Against one stable release candidate, execute the existing staging soak, rollback rehearsal and release gate once, then store a single evidence set. | `docs/launch-operator-runbook.md`; `docs/capacity-review.md`; `docs/production-readiness-checklist.md` | 2026-07-24 | 15 | Requires provider approval | Advanced release agent plus credentialed operators/reviewer | Before the next material schema/runtime release, not immediately | 2–4 h active; 1–2 days elapsed | Stable candidate; Supabase/Railway/GitHub/OpenAI approval; spend ceiling | Soak meets documented SLOs, rollback is rehearsed, required release gates pass, and failures have an owner/disposition. | Existing local readiness checks first; approved staging/provider workflows and captured artifact checksums. | Stop after one unchanged-candidate evidence set; do not repeat paid gates or deploy production as part of verification. | +| #057 | P3 | task | Verify catalogue data before any production seed | Run approved read-only counts/representative queries for registry, differentials and medications; seed only a dataset proven absent under a separate mutation approval. | `docs/operator-backlog.md`; `docs/launch-operator-runbook.md` §6 | 2026-07-24 | 16 | Requires provider approval | Credentialed database operator plus product reviewer | After #054 and before relying on catalogue surfaces | 1–2 h read-only; 2–4 h only if an approved seed is needed | Correct project; read approval; separate write approval and reviewed source data | Each surface is non-empty and representative, or a precisely scoped missing dataset is documented and safely seeded. | Approved read-only counts/UI smoke; if separately authorised, idempotent seed verification and rollback evidence. | Existing valid data means stop with no mutation; never seed speculatively or overwrite production data. | +| #001 | P2 | task | Reconsider semantic reranking only for measured ambiguity benefit | Keep the flag off unless a concrete ambiguity fixture and stable baseline justify an approved canary pair. | `docs/process-hardening.md`; PR #901 | 2026-07-21 | 17 | Defer until dependency is resolved | Advanced RAG agent plus independent RAG reviewer | Only after #051 is stable and an ambiguity failure is demonstrated | 1–2 days plus canary pair | Stable canary; concrete fixture; explicit user/provider/spend approval | 36/36 retrieval recall, no per-case regression, and a material ambiguity improvement are all recorded. | Offline ambiguity/golden tests plus approved baseline/post canary pair. | Any missing gate or neutral/regressive result means leave `RAG_SEMANTIC_RERANK_ENABLED=false` and close the experiment. | +| #011 | P3 | task | Change Auth allocation immediately before compute scale-up | At the first approved vertical scale, replace the fixed GoTrue DB connection cap with the reviewed percentage and observe staging before production. | `docs/auth-connection-cap-runbook.md`; `docs/process-hardening.md` | 2026-07-21 | 18 | Defer until dependency is resolved | Credentialed Supabase operator plus database reviewer | Immediately before the first vertical compute scale-up | 30–60 min plus soak | Approved scale event; Supabase dashboard approval; staging | Percentage setting is visible, staging remains within connection/SLO limits, and the advisor no longer flags the fixed-cap mismatch. | Approved dashboard evidence, staging soak and read-only advisor recheck. | No scale event means no change; stop on pool pressure or advisor regression and roll back per runbook. | +| #017 | P3 | task | Measure field Web Vitals before selecting performance work | Capture representative LCP, INP and CLS for priority production routes and select at most one optimization supported by the measurements. | session 2026-07-21 measurement pass | 2026-07-21 | 19 | Optional | Performance agent plus product reviewer | Only when field performance becomes a product priority | 1–2 h measurement; 1–3 days only for a selected fix | Product priority; approval for live measurement if required | Representative metrics and test conditions are recorded; either metrics are acceptable or one bounded bottleneck is named. | Local lab baseline plus approved production/RUM or Lighthouse evidence; browser verification for any selected change. | Good metrics close the task; do not implement #012–#016 ideas without measured need. | +| #028 | P3 | rec | Decide whether privacy-safe runtime error tracking is worth adding | Compare the operational blind spot with cost, dependency, retention and sensitive-data risks; choose no integration or one tightly scoped provider. | session 2026-07-22 webhook review; `docs/privacy-impact-assessment.md` | 2026-07-22 | 20 | Requires user/operator decision | Product/privacy authority plus operations engineer | When runtime exceptions materially limit diagnosis | 1 h decision; 0.5–1 day if approved | Product/privacy decision; provider/dependency approval; retention/redaction design | A recorded decision names scope, owner, data controls and cost; if adopted, a sanitized exception reaches the owned destination. | Dependency/security review and local redaction tests; approved provider proof only after sign-off. | Stop with a documented no; do not add a provider speculatively or send clinical content. | +| #037 | P3 | rec | Decide whether to cap trust for all supported claims | After governance policy is settled, make a clinical/product decision on the tested all-claims trust-cap flag and rebaseline only if enabled. | `src/lib/answer-render-policy.ts`; PR #1051 | 2026-07-22 | 21 | Requires user/operator decision | Clinical/product authority plus standard agent | After #022 | 30–60 min decision; 2–4 h if adopted | #022; clinical/product approval | The flag's intended state and rationale are recorded; if enabled, UI/answer-policy expectations pass review. | Existing unit tests plus focused answer-render/UI checks and clinical/product sign-off. | Leaving the flag off is a valid completion; do not treat the parked flag as a defect. | +| #010 | P3 | task | Build a coming-soon control only when its feature enters the roadmap | Select one named disabled control, define its product contract, implement and verify that surface without a cross-product sweep. | forms/favourites components cited in the historical snapshot | 2026-07-21 | 22 | Optional | Product owner plus standard agent | Only when a named feature is approved for the roadmap | 0.5–2 days per control | Product scope, UX contract and acceptance criteria | The chosen control is functional and accessible; all unselected placeholders remain honestly disabled. | Focused unit/a11y/browser checks, `ensure`, and `verify:ui` as appropriate. | No approved feature means no work; one control/surface per task. | +| #040 | P3 | rec | Add a small visual baseline set only when manual review is costly | Select high-value desktop/phone states with repeated regression cost, define ownership/update rules, and add only stable comparisons. | design-audit reconciliation, session 2026-07-22 | 2026-07-22 | 23 | Optional | Standard UI agent plus design reviewer | When repeated manual review or a real regression justifies a blocking baseline | 1–2 days | Reviewed baseline ownership; stable environment; product-design approval | Selected comparisons are deterministic, reviewed and low-noise with an intentional update path. | Repeat local Chromium runs at target breakpoints, then the relevant UI gate. | Stop if snapshots remain flaky or ownership is absent; never snapshot every route. | +| #058 | P3 | task | Recreate provider-managed non-schema state after recovery | Use the disaster-recovery checklist to restore schedules, Vault secrets, GUCs, edge functions and dashboard configuration after an actual restore/rehearsal. | `docs/disaster-recovery-runbook.md`; `docs/operator-backlog.md` | 2026-07-24 | 24 | Defer until dependency is resolved | Credentialed recovery operator plus security/database reviewer | Only after an actual restore or approved recovery rehearsal | 2–4 h plus validation | Recovery event; provider approvals; approved secret sources | All required non-schema state is restored, least-privilege checked and validated against the recovered environment. | Runbook checklist, approved provider inspection and application/readiness smoke. | No restore/rehearsal means no action; stop on identity mismatch, missing secret authority or unexplained drift. | -| ID | Pri | Type | Summary | Detail / next action | Source | Added | -| ---- | --- | ----- | --------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | ---------- | -| #051 | P2 | task | Stabilise the live answer-quality canary before more RAG tuning | Diagnostics landed in PR #1095: structured JSON/Markdown artifacts now record the actual checked-out SHA, run identity and latency context, and the offline trend tool separates content, provider-route and latency outcomes. First validating run `30018289898` recorded the expected tree and cost, with 36/36 retrieval green, but one report cannot establish variability; PR #1097 prevents a single failure being mislabeled as repeated. Next: compare the scheduled 2026-07-26 structured report with this run. Do not spend on an immediate retry or reapply the archived lithium guard before that comparison. | PR #1095; run `30018289898`; PR #1097; archive ref `refs/archive/rejected-rag/20260723/monitoring-subject-gate` | 2026-07-23 | -| #001 | P2 | task | Semantic reranking still gated off | `RAG_SEMANTIC_RERANK_ENABLED=false` from PR #901. Do not enable until the provider-backed 36/36 retrieval-quality gate **and** an ambiguity-focused canary are explicitly approved and recorded. | `docs/process-hardening.md` (Semantic reranking rollout debt); PR #901 | 2026-07-21 | -| #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 | -| #010 | P3 | task | Un-built "Coming soon" controls across forms/favourites | ~10 disabled placeholders (forms refine/reset, favourites sort/add/new-set, move-to-set, remove-favourite). Correctly flagged (`aria-disabled` + "Coming soon"), not defects — wire when the underlying features land. | `forms-search-results-page.tsx`; `favourites-hub.tsx`; `favourites-command-library-page.tsx` | 2026-07-21 | -| #011 | P3 | task | Auth DB-connection allocation is operator-only | Supabase Auth (GoTrue) is capped at ~10 absolute DB connections (Supabase perf advisor). Switch to **percentage-based** allocation in the Supabase **dashboard** before the first compute scale-up — **not settable via SQL/MCP** (operator-owned). Verify via a staging soak + an approval-gated read-only advisor re-check. | `docs/auth-connection-cap-runbook.md`; `docs/process-hardening.md` (Known follow-up debts) | 2026-07-21 | -| #012 | P3 | rec | Slim the lazy cross-mode differentials chunk | `cross-mode-differentials.ts` is dynamically imported (correctly code-split **out** of the initial/dashboard bundle — verified), but it pulls the full ~860 KB differentials snapshot (~125 KB gzip lazy chunk) just to build a tiny `{slug,title,clinicalHinge}` + presentations + aliases catalog. A precomputed lightweight index (generator + drift check, like the `specifiers-content` split / medications `fields=index`) would cut that lazy chunk ~5–10×. Not a bundle leak — an M-effort slim. | `src/lib/cross-mode-differentials.ts`; `src/components/clinical-dashboard/cross-mode-links.tsx:150`; session 2026-07-21 (build:analyze) | 2026-07-21 | -| #013 | P3 | rec | Route-chunk + mockup catalogue JSON weight | `build:analyze`: `/specifiers` ships `specifiers-search-index.json` (~180 KB parsed), `/forms` ships `forms-catalog.json` (~132 KB), `/formulation` ships `formulation-content.json` (~52 KB, client-side local search — needs index/full split or a search endpoint, architectural). All route-scoped (not initial bundle). Also `*-mockups.tsx` (~100 KB across chunks) build though `/mockups` 404s in prod — exclude from the prod artifact. | session 2026-07-21 (build:analyze) | 2026-07-21 | -| #014 | P3 | rec | Realize the `next/image` win on signed previews | `next.config` `images` (AVIF + `*.supabase.co` `remotePatterns` pinned to the project host, from #1024) is currently inert — signed document/image previews still render as raw ``. Route them through `next/image` to actually get AVIF + lazy optimization. | #1024; `src/components/clinical-dashboard/signed-image.tsx`; session 2026-07-21 | 2026-07-21 | -| #016 | P3 | rec | "Big but not easy" structural + motion perf | Deferred larger levers: (a) nonce-CSP forces every product route to `ƒ Dynamic` (zero static generation) — evaluate Partial Prerendering / static shells for the static clinical catalogues (DSM/differentials/therapy/specifiers/formulation); (b) sidebar expand/collapse animates `grid-template-columns` (biggest smoothness cost, motion-gated — needs a transform-overlay rethink); (c) Therapy Compass fetches 692 KB / 2.5 MB JSON client-side (defer until interaction + confirm brotli); (d) settings/setup/admin dialogs static-imported into the home chunk (`next/dynamic` them). | session 2026-07-21 (build route table + design audit) | 2026-07-21 | -| #017 | P3 | task | Field Web-Vitals baseline via live Lighthouse | In-sandbox runtime vitals were blocked (prod server hard-requires Supabase secrets; dev-mode CLS measured excellent at 0.00–0.04, content-first pages 0.000). Run Lighthouse against `psychiatry.tools` for real LCP/INP/CLS to prioritize #012–#016 by measured impact rather than reasoning. | session 2026-07-21 (measurement pass) | 2026-07-21 | -| #018 | P2 | task | Split the lithium, ADHD and metabolic residuals by mechanism | Revalidated on current main 2026-07-23: these are not one composer defect. Lithium reproduced an unrelated-table retrieval fast-path defect; ADHD retrieves a relevant chart-heavy CAMHS source but exhausts the extractive route budget; metabolic retrieves the correct AKG source but selects schedule-free prose. The narrow lithium subject-evidence guard improved targeting from 0 to 1 with golden recall 1.0 and no reciprocal-rank regressions, but it was reverted because the full canary failed. After #051 stabilises the canary, add independent current-main reproducers and assess each mechanism separately. Do not widen the matcher or combine these into a broad ranking/composer change. | runs `30007833352` and `30009207429`; PR #1093; session 2026-07-23 | 2026-07-21 | -| #019 | P2 | task | Admission doc dropped after deterministic comparison packing | Reconfirmed on merged-main run `30018289898`: golden retrieval remained 36/36 and retrieved `MHSP.AdmissionCommunityPts.pdf`, but the answer's top five sources retained only `MHSP.Discharge.pdf` after `generation_fallback:generation_quality_failed; comparison_source_extractive_fallback`. PR #1096 replays the live score/order shape and proves deterministic answer ranking plus cross-document packing retain both admission and discharge evidence, so retrieval scores, aliases and comparator ordering are not the fix. Next: create a red fallback-layer unit reproducer using the live source shape; any behavior change still needs the existing baseline and a passing post canary. | run `30018289898`; PR #1096; session 2026-07-23 | 2026-07-21 | -| #021 | P3 | rec | E-3d H2 residual: strong/comparison generation discards | approx. 6 generation attempts per full 44-case run still fail the final quality gate and fall to extractive on strong-route comparison/complex shapes (the designed-conservative outcome). PARKED: weakest cost/benefit on the queue — a wave (approx. $2-4 pair + reviewer cycle) to shave seconds off a few hard cases. Revisit only if latency/waste complaints or a cheaper lever appears. | E-3c design record; runs #59-#61 diagnostics | 2026-07-21 | -| #022 | P2 | task | Source-governance metadata refresh (operator) | **Worklist generated 2026-07-22 ($0, read-only): `docs/source-governance-refresh-worklist-2026-07-22.md`.** Reframed - this is NOT 59 clinical reviews. Of the 124 documents surfacing in canary top results, 59 are review-required, and **38 (64 pct) are the BMJ published-reference tier all sitting at `clinical_validation_status: unverified`** - one attestation-policy decision, not 38 reviews. The remaining 21 are genuine local WA health-service reviews (FSH 7, NMHS 4, CAMHS 3, AKG 2, KEMH 2, RPBG 2, RKPG 1), mostly `document_status: review_due`. Burn-down: top-10 documents clear 44 pct of flagged slots, top-20 clear 66 pct. Next: decide the BMJ attestation policy, then attest local docs by visibility (start `Clozapine Management by GP (NMHS)`, 22 slots at rank 1). | runs #61/#57 Source Governance data; `docs/source-governance-refresh-worklist-2026-07-22.md` | 2026-07-21 | -| #023 | P3 | task | Read Sunday 2026-07-26 scheduled-run artifacts | The 18:00 UTC scheduled runs deliver three free datapoints at once: first full-44 weekly canary (validates the #1044 ANSWER_CASE_LIMIT raise), browser-matrix flake second datapoint (webkit ui-route-coverage now reproduced + root-caused 2026-07-22 → see #024; firefox ui-formulation:91 still awaits a datapoint), and the irrelevant@10 labeling-audit artifact (§3.1 human-decision class). Read all three, then disposition. | sessions 2026-07-20/21; branch-review-ledger convergence notes | 2026-07-21 | -| #024 | P3 | issue | WebKit e2e `_rsc`-prefetch access-control-checks errors | verify:release:offline on `main` ce32fe170 (2026-07-22) reproduced #023's webkit clause: **6/6 deterministic** failures in `tests/ui-route-coverage.spec.ts` (Therapy Compass; DSM home/comparison; Specifier comparison/map; Differential stream), each a `pageerror … ?_rsc=… due to access control checks` on Next.js RSC prefetch — Chromium + Firefox clean. Not merge-blocking (required gate `test:e2e:pr` is chromium-only; the full webkit matrix is advisory/release-time). Most likely a Playwright route-interception × WebKit interaction, not a Safari user defect. Next: decide (a) allow/mock the `_rsc` routes for the `webkit` e2e project, or (b) confirm real Safari impact — before trusting the full-matrix webkit gate at release. NB the 2 other webkit fails (`ui-stress:412`, `ui-universal-search:210`) passed on isolated re-run = true flake. | session 2026-07-22 (verify:release:offline, `main` ce32fe170); refines #023 | 2026-07-22 | -| #025 | P2 | task | Activate the three webhooks (operator secrets) | Merged (#968/#1100) + deployed but inert — verified live: `POST /api/webhooks/railway` returns `503 webhook_not_configured`; the Supabase document-change trigger exists but lacks both activation inputs. To turn on: (1) Railway → set `RAILWAY_WEBHOOK_SECRET` + add the `?token=…` webhook URL; (2) set `SLACK_WEBHOOK_URL`/`DISCORD_WEBHOOK_URL` in BOTH the Railway **app/server env** and **GitHub repo secrets**; (3) set one matching document-change secret in the Railway app env as `SUPABASE_INGESTION_WEBHOOK_SECRET` and in Supabase Vault as `ingestion_webhook_secret`, then set the per-environment database GUC `app.ingestion_webhook_base_url` to the deployed app origin. Each path fails closed until fully configured, so this is pure ops. See `docs/webhooks.md` for verification and rotation. | sessions 2026-07-22/24; PRs #968/#1100; docs/webhooks.md | 2026-07-22 | -| #027 | P3 | rec | External uptime monitor independent of GitHub/Railway | `live-domain-monitor.yml` runs on GitHub's cron, so it won't run in exactly the outage it should catch (Actions or the deploy itself down). Add an off-platform synthetic monitor (UptimeRobot / Better Stack / Checkly) hitting `/api/health` with a webhook alert. Provider setup, not code. | session 2026-07-22 webhook review | 2026-07-22 | -| #028 | P3 | rec | Runtime error tracking (Sentry or similar) | No error tracking in the repo — production exceptions on `psychiatry.tools`, including how often `RAG_PROVIDER_MODE=auto` silently degrades to source-only, are invisible. Weigh adding `@sentry/nextjs` (dependency + DSN secret + instrumentation) vs cost; alert → chat/issue. Provider-backed; needs explicit sign-off before adding the dependency. | session 2026-07-22 webhook review | 2026-07-22 | -| #029 | P2 | issue | 12 of 30 answer-quality cases return the fallback stub | run #61 --dump-answers: 12/30 quality cases emit the source_backed_review_fallback boilerplate with answer_sections: [], all grounded with 4-6 citations. Some still PASS targeting because the stub echoes query keywords (the contraindication/document_lookup matchers need only a keyword), so the targeting metric MASKS the problem for those intents. Superset of #018 — fix in the extractive composer, validate with the provider-backed answer eval. | run #61 dump artifact; session 2026-07-22 | 2026-07-22 | -| #030 | P3 | issue | Wide-tier alias lets one doc satisfy both comparison slots | In src/lib/eval-document-matching.ts, "Admission to Discharge for Mental Health Inpatients" appears in BOTH the AdmissionCommunityPts and Discharge alias lists, so a single document can satisfy both expectedFiles slots and make allHit true — a latent false-pass on admission-discharge cases. Not firing today (that doc is not in the failing top-5) but it would mask a real miss. Tighten the tables so one doc cannot fill both sides. | src/lib/eval-document-matching.ts:32-65; session 2026-07-22 | 2026-07-22 | -| #032 | P3 | rec | Governance ranking weighting: REFUTED, not debt | The source-governance audit (PR #1051) flagged three "gaps": `review_due` carries no ranking penalty, `unknownCurrentnessPenalty` ships at 0, and `selectBestSourceRecommendation` ignores governance metadata. **These are deliberate, measured decisions — do NOT implement them as written.** Blanket metadata boosts/penalties in selection ordering were measured on 2026-07-02 to regress the golden retrieval eval to 16/23 (doc-recall@5 1.0→0.76, mrr 0.75→0.64). Two corpus facts make it unsafe: scores saturate at the clamp so stacked boosts fully override lexical relevance, and the corpus is only partially metadata-enriched while `normalizeSourceMetadata` coerces unenriched docs to `unknown`/`unverified` — so "unknown" ≠ "bad" and blanket weighting swings ranking approx. 0.35 for reasons unrelated to relevance. Even governance-as-tiebreak buried correct unenriched docs (3 designs bisected). Next action: none — treat as a guardrail. If ever revisited, RC8 (source-strength as a _filter_) is the tracked path, gated on `eval:retrieval:quality` 36/36 plus a live canary pair. | PR #118; `docs/rag-behaviour/refuted-approaches.md`; PR #1051 items 4/5/6 | 2026-07-22 | -| #033 | P3 | rec | Source governance metadata absent from the LLM prompt | `buildRagSourceBlock` omits `document_status`, `clinical_validation_status`, and `extraction_quality`, so the model cannot self-caveat during generation and governance is enforced only post-hoc. Generation-surface change: needs `eval:rag` plus `eval:quality --rag-only` (grounded-supported must not drop, citation-failure 0) and explicit approval. Carries the same "unknown ≠ bad" hazard as #032 — on a partially-enriched corpus the model would likely over-caveat correct sources, so design the prompt wording before spending an eval. | `src/lib/rag/rag-source-block.ts:126-198`; PR #1051 audit item 8 | 2026-07-22 | -| #034 | P3 | issue | Answer cache can serve stale governance metadata | `cacheIndexingVersion` derives the version from `updated_at` / `indexed_at` / `index_generation_id`, so a metadata-only `document_status` flip that bumps none of those is invisible to the passive guard. **Already mitigated**: every known status-write path calls `invalidateRagCachesForOwner` or `invalidateRagCachesForDocumentMutation`. Residual risk only — a future write path that omits the invalidator would serve stale governance until TTL. Next action: add a regression test pinning the invalidator call on status-mutating routes (cheaper and safer than touching the protected cache key). | `src/lib/rag/rag-cache.ts:382-438`; PR #1051 audit item 10 | 2026-07-22 | -| #035 | P3 | rec | Threshold-conflict detection covers only 3 params | `detectThresholdDisagreements` checks only ANC, WBC, and platelets paired with withholding verbs, so cross-source conflicts on medication doses, lithium/thyroid levels, or vital signs go undetected. Deliberately narrow (see the comment at `:469-474`). Broadening changes when an answer is classified `conflicting` and adds warnings — real false-positive risk. Needs new fixtures plus a behaviour review before any change. | `src/lib/evidence.ts:469-574`; PR #1051 audit item 7 | 2026-07-22 | -| #036 | P3 | rec | No explicit `is_public` visibility flag on documents | Public-corpus visibility is implicit: `owner_id IS NULL` on an `indexed` document (`resolveSearchScope`). The `metadata.public_corpus` marker is written by the promotion migrations but never used as a retrieval filter. Promotion is unconditional on `clinical_validation_status`, so unverified documents are publicly searchable — compensated by keeping `unverified_source` in the frontend-visible warning set. A hard schema flag touches RLS and the clinical-risk-gated retrieval RPCs; weigh against the existing compensating control before acting. | `supabase/schema.sql:61-108`; `src/lib/search-scope.ts:181-236`; PR #1051 audit item 3 | 2026-07-22 | -| #037 | P3 | rec | D5 trust-cap-all-claims flag parked OFF | `NEXT_PUBLIC_RAG_TRUST_CAP_ALL_CLAIMS` extends authority gating from high-risk claims to **all** supported claims (`deriveTrust`). Ships OFF by design; flipping it caps trust to `medium` for routine claims across the board — a product/clinical-UX decision, not a defect. Both states are test-pinned. Next action: product decision, then flip and re-baseline the UI expectations. | `src/lib/answer-render-policy.ts:159-177`; PR #1051 audit item 11 | 2026-07-22 | -| #038 | P3 | rec | Consolidate shared comparison behavior | Several clinical modes expose comparison workflows with similar selection, empty-state and mobile-dock needs. Define one shared behavioral contract before another comparison surface is added; keep mode-specific clinical content separate. This is a design-system recommendation, not a current defect. | design audit reconciliation; session 2026-07-22 | 2026-07-22 | -| #039 | P3 | rec | Consolidate catalogue toolbar patterns | Catalogue/search pages have independently evolved filter, sort, result-count and mobile toolbar behavior. Inventory the existing implementations and converge only the repeated interaction contract; do not flatten mode-specific search semantics. | design audit reconciliation; session 2026-07-22 | 2026-07-22 | -| #040 | P3 | rec | Add targeted visual-regression baselines | Keep a small approved baseline set for high-value desktop/mobile surfaces and accessibility modes instead of screenshotting every route. Start with account/settings, document viewer, mode homes and bottom-composer interactions; define an intentional-update workflow before enabling blocking comparisons. | design audit reconciliation; session 2026-07-22 | 2026-07-22 | -| #041 | P3 | rec | Extend the existing Factsheets reading model | Do not add a second patient-facing Factsheets mode. Future patient-content work should extend the existing Easy Read/Standard presentation and its accessibility/content contracts. Revisit only with a concrete user need and source-governance plan. | design audit reconciliation; session 2026-07-22 | 2026-07-22 | +## Superseded backlog provenance + +The pre-2026-07-24 open table was removed after evidence-based reconciliation. Git history and the +row-level **Source** fields preserve provenance; completed work remains in **Resolved / archive**. ## Resolved / archive @@ -77,7 +85,7 @@ Move resolved rows here with the resolution date and a one-line outcome. Keep th | ID | Type | Summary | Outcome | Resolved | | ---- | ----- | ---------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | -| #026 | task | Wire the Supabase document-change trigger | PR #1100 merged after disposable PostgreSQL replay and hosted migration replay. Production migration history and read-only catalog proof confirm the enabled metadata trigger, security-definer function, pinned search path and denied anonymous/authenticated execution; `npm run check:drift` reports no unexpected live drift. Delivery remains intentionally inert until the operator inputs tracked in #025 are configured. | 2026-07-24 | +| #026 | task | Wire the Supabase document-change trigger | PR #1100 merged the reviewed trigger and PR #1101 recorded disposable and hosted replay plus production catalog/drift proof. The database object is present; delivery remains intentionally inert until the provider inputs tracked in active #025 are approved and configured. | 2026-07-24 | | #031 | issue | Populate canary Source Governance table | The answer-quality step now consumes the preceding `golden-retrieval.json` only for source-governance reporting. Offline replay of run `30018289898` populated 338 top results, including 202 review-required entries, while retaining zero retrieval cases and no additional threshold failures. Retrieval and ranking behavior are unchanged. | 2026-07-24 | | #020 | task | Validate eval:quality cost readout post-fix | Confirmed on merged-main canary run `30018289898`: Answer Metrics reported 9 nonzero-cost cases and an estimated answer cost of `$0.234736`; the structured report retained the same value. The PR #1050 estimator fix is operationally proven. | 2026-07-23 | | #003 | task | Staging tenancy release evidence outstanding | Ran GitHub Action and validated isolation | 2026-07-21 |