feat(eval): offline golden-set eval harness (Step 5.2) - #133
Merged
officialCodeWork merged 2 commits intoJun 5, 2026
Conversation
Complete the Step 0.8 eval skeleton into a deterministic, offline, CI-stable golden-set eval. A new eval/golden_set_v0 harness drives the real HybridRetriever over a synthetic 5-domain corpus on the noop SPIs (a HashingEmbedder gives the zero-vector dense path real signal, fused with NoopKeywordStore token overlap via RRF) and reports Recall@k / MRR / nDCG@k / Faithfulness / Citation Precision overall + per-domain + per-difficulty, as report.json/md and a self-contained HTML report. - 500-query / 5-domain golden set committed under tests/eval/golden/, generated reproducibly from the corpus and drift-gated. - ndcg_at_k + dependency-free lexical_faithfulness added to rag_config.eval (RAGAS stays optional); render_html_report added. - EvalMetrics/EvalReport gain additive nDCG + by_domain/by_difficulty fields (new GroupEvalMetrics); run_eval defaults unchanged. - ragctl eval run --html + nDCG/per-domain output; eval show per-domain. - harness --check enforces the thresholds.yaml hard-gate floor (regression-delta + baseline commit are Step 5.3). Docs: ADR-0027, reference/eval-harness.md, architecture/golden-set-eval.md. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The agent_loop_v0 harness bulk-indexes into noop SPIs but only escaped the PolicyEngine coverage linter accidentally — a synthetic corpus sentence contains the word "PolicyEngine", tripping the marker exemption. Make the exemption explicit (same benchmarking-tooling rationale as golden_set_v0/corpus.py) so a future edit of that corpus text can't silently fail CI. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Completes the Step 0.8 eval skeleton (stub retrieval, no nDCG, RAGAS-only faithfulness) into a deterministic, offline, CI-stable golden-set eval.
eval/golden_set_v0/harness drives the realHybridRetrieverover a 5-domain synthetic corpus on the noop SPIs.NoopKeywordStorealready ranks by token overlap; a deterministicHashingEmbeddergives the dense path real signal (NoopEmbedderreturns zero vectors), and the two fuse via RRF — no network, no LLM, identical numbers on every OS.tests/eval/golden/, generated reproducibly from the corpus and drift-gated (a test fails if the committed files diverge from the generator). 3 passages/concept so Citation Precision and nDCG aren't degenerate.lexical_faithfulness; RAGAS optional), Citation Precision — reported overall + per-domain + per-difficulty, asreport.json/report.mdand a self-contained HTML report (render_html_report).EvalMetrics/EvalReportgain defaulted nDCG +by_domain/by_difficulty(newGroupEvalMetrics);run_eval's defaults are unchanged so the Step 0.8 contract + tests hold.python -m eval.golden_set_v0.harness [--domain/--queries/--k/--check];ragctl eval run --html+ nDCG/per-domain output;eval showper-domain.--checkenforces thethresholds.yamlhard-gate floor now; the regression-delta comparison + committedbaselines/main.json+ PR-comment workflow are Step 5.3.Default full run: recall@10 0.91 · mrr 0.88 · nDCG@10 0.86 · faithfulness 0.93 · citation precision 0.27 — clearing the 0.70/0.60/0.80 floors, with real per-domain (0.82–0.98) and easy>medium>hard spread.
Documentation
docs/adr/ADR-0027-offline-eval-harness.md— decisions (synthetic corpus on noop SPIs, dependency-free lexical faithfulness vs RAGAS, committed+drift-gated golden set, harness ineval/notrag_config).docs/reference/eval-harness.md— public API: metrics, golden-set format, harness +ragctl evalusage,EvalReportshape, extension points.docs/architecture/golden-set-eval.md— design/internals: why noop backends give a real signal, corpus/golden-set co-design, metric edge cases, relationship to Step 5.3, reviewer checklist.docs/README.md,TRACKER.md(5.2 ✅, Phase 5 → 2/7, 59/84, next = 5.3),CLAUDE.mdupdated.Test plan
ruff check .+ruff format --check .cleanmypy --strict packages/ apps/gateway/— no issues (278 files)python -m eval.golden_set_v0.generate --checkup to datepython -m eval.golden_set_v0.harness --checkpasses the threshold floor🤖 Generated with Claude Code