Skip to content

Add payload-based grader execution command - #58634

Merged
pelikhan merged 7 commits into
mainfrom
copilot/add-subcommand-for-graders
Sep 5, 2026
Merged

Add payload-based grader execution command#58634
pelikhan merged 7 commits into
mainfrom
copilot/add-subcommand-for-graders

Conversation

Copilot AI commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Adds a graders run subcommand for executing one workflow grader against either a completed run’s archived payload or JSON from standard input.

  • CLI

    • Adds gh aw graders run <workflow-id> <grader-id> [run-id].
    • Supports repository overrides with --repo.
  • Payload replay

    • Persists preprocessed grader payloads in agent artifacts.
    • Redacts payloads before upload.
    • Enforces payload size and JSON validation.
  • Execution

    • Runs built-in and sandboxed inline graders.
    • Supports operational-value evaluator payloads.
    • Preserves grader thresholds, metadata, and implementation digests.
gh aw graders run weekly-research loops 123456789
cat payload.json | gh aw graders run weekly-research custom-score
  • Documentation
    • Documents artifact-based and stdin-based usage.
    • Adds release metadata for the new command.


✨ PR Review Safe Output Test - Run 33932452774

Warning

Firewall blocked 2 domains

The following domains were blocked by the firewall during workflow execution:

  • clients2.google.com
  • mtalk.google.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "clients2.google.com"
    - "mtalk.google.com"

See Network Configuration for more information.

💥 [THE END] — Illustrated by Smoke Claude · claude · sonnet46 · 50.6 AIC · ⌖ 18.2 AIC · ⊞ 7.8K ·
Comment /smoke-claude to run again


Generated by 👨‍🍳 PR Sous Chef · pi · gpt54 · 54.6 AIC · ⌖ 9.63 AIC · ⊞ 9.2K ·
Comment /souschef to run again

Copilot AI and others added 2 commits September 4, 2026 23:25
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 Add graders run subcommand Add payload-based grader execution command Sep 4, 2026
Copilot AI requested a review from pelikhan September 4, 2026 23:40

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

Warning

Firewall blocked 2 domains

The following domains were blocked by the firewall during workflow execution:

  • clients2.google.com
  • mtalk.google.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "clients2.google.com"
    - "mtalk.google.com"

See Network Configuration for more information.

💥 [THE END] — Illustrated by Smoke Claude · claude · sonnet46 · 50.6 AIC · ⌖ 18.2 AIC · ⊞ 7.8K
Comment /smoke-claude to run again

@@ -0,0 +1,5 @@
---
"gh-aw": minor

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.

✅ Smoke test review comment #1: Changeset entry looks good — gh-aw: minor bump is appropriate for a new subcommand. Consider documenting any migration steps for users. — Run 33932452774

/tmp/gh-aw/agent_output.json
/tmp/gh-aw/safeoutputs.jsonl
/tmp/gh-aw/agent/graders/grader_manifest.json
/tmp/gh-aw/agent/graders/grader_payload.json

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.

✅ Smoke test review comment #2: Adding /tmp/gh-aw/agent to artifact paths is a good practice for capturing agent outputs. Ensure this path is cleaned up between runs to avoid stale artifacts. — Run 33932452774

@pelikhan

pelikhan commented Sep 5, 2026

Copy link
Copy Markdown
Collaborator

@copilot test support for running script directly (run: script file.sh) and inline scripts.

Copilot AI and others added 2 commits September 5, 2026 01:40
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>

Copilot AI commented Sep 5, 2026

Copy link
Copy Markdown
Contributor Author

@copilot test support for running script directly (run: script file.sh) and inline scripts.

Added explicit execution coverage for both forms in b18f6dc: an operational-value run: .github/graders/test-operational-value.sh fixture that validates stdin payload delivery, and an inline JavaScript grader test that verifies its complete normalized result and digest.

@pelikhan
pelikhan marked this pull request as ready for review September 5, 2026 02:13
Copilot AI balanced review requested due to automatic review settings September 5, 2026 02:13
@github-actions

github-actions Bot commented Sep 5, 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 Sep 5, 2026

Copy link
Copy Markdown
Contributor

Test Quality Sentinel completed test quality analysis.

Warning

Threat Detection Engine Failure — The analysis engine could not complete. This is a tooling failure, not a security finding.

What happened

The threat detection engine failed to produce results.

Review the workflow run logs for details.

🧪 Test quality analysis by Test Quality Sentinel

@github-actions

github-actions Bot commented Sep 5, 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 Sep 5, 2026

Copy link
Copy Markdown
Contributor

PR Code Quality Reviewer completed the code quality review.

Warning

Firewall blocked 4 domains

The following domains were blocked by the firewall during workflow execution:

  • api.github.com
  • github.com
  • pypi.org
  • raw.githubusercontent.com

[!TIP]
api.github.com is blocked because GitHub API access uses the built-in GitHub tools by default. Instead of adding api.github.com to network.allowed, use tools.github.mode: gh-proxy for direct pre-authenticated GitHub CLI access without requiring network access to api.github.com:

tools:
  github:
    mode: gh-proxy

See GitHub Tools for more information on gh-proxy mode.

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "api.github.com"
    - "github.com"
    - "pypi.org"
    - "raw.githubusercontent.com"

See Network Configuration for more information.

🔎 Code quality review by PR Code Quality Reviewer

@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Ponytail Reviewer completed successfully!

Warning

Firewall blocked 2 domains

The following domains were blocked by the firewall during workflow execution:

  • ab.chatgpt.com
  • github.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "ab.chatgpt.com"
    - "github.com"

See Network Configuration for more information.

Generated by Ponytail Reviewer for #58634

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.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Note

This error may be related to your runner configuration. You can now configure runners for Copilot code review separately from Copilot cloud agent by creating a copilot-code-review.yml file with your setup steps. Read the docs for details.

@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor
🏗️ ADR required — draft added for PR #58634

I enforced the ADR gate for this PR because the prefetch summary shows 590 added lines in default business logic directories, which is above the 100-line threshold.

Evidence used

  • PR title: Add payload-based grader execution command
  • PR body describes a new gh aw graders run subcommand, persisted grader payloads, replay from artifacts/stdin, and redaction before upload.
  • Diff adds:
    • pkg/cli/graders_command.go and pkg/cli/graders_run.go for a new grader replay execution path
    • actions/setup/js/trace_graders.cjs persistence of grader_payload.json
    • workflow artifact updates to archive that payload
    • documentation for the new replay flow
  • No existing ADR was referenced in the PR body, and the most recent ADR on the branch (docs/adr/58607-...) covers a different decision.

Gate result

A draft ADR has been added at:

  • docs/adr/58634-add-payload-based-grader-execution.md

Inferred decision captured in the draft

  • Decision: persist preprocessed grader payloads and support replaying one grader via gh aw graders run from either a saved run artifact or stdin.
  • Primary driver: enable reproducible, standalone grader execution without rerunning the full workflow.
  • Alternatives covered: keeping grading tied to full workflow execution only; reconstructing replay input from raw logs/artifacts on demand.
  • Consequences covered: faster debugging and reproducibility, balanced against a new persisted artifact contract and added artifact/security complexity.

Next action for the author

Please review and refine docs/adr/58634-add-payload-based-grader-execution.md, then keep it with this PR as the design record for the new grader replay architecture.

🏗️ ADR gate enforced by Design Decision Gate 🏗️ · pi · gpt54 · 35.6 AIC · ⌖ 12.5 AIC · ⊞ 9.7K ·
Comment /review to run again

@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Comment Memory

reviewed_at: 2026-09-05T02:19:21Z
review_event: COMMENT
top_themes:
  - no blocking issues found in changed grader replay scope
  - grader payload archival is now covered by redaction and artifact tests
files_reviewed:
  - actions/setup/js/trace_graders.cjs
  - docs/src/content/docs/setup/cli.md
  - pkg/cli/graders_command.go
  - pkg/cli/graders_integration_test.go
  - pkg/cli/graders_run.cjs
  - pkg/cli/graders_run.go
  - pkg/cli/graders_run_test.go
  - pkg/constants/job_constants.go
  - pkg/workflow/compiler_yaml_graders.go
  - pkg/workflow/graders_config_test.go
comment_count: 0

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

Warning

Firewall blocked 4 domains

The following domains were blocked by the firewall during workflow execution:

  • api.github.com
  • github.com
  • pypi.org
  • raw.githubusercontent.com

[!TIP]
api.github.com is blocked because GitHub API access uses the built-in GitHub tools by default. Instead of adding api.github.com to network.allowed, use tools.github.mode: gh-proxy for direct pre-authenticated GitHub CLI access without requiring network access to api.github.com:

tools:
  github:
    mode: gh-proxy

See GitHub Tools for more information on gh-proxy mode.

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "api.github.com"
    - "github.com"
    - "pypi.org"
    - "raw.githubusercontent.com"

See Network Configuration for more information.

🔎 Code quality review by PR Code Quality Reviewer · copilot · gpt54 · 56.7 AIC · ⌖ 7.32 AIC · ⊞ 23.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.

No blocking issues found in the grader replay changeset. The new graders run path, payload archival, and redaction wiring are internally consistent, and the targeted coverage around the new artifact path and command surface is adequate.

Warning

Firewall blocked 4 domains

The following domains were blocked by the firewall during workflow execution:

  • api.github.com
  • github.com
  • pypi.org
  • raw.githubusercontent.com

[!TIP]
api.github.com is blocked because GitHub API access uses the built-in GitHub tools by default. Instead of adding api.github.com to network.allowed, use tools.github.mode: gh-proxy for direct pre-authenticated GitHub CLI access without requiring network access to api.github.com:

tools:
  github:
    mode: gh-proxy

See GitHub Tools for more information on gh-proxy mode.

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "api.github.com"
    - "github.com"
    - "pypi.org"
    - "raw.githubusercontent.com"

See Network Configuration for more information.

🔎 Code quality review by PR Code Quality Reviewer · copilot · gpt54 · 56.7 AIC · ⌖ 7.32 AIC · ⊞ 23.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.

Skills-Based Review 🧠

Applied /diagnosing-bugs, /tdd, and /codebase-design to the new graders run payload-execution command — requesting changes for one functional bug.

📋 Key Themes & Highlights

Key Themes

  • Bug: runOperationalValuePayload never uses config.Repo, calling getGitHubHostForRepo("") twice — the --repo override silently has no effect on host resolution for operational-value graders.
  • Test coverage gap: graders_run_test.go only exercises the stdin payload path; the artifact-download branch (RunID != 0) and the --repo override are completely untested.
  • Architecture: graders_run.cjs duplicates the VM sandbox (deepFreeze, context lockdown, safeMath, helpers) already implemented in actions/setup/js/trace_graders_worker.cjs, risking security-hardening drift between the two copies.

Positive Highlights

  • ✅ Solid payload validation (readGraderPayload): size limit, empty check, JSON validity, all with source-aware errors.
  • ✅ Sensible timeout and stderr handling around the Node subprocess (runJavaScriptGrader), including a distinct message for deadline exceeded.
  • ✅ Good CLI ergonomics — graders run docs, examples, and integration test coverage for help text and invalid run IDs.

@copilot please address the review comments above.

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · copilot · sonnet50 · 56.2 AIC · ⌖ 16.1 AIC · ⊞ 10.3K
Comment /matt to run again

Comment thread pkg/cli/graders_run.go Outdated
return nil
}

func runOperationalValuePayload(ctx context.Context, workflowArg string, payload json.RawMessage, output io.Writer) error {

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] runOperationalValuePayload ignores config.Repo entirely, calling getGitHubHostForRepo("") twice instead of getGitHubHostForRepo(config.workflowArg)-equivalent using the actual repo override. This defeats the --repo flag for the operational-value grader path, since the host is always resolved from empty string (falling back to the default host) regardless of what the user passed.

💡 Suggested fix
func runOperationalValuePayload(ctx context.Context, workflowArg, repo string, payload json.RawMessage, output io.Writer) error {
	host := getGitHubHostForRepo(repo)
	evaluator, err := loadOperationalValueReportEvaluator(ctx, workflowArg, host)
	...
	runOperationalValueEvaluatorBash(ctx, "/bin/bash", evaluator.EvaluatorPath,
		[]string{evaluator.EvaluatorPath, "--grade-run"}, payload, operationalValueEvaluatorTimeout, host)

and update the call site in runGrader to pass config.Repo through. Also worth adding a regression test that sets Repo and asserts the evaluator/bash call receives the expected host, since graders_run_test.go currently never exercises config.Repo at all.

@copilot please address this.

return "test"
}

func TestRunGraderFromStdin(t *testing.T) {

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] No test exercises loadGraderRunPayload's artifact-download branch (config.RunID != 0) or the config.Repo override — only the stdin path is covered. This is the more complex, higher-risk branch (temp dirs, artifact listing/downloading, flattenUnifiedArtifact, file lookup) and it currently has zero regression coverage.

💡 Suggested test

Add a test that fakes/mocks the artifact download (or uses a lightweight seam) to verify: (1) the correct artifact names are requested, (2) findGraderFile locates grader_payload.json after flattenUnifiedArtifact, and (3) an error is returned when the payload file is missing from the artifact — this last case is easy to assert without network access by pre-seeding a temp dir.

@copilot please address this.

Comment thread pkg/cli/graders_run.cjs
}
return value;
}

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] This file reimplements the inline-grader VM sandbox (deepFreeze, vm.createContext with codeGeneration lockdown, safeMath, helpers, timeouts) that already exists in actions/setup/js/trace_graders_worker.cjs. Two independently-maintained copies of a security-sensitive sandbox is a risk: a future hardening fix (e.g. new blocked global, stricter timeout) applied to one will silently miss the other.

💡 Suggested improvement

Consider extracting the shared sandbox construction (deepFreeze, context setup, safeMath, helpers) into a common module both trace_graders_worker.cjs and graders_run.cjs can require, or at minimum add a code comment cross-referencing the other file so changes are kept in sync, plus a shared test asserting both sandboxes reject the same set of dangerous globals.

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

Two simplifications are worth cutting in the new grader runner: the bespoke Node sandbox and the temp-script subprocess wrapper. net: -20 lines possible.

Warning

Firewall blocked 2 domains

The following domains were blocked by the firewall during workflow execution:

  • ab.chatgpt.com
  • github.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "ab.chatgpt.com"
    - "github.com"

See Network Configuration for more information.

Generated by ✂️ Ponytail Reviewer for #58634 · codex · mai10 · 11.6 AIC · ⌖ 24.2 AIC · ⊞ 14K
Comment /ponytail to run again

Comment thread pkg/cli/graders_run.cjs
return value;
}

function runInline(grader, trace) {

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/graders_run.cjs:L56: yagni: 140-line custom VM sandbox for one-off graders. Keep a small adapter and reuse the workflow runner until a second runtime shape exists.

Comment thread pkg/cli/graders_run.go
return data, nil
}

func runJavaScriptGrader(ctx context.Context, grader graderRunDefinition, payload json.RawMessage, output io.Writer) error {

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/graders_run.go:L174: shrink: temp-file staging plus a subprocess wrapper around every grader run. A single in-process helper or direct node -e entrypoint would remove most of this ceremony.

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

Reviewed graders_run.go/graders_run.cjs (new payload-based grader execution). Sandboxing (frozen vm context, disabled require/process/eval), payload size limits, JSON validation, and temp-file permissions all look solid.

One correctness bug found: --repo is ignored for operational-value graders (see inline comment on pkg/cli/graders_run.go:223). Everything else in this diff — CLI wiring, artifact download path, JS grader execution, redaction-step change (now unconditional, matches the fact that built-in payloads also contain trace data) — looks correct and well tested.

🧵 Reviewed using Impeccable skills by Impeccable Skills Reviewer · copilot · sonnet50 · 76.6 AIC · ⌖ 13.4 AIC · ⊞ 8.3K

Comment thread pkg/cli/graders_run.go Outdated
}

func runOperationalValuePayload(ctx context.Context, workflowArg string, payload json.RawMessage, output io.Writer) error {
evaluator, err := loadOperationalValueReportEvaluator(ctx, workflowArg, getGitHubHostForRepo(""))

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.

--repo is silently ignored when the grader is operational-value. runGrader never threads config.Repo into runOperationalValuePayload, which calls getGitHubHostForRepo("") twice (line 223 and 229) instead of getGitHubHostForRepo(config.Repo). Elsewhere in this file (loadGraderRunPayload) and in the existing graders operational-value command, --repo correctly overrides host/owner/repo resolution. Here, running gh aw graders run my-workflow operational-value 123 --repo other/repo will resolve the evaluator using the default host config instead of the repo the user asked for, which is surprising and inconsistent with the rest of the command.

Fix: pass config.Repo through to runOperationalValuePayload and use getGitHubHostForRepo(config.Repo) for both calls.

@copilot please address this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in the follow-up commit: --repo is normalized to the requested repository host and passed to both evaluator loading and --grade-run execution. The script-file regression test now exercises Repo and verifies GH_HOST.

@gh-aw-bot

Copy link
Copy Markdown
Collaborator
pr-sous-chef

@copilot Please take the next forward-progress pass on this PR.

  • Two fresh reviews on the current branch still point at follow-up work, including the --repo override being ignored for operational-value graders.
  • Please address the current review feedback on HEAD, refresh the branch if needed, and run the pr-finisher skill before handing back to maintainers.
  • In your handoff, summarize which review findings were fixed and whether any remaining blocker is only routine CI or maintainer approval.

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

Generated by 👨‍🍳 PR Sous Chef · pi · gpt54 · 54.6 AIC · ⌖ 9.63 AIC · ⊞ 9.2K ·
Comment /souschef to run again

Copilot AI and others added 2 commits September 5, 2026 02:41
Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>
Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>

Copilot AI commented Sep 5, 2026

Copy link
Copy Markdown
Contributor Author
pr-sous-chef
```...

Fixed in commit d34da01: graders run now normalizes and propagates --repo to operational-value evaluator execution, with regression coverage asserting the evaluator receives the overridden host. Local focused tests and change-scoped validation pass; CI will need a maintainer-triggered rerun after this push.

Copilot AI requested a review from gh-aw-bot September 5, 2026 02:49
@pelikhan
pelikhan merged commit c496aa9 into main Sep 5, 2026
44 checks passed
@pelikhan
pelikhan deleted the copilot/add-subcommand-for-graders branch September 5, 2026 04:36
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.

4 participants