Skip to content

Apply cross-run audit clustering to graders and evals - #56146

Merged
pelikhan merged 3 commits into
mainfrom
copilot/ensure-clustering-in-graders-evals
Aug 27, 2026
Merged

Apply cross-run audit clustering to graders and evals#56146
pelikhan merged 3 commits into
mainfrom
copilot/ensure-clustering-in-graders-evals

Conversation

Copilot AI commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Cross-run gh aw audit clustering previously covered runtime/task dimensions but omitted grader and eval signals, making multi-run cohort analysis incomplete. This update adds first-class clustering for both so grader outcomes and eval availability are grouped alongside existing dimensions.

  • Cross-run input enrichment

    • Added GradersCluster and EvalsCluster fields to crossRunInput.
    • Populated these in processedRunsToCrossRunInputs(...) from run artifacts/log paths.
  • New clustering dimensions

    • Extended buildClusterAnalysis(...) to include:
      • graders dimension (e.g., pass, fail, error, unavailable, absent, mixed)
      • evals dimension (present / absent)
    • Kept existing trivial-dimension filtering behavior so single-value dimensions are dropped as before.
  • Derivation logic

    • Added deriveGradersClusterValue(logsPath) using extracted grader summary state.
    • Added deriveEvalsClusterValue(logsPath) using eval artifact presence (evals.jsonl detection path).
  • Coverage

    • Added targeted test coverage asserting grader/eval clusters are produced with expected counts.
clusters = append(clusters, buildDimensionClusters("graders", inputs, func(in crossRunInput) string {
	if in.GradersCluster == "" {
		return "absent"
	}
	return in.GradersCluster
})...)
clusters = append(clusters, buildDimensionClusters("evals", inputs, func(in crossRunInput) string {
	if in.EvalsCluster == "" {
		return "absent"
	}
	return in.EvalsCluster
})...)

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title Apply audit clustering to graders and evals Apply cross-run audit clustering to graders and evals Aug 26, 2026
Copilot AI requested a review from pelikhan August 26, 2026 22:42
@pelikhan
pelikhan marked this pull request as ready for review August 26, 2026 22:43
Copilot AI balanced review requested due to automatic review settings August 26, 2026 22:43

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

Adds grader and eval signals to cross-run audit clustering.

Changes:

  • Derives grader outcome and eval-presence labels from run artifacts.
  • Adds graders and evals clustering dimensions.
  • Adds cluster-count coverage for the new dimensions.
Show a summary per file
File Description
pkg/cli/logs_orchestrator_render.go Derives grader and eval cluster values.
pkg/cli/audit_cross_run.go Stores new cluster inputs.
pkg/cli/audit_cross_run_clusters.go Builds grader and eval clusters.
pkg/cli/audit_cross_run_clusters_test.go Tests grouping and counts.

Review details

💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

  • Files reviewed: 4/4 changed files
  • Comments generated: 1
  • Review effort level: Balanced

Comment thread pkg/cli/logs_orchestrator_render.go Outdated
Comment on lines +210 to +222
if graders.ErrorCount > 0 {
return "error"
}
if graders.Failed > 0 {
return "fail"
}
if graders.UnavailableCount > 0 {
return "unavailable"
}
if graders.Passed == graders.Total {
return "pass"
}
return "mixed"
@github-actions

github-actions Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

PR Code Quality Reviewer completed the code quality review.

🔎 Code quality review by PR Code Quality Reviewer

@github-actions

github-actions Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

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

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer

@github-actions

github-actions Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Design Decision Gate 🏗️ completed the design decision gate check. See the comment below for the result and any generated ADR draft.

🏗️ ADR gate enforced by Design Decision Gate 🏗️

@github-actions

github-actions Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Test Quality Sentinel completed test quality analysis.

Test Quality Sentinel skipped because pre-fetch PR data was unavailable: unable to fetch test file diff

🧪 Test quality analysis by Test Quality Sentinel

@github-actions

github-actions Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Ponytail Reviewer completed successfully!

Generated by Ponytail Reviewer for #56146

@github-actions

Copy link
Copy Markdown
Contributor

Comment Memory

reviewed_at: 2026-08-26T22:55:00Z
review_event: REQUEST_CHANGES
top_themes:
  - grader clustering misclassifies mixed-status runs as fail
  - missing test coverage for mixed grader outcomes
files_reviewed:
  - pkg/cli/audit_cross_run.go
  - pkg/cli/audit_cross_run_clusters.go
  - pkg/cli/audit_cross_run_clusters_test.go
  - pkg/cli/logs_orchestrator_render.go
comment_count: 1

Note

This comment is managed by comment memory.

