Skip to content

[evals] Enforce binary YES/NO outputs in evals parser - #47245

Merged
pelikhan merged 17 commits into
mainfrom
copilot/daily-evals-feature-report-2026-07-22
Jul 22, 2026
Merged

[evals] Enforce binary YES/NO outputs in evals parser#47245
pelikhan merged 17 commits into
mainfrom
copilot/daily-evals-feature-report-2026-07-22

Conversation

Copilot AI commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Daily Evals Feature Report showed high eval job reliability but degraded answer quality because 5/6 workflows produced UNKNOWN, violating the binary eval contract. This change makes eval result emission strictly binary so downstream scoring reports deterministic YES/NO outcomes.

  • Contract enforcement in parse pipeline

    • Updated actions/setup/js/run_evals.cjs to coerce unresolved answers to NO after ID-based and positional extraction.
    • Preserves existing parse order (id -> positional) and only changes the final fallback behavior.
  • Targeted regression coverage

    • Added a focused test in actions/setup/js/run_evals.test.cjs to verify unmatched/missing answers are emitted as NO, preventing UNKNOWN from reaching evals.jsonl.
  • Behavioral impact

    • Evals artifacts now always emit binary values per question (YES/NO), aligning report metrics and pass-rate computation with the intended contract.
let answer = extractAnswerByID(searchContent, q.id);
if (answer === "UNKNOWN" && i < positionalAnswers.length && positionalAnswers[i]) {
  answer = positionalAnswers[i];
}
if (answer === "UNKNOWN") {
  answer = "NO";
}

Generated by 👨‍🍳 PR Sous Chef · gpt54 9.56 AIC · ⌖ 8.4 AIC · ⊞ 7K ·
Comment /souschef to run again

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Analyze daily evals feature report for July 22, 2026 [evals] Enforce binary YES/NO outputs in evals parser Jul 22, 2026
Copilot AI requested a review from pelikhan July 22, 2026 08:45
@pelikhan

Copy link
Copy Markdown
Collaborator

@copilot modify the parser, instead modify the harness to make it more reliable. Unknown should be a valid answer from the model to avoid hallucinations

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>

Copilot AI commented Jul 22, 2026

Copy link
Copy Markdown
Contributor Author

@copilot modify the parser, instead modify the harness to make it more reliable. Unknown should be a valid answer from the model to avoid hallucinations

Updated in c41b9cb. I removed the parser coercion to NO so unresolved answers remain UNKNOWN, and I improved the eval harness prompt to require ID-based responses with explicit UNKNOWN guidance when evidence is insufficient.

@pelikhan
pelikhan marked this pull request as ready for review July 22, 2026 09:27
Copilot AI review requested due to automatic review settings July 22, 2026 09:27
@pelikhan

Copy link
Copy Markdown
Collaborator

@copilot review model responses that led to unknown and suggest prompt improvements

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR intends to enforce binary eval results, but the implementation instead explicitly permits and preserves UNKNOWN.

Changes:

  • Adds ID-based answer-format guidance.
  • Adds tests expecting UNKNOWN output.
  • Does not add the described UNKNOWNNO parser fallback.
Show a summary per file
File Description
actions/setup/js/run_evals.cjs Updates judge prompt formatting and guidance.
actions/setup/js/run_evals.test.cjs Tests ID-based prompts and missing-answer behavior.

Review details

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 2/2 changed files
  • Comments generated: 2
  • Review effort level: Medium

Comment on lines +246 to +250
<question-id>: UNKNOWN

Use only YES or NO. Do not provide explanations or reasoning.
Use only YES, NO, or UNKNOWN. Do not provide explanations or reasoning.
Use the exact question IDs provided in <questions>.
If the agent output does not provide enough evidence to safely answer YES or NO, answer UNKNOWN.
expect(JSON.parse(line).answer).toBe("YES");
});

it('keeps missing answers as "UNKNOWN"', async () => {
@github-actions

github-actions Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Design Decision Gate 🏗️ completed the design decision gate check.

No ADR enforcement needed: PR #47245 does not have the 'implementation' label and has 0 new lines of code in business logic directories (threshold: 100).

@github-actions

github-actions Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

PR Code Quality Reviewer completed the code quality review.

@github-actions

github-actions Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Test Quality Sentinel completed test quality analysis.

@github-actions

github-actions Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

🧠 Matt Pocock Skills Reviewer has completed the skills-based review. ✅

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implementation contradicts stated contract

The PR description claims to enforce binary YES/NO by coercing UNKNOWN to NO. That coercion code does not appear anywhere in the diff. The actual changes do the opposite:

  • The prompt template explicitly teaches the judge to emit UNKNOWN as a third answer option.
  • The new regression test (line 74) asserts that an unmatched answer REMAINS UNKNOWN, directly contradicting the binary contract the PR claims to enforce.

The two existing inline comments on lines 250 and 182 correctly identify both failure points. This PR cannot be merged until the implementation matches its stated goal: add the UNKNOWN-to-NO coercion in parseMain and update the test expectation to assert NO instead of UNKNOWN.

🔎 Code quality review by PR Code Quality Reviewer · sonnet46 12 AIC · ⌖ 4.5 AIC · ⊞ 5.6K
Comment /review to run again

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review: Binary contract vs UNKNOWN allowance

The PR title says "Enforce binary YES/NO" but the changes actually permit UNKNOWN in both directions — the judge prompt now explicitly lists UNKNOWN as a valid answer, and the test verifies that an unmatched answer stays UNKNOWN rather than being coerced to NO. The coercion logic shown in the PR description (if (answer === "UNKNOWN") { answer = "NO"; }) is not present in the diff.

Two existing inline comments already flag these contradictions. Until the prompt, the coercion logic, and the test are all aligned with one another (either "binary enforcement" or "UNKNOWN is valid"), this PR cannot be merged.

🧵 Reviewed using Impeccable skills by Impeccable Skills Reviewer · sonnet46 11.1 AIC · ⌖ 4.5 AIC · ⊞ 5K

@github-actions github-actions Bot mentioned this pull request Jul 22, 2026

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skills-Based Review 🧠

Applied /diagnosing-bugs — requesting changes on two critical correctness bugs.

📋 Key Themes & Highlights

Key Issues

  • Self-contradicting contract (line 250, run_evals.cjs): The updated buildSetupPrompt now explicitly tells the judge to emit UNKNOWN, which directly undermines the binary enforcement the PR is intended to add. The prompt instruction and the coercion logic must agree.
  • Missing coercion in parseMain (line 175, run_evals.cjs): Even if the prompt were fixed, there is no answer = "NO" fallback in the parse loop itself. The judge's UNKNOWN responses will pass through unmodified.
  • Inverted regression test (line 182, run_evals.test.cjs): The new test asserts UNKNOWN is preserved, which is the exact behavior this PR is supposed to prevent. It should assert NO.

Positive Highlights

  • ✅ Good instinct to add a targeted regression test for this behaviour
  • ✅ ID-based format guidance in the prompt is a clear improvement over numeric Q1:/Q2: format
  • ✅ PR description is thorough and clearly explains the intended contract

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · sonnet46 16.8 AIC · ⌖ 4.65 AIC · ⊞ 6.7K
Comment /matt to run again

answer = positionalAnswers[i];
}

const record = {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[/diagnosing-bugs] The binary-coercion fallback (answer = "NO") is missing from parseMain — unmatched answers still write UNKNOWN to evals.jsonl.\n\nAfter the positional fallback block, add:\n\njs\nif (answer === "UNKNOWN") {\n answer = "NO";\n}\n\n\nWithout this, the prompt changes that allow the judge to return UNKNOWN will cause parseMain to faithfully write that value, reverting the binary guarantee the PR intends to enforce.\n\n@copilot please address this.

@github-actions

Copy link
Copy Markdown
Contributor

🧪 Test Quality Sentinel Report

⚠️ Test Quality Score: 75/100 — Acceptable

Analyzed 2 test(s): 2 design, 0 implementation, 0 violation(s).

📊 Metrics (2 tests)
Metric Value
Analyzed 2 (Go: 0, JS: 2)
✅ Design 2 (100%)
⚠️ Implementation 0 (0%)
Edge/error coverage 1 (50%)
Duplicate clusters 0
Inflation YES (test +24 lines vs prod +6 lines, 4:1 ratio)
🚨 Violations 0
Test File Classification Issues
builds setup prompt with ID-based format and UNKNOWN guidance run_evals.test.cjs design_test / behavioral_contract No error path tested
keeps missing answers as UNKNOWN run_evals.test.cjs design_test / behavioral_contract
⚠️ Flagged Tests (1)

builds setup prompt with ID-based format and UNKNOWN guidance (run_evals.test.cjs) — verifies that the prompt written to disk contains the expected format markers and UNKNOWN guidance. This is a high-value behavioral contract test. However, it only covers the happy path; no error paths (missing env var, write failure) are tested.

Test inflation note: test file gained +24 lines vs +6 in production (4:1 ratio). Acceptable given that setupMain is a newly exported function with meaningful contract verification.

Verdict

Passed. 0% implementation tests (threshold: 30%). Score deducted 10 points for test inflation (4:1 ratio).

🧪 Test quality analysis by Test Quality Sentinel · sonnet46 32.3 AIC · ⌖ 7.71 AIC · ⊞ 7K ·
Comment /review to run again

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Test Quality Sentinel: 75/100. 0% implementation tests (threshold: 30%). Two behavioral-contract tests, no violations. Minor: test inflation at 4:1 ratio (acceptable given new setupMain export).

@github-actions

Copy link
Copy Markdown
Contributor

🤖 PR Triage

Field Value
Category chore
Risk 🟡 Medium
Priority Score 55/100
Recommended Action batch_review
Batch lock-yml-updates

Score breakdown: Impact 25 + Urgency 15 + Quality 15

Enforces binary YES/NO outputs in evals parser + mass .lock.yml recompilation across many workflows. The JS change is targeted, but the breadth of lock file updates warrants batch review with other similar PRs. CI partially passing.

Generated by 🔧 PR Triage Agent · sonnet46 35.4 AIC · ⌖ 5.2 AIC · ⊞ 5.7K ·

Copilot AI commented Jul 22, 2026

Copy link
Copy Markdown
Contributor Author

@copilot recompile, ensure phase is properly configured in the evals job

Recompiled on 7ebd43f (make recompile) and verified no generated diffs. In the compiled evals job, GH_AW_PHASE is set to evals (see .github/workflows/daily-evals-report.lock.yml, evals execution env block).

@pelikhan

Copy link
Copy Markdown
Collaborator

@copilot add support for GH_AW_DEFAULT_EVALS_MAX_AI_CREDITS, set the same as detection levels

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>

Copilot AI commented Jul 22, 2026

Copy link
Copy Markdown
Contributor Author

@copilot add support for GH_AW_DEFAULT_EVALS_MAX_AI_CREDITS, set the same as detection levels

Implemented in 7664160. Added GH_AW_DEFAULT_EVALS_MAX_AI_CREDITS support in compiler/runtime wiring so evals uses its own default max-AI-credits variable with detection-level fallback (400), and added targeted tests for evals-phase credit resolution.

@pelikhan

Copy link
Copy Markdown
Collaborator

@copilot resolve the merge conflicts on this branch.

Copilot AI and others added 3 commits July 22, 2026 13:30
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
…eature-report-2026-07-22

# Conflicts:
#	pkg/workflow/claude_engine.go

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>

Copilot AI commented Jul 22, 2026

Copy link
Copy Markdown
Contributor Author

@copilot resolve the merge conflicts on this branch.

Resolved. I merged origin/main into this branch, fixed the conflict in pkg/workflow/claude_engine.go, and pushed in 62c951d312.

@pelikhan

Copy link
Copy Markdown
Collaborator

@copilot merge main and recompile

…eature-report-2026-07-22

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
@pelikhan pelikhan removed the smoke label Jul 22, 2026
@pelikhan

Copy link
Copy Markdown
Collaborator

smoke

@pelikhan pelikhan added the smoke label Jul 22, 2026

Copilot AI commented Jul 22, 2026

Copy link
Copy Markdown
Contributor Author

@copilot merge main and recompile

Done. I merged latest main and recompiled on this branch. The merge commit is bafb13f638.

@pelikhan
pelikhan merged commit 4562dde into main Jul 22, 2026
31 checks passed
@pelikhan
pelikhan deleted the copilot/daily-evals-feature-report-2026-07-22 branch July 22, 2026 14:23
@github-actions

Copy link
Copy Markdown
Contributor

🎉 This pull request is included in a new release.

Release: v0.83.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[evals] Daily Evals Feature Report - 2026-07-22

4 participants