Harden the eval-canary safeguards: per-case rr diff, dispatch failure issues, contract pins - #1843
Conversation
… issues, contract pins Review of the RAG canary infrastructure (2026-08-12) found the mechanism sound but with manual/silent gaps. This change mechanizes and pins them; no retrieval behaviour changes. - compare-retrieval-eval: new per-case rr@10/contentRR@10 diff with --fail-on-regression, mechanizing the canary-pair protocol's 'zero per-case rr regressions' gate that was previously eyeballed from tee'd logs; fails closed on summary-only artifacts and non-identical case sets. - eval-canary.yml: open the failure issue on failed dispatches too (a red dispatch is usually half a canary pair), and feed answer-targeting.log, validate_override and answer_targeting outcomes into the issue body. - build-ranking-snapshot: fail loudly when a hardNegativeTemplates caseId matches no artifact case (a renamed golden case previously dropped its hard negatives silently); CLI guarded so tests can import convertArtifact. - New contract tests: hard-negative attachment guard, and a strict/wide alias-tier pin so a bulk merge of src/lib/eval-document-matching.ts into scripts/lib/clinical-aliases.ts can no longer pass CI. - docs/rag-behaviour: fix stale claims that the canary has workflow_dispatch / a ref input (both deliberately absent); document the per-case compare command. - outstanding-issues: capture the snapshot-freshness dispatch handoff (#304) and deferred canary observations (#305). RAG impact: no retrieval behaviour change — canary tooling, docs, and contract-test hardening only; golden fixture and ranking code untouched. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UoHPMZ1FinSYzH7rJ42xTo
This pull request has been ignored for the connected project Preview Branches by Supabase. |
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UoHPMZ1FinSYzH7rJ42xTo
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in:7 minutes 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 (6)
📝 WalkthroughWalkthroughThe PR changes eval-canary failure reporting and dispatch rules. It adds hard-negative snapshot validation and per-case retrieval regression checks. Tests cover workflow diagnostics, snapshot cases, ranking comparisons, and clinical alias tiering. Documentation records safeguards and follow-up issues. ChangesEval canary validation
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant RepositoryDispatch
participant EvalCanaryWorkflow
participant CompareRetrievalEval
participant FailureIssue
RepositoryDispatch->>EvalCanaryWorkflow: start default-branch canary
EvalCanaryWorkflow->>CompareRetrievalEval: compare JSON evaluation artifacts
CompareRetrievalEval-->>EvalCanaryWorkflow: report regressions and case-set differences
EvalCanaryWorkflow->>FailureIssue: create or update failure issue with diagnostics
Possibly related PRs
🚥 Pre-merge checks | ✅ 2 | ❌ 3❌ Failed checks (3 warnings)
✅ Passed checks (2 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Comment |
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit:bcf357a96f
ℹ️ 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".
Uh oh!
There was an error while loading. Please reload this page.
BigSimmo
commented
Aug 12, 2026
@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. The only repository destination is BigSimmo/Database, and the only branch destination is the pull request head branch claude/rag-canary-test-review-seprbt at starting commit a462ab5; never publish fixes to a detached or synthetic work branch and never create a stacked pull request. Use the authenticated GitHub connector to commit each approved fix to BigSimmo/Database:claude/rag-canary-test-review-seprbt, then verify that the pull request head contains the published commit before reporting success. 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. For a fixed thread, reply with as the first line and as the second line. For a no-code disposition, use followed by . These result markers authorize the workflow to close that exact thread only after it verifies a fixed commit is the pull request head; a local-only commit is not a fix. If publication or verification fails, do not use either result marker, do not claim success, and leave the thread open with the blocker. If human input or new authorization is required, do the same. 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. |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 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 @.github/workflows/eval-canary.yml:
- Around line 200-203: Update the “Open or update canary failure issue” step to
guard the dynamic import of productivity-core.mjs, falling back to a fixed
diagnosis derived from recorded step outcomes when checkout or the analyzer is
unavailable. Preserve the existing analyzer-based diagnosis when the import
succeeds, and ensure the fallback still reaches the issue creation or comment
update calls.
In `@scripts/compare-retrieval-eval.ts`:
- Around line 155-165: Update the per-case comparison around readCaseRank so
absent or non-finite baseline/candidate metrics are recorded as non-comparable
instead of skipped, allowing the gate to fail closed rather than reporting zero
regressions. Update the --fail-on-regression condition around the final result
handling to fail when either missingInCandidate or missingInBaseline is
non-empty, and add tests covering both incomplete metric comparisons and
candidate-only case IDs.
🪄 Autofix
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: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: ef92f7c1-4cb6-4624-ab6e-05feee95b074
📒 Files selected for processing (11)
.github/workflows/eval-canary.ymldocs/branch-review-ledger.mddocs/outstanding-issues.mddocs/rag-behaviour/README.mddocs/rag-behaviour/safeguards.mdscripts/build-ranking-snapshot.tsscripts/compare-retrieval-eval.tstests/build-ranking-snapshot.test.tstests/clinical-aliases-tiering.test.tstests/compare-retrieval-eval.test.tstests/eval-canary-workflow.test.ts
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Codex Review: Didn't find any major issues. 🎉 Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
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". |
There was a problem hiding this comment.
Pull request overview
This PR hardens the repo’s eval-canary safeguards and related RAG evaluation tooling by mechanizing previously manual checks (per-case RR diffs), improving failure reporting for canary runs (including dispatch runs), and adding contract tests/docs to prevent silent drift—without changing retrieval/ranking behavior.
Changes:
- Add per-case
rr@10/contentRR@10comparisons (with a fail-closed mode) to enforce “zero per-case regressions” mechanically. - Improve eval-canary failure issue creation/update to include dispatched runs, additional logs, and step outcome context.
- Add contract tests and snapshot-building guards to prevent silent fixture/template drift; update docs and ledgers accordingly.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
tests/eval-canary-workflow.test.ts | Extends workflow contract coverage to assert dispatch failures also open issues and include more diagnostic context. |
tests/compare-retrieval-eval.test.ts | Adds unit coverage for the new per-case rank comparison helper. |
tests/clinical-aliases-tiering.test.ts | Pins strict alias-tier keysets to prevent accidental widening of golden-eval ground truth. |
tests/build-ranking-snapshot.test.ts | Adds tests ensuring hard-negative templates attach and that orphan templates fail loudly. |
scripts/compare-retrieval-eval.ts | Implements per-case RR comparison and --fail-on-regression gate behavior. |
scripts/build-ranking-snapshot.ts | Exports convertArtifact, adds orphan hard-negative template guard, and prevents CLI execution on import. |
docs/rag-behaviour/safeguards.md | Updates canary-pair protocol to reflect dispatch-only triggering and the new per-case comparison command. |
docs/rag-behaviour/README.md | Corrects stale claims about how eval-canary is triggered and what it can run against. |
docs/outstanding-issues.md | Captures new operational follow-ups (#304/#305) and bumps issues:next-id. |
docs/branch-review-ledger.md | Records this review/work as a ledger entry. |
.github/workflows/eval-canary.yml | Opens/updates failure issues for scheduled and dispatched runs and includes additional logs + step outcomes. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
…t-review-seprbt # Conflicts: # docs/outstanding-issues.md
…e analyzer import Review fixes for PR #1843 (sentry, codex, coderabbit, copilot all converged on the first item): - compare-retrieval-eval --fail-on-regression now fails on candidate-only cases (missingInBaseline) and on absent/non-finite per-case rank metrics, not just baseline-only cases — a superset candidate could previously pass the identical-case-set gate. CLI-level exit-code tests added. - eval-canary.yml failure-issue step falls back to a fixed diagnosis when the analyzer import fails (e.g. checkout failed), so a red dispatch still opens an issue. - safeguards.md: canary compare command moved to a fenced block so it copy/pastes intact. RAG impact: no retrieval behaviour change — eval tooling and workflow only. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UoHPMZ1FinSYzH7rJ42xTo
Uh oh!
There was an error while loading. Please reload this page.
The Codex auto-resolve pass pushed its own version of the PR #1843 review fixes after the PR had already merged with the same fixes in ea357ca (which main now carries in stronger form: separate unavailableMetrics channel and CLI exit-code tests). Content is taken wholly from the current branch; 5ef02f7 is kept in history only so the branch can push without a rewrite. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UoHPMZ1FinSYzH7rJ42xTo
Summary
docs/rag-behaviour/) and found the mechanism sound but with manual and silent gaps; this PR mechanizes and pins them without changing any retrieval behaviour.scripts/compare-retrieval-eval.ts: new per-caserr@10/contentRR@10comparison with a--fail-on-regressionflag, mechanizing the canary-pair protocol's "zero per-case rr regressions" gate that previously depended on eyeballing two tee'd logs. It fails closed on summary-only artifacts and on non-identical case sets, and prints each regression asREGRESSION <case> <metric>: <baseline> -> <candidate>..github/workflows/eval-canary.yml: the failure issue now opens for failedrepository_dispatchruns too (a red dispatch is usually half of a canary pair gating a behaviour change and previously failed silently); the issue body now also includesanswer-targeting.logand thevalidate_override/answer_targetingstep outcomes, and distinguishes weekly from dispatched runs.scripts/build-ranking-snapshot.ts: fails loudly when ahardNegativeTemplatescaseIdmatches no artifact case — previously a renamed golden case silently dropped its hard negatives. The CLI entry is now guarded so tests can importconvertArtifact.tests/build-ranking-snapshot.test.ts(hard-negative attachment + orphan guard) andtests/clinical-aliases-tiering.test.ts(pins the strict alias-tier key sets so a bulk merge of the wide tier insrc/lib/eval-document-matching.tsintoscripts/lib/clinical-aliases.tscan no longer pass CI — previously comment-enforced only).docs/rag-behaviour/README.md+safeguards.md: corrected stale claims that the canary runs viaworkflow_dispatchor arefdispatch input (both are deliberately absent and asserted absent bytests/eval-canary-workflow.test.ts); the pair protocol now documents the per-case compare command and that post runs are post-merge only.docs/outstanding-issues.md: captured the snapshot-freshness handoff (Remove Evidence-based and All sources chips from answer footer #304 — the ranking snapshot dated 2026-07-20 trips the 30-day gate ~2026-08-19 and needs an operator-senteval-canaryrepository dispatch to regenerate) and deferred canary observations (fix(db): repair Supabase Preview migration replay failures #305 — no latency-mode coverage, cost readout is a lower bound, concurrency-group pair straddling).RAG impact: no retrieval behaviour change — canary tooling, workflow failure reporting, documentation corrections, and contract-test hardening only; the golden fixture, ranking code, comparator chains, and alias tables are byte-identical.
Verification
npm run verify:pr-local— routed fail-closed to the heavy path; all static gates, lint, and typecheck passed; unit suite1 failed | 6082 passed | 4 skippedwhere the single failure is the pre-existing environmental root-container case tracked as ledger#296(tests/pr-handoff-stop.test.ts, reproduced on a clean checkout previously; CI runners are non-root and unaffected).npm run eval:rag:offline—Offline RAG fixture and production-contract checks passed.(23 files, 574 tests).tests/compare-retrieval-eval.test.ts,tests/eval-canary-workflow.test.ts,tests/build-ranking-snapshot.test.ts,tests/clinical-aliases-tiering.test.ts, plus untouched guardstests/ranking-tuning.test.tsandtests/rag-imputation-contract.test.ts— 6 files, 40 tests, all passed.REGRESSION a reciprocalRankAt10: 1.0000 -> 0.3300and exits 1; an identical pair printszero per-case rr regressionsand exits 0.npm run eval:retrieval:qualitynot run: retrieval, ranking, selection, chunking, and scoring behaviour are untouched (tooling/docs/tests only); the source-pin contract test and offline RAG fixture checks above are green and unchanged.Risk and rollout
repository_dispatch.Clinical Governance Preflight
Clinical KB Database(sjrfecxgysukkwxsowpy)Notes
tests/ranking-tuning.test.ts) starts failing the whole unit suite around 2026-08-19. The refresh is approved but blocked on an operator-sent dispatch:gh api repos/bigsimmo/database/dispatches -f event_type=eval-canary, then regenerate withnpm run build:ranking-snapshot -- --input <golden-retrieval.json> --output scripts/fixtures/rag-ranking-candidate-snapshot.v1.json --source-run-id <run-id>. Full handoff recorded as ledger#304.🤖 Generated with Claude Code
https://claude.ai/code/session_01UoHPMZ1FinSYzH7rJ42xTo
Generated by Claude Code
Summary by CodeRabbit
New Features
Bug Fixes
Documentation
Tests