Skip to content

fix(rag): recover grounded source-backed canary answers#603

Merged
BigSimmo merged 5 commits into
mainfrom
codex/rag-canary-recovery
Jul 13, 2026
Merged

fix(rag): recover grounded source-backed canary answers#603
BigSimmo merged 5 commits into
mainfrom
codex/rag-canary-recovery

Conversation

@BigSimmo

@BigSimmo BigSimmo commented Jul 13, 2026

Copy link
Copy Markdown
Owner

Summary

  • Follow up on the post-merge PR fix(rag): require co-located medication evidence #581 canary failure without changing retrieval weights or weakening unsupported behavior.
  • Distinguish document retrieval class from answer intent so natural clinical-content questions select responsive requirements rather than related-policy references.
  • Recover only strong_routine_retrieval document-content answers whose deterministic candidate passes the existing final quality, citation, claim-support, and numeric gates; retrieval-blocked recoveries remain visibly low-trust.
  • Run clinical-value verification after claim assessment so values are checked against their mapped supporting chunks. Comparison values may use their already-attributed matrix sources collectively; ordinary and high-risk claims remain strictly co-located and fail closed.

Touched areas: src/lib/rag.ts, src/lib/rag-extractive-answer.ts, src/lib/answer-verification.ts, and focused RAG trust/fallback tests.

Verification

  • npm run verify:pr-local — not run locally because the shared node_modules junction predates main's new @axe-core/playwright dependency; clean hosted CI will install the committed lockfile.
  • node scripts/run-vitest.mjs run tests/answer-verification.test.ts tests/rag-trust.test.ts tests/rag-answer-fallback.test.ts tests/rag-claim-support.test.ts tests/retrieval-query-variants.test.ts tests/rag-variant-early-exit.test.ts --reporter=dot — 6 files, 190 tests passed on current main.
  • npm run eval:rag:offline — 36 fixture schemas; 21 files and 267 tests passed on current main.
  • Targeted ESLint with --max-warnings 0 — passed for all five changed files.
  • Targeted Prettier --check — passed for all five changed files.
  • npm run eval:retrieval:quality — no retrieval-weight or ranking change; the prior live run for fix(rag): require co-located medication evidence #581 was 36/36 and exposed only answer-quality/latency failures.
  • npm run eval:rag -- --limit 15 + npm run eval:quality -- --rag-only — branch canary required before merge. One authorized single-case retry hit its 240-second provider/backoff timeout and produced no result; it was not repeated.
  • npm run check:production-readiness — run with production secrets after merge/deployment if the branch canary and required CI pass.
  • npm run verify:ui — not applicable; no UI/routing/styling changes.
  • npm run verify:release — deferred until CI/canary completion.

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: this is a conservative answer-validation/fallback correction, not a new clinical capability

Notes

  • Root cause evidence: canary run 29251155102 retrieved every expected source but refused six routine answers and raised two false numeric warnings on the extractive agitation case.
  • No migration, backfill, ranking-weight change, live data mutation, or secret/config change is included.
  • Merge only after required CI and a new branch canary pass.

Summary by CodeRabbit

  • New Features

    • Added a validated fallback for certain routine document-content questions, providing direct extractive answers when model-based generation is unnecessary.
    • Improved document-routed safety-plan responses to prioritize directly relevant requirements and supporting evidence.
  • Bug Fixes

    • Improved numeric claim verification across multiple citations to reduce unsupported-number warnings.
    • Refined document lookup detection to avoid overly broad routing.
    • Expanded evidence matching for general questions and improved handling of source-backed clinical answers.

BigSimmo added 2 commits July 13, 2026 22:53
Use validated deterministic recovery for routine document-content queries and scope clinical-value checks to claim-supporting citations. Focused RAG safety tests and the offline RAG contract pass.
@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

📝 Walkthrough

Walkthrough

RAG answer finalization now supports claim-scoped numeric verification, document lookup intent is narrowed, and blocked routine document retrievals can use validated extractive recovery. Tests cover numeric grounding, source selection, routing outcomes, and model bypass behavior.

