Conversation
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
|
✅ PR Code Quality Reviewer completed the code quality review.
|
|
✅ Design Decision Gate 🏗️ completed the design decision gate check. See the comment below for the result and any generated ADR draft.
|
|
🧠 Matt Pocock Skills Reviewer has completed the skills-based review. ✅
|
|
✅ Ponytail Reviewer completed successfully!
|
|
✅ Test Quality Sentinel completed test quality analysis. Test Quality Sentinel skipped because pre-fetch PR data was unavailable: unable to fetch test file diff
|
Comment MemoryNote This comment is managed by comment memory.It stores persistent context for this thread in the code block at the top of this comment.
|
There was a problem hiding this comment.
Request changes
--graders introduces a correctness regression in run filtering: it can silently exclude runs that actually have grader output, which makes both the CLI filter and the new daily audit workflow produce incomplete results.
Blocking theme
- grader-run detection is less robust than the existing evals path and currently has a false-negative failure mode
- the new scheduled audit depends on that filter, so the bug directly affects report accuracy
🔎 Code quality review by PR Code Quality Reviewer · pi · gpt54 · 25 AIC · ⌖ 8.27 AIC · ⊞ 7K
Comment /review to run again
| } | ||
|
|
||
| func skipByGradersFilter(result DownloadResult, opts runFilterOpts, verbose bool) bool { | ||
| if !opts.gradersOnly || runHasGraders(result.LogsPath) { |
There was a problem hiding this comment.
The new --graders filter can silently drop valid runs because it only checks for grader_results.json under the downloaded artifacts and never attempts the same branch fallback that --evals uses, so any run where the usage artifact omitted grader results will be misreported as “no grader results” even though the workflow did produce them.
💡 Why this blocks merge
skipByGradersFilter calls runHasGraders(result.LogsPath) and immediately filters the run out when that file is absent. Unlike the evals path just above it, there is no recovery path analogous to ensureEvalsResultsFromBranch(...).
That means the correctness of gh aw logs --graders now depends on every historical run having grader artifacts mirrored into the downloaded bundle. If that mirroring regresses, if an older run predates it, or if only the fallback artifact contains the data, this filter returns false negatives and the new daily audit workflow will undercount or completely miss grader runs.
Please either add a grader-specific fallback with the same robustness as evals, or explicitly prove at the download layer that grader results are always materialized before filtering.
There was a problem hiding this comment.
Review: Daily Grader Audit Workflow
Modes applied: audit + critique (new feature)
The PR is well-structured. The workflow prompt is clear, Go changes follow existing patterns (applyEvalsArtifact → applyGradersArtifact), and test coverage is adequate. No blocking issues found.
Non-blocking observations
1. Missing test branches for applyGradersArtifact
The test suite doesn't cover:
gradersOnly=falsewith a non-empty list → should return unchanged.gradersOnly=truewith"all"already present → should not append"graders".
These mirror gaps that exist in applyEvalsArtifact tests too, so this is consistent with the existing codebase — but they are the exact branches guarding against duplicate injection.
2. graders: {} in frontmatter
The empty graders: {} map is presumably intentional (the audit workflow itself runs no deterministic graders). Confirm this is the correct idiom for "no graders" vs. simply omitting the key.
3. Phase 4 copy step fragility
The prompt instructs the agent to cp the report file to the safeoutputs staging directory before calling upload_artifact. If the copy fails silently, the upload will proceed with a missing or empty file and the eval downloadable_report_uploaded will fail. Consider adding an explicit file-existence check in the prompt, or referencing the source path directly if the tool supports it.
🧵 Reviewed using Impeccable skills by Impeccable Skills Reviewer · copilot · sonnet46 · 26.5 AIC · ⌖ 12 AIC · ⊞ 6.2K
There was a problem hiding this comment.
Pull request overview
Adds grader-aware log filtering and a scheduled workflow that publishes daily grader health reports.
Changes:
- Adds
--gradersfiltering across CLI and MCP paths. - Adds grader artifact selection and focused tests.
- Adds the daily grader audit workflow and generated lock file.
Show a summary per file
| File | Description |
|---|---|
pkg/cli/mcp_tools_privileged.go |
Exposes and forwards MCP grader filtering. |
pkg/cli/mcp_tools_privileged_test.go |
Tests MCP argument forwarding. |
pkg/cli/logs_orchestrator_types.go |
Adds grader filter options. |
pkg/cli/logs_orchestrator_filters.go |
Implements grader run filtering and refactors filters. |
pkg/cli/logs_orchestrator_filters_test.go |
Tests grader-result filtering. |
pkg/cli/logs_orchestrator_download.go |
Wires filters and refactors collection state. |
pkg/cli/logs_filtering_test.go |
Tests CLI flag registration. |
pkg/cli/logs_command.go |
Registers and loads --graders. |
pkg/cli/logs_artifact_set.go |
Adds the graders artifact set. |
pkg/cli/logs_artifact_set_test.go |
Tests grader artifact expansion. |
.github/workflows/daily-grader-audit.md |
Defines the scheduled audit and report. |
.github/workflows/daily-grader-audit.lock.yml |
Contains the compiled workflow. |
Review details
- Files reviewed: 11/12 changed files
- Comments generated: 2
- Review effort level: Balanced
| Use the agentic-workflows MCP `logs` tool once: | ||
|
|
||
| ```json | ||
| { | ||
| "workflow_name": "", | ||
| "count": 100, |
| SafeOutputType: values.SafeOutputType, | ||
| FilteredIntegrity: values.FilteredIntegrity, | ||
| EvalsOnly: values.EvalsOnly, | ||
| GradersOnly: values.GradersOnly, |
🧪 Test Quality Sentinel ReviewScore: 78/100 SummaryThis PR adds 59 new test scenarios across 4 test files for the daily grader audit workflow feature. Tests demonstrate strong behavioral coverage with table-driven testing patterns and comprehensive edge-case handling. Test Files
✅ Strengths
|
There was a problem hiding this comment.
pkg/cli/logs_orchestrator_filters.go:L62: yagni: one helper per filter plus a generic skip logger. Inline the existing checks in applyRunFilters; the extra indirection doesn't buy anything yet.
net: -18 lines possible.
Generated by ✂️ Ponytail Reviewer for #56359 · codex · mai10 · 6.33 AIC · ⌖ 2.14 AIC · ⊞ 17K
Comment /ponytail to run again
| var awInfoErr error | ||
| if opts.engine != "" || opts.runtime != "" || opts.noStaged || opts.firewallOnly || opts.noFirewall { | ||
| awInfoPath := filepath.Join(result.LogsPath, "aw_info.json") | ||
| awInfo, awInfoErr = parseAwInfo(awInfoPath, verbose) |
There was a problem hiding this comment.
pkg/cli/logs_orchestrator_filters.go:L62: yagni: one helper per filter plus a generic skip logger. Inline the existing checks in applyRunFilters; the extra indirection doesn't buy anything yet.
There was a problem hiding this comment.
Skills-Based Review 🧠
Applied /codebase-design and /diagnosing-bugs — requesting changes on three issues: one dead-code function, one misleading flag description/behaviour gap, and two correctness concerns introduced in the orchestrator refactor.
📋 Key Themes & Highlights
Key Themes
- Dead code:
isGradersArtifactRequestedis defined but never called in production paths. Either wire it up (asisEvalsArtifactRequestedis) or remove it. - Behaviour/docs mismatch:
applyGradersArtifactis only invoked when--artifactsis already set, so--gradersalone does not auto-include grader artifacts despite the flag usage text saying it does. - Iteration accounting: Rate-limit errors increment
state.iterationbeforecontinue, silently burning towardMaxIterationswith no fetch. - Partial-result contract change:
handleLogsBatchErrornow returns partialstate.processedRunsfor generic errors where the old code returnednil— the new contract should be documented or reverted to match the old behaviour.
Positive Highlights
- ✅ Excellent decomposition of
applyRunFiltersinto focusedskipBy*helpers — the filter chain via||short-circuiting is clean and readable. - ✅
logsCollectionStatestruct cleanly captures loop state; the extraction offetchAndProcessLogsBatchmakes the batch loop much easier to test. - ✅ Good test coverage for the new
--gradersflag registration, artifact expansion, and MCP forwarding. - ✅
logAndMaybeExplainSkipremoves duplication across all filter helpers — good DRY refactor. - ✅ The daily audit workflow is well-scoped: it targets a clear time window, specifies exact output structure, and correctly uses
upload_artifactsafe-output with 1-day retention.
🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · copilot · sonnet46 · 97.3 AIC · ⌖ 10.6 AIC · ⊞ 7.6K
Comment /matt to run again
Comments that could not be inline-anchored
pkg/cli/logs_artifact_set.go:389
[/codebase-design] isGradersArtifactRequested is defined but never called in production code — it is dead code as introduced.
isEvalsArtifactRequested is called in audit_run_pipeline.go (line ~81) and logs_run_processor.go (line ~78) to gate fallback download behaviour. If graders need the same integration, those call sites need to be wired up; if not, the function should be removed to keep the codebase navigable.
<details>
<summary>💡 Options</summary>
Option A — wire it up …
pkg/cli/logs_command.go:283
[/codebase-design] applyGradersArtifact is only called when len(options.ArtifactSets) > 0, so gh aw logs --graders without --artifacts will not automatically include grader artifacts — but the flag's usage text claims it does.
The same pattern exists for --evals, so this may be intentional, but the documentation is misleading and the PR description's example (gh aw logs --graders --artifacts graders) suggests users are expected to pass --artifacts graders manually when us…
pkg/cli/logs_orchestrator_download.go:218
[/diagnosing-bugs] Rate-limit error path increments state.iteration before continue, burning an iteration slot even though no batch fetch occurred.
When waitForLogsRateLimit returns a non-deadline/non-canceled error, the code does state.iteration++; continue. On the next loop body waitForLogsRateLimit is called again with the bumped iteration index, but the HTTP fetch is still skipped. If this error recurs repeatedly, MaxIterations can be exhausted with zero successful fetches …
pkg/cli/logs_orchestrator_download.go:293
[/diagnosing-bugs] handleLogsBatchError returns (false, err) for generic (non-context) errors, which causes collectProcessedWorkflowRuns to return partial state.processedRuns to the caller. The old code returned nil for these errors.
Returning partial results on a fetch error can mislead the caller into thinking the scan was complete up to that point, when in fact it was interrupted mid-run. If partial data is acceptable, the function and its caller should document this explicitl…
…workflow Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds a scheduled grader audit that finds workflow runs with defined or imported graders and publishes a downloadable 24-hour report. Also adds grader-aware log filtering so audits can target runs with grader output.
CLI filtering
gh aw logs --gradersto filter downloaded workflow runs to those containing grader results.MCP support
gradersparameter to the privilegedlogsMCP tool.Daily audit workflow
.github/workflows/daily-grader-audit.md.Coverage
Example: