fix(rag): recover fast-route final-gate source gaps extractively (packet S1d) - #2054
Conversation
…ket S1d) A hedged, cited, low-confidence fast answer whose body matches the finalizer's broad gap-like regex used to collapse into a citation-free evidence_gap (final_quality_gate:provider_source_gap) with no recovery, while the identical failure shape caught in the generation loop or the outer generation-fallback catch rebuilds a source-backed extractive answer — model phrasing alone chose the branch (canary 32038751592 red vs 32039841070 green on identical retrieval). finalizeRagAnswerQualityCore's gap conversion now first attempts the same source-backed extractive recovery (recoverFinalGateGapExtractively) when the route was fast + strong_routine_retrieval and answer-input results exist, validated by the existing isSafeExtractiveFallbackCandidate battery and stamped with the established generation_fallback / source_backed_extractive_fallback markers plus final_quality_gate_source_backed_recovery:<reason>. Empty-retrieval, strong-route, comparison, and dose/threshold gaps stay terminal and are now pinned by tests. No rag.ts change (4362-line budget untouched). Also queues an inbox cancellation for the pending S1d ledger add from PR #2048 (a done request cannot fingerprint a not-yet-reconciled row) and documents the recovery in docs/rag-behaviour/behaviour-map.md §7. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S5QKovS1ZhbZA5kETfQoaR
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in:43 minutes Limit details: You’ve used all 1 included review currently available under your plan. You completed 96 included PR reviews in the past 7 days; at that activity level, included reviews refill at 1 review per hour. Your organization has reached its usage spending cap. Adjust your spending cap in the billing tab. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (7)
Comment |
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S5QKovS1ZhbZA5kETfQoaR
This pull request has been ignored for the connected project Preview Branches by Supabase. |
…-gap-recovery-dxgrn2 # Conflicts: # docs/rag-improvement/HANDOVER.md
…-gap-recovery-dxgrn2 # Conflicts: # docs/rag-improvement/HANDOVER.md
…-gap-recovery-dxgrn2 # Conflicts: # docs/rag-improvement/HANDOVER.md
CI triageCI failed on this PR. Automated classification of the 2 failed job(s):
Compared with main CI run #11609 (success). Classification is evidence routing, not permission to ignore a failure. Exact quarantined Playwright identities remain governed by the flake ledger. |
Uh oh!
There was an error while loading. Please reload this page.
Summary
docs/rag-improvement/HANDOVER.md§3): a hedged, cited,confidence:"low", grounded fast-route answer whose lead missesproviderSourceGapLeadPatternbut whose body matches the finalizer's broad gap-like regex used to be converted byfinalizeRagAnswerQualityCoreinto a citation-freeevidence_gap(final_quality_gate:provider_source_gap) with no extractive recovery, while the same failure shape caught in the generation loop or the outer generation-fallback catch recovers to a source-backed extractive answer. Model phrasing alone chose the branch: the post-S1b canary run 32038751592 failedsummary-discharge-guidanceon the citation-free branch (grounded false, 0 citations), while re-run 32039841070 and 3/3 cache-bypassed live probes on identical retrieval (36/36, live index unchanged) took the extractive branch (grounded, 4 citations).src/lib/rag/rag-extractive-answer.ts: new private helperrecoverFinalGateGapExtractivelyruns at the top of the gap-conversion branch. When the answer isroutingMode:"fast", itsroutingReasoncarriesstrong_routine_retrieval,answer.sourcesis non-empty, and the query class is notcomparison/medication_dose_risk/table_threshold, it rebuilds a deterministic source-backed answer with the in-filebuildExtractiveAnswerfrom the answer-carried artifacts, rebuilds the smart API plan for the extractive route, and ships it only if it passes the existingisSafeExtractiveFallbackCandidatevalidation battery (grounded, cited, zero unverified numeric tokens, not a bare cross-reference). Any gate or validation failure returns null and the citation-free gap ships exactly as before.generation_fallback:provider_source_gap; source_backed_extractive_fallback) plus the in-file recovery markerfinal_quality_gate_source_backed_recovery:provider_source_gap, and deliberately does not carry the terminalfinal_quality_gate:token, so recovered and terminal outcomes stay distinguishable inrag_queries.modelUsedis cleared soapplyProviderLabelslabels itsource_onlywithdegradedMode.active, matching the existing recovery paths.evidence_gap. The dose/threshold exclusion is deliberately stricter than the outer catch's comparison-only gate because that path pairs those classes with dedicated single-chunk candidate handling (never stitch dose/threshold figures across chunks), which a finalizer-local multi-chunk rebuild would bypass.docs/rag-behaviour/behaviour-map.md§7 describing the new recovery and its terminal exclusions;docs/rag-improvement/HANDOVER.md§2 S1d status row updated in this PR.docs/outstanding-issues-inbox/776405e0-c2d9-4dec-b688-e26c22143f04.json). Anpm run issues:donerequest cannot be produced yet because the S1d add has not been reconciled into the canonical ledger (done requests fingerprint the canonical row), so the supported cancellation mechanism prevents a stale open row from materializing; if the cancellation loses the race to an earlier reconcile, the reconcile reports it and the materialized row should then be closed withissues:doneciting this PR.RAG impact: behaviour change — canary pair 32039841070 (e6ad0d5, latest green baseline) -> post-merge dispatch (owner-approved, requested below). Non-inferiority argument: the change only widens recovery to a validated path that already exists on two adjacent branches (in-loop fast-failure recovery and the outer generation-fallback catch), whose selection today is decided by model phrasing alone on identical retrieval; every recovered answer must pass the same extractive validation battery those paths use; anything failing validation degrades to today's exact citation-free gap; retrieval, ranking, routing, and all terminal gap classes are untouched.
Verification
npm run verify:pr-local— exit 0, heavy scope:completed: check:runtime, check:installed-lock-parity, format:changed, lint, typecheck, test, build, eval:rag:offline, check:medication-interactions, check:medication-lexicon-report — failed: (none) — not reached: (none)npm run eval:rag:offline—Test Files 25 passed (25),Tests 604 passed (604),Offline RAG fixture and production-contract checks passed.npm run check:rag:fixtures—Offline RAG fixture and manifest validation passed (36 golden cases, 25 suites).npx vitest run tests/extractive-answer-formatting.test.ts tests/rag-answer-fallback.test.ts—Tests 227 passed (227)including the six new S1d tests; adjacent suitestests/rag-trust.test.ts tests/source-backed-recovery-cross-reference.test.ts tests/rag-extractive-procedural-artifact.test.ts tests/rag-generation-failure-diagnostics.test.ts tests/rag-imputation-contract.test.ts—Tests 91 passed (91).src/lib/rag/rag-extractive-answer.tsdiff stashed, the two new recovery tests fail (Tests 2 failed | 225 skipped); with the diff restored, all pass.npm run check:maintainability-budgets—Maintainability hotspot budgets passed.(src/lib/rag/rag.tsuntouched at its 4362-line budget; all changes live inrag-extractive-answer.ts, which has no budget entry.)npm run check:production-readiness— code checks PASS (Node runtime, query-hash boot guard); the two FAILs areMissing server env config: NEXT_PUBLIC_SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEYandMissing OPENAI_API_KEY, the documented provider capability gap of this offline cloud session (no.env.local/secrets), not a regression of this diff.npm run eval:retrieval:qualityand the live canary dispatch — provider-backed and owner-approval-gated; retrieval/ranking/selection are untouched by this diff, and the required live canary pair is requested post-merge perdocs/rag-behaviour/safeguards.md(baseline run 32039841070 one6ad0d5db-> post-mergeeval-canarydispatch).npm run verify:ui— no UI, routing, or styling change.Risk and rollout
evidence_gap; every recovered answer passes the existingisSafeExtractiveFallbackCandidatebattery (grounded, cited, zero unverified numeric tokens, no bare cross-reference), and any failure returns the branch to today's exact terminal gap. Recursion terminates structurally: the rebuilt candidate isroutingMode:"extractive", which cannot re-enter the fast-gated recovery. Strong-route, empty-retrieval, comparison, and dose/threshold gaps are pinned unchanged by new tests.Clinical Governance Preflight
Clinical KB Database(sjrfecxgysukkwxsowpy)Notes
eval-canaryrun and compare against baseline run 32039841070 (e6ad0d5db) withnpm run eval:retrieval:compare -- <baseline.json> <post.json> --fail-on-regression; the failing casesummary-discharge-guidanceshould now take the recovered extractive branch deterministically.docs/branch-review-ledgerrecord appended for this branch head underdocs/branch-review-records/.🤖 Generated with Claude Code
https://claude.ai/code/session_01S5QKovS1ZhbZA5kETfQoaR
Generated by Claude Code