Skip to content

Fix lithium answer recovery and Australian source fallback#607

Merged
BigSimmo merged 20 commits into
mainfrom
codex/lithium-answer-recovery-pr
Jul 13, 2026
Merged

Fix lithium answer recovery and Australian source fallback#607
BigSimmo merged 20 commits into
mainfrom
codex/lithium-answer-recovery-pr

Conversation

@BigSimmo

@BigSimmo BigSimmo commented Jul 13, 2026

Copy link
Copy Markdown
Owner

Summary

  • recover a grounded, cited answer when OpenAI generation fails or times out instead of returning the generic finalization failure shown for Lithium dosing
  • prioritise verified WA and Australian sources through a shared authority registry and conservative supplementary-source fallback
  • expose a public-safe, detailed answer progress lifecycle through retrieval, ranking, generation, retry, fallback, verification, and completion
  • harden source-locality audit/backfill tooling so registry projections and parent-folder names cannot create unsafe metadata proposals

Verification

  • npm run verify:pr-local
    • 1,988 tests passed, 1 skipped
    • production build and client-bundle secret scan passed
    • 36 offline retrieval fixtures and 267 offline RAG contract tests passed
  • npm run verify:ui when UI, routing, styling, browser behavior, reduced-motion, or forced-colors behavior changed
    • focused progress flow passed 2/2 and critical Chromium passed 9/9
    • the aggregate run lost the repo server during an unrelated overlap case; that isolated case passed after restart
  • npm run verify:release before release or handoff confidence claims
    • not run: deployment is out of scope and the gate would exceed the bounded provider authorization
  • npm run eval:retrieval:quality (must stay 36/36) when retrieval, ranking, selection, chunking, or scoring behavior changed
    • not run: requires a broader live-key evaluation; offline retrieval remained 36/36
  • npm run eval:rag -- --limit 15 + npm run eval:quality -- --rag-only when answer generation, the synthesis prompt, or answer post-processing changed
    • not run: would exceed the authorised single live query
    • one uncached live Lithium dosing evaluation passed with a grounded FSH citation, no generic failure, no invalid citations, no unverified numeric tokens, no authority conflict, and no threshold failures; generation timed out and the new source-backed fallback completed
  • npm run check:production-readiness when clinical workflow, privacy, environment, Supabase, source governance, or deployment behavior changed
    • READY, 5/5 checks passed
  • npm run check:deployment-readiness when deployment startup, hosting, or rollout behavior changed
    • not applicable; no deployment behavior changed

Clinical Governance Preflight

  • Source-backed claims still require linked source verification before clinical use
  • No patient-identifiable document workflow was introduced or expanded without explicit governance approval
  • Supabase target remains Clinical KB Database (sjrfecxgysukkwxsowpy)
  • Service-role keys and private document access remain server-only
  • Demo/synthetic content remains clearly separated from real clinical sources
  • Source metadata, review status, and outdated/unknown-source behavior remain conservative
  • Deployment classification/TGA SaMD impact was checked when clinical decision-support behavior changed
    • no intended-use or autonomous decision-support expansion; this is reliability, source-selection, and progress feedback hardening

Notes

  • Read-only live governance audit: 2,851 indexed rows; 2,065 clinical documents; 786 registry projections correctly excluded; 0 required metadata gaps; 0 authority conflicts; 0 locality proposals.
  • Independent locality-only backfill dry-run also found 0 changes. No production metadata write was made.
  • Highest residual risk is provider latency: the bounded live generation path took 40.7 seconds before fallback. Users now receive detailed progress and a grounded source-backed answer instead of an unanswered state.
  • Virtual merge against current origin/main completed cleanly. This PR does not deploy or merge anything.

Summary by CodeRabbit

  • New Features

    • Added a structured answer-progress stepper showing retrieval, ranking, generation, fallback, and verification stages.
    • Added elapsed-time tracking, processing details, and clearer completion states during answer generation.
    • Improved Australian clinical source selection, prioritizing authoritative Australian and WA evidence.
    • Added safer extractive recovery when generated answers are incomplete, with stronger numeric verification and source citations.
  • Bug Fixes

    • Prevented duplicate completion events and ensured completion consistently appears before final answers.
    • Improved handling of invalid or incomplete streaming responses and stale progress states.

@supabase

supabase Bot commented Jul 13, 2026

Copy link
Copy Markdown

This pull request has been ignored for the connected project sjrfecxgysukkwxsowpy because there are no changes detected in supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 4ab184e0-0087-42d3-a141-bdc5ff994b25

📥 Commits

Reviewing files that changed from the base of the PR and between 6f5162d and 5bc19c6.

📒 Files selected for processing (7)
  • docs/branch-review-ledger.md
  • src/app/api/answer/stream/route.ts
  • src/components/ClinicalDashboard.tsx
  • src/components/clinical-dashboard/answer-status.tsx
  • src/lib/rag.ts
  • tests/private-access-routes.test.ts
  • tests/rag-answer-fallback.test.ts
🚧 Files skipped from review as they are similar to previous changes (7)
  • src/app/api/answer/stream/route.ts
  • tests/rag-answer-fallback.test.ts
  • docs/branch-review-ledger.md
  • src/components/clinical-dashboard/answer-status.tsx
  • tests/private-access-routes.test.ts
  • src/components/ClinicalDashboard.tsx
  • src/lib/rag.ts

📝 Walkthrough

Walkthrough

The PR adds source-authority governance and locality tooling, prioritizes Australian clinical context, hardens generation fallback and caching, and standardizes answer-progress SSE events with a staged dashboard UI and expanded evaluation and integration tests.

Changes

Answer governance and recovery

