feat(rag): budget-aware generation deadlines + retrieval-exhausted telemetry (Phase E-3b)#1028
Conversation
…lemetry (E-3b core) Implements the E-3b design: generation attempts are clamped to the route budget minus a measured 2s recovery reserve (single call-site covers all four attempt kinds); the truncation self-heal is gated on retry viability (reserve + 5s floor) with an observable truncation_retry_skipped_budget_reserve marker instead of a guaranteed-discard retry; the runtime records an additive route_budget_exhausted_by_retrieval flag; and the eval route-ceiling gate gains the triple-condition cross-region carve-out (context + runtime flag + zero generation) with a retrieval-exhausted audit cell - local/release gates stay strict, pinned by new unit tests. Unit coverage: route-budget 9/9 (constants + reserve/floor boundaries), eval-quality 27/27 (carve-out matrix). Integration tests for the fallback paths follow in the next commit. RAG impact: no retrieval behaviour change - answer-side timing/gating and telemetry only; retrieval, ranking, selection, comparators untouched. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EXsJcLrbZUXwnBeG91cVo9
…l gate, retrieval-exhausted flag Five fake-timer integration tests: the reserve-aware timeout is pinned three independent ways (exact 23000ms grant, deadline flag stays clear, total under budget - a revert to requestTimeoutMs fails all three); the truncation self-heal skip pins the exact answer_retry_reasons marker with no retry-count increment and provider called once; the offline harness pins route_budget_exhausted_by_retrieval both true (13s retrieval on a 12s extractive budget, provider never called, grounded extractive answer) and false (fast retrieval). 52/52 across both files. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EXsJcLrbZUXwnBeG91cVo9
…VE-WITH-NITS) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EXsJcLrbZUXwnBeG91cVo9
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EXsJcLrbZUXwnBeG91cVo9
|
This pull request has been ignored for the connected project Preview Branches by Supabase. |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughThe RAG route budget reserves recovery time for generation fallback, gates truncation retries, records retrieval-attributed exhaustion, and updates cross-region evaluation diagnostics with a specific deadline carve-out and status. ChangesBudget-aware RAG generation
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant RAG
participant RouteDeadline
participant OpenAI
participant ExtractiveFallback
RAG->>RouteDeadline: calculate reserve-aware timeout
RouteDeadline-->>RAG: return generation timeout
RAG->>OpenAI: request structured answer
OpenAI-->>RAG: return truncated answer
RAG->>RouteDeadline: check retry budget
RouteDeadline-->>RAG: allow or deny retry
RAG->>ExtractiveFallback: use source-backed recovery when denied
Suggested labels: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
…ity budget Static-pr caught rag.ts at 5033 lines vs the 5030 no-growth budget - the E-3b additions tipped the tracked monolith over its cap. Rationale comments live in rag-route-budget.ts and the design record; the rag.ts copies shrink to one-liners (comments only, zero logic change - suites re-verified). The real extraction debt stays tracked in the maturity audit. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EXsJcLrbZUXwnBeG91cVo9
There was a problem hiding this comment.
🧹 Nitpick comments (1)
tests/rag-answer-fallback.test.ts (1)
2979-3118: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDuplicate
waSourcefixture helper.The
waSourcebuilder insidelithiumTruncatedGenerationAnswer(lines 2988-3007) duplicates the existing top-levelwaSourcehelper (~line 1785) verbatim. Consider hoisting one shared helper to avoid the two copies drifting apart over time.🤖 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 `@tests/rag-answer-fallback.test.ts` around lines 2979 - 3118, Remove the locally defined waSource helper from lithiumTruncatedGenerationAnswer and reuse the existing top-level waSource fixture helper near the other lithium tests. Preserve the current source construction and publisher-specific metadata behavior while eliminating the duplicate definition.
🤖 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 `@tests/rag-answer-fallback.test.ts`:
- Around line 2979-3118: Remove the locally defined waSource helper from
lithiumTruncatedGenerationAnswer and reuse the existing top-level waSource
fixture helper near the other lithium tests. Preserve the current source
construction and publisher-specific metadata behavior while eliminating the
duplicate definition.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: ad83614d-7ba1-4d42-8f4d-0bc086a36dad
📒 Files selected for processing (9)
docs/branch-review-ledger.mdscripts/eval-quality.tssrc/lib/rag/rag-route-budget.tssrc/lib/rag/rag.tssrc/lib/types.tstests/eval-quality.test.tstests/rag-answer-fallback.test.tstests/rag-offline-answer.test.tstests/rag-route-budget.test.ts
Summary
Phase E-3b of the approved plan — fixes the three measured latency/waste defects from baseline run #57 and live telemetry (issues I3, I5, I2):
route budget − 2,000ms recovery reserve. The reserve is measured, not guessed (recovery costs 26–100ms locally, ≤1s cross-region). Replaying the run-#57 agitation failure: the attempt now times out with ~2.4s to spare and the source-backed recovery lands inside budget instead of 54ms over.truncation_retry_skipped_budget_reservemarker inanswer_retry_reasons— and the existing source-backed recovery delivers. Kills the live 82s-wastedmax_output_tokensclass.route_budget_exhausted_by_retrievalflag, and the eval suppresses the route-ceiling only when cross-region context AND the runtime flag AND zero generation time all hold. Local/release gates provably unchanged (pinned by tests); suppressed cases stay auditable via aretrieval-exhaustedreport cell.Both reviewer subagents ran pre-push, zero P0/P1/P2:
fallback_reason, neveranswer_retry_reasons), and the cached-replay invariant proven: budget-exhausted answers are never cached, so the carve-out is unreachable via replay. 2 P3 nits (prod-deadrequestTimeoutMsretained for symmetry; cosmetic report-cell coupling).PublicApiError→ existing fallback; never the abort re-throw); claim-support, numeric verification, final quality gate, and source-only fallback all still applied to recovery answers; telemetry additions carry no PHI.Also banked in the ledger: the run #58 targeting baseline (relevance 0.6; targeting 0.59 with dose 1/5 and monitoring 1/5 — the E-3c targets).
RAG impact: no retrieval behaviour change — answer-side timing/gating and telemetry only; retrieval, ranking, selection, and comparators untouched (adversarially verified by the retrieval reviewer).
Verification
npm run test— 3043 passed / 1 known container-only pdf-budget artifact / 3 skippednpm run typecheck,npm run lint, prettier — cleanRisk and rollout
generation_fallback:provider_timeoutrate and the new skip marker. No new failure modes: every new branch terminates on a pre-existing path.Clinical Governance Preflight
Clinical KB Database(sjrfecxgysukkwxsowpy) — no schema/config/data changes🤖 Generated with Claude Code
https://claude.ai/code/session_01EXsJcLrbZUXwnBeG91cVo9
Generated by Claude Code
Summary by CodeRabbit
Bug Fixes
Diagnostics
Tests