---
name: pr-next-step
description: "Use when an agent must pick its next step on a pull request (analyze, compare, draft, or validate) and merging or posting stays with the owner."
---

# Choosing an agent's next step on a PR

An agent that works pull requests and needs one bounded next step chosen before it touches anything, with the merge decision kept outside the agent.

DeltaX Evaluate is the checkpoint in the middle of this recipe. It selects one step from the eligible candidates you submit, or refuses, and returns an auditable trace. It does not give a reason for its choice. The scenario that ships with this skill is illustrative: replace its values with your own.

## Setup

- Create a Free account at https://deltaxevaluate.com/account and create an API credential. Allowance and plans are on https://deltaxevaluate.com/pricing.
- Set `DELTAX_CLIENT_ID` and `DELTAX_CLIENT_SECRET` in your server or agent environment. `DELTAX_ACCESS_TOKEN` is also read if you already have a token. Never paste any of them into chat, files, repositories, or logs.
- `integration.py` needs Python 3.9 or newer and no packages. Contract: `2026-09-16.beta2`, profile `deltax-hosted-bounded-review-evaluation-v1`. If a request is blocked, a descriptive User-Agent (`DELTAX_USER_AGENT`) may help.

## Steps

1. **Collect observed pull request facts.** Read check status, changed file count, and review state from your code host. Put only scalar values in context. Leave out repository URLs, paths, and anything secret.
2. **State the situation.** Write the objective (at most 1024 characters): what is being decided and what is not allowed. Add context as scalar values only (string up to 256 characters, number, boolean, or null; at most 16 entries). No secrets, no personal data, and no reserved keys such as `url`, `path`, `token`, or `tool`. Include `evidence_kind` and a date. A changed situation needs a changed request.
3. **Build the candidates.** List 1 to 8 candidates with unique ids of at most 64 characters. Use `analyze`, `compare`, `draft`, or `validate` for steps your agent can perform and the owner can review. Describe exactly what happens and state that nothing is sent, merged, or published. Add every consequential outside action you are considering as one `external` candidate. External candidates are shadow only and cannot be selected.
4. **Set support.** Set support from your own logged results if you have them, otherwise report labeled judgment and say so in each description (the sample labels its values illustrative).
5. **Declare your fallback before calling.** Decide now what your own system does if Evaluate refuses (for example, hand the case to a person). The fallback is your action, with its own risks. Evaluate does not perform it.
6. **Run it.** Run `python3 integration.py scenario.json --dry-run` to check the request locally, then run it without `--dry-run`. It sends one evaluation with an `Idempotency-Key` and credentials from the environment. Reuse the same key and body to retry. Never turn a timeout into a new request.
7. **Reconcile before you act.** Reject the result if `api_version` is not `2026-09-16.beta2`, if `profile_id` is not the profile you sent, if the selected id is not one of your submitted review candidates, or if any `authority` or `trace` flag is not `false`. On HTTP 202 stop and reuse the original key. On 429 stop.
8. **Act within your own rules.** If the outcome is `selected`, perform that one review step yourself and hand the result to the owner. If it is `governed_noop_refusal`, stop this path and use your declared fallback. A selection is never permission or authority. Anything with an outside effect needs its own separate yes from the owner, outside Evaluate.
9. **Record it.** Store the request, the full response, the top-level `receipt_id`, `result.commercial_receipt.receipt_id`, and `result.trace.trace_id` with the work. Keep the receipt with the pull request record. Merging, posting a comment, or pushing a change is a separate decision by the owner.

## Sample candidates

The files `scenario.json` and `integration.py` ship with this skill. Every support value in the sample is an illustrative placeholder, labeled as such (see `scenario.README.md`).

| candidate_id | semantic_class | operator_reported_support |
| --- | --- | --- |
| `analyze-failing-check` | analyze | 0.8 |
| `compare-diff-to-description` | compare | 0.7 |
| `draft-review-comment` | draft | 0.6 |
| `validate-tests-cover-change` | validate | 0.6 |
| `merge-pull-request-now` | external | 0.9 |

## Setting support

- **Labeled judgment is the starting point.** Most teams have no history of which agent step helped on which kind of pull request. Report your own judgment for each candidate and say so in its description. The sample's own values are labeled illustrative; replace them.
- **Measured data when you have it.** If you log what happened after each step (for example, how often the step led to a fixed check or an accepted review comment), use that dated, sourced rate as the support value and name the window in the description. Do not use the agent's own confidence.
- Facts in `context` such as the check status are reported by you. Evaluate does not verify them.

## Reading the response

The result sits inside `result`. `outcome` is `selected` or `governed_noop_refusal`, and `selected_candidate_id` is a submitted id or `null`. `reason_codes` holds bounded outcome codes, such as `candidate_selected_within_bounded_evaluation`; store it with the receipt, and do not present it, or any entry in `trace.lambda_decisions`, as a reason for or against any single candidate. The account record id (`receipt_id`) and the evaluator receipt id (`result.commercial_receipt.receipt_id`) are different records. Keep both.
