Agent review plans and receipts¶
Use these provider-neutral commands to describe review work for an external adapter and evaluate its results. YAGA validates policies and receipts; it does not execute the configured agents. The adapter is responsible for running each lens and authenticating its evidence.
For the experimental fixed Codex request/completion protocol, see the separate GitHub review adapter. That adapter cannot execute configured lens instructions or bind outcomes to a policy digest. Neither surface is required for ordinary CI checks.
Named lenses¶
One pull request can be reviewed by multiple named agents, each with a distinct lens and blocking policy. The configuration is policy, not credentials:
[agent-review]
version = 1
required = ["correctness", "security"]
aggregation = "all-required"
[agent-review.agents.correctness]
preset = "codex"
instruction = "Review behavior, tests, and compatibility."
outcome = "review"
publication = "inline"
[agent-review.agents.security]
preset = "codex"
instruction = "Review trust boundaries and least privilege."
outcome = "review"
[agent-review.agents.documentation]
preset = "codex"
instruction = "Review public documentation and developer ergonomics."
outcome = "advisory"
publication = "comment"
Required lenses participate in the aggregate gate; advisory lenses can publish findings without
blocking it. Every lens must have a unique name, a bounded instruction, a bounded adapter preset
label, and one publication mode: comment, inline, reaction, review, or check. The mode describes
the intended provider output; it does not grant credentials or bypass provider capabilities.
Credentials, tokens, and provider-specific secrets stay in the trusted workflow environment.
Adapters return only the closed outcomes passed, failed, or pending, keyed by lens name. The
provider-neutral evaluator applies all-required or any-required to required lenses, preserves
advisory failures and pending work for reporting, and never lets an advisory lens block the gate.
Unknown lens names and outcome values are configuration errors.
Validate the policy before wiring it into a workflow:
yaga gate agent-review policy check --file .yaga.toml
yaga gate agent-review policy check --file .yaga.toml --format json
The JSON check report is a validation summary for wrappers and CI tooling. It contains the schema
version, passed status, aggregation mode, lens and required counts, required lens order, and the
matching plan_digest; it does not contact a provider or include credentials. Use policy plan
--format json when an adapter needs the full instructions and provider-neutral lens items.
To inspect the exact provider-neutral work the policy describes, render its execution plan:
yaga gate agent-review policy plan --file .yaga.toml
yaga gate agent-review policy plan --file .yaga.toml --format json
yaga gate agent-review policy template --file .yaga.toml > review-results.json
yaga gate agent-review policy evaluate --file .yaga.toml --results review-results.json
yaga gate agent-review policy evaluate --file .yaga.toml --results review-results.json --format github
The plan preserves configuration order, marks every lens as required or advisory, and carries
the requested publication mode. Its plan_digest is a deterministic SHA-256 identity of the
version, aggregation, and ordered lens definitions. It does not contact an agent, resolve a preset,
or read credentials. Adapters can use the JSON document as their input and must copy its digest into
the result receipt while returning one closed outcome for each named lens.
Text plan output prints the same digest on a separate Plan digest: line; JSON plan output carries
it as plan_digest. Evaluation text, JSON, and GitHub notice output repeat the digest so CI logs
can be correlated with the exact configuration used.
When an adapter needs a result file before all providers have completed, use policy template to
create a complete JSON scaffold:
The scaffold contains the current policy version, matching plan_digest, and exactly one explicit
pending result for every configured lens in policy order. Replace each pending outcome with the
adapter's passed, failed, or pending result and optionally add a bounded summary; do not
remove lenses or edit the digest. The command is read-only and prints only JSON, so it is suitable
for a temporary handoff file or a job artifact. Evaluation still revalidates the file against the
current policy.
Adapter integration checklist¶
An adapter can be implemented in any language or workflow system. Keep provider-specific execution outside YAGA and make the YAGA boundary a small, deterministic handoff:
- Load the trusted policy and run
policy checkbefore contacting a provider. - Render
policy plan --format jsonand retain itsplan_digestwith the adapter run. - For each ordered lens, select the adapter named by
preset, pass itsinstructionas data, and preserve the requestedoutcomeandpublicationmode. Do not treat the instruction as executable shell or workflow source. - Correlate every provider result to the exact pull request, base SHA, head SHA, lifecycle
boundary, and adapter request before accepting it. An uncorrelated result is
pendingor an operational failure, never an implicit pass. - Start from
policy templateor construct the same complete receipt: one result per lens, in any order, with the exact plan digest. Usepassedfor a completed clean lens,failedfor a completed finding, andpendingwhen the provider has not completed. - Run
policy evaluate --format githubin the publishing step. Exit0means the configured aggregation passed: every required lens forall-required, or at least one forany-required. Exit1means the aggregate failed or remains pending, and2means the policy, receipt, provider handoff, or invocation could not be validated safely.
The adapter may publish comments, inline findings, reactions, reviews, or checks while it runs,
but those provider artifacts are not the receipt itself. Keep the receipt summary short and
bounded; store detailed provider output in the provider's own bounded artifact or review surface.
Never put credentials, access tokens, or unbounded provider responses in the policy, plan, receipt,
GitHub outputs, or error text. If a lens fails before a provider result can be correlated, retain
the explicit pending result and report the operational cause separately rather than fabricating a
failed review outcome.
Treat the plan and receipt as one versioned handoff. A trusted adapter should generate the plan from the policy, pass each ordered lens to its selected provider, preserve the lens name and requested publication mode in its own provider work, and write one result for every plan item. If the policy file, lens order, aggregation, instruction, preset label, outcome role, or publication mode changes, the digest changes and the adapter must generate a new receipt before evaluation. The result contract is deliberately small:
{
"version": 1,
"plan_digest": "8fab465b0b8ea9bf25e0c993387673ddde272405e885573f2094e09611c02cf0",
"results": [
{"lens": "correctness", "outcome": "passed", "summary": "No findings."},
{"lens": "documentation", "outcome": "failed", "summary": "The setup example is stale."}
]
}
policy evaluate rejects malformed, duplicate, unknown, incomplete, oversized, or plan-mismatched
results. An adapter must explicitly return pending when a lens has not completed; omission is an
invalid handoff rather than an implicit pending state. Evaluation applies the configured
aggregation and returns exit 0 only when all blocking policy requirements pass.
Operational and configuration failures honor the selected output format too: JSON emits the
versioned error document on standard error, while GitHub output emits one escaped error command.
Advisory failures remain visible without changing that exit state. Use --format github when the
adapter runs in a GitHub Actions step: it emits escaped error annotations for blocking failures and
pending lenses, warning annotations for advisory findings, and one bounded notice summary. The
format never prints the full untrusted result summary and keeps the same exit codes as text and
JSON.
An explicitly returned result without a summary is reported as provider returned no summary; the
distinct no result was returned detail is reserved for internal incomplete-state rendering.
End-to-end adapter example¶
The repository contains a synthetic, provider-neutral example in
examples/agent-review-policy.toml
and its matching result receipt in
examples/agent-review-results.json.
Run the complete local flow from the repository root:
yaga gate agent-review policy check --file examples/agent-review-policy.toml
yaga gate agent-review policy plan \
--file examples/agent-review-policy.toml \
--format json
yaga gate agent-review policy evaluate \
--file examples/agent-review-policy.toml \
--results examples/agent-review-results.json
The example exits 0: both blocking lenses passed even though the advisory documentation lens
failed. A real adapter replaces the example result file after it runs its configured lenses. It
should translate provider-specific comments, inline findings, reactions, native reviews, or check
runs into exactly one result per configured lens, preserving a short human-readable summary.
YAGA does not execute the configured preset or instruction and does not grant provider credentials;
the trusted integration owns that work and must correlate its evidence to the current pull request,
commit, lifecycle boundary, and request before writing the receipt.
Use a blocking failure to exercise CI behavior:
{"version":1,"plan_digest":"8fab465b0b8ea9bf25e0c993387673ddde272405e885573f2094e09611c02cf0","results":[
{"lens":"correctness","outcome":"failed","summary":"A regression is present."},
{"lens":"security","outcome":"passed"},
{"lens":"documentation","outcome":"passed"}
]}
In that case policy evaluate exits 1 and prints the blocking lens. Exit 2 is reserved for
malformed policy/results or an operational error, so adapters can distinguish a review finding
from a broken handoff. The result document is a bounded local interchange format, not an
authorization token or security authority by itself.
The validator requires schema version 1, at least one required lens, unique lower-case lens names,
known outcomes (review or advisory), publication modes, bounded instructions, and a bounded
preset label. The label is intentionally not a YAGA provider registry: an external adapter decides
which service, model, or human workflow it represents. The validator does not contact an agent or
read credentials. Run the installed policy check, plan, template, and evaluate commands in
that adapter's trusted workflow. The fixed GitHub composite Action does not accept configured policies. PR-controlled policy or receipt content must
never be used as security authority.
Evidence responsibility¶
An external adapter must correlate results to the exact pull request, base and head commits, named lens, adapter preset, lifecycle boundary, and request. The local receipt evaluator validates policy identity and aggregates outcomes; it does not independently authenticate provider evidence. PR-controlled policy or receipt content must never be treated as security authority.