It stores persistent context for this thread in the code block at the top of this comment.
Edit only the text inside the backtick fences; workflow metadata and the footer are regenerated automatically.

Learn more about comment memory

🔎 Code quality review by PR Code Quality Reviewer · pi · gpt54 · 12.9 AIC · ⌖ 8.1 AIC · ⊞ 4.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.

Request changes

The new grader/eval clustering is headed in the right direction, but the grader bucketing logic currently collapses mixed outcomes into fail, which throws away the distinction this PR claims to add and makes the new cohort analysis misleading.

Blocking theme
  • deriveGradersClusterValue uses priority checks that make mixed unreachable for common multi-status runs, so partial-pass / partial-fail cohorts are silently misclassified.
  • The added test coverage only exercises pure pass and pure fail inputs, so the broken mixed-state behavior is not protected.

🔎 Code quality review by PR Code Quality Reviewer · pi · gpt54 · 12.9 AIC · ⌖ 8.1 AIC · ⊞ 4.6K
Comment /review to run again

Comments that could not be inline-anchored

pkg/cli/logs_orchestrator_render.go:167

The mixed grader cluster is effectively dead code here: any run with both passing and failing grader results is classified as fail (and unavailable is also swallowed by fail), so the new clustering loses the distinction between partial failure and a pure fail cohort.

<details><summary>💡 Why this blocks merge</summary>

countGraderStatuses produces independent counters, but deriveGradersClusterValue short-circuits on Failed &gt; 0 before checking whether the run also had passes or u…

@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: Apply cross-run audit clustering to graders and evals

The refactoring is clean — extracting the inline cluster-building into buildRunClusters improves readability and makes extending dimensions straightforward. The new graders and evals clustering dimensions follow the established pattern consistently.

One pre-existing inline comment (line 222, logs_orchestrator_render.go) flags a potential logic issue in deriveGradersClusterValue: if countGraderStatuses assigns every result to exactly one counter, the "mixed" branch may be unreachable. Worth verifying or adding a test case that exercises the "mixed" path to confirm the "mixed" return is reachable before merging.

No other blocking issues found.

🧵 Reviewed using Impeccable skills by Impeccable Skills Reviewer · copilot · sonnet46 · 18.6 AIC · ⌖ 9.06 AIC · ⊞ 6.2K

@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, /diagnosing-bugs, and /codebase-design — requesting changes on one correctness issue and two supporting improvements.

📋 Key Themes & Highlights

Key Themes

  • mixed cluster unreachable (correctness): deriveGradersClusterValue uses sequential > 0 guards; a run with errors is returned as "error" before the "fail" or "unavailable" checks run, and "mixed" is never reached for any combination of counters with Passed < Total. See existing inline comment on line 222 and the new comment on line 209.
  • Derivation logic untested: The new test exercises buildClusterAnalysis with pre-filled GradersCluster fields, so deriveGradersClusterValue is never exercised by the test suite. Edge cases (mixed, error+fail, nil graders with zero Total) are uncovered.
  • Magic boolean: runHasEvals(logsPath, false) buries intent; a named constant or wrapper removes ambiguity.

Positive Highlights

  • ✅ Clean extraction of cluster-building into buildRunClusters — easy to extend.
  • absent fallback for empty strings is consistent across both new dimensions.
  • ✅ Good test structure: parallel, named RunIDs, explicit cluster lookup loop.

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · copilot · sonnet46 · 31.2 AIC · ⌖ 10.2 AIC · ⊞ 7.6K
Comment /matt to run again

@@ -49,6 +49,48 @@ func TestBuildClusterAnalysis_ClustersConclusion(t *testing.T) {
assert.Contains(t, failureCluster.RunIDs, int64(3))
}

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 test sets GradersCluster directly on the struct, bypassing deriveGradersClusterValue entirely — so the derivation logic (including the mixed-reachability bug in logs_orchestrator_render.go) has no unit test coverage.

💡 Add a focused unit test for `deriveGradersClusterValue`

A direct unit test would have caught the > 0 guard that makes mixed unreachable. The cluster-analysis test only exercises the grouping; it never exercises the derivation path.

@copilot please address this.

graders := extractGradersData(logsPath)
if graders == nil || graders.Total == 0 {
return "absent"
}

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 priority ordering here (errorfailunavailablepass) means a run with both failures and unavailable graders returns "fail" and never "unavailable". If the intent is a strict precedence, document it; if not, consider returning "mixed" when multiple non-passing states are present.

