Repository navigation
fix(evals): handle login failures in live promise evaluations - #198
Conversation
|
Verdict: FAIL Round 1 swarm at this head: gates + free live preflight + fake-CLI regression (sonnet@high), ERROR-masking review and consumer review (opus@xhigh each; work model sonnet@high). No paid turn ran. Gates: PASS (lint 5/5; only known host noise). Live: host preflight passes Claude and Codex and stops Grok (token expired 2026-10-08) with exit 3 and no run dir; Fix-forward (in scope):
Not in scope (no change): Codex preflight lets a missing binary raise a traceback (same as before the PR, fails closed). Claude preflight calls a missing binary a login failure; note for a follow-up. |
0f8309d to
fdd187c
Compare
|
Verdict: FAIL Round 2 swarm at this head: gates + free preflight + recorded-run replay (sonnet@high), auth-death semantics review and consumer/integration review (opus@xhigh each; work model sonnet@high). This is the second FAIL; a third stops the PR. Round-1 items 1, 2, 4 fixed; item 3 holds. Policy question settled with evidence: keeping every grader-decided verdict after an auth death (the current code) is the only policy that hid no real FAIL across 11 recorded deaths and 1,215 synthetic cut-short runs; the remaining false FAILs belong to the oracles and are filed as #208. Gates pass; merges clean with main, #199, #202. Fix-forward (in scope; proven on recorded runs):
Notes (no change): Claude preflight reads |
…ERROR Each adapter gets a free login check that stops 'live.py run' before any case spends a token and names the CLI and its login command. A run whose turn dies on a login failure gets an ERROR verdict for every promise, skips grading, stops the wave, and drops out of the pass-rate denominator in 'live.py report'. Closes #168
…ok External-auth death - A turn that dies on auth after earlier turns ran is still harvested and graded. A PASS or FAIL the grader decides stands, undecided promises become ERROR, and the wave still stops. - error_verdict leaves a promise the oracle marks not_applicable for the harness blank instead of ERROR, so a dead Codex feature run no longer shows ERROR for Claude-only and Hermes/Grok-only promises. - The Grok death pattern covers the External-auth 401 text, recorded from a live run that still graded FAIL. - The README says the Claude preflight checks the host login without the turn's private CLAUDE_CONFIG_DIR.
error_verdict now takes the error record a verdict.json carries, so a later re-grade can rebuild the verdict from the record alone.
Recorded shapes: the 2026-10-05 Claude feature-run that died on a 401 before any tool call, and the Hermes feature-run whose transcript read was refused. The tests cover harness-gated promises marked ERROR, gated promises counted in the pass rate, a re-grade that drops the ERROR marks, and an ERROR that drops needs_judge.
- error_verdict asks each oracle about an empty trace from the harness, so a run that never started no longer marks a harness-gated promise ERROR. - report.py drops a promise that does not apply to the harness even when its grade returned early, so a refused Hermes transcript reads 0 of 10, not 0 of 11. - live.py grade keeps a dead login's error record and marks every promise the new grade leaves undecided ERROR again. run_case grades through the same path. - An ERROR that replaces an INCONCLUSIVE keeps its needs_judge flag and excerpt.
A harvest refusal after an auth death again stops the batch before the run gets a verdict.json, as the README says. Also moved the exit 3 sentence to the live-run sentences, and named recorded verdicts among the testdata fixtures.
…ing documentation
fdd187c to
ef2b2f4
Compare
|
Verdict: PASS+NOTES Round 3 swarm at this head: gates + recorded-run replays (sonnet@high), fix review and consumer review (opus@xhigh each; round-3 work was on opus@high, so these two lanes may be same-family reviews). Gates pass (only known host noise). Replays: Claude never-started run reports ERROR 10 excluded and stays so after re-grade; Codex ERROR 9; Hermes refused-read run 0 of 10; late deaths keep their decided verdicts after re-grade; ERROR keeps needs_judge and the excerpt; a never-sealed run makes Notes (follow-ups, not blocking): a kill in the ~11 ms between grade() writing verdict.json and grade_run adding |
What Changed
ERRORafter login failures, preserve decidedPASS/FAILresults, and retain authentication errors when regrading.ERRORcounts in reports, exclude them from pass rates, and filter out promises that do not apply to each harness.Validation
Risk Assessment
✅ Low: The change is limited to eval tooling and does exactly the four round-2 items: applicability comes from an empty-trace probe, the report counts only applicable promises, a re-grade keeps the stored error record, and an ERROR keeps needs_judge and its excerpt. Tracing the never-started, re-grade, unsealed-refusal and harvest-refusal paths found no wrong result, and oracles.py is untouched.
Testing
Targeted tests passed, and seven scenarios passed through real grading/reporting code using isolated recorded and synthetic inputs. CLI transcripts and persisted verdicts provide evidence. No paid wave, full suite, or other pipeline phase ran; disposable files were removed.
Evidence: Real grade/report CLI transcripts
Evidence: Never-started verdict with ten applicable ERROR promises
Evidence: ERROR preserves judge metadata and decided FAIL
Evidence: Decided PASS survives auth death
Pipeline
Updates from git push no-mistakes
✅ **Intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
✅ **Review** - passed
✅ No issues found.
✅ **Test** - passed
✅ No issues found.
TMPDIR="$PWD/.phase-test/tmp" PYTHONPATH=evals/promises python3 -m unittest test_live.ErrorRun test_live.ErrorVerdict test_live.LoginPreflight test_live.AuthDeath test_report.Render -vTMPDIR="$PWD/.phase-test/tmp" python3 .phase-test/drive.py: created isolated projects and controller-authorized recorded/synthetic traces, then exercised real grading and CLI commandspython3 evals/promises/live.py grade <authorization-id> --out <isolated-output>for never-started, unreadable, host-skill, judge, decided-PASS, and unsealed runs; exact invocations captured in cli-transcript.txtpython3 evals/promises/live.py report <isolated-output>for Claude early-return runs and the recorded Hermes refused-read verdictCompared persisted verdicts before and after re-grading; checked unsealed refusal preserved exact bytesRemoved disposable projects and generated caches;git status --shortreturned no changes✅ **Document** - passed
✅ No issues found.
✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.