Changes

RAG quality and routing

Layer / File(s) Summary
Answer intent and finalization
src/lib/rag-extractive-answer.ts, tests/rag-trust.test.ts
Document lookup detection and general intent evidence matching are updated; finalization defers numeric verification and preserves validated direct-requirement content.
Claim-scoped numeric verification
src/lib/answer-verification.ts, tests/rag-trust.test.ts, tests/rag-answer-fallback.test.ts
Clinical numeric claims are checked against their supporting chunks, with the previous answer and section citation fallback retained when no claim-scoped numeric atoms exist.
Validated routine extractive recovery
src/lib/rag.ts, tests/rag-answer-fallback.test.ts
Blocked routine document retrievals can be routed to extractive answers after grounding, citation, confidence, and quality checks; gate-passed cases continue to model synthesis.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

  • BigSimmo/Database#438: Overlaps in RAG routing, extractive handling, and grounding enforcement.
  • BigSimmo/Database#510: Overlaps in numeric verification and the evidence sources used to calculate unverified tokens.

Sequence Diagram(s)

sequenceDiagram
  participant RAGAnswerFlow
  participant RetrievalDiagnostics
  participant buildExtractiveAnswer
  participant finalizeRagAnswerQuality
  RAGAnswerFlow->>RetrievalDiagnostics: inspect blocked routine retrieval
  RAGAnswerFlow->>buildExtractiveAnswer: build extractive candidate
  buildExtractiveAnswer->>finalizeRagAnswerQuality: finalize candidate
  finalizeRagAnswerQuality-->>RAGAnswerFlow: return grounded candidate
  RAGAnswerFlow->>RAGAnswerFlow: select extractive route before confidence gating
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately reflects the main change: recovering grounded canary answers in RAG.
Description check ✅ Passed The description follows the required template and includes Summary, Verification, Clinical Governance Preflight, and Notes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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/rag-canary-recovery

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

@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: 5638931fdb

ℹ️ 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.

Preserve model synthesis for gate-passed routine document queries while retaining validated extractive recovery for blocked low-signal cases. Focused tests, ESLint, and Prettier pass.
@BigSimmo
BigSimmo enabled auto-merge (squash) July 13, 2026 15:21
@BigSimmo

Copy link
Copy Markdown
Owner Author

@copilot resolve the merge conflicts in this pull request

@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: c0eb3e7aa1

ℹ️ 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-extractive-answer.ts
…very

# Conflicts:
#	src/lib/answer-verification.ts

Copilot AI commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

@copilot resolve the merge conflicts in this pull request

Resolved on b2d0764 and pushed. The branch now merges main, keeps the lexical-score retrieval fix/tests from main, and preserves the claim-scoped numeric verification behavior in src/lib/answer-verification.ts.

@BigSimmo
BigSimmo merged commit 1b5ec7f into main Jul 13, 2026
16 checks passed
Copilot stopped work on behalf of BigSimmo due to an error July 13, 2026 15:33

@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: e476df734d

ℹ️ 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".

const claimScopedValues = (answer.supportedClaims ?? []).filter(
(claim) => extractClinicalValueAtoms(claim.text).length > 0,
);
if (claimScopedValues.length > 0) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Verify raw sections even when claim-scoped values exist

When any supported claim contains a clinical value, this branch skips the previous raw answer/section scan and only verifies values that made it into supportedClaims. claimInputs derives those claims via splitClaims, which drops short snippets under eight characters, so a model section like Maximum dose: 500 mg (body 500 mg) can bypass numeric faithfulness whenever another longer supported numeric claim is present; before this change every section body was scanned directly. Please keep the claim-scoped check but also scan answer/section text for clinical value atoms that were not covered by a claim.

Useful? React with 👍 / 👎.

@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.

🧹 Nitpick comments (2)
src/lib/rag-extractive-answer.ts (1)

335-352: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Duplicated evidence regex between answerIntentEvidencePattern default and factSupportsAnswerIntent general branch.

The default-intent regex here (Lines 350) is copy-pasted verbatim into factSupportsAnswerIntent's general/default branch (Lines 743-745). Since both lists gate what counts as "general" clinical evidence, any future tuning of one without the other will silently desynchronize evidence-pattern matching from fact-support filtering.

♻️ Extract a shared constant
+const GENERAL_INTENT_EVIDENCE_PATTERN =
+  /\b(?:assess|arrange|check|collaborat\w*|complete|conduct|continue|develop|diagnos\w*|document|dose|ensure|identify|include|incorporate|involve|link|manage|monitor|provide|record|refer|revise|review\w*|risk|share|therapy|treat|update)\b/i;
+
 function answerIntentEvidencePattern(intent: AnswerIntent) {
   switch (intent) {
     ...
     default:
-      return /\b(?:assess|arrange|check|...)\b/i;
+      return GENERAL_INTENT_EVIDENCE_PATTERN;
   }
 }

Then reuse GENERAL_INTENT_EVIDENCE_PATTERN at Line 743-745.

🤖 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-extractive-answer.ts` around lines 335 - 352, Extract the default
regex from answerIntentEvidencePattern into a shared
GENERAL_INTENT_EVIDENCE_PATTERN constant, then return or reuse that constant for
the default case. Update factSupportsAnswerIntent’s general/default branch to
use the same constant, preserving the existing matching behavior while
eliminating the duplicated pattern.
src/lib/rag.ts (1)

916-961: 🚀 Performance & Scalability | 🔵 Trivial | 🏗️ Heavy lift

Trial candidate duplicates the full extractive build+finalize pass that runs again for the real answer.

hasValidatedRoutineExtractiveRecovery calls buildExtractiveAnswer + finalizeRagAnswerQuality purely to validate; when it returns true, the extractive branch at Lines 4463-4538 rebuilds the same buildExtractiveAnswer (with fuller metadata) and calls finalizeRagAnswerQuality again — meaning fact synthesis, citation compaction, memory-card ranking, claim-support assessment, and numeric verification each run twice for exactly the queries this PR is designed to recover (i.e. this is expected to become a real, non-rare path). Since relatedDocuments isn't resolved yet at validation time, fully caching/reusing the trial candidate would require restructuring the async ordering; a smaller win is available now: the outer-scope quoteCards (Line 4166) is already computed by validation time and could be passed in here instead of [] to avoid one extra extractQuoteCards call.

🤖 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 916 - 961, Update
hasValidatedRoutineExtractiveRecovery to accept the already-computed outer-scope
quoteCards and pass them into its buildExtractiveAnswer call instead of creating
an empty list. Update every invocation to provide quoteCards, preserving the
existing validation flow while eliminating the duplicate extractQuoteCards work.
🤖 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.

Nitpick comments:
In `@src/lib/rag-extractive-answer.ts`:
- Around line 335-352: Extract the default regex from
answerIntentEvidencePattern into a shared GENERAL_INTENT_EVIDENCE_PATTERN
constant, then return or reuse that constant for the default case. Update
factSupportsAnswerIntent’s general/default branch to use the same constant,
preserving the existing matching behavior while eliminating the duplicated
pattern.

In `@src/lib/rag.ts`:
- Around line 916-961: Update hasValidatedRoutineExtractiveRecovery to accept
the already-computed outer-scope quoteCards and pass them into its
buildExtractiveAnswer call instead of creating an empty list. Update every
invocation to provide quoteCards, preserving the existing validation flow while
eliminating the duplicate extractQuoteCards work.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: aaf7f029-58c8-4203-9ea3-f920314691c1

📥 Commits

Reviewing files that changed from the base of the PR and between ce99cbc and e476df7.

📒 Files selected for processing (5)
  • src/lib/answer-verification.ts
  • src/lib/rag-extractive-answer.ts
  • src/lib/rag.ts
  • tests/rag-answer-fallback.test.ts
  • tests/rag-trust.test.ts

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.

2 participants