💡 Suggested fix for mixed-state detection
nonPassCount := graders.ErrorCount + graders.Failed + graders.UnavailableCount
if nonPassCount > 1 {
    return "mixed"
}
if graders.ErrorCount > 0 {
    return "error"
}
if graders.Failed > 0 {
    return "fail"
}
if graders.UnavailableCount > 0 {
    return "unavailable"
}
return "pass"

Alternatively, add a comment explaining the intended precedence so future readers don't change the order inadvertently.

@copilot please address this.

func deriveEvalsClusterValue(logsPath string) string {
if runHasEvals(logsPath, false) {
return "present"
}

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.

[/codebase-design] deriveEvalsClusterValue calls runHasEvals(logsPath, false) with a hard-coded false argument, but the boolean's meaning is not obvious at the call site. Consider naming the parameter or using a named constant so the intent is self-documenting.

💡 Example
const includePending = false
if runHasEvals(logsPath, includePending) {

Or, if false is the only ever-needed value here, a wrapper runHasCompletedEvals(logsPath) removes the ambiguity entirely.

@copilot please address this.

…sions

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

🏗️ Design Decision Gate — ADR Required

This PR makes significant changes to core business logic (112 new lines in pkg/cli/) but does not have a linked Architecture Decision Record (ADR).

📄 Draft ADR committed: docs/adr/56146-add-graders-evals-clustering-dimensions.md — review and complete it before merging.

🔒 This PR cannot merge until an ADR is linked in the PR body.

📋 What to do next
  1. Review the draft ADR committed to your branch — it was generated from the PR diff
  2. Complete the missing sections — add context the AI couldn't infer, refine the decision rationale, and list real alternatives you considered
  3. Commit the finalized ADR to docs/adr/ on your branch
  4. Reference the ADR in this PR body by adding a line such as:

    ADR: ADR-56146: Add Graders and Evals Clustering Dimensions

Once an ADR is linked in the PR body, this gate will re-run and verify the implementation matches the decision.

❓ Why ADRs Matter

"AI made me procrastinate on key design decisions. Because refactoring was cheap, I could always say 'I'll deal with this later.' Deferring decisions corroded my ability to think clearly."

ADRs create a searchable, permanent record of why the codebase looks the way it does. Future contributors (and your future self) will thank you.

📋 Michael Nygard ADR Format Reference

An ADR must contain these four sections to be considered complete:

  • Context — What is the problem? What forces are at play?
  • Decision — What did you decide? Why?
  • Alternatives Considered — What else could have been done?
  • Consequences — What are the trade-offs (positive and negative)?

All ADRs are stored in docs/adr/ as Markdown files numbered by PR number (e.g., 56146-add-graders-evals-clustering-dimensions.md for PR #56146).

🏗️ ADR gate enforced by Design Decision Gate 🏗️ · claude · sonnet46 · 66.7 AIC · ⌖ 24.8 AIC · ⊞ 8.4K ·
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.

One small helper is just a wrapper over six cluster appends and has one caller; inlining it would keep the logic local. net: -20 lines possible.

Generated by ✂️ Ponytail Reviewer for #56146 · codex · mai10 · 6.02 AIC · ⌖ 3.21 AIC · ⊞ 16.7K
Comment /ponytail to run again

}
}

func buildRunClusters(inputs []crossRunInput) []RunCluster {

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.

pkg/cli/audit_cross_run_clusters.go:94: yagni: buildRunClusters is just a thin wrapper around six one-line buildDimensionClusters calls and has one caller. Inline those appends in buildClusterAnalysis and keep the logic local.

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot PR #56146 still needs follow-up.

Generated by 👨🍳 PR Sous Chef

Generated by 👨‍🍳 PR Sous Chef · pi · gpt54 · 13.9 AIC · ⌖ 8.09 AIC · ⊞ 8.7K ·
Comment /souschef to run again

…erogeneous runs

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

Copilot AI commented Aug 27, 2026

Copy link
Copy Markdown
Contributor Author

@copilot PR #56146 still needs follow-up.

  • Please address the outstanding requested-changes reviews from automated reviewers....

Addressed the outstanding review: deriveGradersClusterValue now compares each status counter against Total, so a run is labeled pass/fail/error/unavailable only when every grader shares that status, and any heterogeneous combination (including the four-status fixture) is mixed. Added derivation tests covering homogeneous, mixed, and absent grader artifacts, and updated ADR-56146 to match. Branch is up to date with main and make agent-report-progress passes.

Copilot AI requested a review from gh-aw-bot August 27, 2026 00:01
@pelikhan
pelikhan merged commit 8880259 into main Aug 27, 2026
@pelikhan
pelikhan deleted the copilot/ensure-clustering-in-graders-evals branch August 27, 2026 00:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants