fix(bench): debug fixture meta — eval_turns point at canonical answers (#687) - #727
Conversation
#687) debugging_session_001.meta.json eval_turns flipped from [8,10,12,14] (user-prompt indices, expected=user_question_text) to [9,11,13,15] (assistant-continuation indices, expected=canonical answer). Mirrors the analogous hot_start fixture patch shipped under PR #639 / #687. Without this, substring scoring always missed and the LLM judge was asked to compare candidate answers against user questions — the speech-act split that drove inter-judge κ=0.0 on the prior hot_start single-judge run. With the patch, the judge prompt compares answer-against-answer; the κ artifact for #687 now reports κ=1.0 inter-judge agreement with hot_start fidelity 1.0 at trigger_threshold ≤ 0.6. No code change. Tests/test_context_rebuilder_eval_harness_wiring.py already asserts the hot_start eval_turns shape; the debug fixture shape isn't asserted anywhere so no test edit needed.
There was a problem hiding this comment.
Sorry @robotrocketscience, you have reached your weekly rate limit of 500000 diff characters.
Please try again later or upgrade to continue using Sourcery
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughUpdated eval_turns indices from ChangesFixture metadata alignment
Estimated code review effort🎯 1 (Trivial) | ⏱️ ~2 minutes Possibly related issues
Suggested labels
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
approved LGTM |
|
merge-train: merged 0cc251f → |
Summary
Closes #687 and unblocks #592.
Two-part change for the v3.0 release gate:
Code: flip
debugging_session_001.meta.jsoneval_turnsfrom[8, 10, 12, 14](user-prompt indices,expected = user_question_text) to[9, 11, 13, 15](assistant-continuation indices,expected = canonical answer). Mirrors PR feat(eval-harness): hot_start synthetic fixture (#592) #639's analogous fix to thehot_startfixture.Bench artifact for eval-harness: Cohen's-κ judge calibration before #592 close #687 calibration (run on the patched corpus, posted below as the closing evidence). Bench artifacts remain uncommitted per project policy.
Why
Without the fixture-meta flip, the LLM judge was being asked to compare candidate answers against user questions — the speech-act split that drove
inter_judge_kappa=0.0on the prior single-judge hot_start run, documented in #687's body and the hot_start metanotesfield. The earlier hot_start patch (PR #639) noted the debug fixture would be flipped alongside once the cold-start sweep was re-ratified separately; this is that follow-up.κ artifact —
687_hot_start_t_le_0.6(calibrated cut)3 independent Sonnet 4.6 judges, hot-start rows at
trigger_threshold ≤ 0.6, 6 pairs aligned.--judge-model "claude-sonnet-4-6 (anchor tier per llm_judge.py)". Baseline:score_substring_exact_match.{ "run_id": "687_hot_start_t_le_0.6", "n_runs": 3, "n_pairs": 6, "judge_model": "claude-sonnet-4-6 (anchor tier per llm_judge.py)", "baseline": "score_substring_exact_match", "inter_judge_kappa": { "judge_run1_hot_t06_vs_judge_run2_hot_t06": 1.0, "judge_run1_hot_t06_vs_judge_run3_hot_t06": 1.0, "judge_run2_hot_t06_vs_judge_run3_hot_t06": 1.0, "mean": 1.0, "min": 1.0 }, "judge_vs_baseline_kappa": { "judge_run1_hot_t06": 0.0, "judge_run2_hot_t06": 0.0, "judge_run3_hot_t06": 0.0, "mean": 0.0 }, "per_run_hot_start_fidelity": [1.0, 1.0, 1.0], "hot_start_fidelity_mean": 1.0, "calibrated": true, "failure_reasons": [] }Calibration gates
docs/BENCHMARKS.md §Eval-judge calibration+kappa.pythresholds)inter_judge_kappa.min ≥ 0.70hot_start_fidelity_mean ≥ 0.80n_runs ≥ 3calibratedJudge-vs-baseline κ = 0.0 across all runs because the substring baseline matched zero rows (every candidate paraphrases rather than substring-quoting the reference), while the judges agreed on 10/35 matches. This is the expected "the judge is earning its API cost" pattern documented in
kappa.py's docstring — judge-vs-baseline is report-only, not a gate.κ artifact —
687_all_35_rows(informational)Full 35-row sweep across both fixtures and all 5 trigger_threshold values:
{ "run_id": "687_all_35_rows", "n_runs": 3, "n_pairs": 35, "inter_judge_kappa": { "judge_responses_run1_vs_judge_responses_run2": 1.0, "judge_responses_run1_vs_judge_responses_run3": 1.0, "judge_responses_run2_vs_judge_responses_run3": 1.0, "mean": 1.0, "min": 1.0 }, "judge_vs_baseline_kappa": {"mean": 0.0}, "per_run_hot_start_fidelity": [0.2857, 0.2857, 0.2857], "hot_start_fidelity_mean": 0.2857, "calibrated": false, "failure_reasons": ["hot_start_fidelity_mean=0.2857 < threshold 0.8"] }The informational run intentionally fails the calibration gate — at
trigger_threshold ∈ {0.7, 0.8, 0.9}the rebuilder doesn't fire and the candidate hedges with "I don't have that in context." This is the expected behaviour the #587 AC qualifies with "at threshold ≤0.6"; the calibrated artifact above is the AC-aligned cut.Per-(task, threshold) fidelity (mean across 3 judge runs)
Cold-start (debug) fidelity is 25% at low thresholds and 0% at t=0.9 — substantially below the patched-fixture pass rate the prior single-judge run reported (~75%) because the patched
expectedis the canonical assistant answer rather than the user prompt. This is the calibration improvement the #687 fixture-meta work was designed to deliver: cold-start scores now reflect actual continuation fidelity, not subject-match leniency. Cold-start AC isn't gated on a specific number for v3.0; this PR re-establishes the cold-start baseline at25% at t≤0.8, 0% at t=0.9for #592 future reference.Methodology
debugging_session_001.meta.json(this PR's single commit).benchmarks/context-rebuilder/fixtures/synthetic/with--mode threshold-sweep --run-dir, producing 10 case-config dirs × 35replay_requests.jsonlrows total.actualcontinuations from each row'srebuilt_block + user_turnunder explicit no-cross-row-contamination instructions perjudges/llm_judge.py§"Contamination protocol".needs_llm_judge).judge_requests.jsonl(35 rows × 3 = 105 judge calls). Each saw only(turn_idx, expected, actual)per the contamination protocol.benchmarks/qa_scoring.score_substring_exact_match.python -m benchmarks.context_rebuilder.kappaon the AC-aligned subset (hot-start att≤0.6) and on the full 35-row sweep.All 3 judge runs produced identical verdicts (10/35 matched, same
turn_idxset: 1, 5, 9, 13, 20, 21, 22, 23, 24, 25). The κ=1.0 across all run-pairs reflects that determinism within the Sonnet 4.6 judge tier for these prompts — agents on this fixture's signal/noise distribution land on the same verdict.Sample-size caveat
The
docs/BENCHMARKS.md §Eval-judge calibrationdoc already flags: at N=3 over ~18 deduplicated pairs the 95% CI on a 0.70 point estimate spans ≈ 0.45–0.90. The hot-start calibrated cut here is 6 pairs (3 turns × 2 thresholds), even tighter. A pre-release N=5 ratification run is still recommended as future work; this PR ships the gate-pass for v3.0 only.Local verification
No assertion in tests references the debug fixture's
eval_turnsshape (only the hot_start shape is asserted attest_context_rebuilder_eval_harness_wiring.py:534); the patch is invariant under the existing test suite.Refs
Bench artifacts (run dirs, judge JSONLs, kappa JSONs) are local-only at
/tmp/592_run/per project policy of "uncommitted run artifacts".Summary by CodeRabbit