fix(eval): harden LLM judge against contradictory / journey-based verdicts#988
Merged
Conversation
… verdicts The docs agent-eval CI slice flaked on scenario 02: the LLM judge marked the Execution criterion pass=false while its own evidence concluded it passed, penalizing self-corrected mid-session failures (wrong cwd, later-fixed SDK args) even though the final script ran and published an event. - Prompt: judge the FINAL state and last run; ignore self-corrected intermediate failures; enforce pass matches evidence. - Add conservative contradiction detection + a targeted re-ask (no silent flips) as a safety net in the judge loop. - Unit tests for the detector, including the observed false negative. - Ignore .worktrees/ (matches sibling-repo convention). Co-Authored-By: Claude <noreply@anthropic.com> Co-authored-by: Cursor <cursoragent@cursor.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Hardens the docs agent-evaluation “LLM judge” to avoid false-negative CI failures caused by criteria where pass contradicts the criterion’s own evidence, and to ensure verdicts are based on the final deliverable/last successful run rather than intermediate missteps.
Changes:
- Strengthens the judge prompt to explicitly score the final artifact + last run and enforce evidence↔boolean alignment.
- Adds a conservative contradiction detector (
criterionSelfContradicts/findContradictoryCriteria) that triggers a single targeted re-ask (within the existing retry budget) instead of silently flipping booleans. - Adds unit tests covering the observed failure mode, inverse contradictions, aligned cases, and mixed-evidence cases; updates
.gitignoreto ignore.worktrees/.
Reviewed changes
Copilot reviewed 2 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| docs/agent-evaluation/src/llm-judge.ts | Adds contradiction detection + retry note wiring, and tightens judge instructions to focus on final deliverable/last run. |
| docs/agent-evaluation/src/llm-judge-parse.test.ts | Adds unit tests for the new contradiction detection behavior. |
| .gitignore | Ignores .worktrees/ directory. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
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
The Docs agent eval (CI slice) flaked on
main(run 28672821140). Scenario02-basics-typescript.mdpassed every heuristic (9/9) and its generated script ran and published a live event (evt_…), but the LLM judge marked the Execution criterionpass=false— while its own evidence said "Overall execution criterion passes based on live API evidence." It penalized self-corrected mid-session stumbles (a run from the wrong working directory →ERR_MODULE_NOT_FOUND, and an SDK argument shape that was fixed) rather than judging the final deliverable. Because the overall verdict is the AND of all criteria, that one contradictoryfalsefailed the whole run.This hardens the judge in two layers so this class of false negative doesn't recur.
Changes
llm-judge.ts) — generalizable fix:ERR_MODULE_NOT_FOUND, later-fixed args) when a later run clearly succeeded.false.criterionSelfContradicts()/findContradictoryCriteria()conservatively detect a criterion whosepassboolean contradicts an explicit conclusion in its own evidence (never fires on mixed/ambiguous evidence). The judge loop re-asks the model once (within the existing 3-attempt budget) to reconcile — it never silently flips a verdict, and the model's booleans stay authoritative if unresolved.llm-judge-parse.test.ts, including the exact observed false negative, the inverse, aligned non-contradictions, and mixed-evidence (no false trigger)..gitignore— ignore.worktrees/(matches the website/core convention).Test plan
npm testindocs/agent-evaluationpasses (llm-judge-parse.test: OK).Co-Authored-By: Claude noreply@anthropic.com
Made with Cursor