Layer / File(s) Summary
Source authority registry and audit tooling
docs/branch-review-ledger.md, scripts/*source*metadata.ts, scripts/audit-source-governance.ts, src/lib/source-authority-*, src/lib/source-metadata.ts, tests/source-*
Adds authority classification, locality inference and auditing, constrained locality patches, CLI parsing, governance reporting, and registry-backed tests.
Australian retrieval and fallback recovery
src/lib/australian-source-priority.ts, src/lib/rag-context-selection.ts, src/lib/rag.ts, tests/rag-answer-fallback.test.ts, tests/rag-context-budget.test.ts
Ranks Australian evidence, changes high-risk context selection, centralizes fallback artifacts, verifies extractive recovery, and restricts fallback caching.
Public progress streaming and dashboard stepper
src/lib/answer-progress-public.ts, src/app/api/answer/stream/route.ts, src/components/ClinicalDashboard.tsx, src/components/clinical-dashboard/*, tests/answer-progress*, tests/private-access-routes.test.ts
Shapes public progress DTOs, emits one completion before final responses, buffers invalid completions, and renders timed staged progress.
Australian evaluation diagnostics
src/lib/rag-eval-diagnostics.ts, scripts/eval-rag.ts, scripts/eval-utils.ts, tests/rag-eval-source-governance.test.ts, tests/eval-utils.test.ts
Reports Australian source and progress diagnostics, captures successful-attempt progress during retries, and evaluates governance failures and warnings.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant SearchResults
  participant RAG
  participant AnswerStream
  participant ClinicalDashboard
  SearchResults->>RAG: rank and select Australian context
  RAG->>AnswerStream: emit progress and answer result
  AnswerStream->>ClinicalDashboard: send public progress and final SSE events
  ClinicalDashboard->>ClinicalDashboard: render timed progress stepper
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 13.41% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: lithium answer recovery plus Australian source fallback.
Description check ✅ Passed The description follows the template with Summary, Verification, Clinical Governance Preflight, and Notes, and includes detailed results.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/lithium-answer-recovery-pr

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
src/lib/rag.ts (1)

4866-4872: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Defer fallback-only artifact generation until the catch path. generationFallbackArtifacts and generationFallbackSelectionSummary are only read inside the catch block, but they’re computed on every request. Moving them into the fallback path would avoid the quote extraction, breakdown, coverage, and score-explanation work on successful generations.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib/rag.ts` around lines 4866 - 4872, Move the computations of
generationFallbackArtifacts and generationFallbackSelectionSummary from the main
request path into the catch-based fallback path where they are consumed. Keep
generationFallbackResults available to that path, and preserve the existing
fallback artifact and selection-summary behavior while avoiding this work for
successful generations.
scripts/backfill-source-metadata.ts (2)

684-692: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Audit summary logs unbounded document arrays.

authorityAudit embeds full conflicts, missing_australian_locality, and proposed_locality_corrections arrays (one entry per flagged document, with title/file_name/etc.) directly into the console-logged summary, with no sampling. The legacy dry-run path below caps its sample at 20 items; this locality-only path — which runs across the whole corpus — has no equivalent cap and can produce a very large log dump as the document count grows.

♻️ Suggested fix: cap the emitted arrays
   const summary = {
     mode: args.apply ? "apply" : "dry-run",
     scope: "locality-only",
     allowed_metadata_keys: ["publisher_code", "publisher", "jurisdiction"],
     documents_seen: documents.length,
     documents_with_changes: changed.length,
-    ...authorityAudit,
+    ...authorityAudit,
+    conflicts: authorityAudit.conflicts.slice(0, 20),
+    missing_australian_locality: authorityAudit.missing_australian_locality.slice(0, 20),
+    proposed_locality_corrections: authorityAudit.proposed_locality_corrections.slice(0, 20),
   };
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/backfill-source-metadata.ts` around lines 684 - 692, Cap the
document-level arrays emitted through authorityAudit in the summary logged by
the locality-only backfill path. Apply the existing 20-item sampling convention
used by the legacy dry-run path to conflicts, missing_australian_locality, and
proposed_locality_corrections while preserving the aggregate counts and other
summary fields.

676-763: 🩺 Stability & Availability | 🔵 Trivial | 🏗️ Heavy lift

No test coverage for the gated write path (runLocalityOnlyBackfill/main).

Existing tests only cover parseBackfillSourceMetadataArgs and static source-content assertions on the script; the actual --apply --confirm write flow (RPC call, patch validation, per-document error handling) is untested. This is exactly the class of database-write code the guidelines call out for careful regression/rollback-safety review.

Consider extracting a thin, injectable supabase (already parameterized) and adding a unit test that mocks rpc("apply_document_metadata_patch", ...) to confirm: patches are only sent for !unresolvedConflict documents, assertLocalityMetadataPatch rejects disallowed keys before any RPC call, and a single RPC failure surfaces a clear error without silently continuing.

As per coding guidelines, "For high-risk code involving authentication, authorization, private data, database access, clinical output, ingestion, provider calls, billing, uploads, or background jobs, review carefully for regressions, missing tests, rollback safety, and conservative failure behavior."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/backfill-source-metadata.ts` around lines 676 - 763, Add unit
coverage for the apply path in runLocalityOnlyBackfill, using its injected
supabase client and invoking it through the --apply --confirm flow in main where
appropriate. Mock rpc("apply_document_metadata_patch", ...) to verify only
non-conflicting documents produce validated patches, disallowed metadata keys
are rejected before any RPC call, and the first RPC error is surfaced with the
document context without continuing.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@scripts/eval-rag.ts`:
- Around line 237-251: Reset or recreate the progress collection inside each
callback attempt passed to withProviderBackoff, so buildRagEvaluationDiagnostics
receives only events from the attempt that produced the final answer. Update the
surrounding answerQuestionWithScope flow while preserving the existing progress
event handling and diagnostics construction.

---

Nitpick comments:
In `@scripts/backfill-source-metadata.ts`:
- Around line 684-692: Cap the document-level arrays emitted through
authorityAudit in the summary logged by the locality-only backfill path. Apply
the existing 20-item sampling convention used by the legacy dry-run path to
conflicts, missing_australian_locality, and proposed_locality_corrections while
preserving the aggregate counts and other summary fields.
- Around line 676-763: Add unit coverage for the apply path in
runLocalityOnlyBackfill, using its injected supabase client and invoking it
through the --apply --confirm flow in main where appropriate. Mock
rpc("apply_document_metadata_patch", ...) to verify only non-conflicting
documents produce validated patches, disallowed metadata keys are rejected
before any RPC call, and the first RPC error is surfaced with the document
context without continuing.

In `@src/lib/rag.ts`:
- Around line 4866-4872: Move the computations of generationFallbackArtifacts
and generationFallbackSelectionSummary from the main request path into the
catch-based fallback path where they are consumed. Keep
generationFallbackResults available to that path, and preserve the existing
fallback artifact and selection-summary behavior while avoiding this work for
successful generations.
🪄 Autofix (Beta)

❌ Autofix failed (check again to retry)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 06b7b2e3-3d0e-4d79-a251-5597a38a1b1b

📥 Commits

Reviewing files that changed from the base of the PR and between 5098fe3 and 2476d24.

📒 Files selected for processing (24)
  • docs/branch-review-ledger.md
  • scripts/audit-source-governance.ts
  • scripts/backfill-source-metadata.ts
  • scripts/eval-rag.ts
  • src/app/api/answer/stream/route.ts
  • src/components/ClinicalDashboard.tsx
  • src/components/clinical-dashboard/answer-progress.ts
  • src/components/clinical-dashboard/answer-status.tsx
  • src/lib/answer-progress-public.ts
  • src/lib/australian-source-priority.ts
  • src/lib/rag-context-selection.ts
  • src/lib/rag-eval-diagnostics.ts
  • src/lib/rag.ts
  • src/lib/source-authority-metadata.ts
  • src/lib/source-authority-registry.ts
  • src/lib/source-metadata.ts
  • tests/answer-progress-ui-smoke.spec.ts
  • tests/answer-progress.test.ts
  • tests/private-access-routes.test.ts
  • tests/rag-answer-fallback.test.ts
  • tests/rag-context-budget.test.ts
  • tests/rag-eval-source-governance.test.ts
  • tests/source-authority-tooling.test.ts
  • tests/source-metadata.test.ts

Comment thread scripts/eval-rag.ts Outdated
Keep eval progress scoped to the successful provider attempt, bound locality audit output, and cover the metadata apply path. Verified with focused tests, verify:cheap, and production readiness.
coderabbitai[bot]
coderabbitai Bot previously approved these changes Jul 13, 2026
Keep deterministic dose and threshold recovery scoped to evidence cited by the final answer, including after the updated claim-scoped numeric verifier from main.
@github-actions

github-actions Bot commented Jul 13, 2026

Copy link
Copy Markdown

CI triage

CI failed on this PR. Automated classification of the 3 failed job(s):

  • Buildpossible known flake: UI/Playwright job; check tests/flake-ledger.json (tests/ui-smoke.spec.ts, tests/ui-smoke.spec.ts, tests/ui-tools.spec.ts, tests/ui-tools.spec.ts) and re-run before bisecting.
  • Static PR checksneeds investigation.
  • PR requiredpossible known flake: UI/Playwright job; check tests/flake-ledger.json (tests/ui-smoke.spec.ts, tests/ui-smoke.spec.ts, tests/ui-tools.spec.ts, tests/ui-tools.spec.ts) and re-run before bisecting.

Heuristic only — a main-side or flake label is a starting point, not a verdict.

BigSimmo added 5 commits July 14, 2026 00:23
When generation fails, keep deterministic dose and threshold recovery scoped to one complete evidence chunk instead of stitching figures across sources.
…recovery-pr

# Conflicts:
#	src/app/api/answer/stream/route.ts
…' into codex/lithium-answer-recovery-pr

# Conflicts:
#	src/lib/rag.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 43a385d207

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/lib/rag.ts
@github-actions

Copy link
Copy Markdown

@codex resolve actionable Codex review findings for this pull request and current head using the repository instructions. This is the pull request's single automatic repair pass: do not perform a fresh review, create new standalone findings, or request another review. Work only the existing unresolved Codex threads on the current head. Always fix P0 and P1 findings. For P2 and lower findings, fix only clear, scoped, low-risk issues; otherwise disposition them with a concise reason. After fixing or dispositioning a thread, reply in that thread with as the first line, followed by a concise summary; that marker authorizes the workflow to close that exact thread. If human input or new authorization is required, do not use the marker and leave the thread open with the blocker. Finish only after every actionable thread is fixed or dispositioned and closed, or explicitly left open for a human decision. Do not update the branch from main, address unrelated reviews, broaden scope, or create more than one scoped fix commit. Do not use external APIs, paid services, credentials, dependency changes, or broad refactors unless explicitly authorized. Add targeted tests where behavior changes and run the narrowest relevant validation.

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

@BigSimmo
BigSimmo enabled auto-merge (squash) July 13, 2026 16:40
@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Note

Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.

Autofix skipped. No unresolved CodeRabbit review comments with fix instructions found.

BigSimmo added 4 commits July 14, 2026 00:50
Keep the filtered fallback candidate at the RagAnswer boundary so current TypeScript inference accepts the single-source recovery assignment.
…' into codex/lithium-answer-recovery-pr

# Conflicts:
#	src/lib/rag.ts
@BigSimmo
BigSimmo merged commit a2fc61b into main Jul 13, 2026
16 checks passed
@BigSimmo
BigSimmo deleted the codex/lithium-answer-recovery-pr branch July 14, 2026 11:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant