Graders

Graders compute deterministic metrics without LLM calls. Built-in and custom inline graders inspect post-agent execution traces. The reserved operational-value grader evaluates the current run’s operational outcome under a frozen evaluator. Results are persisted in the agent artifact for downstream tools.

For normative requirements, see the Graders Specification.

graders: {}

An empty map enables all built-in graders with default settings. Omitting the graders field entirely disables grading (no step is emitted).

IDDescriptionValue
tool-success-rateFraction of tool calls that succeeded0–1
tool-failure-countNumber of failed tool callsinteger
retriesCount of retry events in MCP gateway logsinteger
loopsConsecutive identical tool calls (same name + args)integer
trajectory-efficiencyUnique tool names / total tool calls0–1
execution-step-countTotal LLM request countinteger
execution-durationTotal execution duration (ms)integer
working-set-rebuild-factorCumulative input tokens / peak invocation input tokens≥1
context-growthTotal tokens / first-request tokens≥1
artifact-productionCount of outputs in agent_output.jsoninteger

These built-ins are deterministic projections over the canonical Trajectory IR (trace.trajectoryIR, trace.ir, or agentOutput.trajectory). They run in-process with no API calls. When the IR data a grader needs is missing, the grader reports unavailable instead of a score. Any IR collection with more than 5,000 items is also reported as unavailable, which bounds the cost of the quadratic graders.

IDDescriptionValue
policy-near-missFraction of successful traces that left guard or policy objectives unsatisfied0–1
skill-constraint-coverageFraction of configured skill constraints that were exercised and passed0–1
exploration-errorUnmet objectives attributable to insufficient search0–1
exploitation-errorUnmet objectives attributable to gathered evidence that was never used0–1
state-revisit-probability-repFraction of canonical state visits that revisit an already visited state0–1
recurrence-determinismRQA DET: fraction of recurrent points forming diagonal (repeated-subsequence) lines0–1
recurrence-laminarityRQA LAM: fraction of recurrent points forming vertical (stagnation) lines0–1
recurrence-trapping-timeRQA TT: average length of vertical recurrence lines≥0
recurrence-rateRQA RR: density of recurrent state pairs across the run0–1
event-entropy-rateNormalized conditional Shannon entropy rate of the ordered event sequence0–1
lempel-ziv-trajectory-complexityNormalized LZ76 complexity of the canonical event sequence0–1
tool-output-consumption-rateFraction of tool outputs referenced by a later action0–1
end-to-end-lineage-completenessFraction of final outputs traceable to tool or observation evidence roots0–1
action-provenance-coverageFraction of consequential actions with a provenance path to tool or observation evidence0–1
premature-termination-gapDeclared completion conditions still unsatisfied at terminationinteger
evidence-saturation-stopping-lagEvents elapsed between all objectives being satisfied and the run stoppinginteger
dependency-order-violation-rateFraction of dependent objectives satisfied before their prerequisites0–1
objective-coverageFraction of declared objectives that were completed0–1
grounding-accuracyFraction of actions that were valid in the state in which they were issued0–1
tool-wise-scoreLongest correct execution prefix against a reference trajectory, with parameter credit0–1
trajectory-ndtwNormalized dynamic time warping similarity to a reference state trajectory0–1
code-search-recallFraction of reference patch files located during the run0–1
code-read-precisionFraction of distinct read or inspected files touched by the reference patch0–1

code-read-precision uses file-level evidence, not symbols: distinct actions[].target paths whose type is exactly read or inspect and whose consequential flag is false. The score is the number of those files in reference.patch.files[] divided by the number of distinct read/inspected files. Reference files may be strings or { path } records. Paths are trimmed and leading ./ or / is stripped, as for code-search-recall. Missing reference data, malformed required fields and runs without file reads report unavailable.

skill-constraint-coverage reads its constraints from config.constraints:

graders:
skill-constraint-coverage:
config:
constraints:
- id: uses-docs-skill
pattern: "skill .*documentation"

Every built-in grader runs on every trace whenever the graders step runs, even if the workflow lists only custom graders. To opt out of a built-in, set enabled: false for it.

Disable a specific built-in:

graders:
loops:
enabled: false

Add a trusted inline JavaScript expression that receives the preprocessed trace object:

graders:
bash-calls:
script: "return trace.toolCalls.filter(t => t.name === 'bash').length"

Custom scripts must return a value and stay within 4096 characters (no require, import, fetch, eval, or process.exit).

trace.toolCalls merges native agent tool calls parsed from the Copilot events.jsonl session log with the MCP gateway records. Native entries always expose name and source: "agent", plus arguments, toolCallId, mcpServerName, and mcpToolName when the underlying event provides them, so built-in tools such as skill are visible to graders. A matching tool.execution_complete event sets success and completed: true; calls that never complete keep completed: false and no success value, and are scored as failures by the built-in tool-success-rate and tool-failure-count graders. Gateway records that duplicate a native call (same tool name and arguments) are dropped, and trace.nativeToolCalls holds the native records on their own.

Configure the reserved operational-value grader with either inline Bash:

graders:
operational-value:
name: Maintainer Time Saved
description: Maintainer effort avoided by the current run's accepted outcome
unit: hours
direction: higher_is_better
script: |
#!/usr/bin/env bash
set -euo pipefail
request=$(cat)
printf '%s\n' '[{"id":"maintainer-hours-saved","value":2.5}]'

or a repository-relative Bash evaluator:

graders:
operational-value:
name: File Diet Decision Conformance
description: Whether the run requested the correct refactoring issue or noop
unit: ratio
direction: higher_is_better
run: .github/graders/daily-file-diet-operational-value.sh

Specify exactly one of script or run. Give the primary metric a concise name, description, unit, and direction; its description is retained in grader artifacts. Document every emitted metric in evaluator comments so its meaning is frozen with the evaluator bytes. The compiler records the evaluator’s SHA-256 digest and packages its exact bytes with the run.

The evaluator runs once with no arguments. It reads a request containing schemaVersion, run, event, outputs, and config from standard input. outputs contains the current run’s validated safe-output requests; those requests do not prove that their GitHub mutations were applied. The evaluator writes one non-empty ordered array of {id,value} metrics. The first metric is primary; later metrics are diagnostics. Values are finite numbers or null. Numeric values retain their native scale; gh-aw does not normalize, clamp, or convert them to pass/fail. Use unit and direction to describe their meaning.

Evaluators receive GH_TOKEN with the agent job’s explicitly declared permissions, but no workflow secrets, and enabling the grader does not add evidence permissions to the agent job.

Use the operational value designer skill (/operational-value-designer) to infer operational value from an agentic workflow and design and verify an operational-value evaluator.

FileDescription
grader_manifest.jsonWhich graders were configured and their enabled state
grader_results.jsonValidated raw values, status, implementation identity, and ordered operational-value metrics
operational_value_evaluator.shExact frozen operational-value evaluator used for this run

All files are included in the unified agent artifact.

The graders step runs as an if: always() post-agent step in the existing agent job, after log parsing and before the unified artifact upload. It uses a single preprocessing pass over trace files shared by all graders.