Skip to content

Fix failure_kind misclassification for safe_outputs post-agent failures - #50037

Merged
pelikhan merged 12 commits into
mainfrom
copilot/deep-report-fix-driver-exit-mistagging
Aug 3, 2026
Merged

Fix failure_kind misclassification for safe_outputs post-agent failures#50037
pelikhan merged 12 commits into
mainfrom
copilot/deep-report-fix-driver-exit-mistagging

Conversation

Copilot AI commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

logs run summaries were over-classifying failed runs as driver_exit when safe_outputs failed after a successful agent job. This hid real in-scope safe-output incidents behind an infra-style failure tag.

  • Failure-kind classification precedence

    • Updated buildLogsData to classify as agent_logic first when job metadata shows:
      • agent job concluded success
      • safe_outputs job concluded in a failure state
    • driver_exit remains a fallback for true zero-turn pre-agent failures.
  • Job-name normalization for robust matching

    • Added normalization to match safe_outputs/safe outputs/safe-outputs consistently in job_details classification.
  • Regression coverage

    • Extended logs report unit coverage with a zero-turn failed run where agent=success + safe_outputs=failure, asserting failure_kind=agent_logic and updated aggregate counters.
failureKind := ""
if isSafeOutputsFailureAfterSuccessfulAgent(pr.JobDetails) {
    failureKind = "agent_logic"
} else if isDriverExitFailure(run) {
    failureKind = "driver_exit"
}

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 20.5 AIC · ⌖ 9.4 AIC · ⊞ 5.9K ·
Comment /souschef to run again


Generated by 👨‍🍳 PR Sous Chef · gpt54 · 7.59 AIC · ⌖ 5.99 AIC · ⊞ 8.3K ·
Comment /souschef to run again


Generated by 👨‍🍳 PR Sous Chef · gpt54 · 15.3 AIC · ⌖ 9 AIC · ⊞ 8.3K ·
Comment /souschef to run again


run: https://github.com/github/gh-aw/actions/runs/30855215929

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 12.2 AIC · ⌖ 8.62 AIC · ⊞ 8.3K ·
Comment /souschef to run again

Copilot AI and others added 2 commits August 3, 2026 16:44
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix failure_kind driver_exit mistagging in safe-output health monitoring Fix failure_kind misclassification for safe_outputs post-agent failures Aug 3, 2026
Copilot AI requested a review from pelikhan August 3, 2026 16:53
@pelikhan
pelikhan marked this pull request as ready for review August 3, 2026 16:58
Copilot AI review requested due to automatic review settings August 3, 2026 16:58
@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

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

@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Test Quality Sentinel completed test quality analysis.

@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

PR Code Quality Reviewer completed the code quality review.

@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

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

No ADR enforcement needed: PR does not have the 'implementation' label and has ≤100 new lines of code in business logic directories (40 additions detected).

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

Fixes safe-output failures being misclassified as driver_exit.

Changes:

  • Prioritizes successful-agent/failed-safe-output metadata as agent_logic.
  • Normalizes safe-output job names.
  • Adds regression coverage and updates counters.
Show a summary per file
File Description
pkg/cli/logs_report.go Updates failure classification and job-name matching.
pkg/cli/logs_report_test.go Covers the corrected classification.

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: Balanced

Comment thread pkg/cli/logs_report.go
Comment on lines +521 to +524
func normalizeJobName(name string) string {
normalized := strings.ToLower(strings.TrimSpace(name))
normalized = strings.ReplaceAll(normalized, " ", "_")
return strings.ReplaceAll(normalized, "-", "_")
Comment thread pkg/cli/logs_report.go Outdated
// non-zero turn count (e.g. backfilled from the usage-activity summary).
failureKind := ""
if isDriverExitFailure(run) {
if isSafeOutputsFailureAfterSuccessfulAgent(pr.JobDetails) {

@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 of PR #50037 — Fix failure_kind misclassification for safe_outputs post-agent failures

The core logic and approach are correct: classifying safe_outputs failures after a successful agent job as agent_logic is the right fix, and normalizeJobName is a clean addition.

One blocking issue found:

The new check at line 252 is not guarded by isFailureConclusion(run.Conclusion). Every other branch in the classification block is gated on the overall run being a failure (either internally in isDriverExitFailure or explicitly in the else if). Without this guard, a run that concluded success at the workflow level but happens to match the job-detail pattern would incorrectly increment totalAgentLogicFailures and receive a non-empty FailureKind.

See inline comment for the one-line fix.

🧵 Reviewed using Impeccable skills by Impeccable Skills Reviewer · sonnet46 · 31.5 AIC · ⌖ 12.2 AIC · ⊞ 5.4K

Comment thread pkg/cli/logs_report.go Outdated
// non-zero turn count (e.g. backfilled from the usage-activity summary).
failureKind := ""
if isDriverExitFailure(run) {
if isSafeOutputsFailureAfterSuccessfulAgent(pr.JobDetails) {

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.

Missing run-level failure guard

isSafeOutputsFailureAfterSuccessfulAgent only inspects job-level conclusions and does not check that the overall workflow run itself failed. A run with Conclusion = "success" that incidentally matches the job-detail patterns will still increment totalAgentLogicFailures and get a non-empty FailureKind.

All other branches here are guarded:

  • isDriverExitFailure calls isFailureConclusion(run.Conclusion) internally
  • The else if branch uses isFailureConclusion(run.Conclusion) explicitly

Suggested fix:

if isFailureConclusion(run.Conclusion) && isSafeOutputsFailureAfterSuccessfulAgent(pr.JobDetails) {

@copilot please address this.

@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 /tdd and /diagnosing-bugs — requesting changes on two issues before merging.

📋 Key Themes & Highlights

Issues

  1. normalizeJobName is untested — the regression test only uses the already-normalised "safe_outputs" literal; the space and hyphen variants that motivated the helper are never exercised. Deleting the function would not break any test.
  2. Cancellation edge caseisFailureConclusion likely includes "cancelled". A user-cancelled run where agent finished success before the cancellation propagated would be misclassified as agent_logic. This needs an explicit policy decision and, at minimum, a comment.

Positive Highlights

  • ✅ Root cause properly addressed — precedence fix, not just a symptom patch
  • ✅ Regression test added alongside the fix
  • normalizeJobName is a clean, reusable helper; just needs coverage

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · sonnet46 · 38.8 AIC · ⌖ 9.94 AIC · ⊞ 7.1K
Comment /matt to run again

}
}

// TestBuildLogsDataNoArtifactsFailureUnclassified verifies that failed runs whose

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.

[/tdd] The new test only exercises the "safe_outputs" (underscore) job name, even though normalizeJobName was added specifically to handle "safe outputs" and "safe-outputs" variants. Those variants are never tested, so normalizeJobName is effectively unverified.

💡 Suggested extra cases

Add two additional ProcessedRun entries (runs 6 and 7) and assert FailureKind=agent_logic for them:

// space-separated variant
{
    Run: WorkflowRun{DatabaseID: 6, Conclusion: "failure", Turns: 0, TurnsAvailable: true},
    JobDetails: []JobInfoWithDuration{
        {JobInfo: JobInfo{Name: "agent", Conclusion: "success"}},
        {JobInfo: JobInfo{Name: "safe outputs", Conclusion: "failure"}},
    },
},
// hyphenated variant
{
    Run: WorkflowRun{DatabaseID: 7, Conclusion: "failure", Turns: 0, TurnsAvailable: true},
    JobDetails: []JobInfoWithDuration{
        {JobInfo: JobInfo{Name: "agent", Conclusion: "success"}},
        {JobInfo: JobInfo{Name: "safe-outputs", Conclusion: "failure"}},
    },
},

Without these, removing normalizeJobName entirely would not break any test.

@copilot please address this.

Comment thread pkg/cli/logs_report.go
}

return agentSucceeded && safeOutputsFailed
}

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] isSafeOutputsFailureAfterSuccessfulAgent does a linear scan but short-circuits only after visiting all jobs. More importantly, a cancelled safe_outputs job ("cancelled") would also be caught by isFailureConclusion — is that intended? If a run was cancelled by the user mid-flight the agent job can finish success before cancellation propagates, producing a false agent_logic classification.

💡 Consider

Clarify whether cancellation should map to agent_logic or remain unclassified. If not, add an explicit guard:

if normalizedName == "safe_outputs" && isFailureConclusion(job.Conclusion) &&
    !strings.EqualFold(job.Conclusion, "cancelled") {
    safeOutputsFailed = true
}

If cancellation should be agent_logic, document that intent with a comment so future readers know it is deliberate.

@copilot please address this.

@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

🧪 Test Quality Sentinel Report

Test Quality Score: 95/100 — Excellent

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

📊 Metrics (4 tests)
Metric Value
Analyzed 4 (Go: 4, JS: 0)
✅ Design 4 (100%)
⚠️ Implementation 0 (0%)
Edge/error coverage 4 (100%)
Duplicate clusters 0
Inflation No (test:prod ratio ≈ 0.48:1)
🚨 Violations 0
Test File Classification Issues
TestBuildLogsDataDriverExitFailureClassification logs_report_test.go:1149 design_test / behavioral_contract None
TestBuildLogsDataNoArtifactsFailureUnclassified logs_report_test.go:1201 design_test / behavioral_contract None
TestBuildLogsDataNoFailuresProducesZeroDriverExitCount logs_report_test.go:1232 design_test / behavioral_contract None
TestBuildLogsDataIntentionalFailure logs_report_test.go:1251 design_test / behavioral_contract None

Key Observations

  • Build tag//go:build !integration on line 1.
  • No mock libraries ✅ No gomock/testify/mock usage.
  • Core fix testTestBuildLogsDataDriverExitFailureClassification directly tests the bug scenario (run 5: safe_outputs failure after successful agent execution must be classified as agent_logic, not driver_exit). This is a precise behavioral contract.
  • Edge cases well coveredTurnsAvailable: false (ErrNoArtifacts path), safe_outputs post-agent failure, and zero-turn success scenarios are all exercised.
  • Assertion messages are descriptive — all t.Errorf calls include the scenario and expected value.
  • Inflation ratio ≈ 0.48:1 (13 test lines / 27 prod lines) — well under 2:1 threshold.

Verdict

passed. 0% implementation tests (threshold: 30%). All new tests enforce design invariants of the failure_kind classification logic.

🧪 Test quality analysis by Test Quality Sentinel · sonnet46 · 44.8 AIC · ⌖ 8.37 AIC · ⊞ 8.5K ·
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: 95/100. 0% implementation tests (threshold: 30%). All 4 new tests enforce design invariants of the failure_kind classification logic, including the core safe_outputs post-agent failure scenario.

@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.

Found one blocking correctness bug in the new classification branch.

💡 Summary of findings
  • isSafeOutputsFailureAfterSuccessfulAgent(pr.JobDetails) is checked without also requiring isFailureConclusion(run.Conclusion), unlike the other two branches in the same if/else chain. This can misclassify a run-level success conclusion as FailureKind="agent_logic" and inflate TotalAgentLogicFailures, contradicting the run's own conclusion.
  • Test coverage only exercises the case where the overall run conclusion is already failure; there's no regression test for the success-conclusion edge case that the missing guard would let through.

🔎 Code quality review by PR Code Quality Reviewer · auto · 125.4 AIC · ⌖ 5.61 AIC · ⊞ 7.9K
Comment /review to run again

Comment thread pkg/cli/logs_report.go Outdated
// non-zero turn count (e.g. backfilled from the usage-activity summary).
failureKind := ""
if isDriverExitFailure(run) {
if isSafeOutputsFailureAfterSuccessfulAgent(pr.JobDetails) {

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.

This branch classifies a run as agent_logic based solely on job metadata, without checking isFailureConclusion(run.Conclusion) — unlike every other branch here — so a run whose overall conclusion is success (e.g. via continue-on-error on the safe_outputs job) can still get FailureKind="agent_logic" and inflate totalAgentLogicFailures.

💡 Details

Compare with the other two branches, both gated on isFailureConclusion(run.Conclusion):

} else if isDriverExitFailure(run) { // itself requires isFailureConclusion
...
} else if isFailureConclusion(run.Conclusion) && (run.TurnsAvailable || run.Turns > 0) {

isSafeOutputsFailureAfterSuccessfulAgent has no equivalent guard — it only inspects pr.JobDetails. If a workflow run's overall GitHub Actions conclusion is success but a safe_outputs job step failed (possible with continue-on-error: true, or if job-level conclusion diverges from the run-level conclusion for any reason), this run will be counted and labeled as an agent-logic failure even though it's not a failed run by the run-level classification used everywhere else in this loop (totalErrors, other counters, etc. still won't be touched, causing inconsistent/contradictory summary counts).

Suggested fix:

if isFailureConclusion(run.Conclusion) && isSafeOutputsFailureAfterSuccessfulAgent(pr.JobDetails) {
    failureKind = "agent_logic"
    totalAgentLogicFailures++
} else if isDriverExitFailure(run) {

Also add a test case where run.Conclusion == "success" but job details show agent=success/safe_outputs=failure, asserting FailureKind stays empty.

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot sous-chef triage:

This PR still has unresolved blocking review feedback and needs another fix pass before maintainers can investigate quickly.

Generated by PR Sous Chef · run: https://github.com/github/gh-aw/actions/runs/30838483274

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 20.5 AIC · ⌖ 9.4 AIC · ⊞ 5.9K ·
Comment /souschef to run again

Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>

Copilot AI commented Aug 3, 2026

Copy link
Copy Markdown
Contributor Author

@copilot sous-chef triage:

This PR still has unresolved blocking review feedback and needs another fix pass before maintainers can investigate quickly....

Addressed in 9ceccd3.

  • Added run-level failure guard for the safe_outputs branch (isFailureConclusion(run.Conclusion)), so success runs no longer classify as agent_logic.
  • Expanded regression coverage for safe_outputs name normalization variants: safe_outputs, safe outputs, safe-outputs, and trimmed/case-variant names.
  • Added regression coverage that a success run with agent=success + safe_outputs=failure metadata keeps empty FailureKind.
  • Updated failure-kind contract comments (LogsSummary.TotalAgentLogicFailures, RunData.FailureKind, and classification block comment) to document the metadata-based agent_logic signal.

I also ran required local validation (make agent-report-progress) and targeted tests for the updated classification path.

Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>
Copilot AI requested a review from gh-aw-bot August 3, 2026 18:21
@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot sous-chef triage:

This PR still needs another pass before maintainers can investigate quickly.

  • Open blocking reviews remain from: github-actions
  • Please refresh the branch if needed, address remaining review/CI blockers, then run the pr-finisher skill and post a concise merge-readiness summary for the current head.

Generated by PR Sous Chef · run: https://github.com/github/gh-aw/actions/runs/30841444939

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 7.59 AIC · ⌖ 5.99 AIC · ⊞ 8.3K ·
Comment /souschef to run again

Copilot AI commented Aug 3, 2026

Copy link
Copy Markdown
Contributor Author

@copilot sous-chef triage:

This PR still needs another pass before maintainers can investigate quickly....

Current head 8a62b8a is locally validated and no further code changes were needed in this pass.

  • Local checks: make fmt, make lint, TEST_UNIT_RUN_FULL=1 make test-unit, make test, make recompile, and make agent-report-progress all passed.
  • CI log triage: latest PR-head workflow runs are action_required with no failed jobs returned by log inspection.
  • Remaining blocker: PR is still mergeable_state=blocked due unresolved github-actions[bot] review threads/changes-requested state.

Merge-readiness for this head is pending human-side review-thread resolution and CI re-trigger on a maintainer push/dispatch.

@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

PR Triage: #50037

  • Category: bug
  • Risk: medium
  • Score: 48/100 (Impact 25 + Urgency 15 + Quality 8)
  • Recommended action: defer

Fixes failure_kind misclassification for safe_outputs post-agent failures. mergeable_state is blocked, CI still pending.

Generated by 🔧 PR Triage Agent · auto · 51.1 AIC · ⌖ 4.08 AIC · ⊞ 8K ·

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot This PR still needs another fix pass before maintainers can investigate quickly. Please address the unresolved review feedback, refresh the branch if needed, then run the pr-finisher skill and summarize merge readiness.

Unresolved reviews:

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 15.3 AIC · ⌖ 9 AIC · ⊞ 8.3K ·
Comment /souschef to run again

Copilot AI commented Aug 3, 2026

Copy link
Copy Markdown
Contributor Author

@copilot This PR still needs another fix pass before maintainers can investigate quickly. Please address the unresolved review feedback, refresh the branch if needed, then run the pr-finisher skill ...

All listed review items are already present on current head 12dab7b (from prior fix commits 9ceccd3 and 8a62b8a):

  • run-level failure guard on the safe_outputs classification branch
  • public failure-kind contract comments updated for metadata-based agent_logic
  • normalization coverage for safe_outputs / safe outputs / safe-outputs (including casing/whitespace)
  • success-run regression guard
  • cancelled safe_outputs excluded from agent_logic classification

This pass required no additional code changes. I re-ran local validation (make agent-report-progress) successfully and re-triaged latest PR-head CI runs via Actions logs (all action_required, no failed jobs returned by failed-job log inspection).

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot This PR still needs another pass before maintainers can investigate quickly.

Generated by PR Sous Chef · run: https://github.com/github/gh-aw/actions/runs/30855215929

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 12.2 AIC · ⌖ 8.62 AIC · ⊞ 8.3K ·
Comment /souschef to run again

Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>
@pelikhan
pelikhan merged commit 4357110 into main Aug 3, 2026
28 checks passed
@pelikhan
pelikhan deleted the copilot/deep-report-fix-driver-exit-mistagging branch August 3, 2026 22:08
@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

🎉 This pull request is included in a new release.

Release: v0.84.4

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.

[deep-report] Fix failure_kind driver_exit mistagging in safe-output health monitoring

4 participants