Verify before you push
Have your coding agent run PR verification inline against a local diff, before a pull request exists.
This page lets you run Spectrace's PR verification from a connected AI agent against a diff the agent supplies, so you get a per-criterion verdict before opening a pull request.
"Verify before you push" is not a separate feature. It is the MCP tool spectrace_pr_verifications_create called with mode: "inline". There is no git hook, no GitHub Action, no CLI and no dedicated pre-push tool — the agent calls the tool, and the result is persisted like any other verification run.
Prerequisites
- An agent connected to Spectrace over MCP. See Connect an agent.
- A requirement in a project with at least one acceptance criterion. Inline verification checks the diff against the requirement's acceptance criteria, user story and linked test cases.
- An organization on a paid plan. The tool requires the
verifications:writescope, which every organization role (owner,admin,member) carries. - For local stdio or self-hosted servers:
OPENAI_API_KEYin the server's environment. Inline verification calls the AI provider. On the hosted endpoint this is handled server-side.
The two modes
spectrace_pr_verifications_create has two modes and they behave very differently.
| Mode | What it does | What it returns |
|---|---|---|
inline | Runs the AI verifier now against the prDiff you pass, plus the requirement's acceptance criteria, user story and linked test cases. Makes no GitHub API call. Persists the run and its results. | verificationId, overallScore (0–100), overallStatus, confidence, summary, recommendations, acResults, coverageSummary |
register (default) | Links a PR to the requirement. The GitHub App webhook honours the link on the next push — rung 0 of requirement resolution, deciding before branch/title/body references. Runs nothing itself. | verificationId, status: "pending", linked: true, verificationRan: false |
If you omit mode, you get register, which never produces a score. Polling a registered run does not change that. Pass mode: "inline" when you want a verdict.
Runs are keyed on (project, prNumber, headSha): calling again with the same three values reuses the existing verification row, whatever requirementId created it. In inline mode the verifier runs again against the prDiff you pass and replaces the row's prior result — repeated runs leave exactly one result. In register mode the existing row is returned unchanged. Use a distinct headSha per commit you want tracked separately.
Any MCP-created run that names a real PR number acts as a registered link — a completed inline run is as deliberate a statement as a register call, so the webhook honours either on the next push. If the pull request's branch, title or body then references a different requirement, the registered requirement still wins and the verification comment carries a "Conflicting reference" note naming the referenced one. Inline runs appear in Spectrace's verification lists with a Pre-push badge.
Required arguments for inline mode
| Argument | Type | Notes |
|---|---|---|
requirementId | UUID | The requirement to verify against. |
prNumber | number | Required by the schema even before a PR exists. Stored on the run. |
prUrl | string, 1–500 chars | Required by the schema. Not validated as a URL. |
headSha | string, 7–40 chars | The commit you are verifying, e.g. git rev-parse HEAD. Part of the run key. |
prDiff | array of file objects | Required for inline mode. Each object has optional filename, status, additions, deletions, patch. Missing or empty → MISSING_REQUIRED_FIELD. |
prTitle, prBody, prAuthor | optional | Passed to the verifier as PR metadata. |
baseSha, repoFullName | optional | Stored on the verification row only; they never reach the verifier. repoFullName falls back to the project's GitHub repository, or unknown. |
Before a pull request exists, pass prNumber: 0 and a recognisable prUrl (for example local:feat/sss-050-login-rate-limit). A run with prNumber: 0 can never act as a registered link, because real GitHub PR numbers start at 1 — so placeholder runs never pin a future PR to a requirement by accident. Once the PR exists, calling with its real number makes the run double as a registered link the webhook honours (rung 0). Use a fresh headSha for each commit you want verified.
A worked flow for an agent
- Load the requirement
Call
spectrace_requirements_get_contextwith therequirementId. It returns the reference number (for examplesss-050), user story, acceptance criteria with theirids, subtasks, linked test cases, linked files and the project. It ends with the same instructions as this page: mark subtasks, toggle criteria, link files, then verify inline.spectrace_workflow_next_stepon the same requirement returns blocking items first — for example an acceptance criterion with no test case. - Implement
As you start and finish each subtask, call
spectrace_tasks_updatewithstatus: "in_progress"or"done". This recomputes the requirement's progress percentage. Callspectrace_requirements_link_filefor each file that realises the requirement; a duplicate path is a no-op, and the links feed traceability and PR resolution later. - Build the diff
Produce the diff for the commit you want checked and shape it as an array of file objects — one entry per file with
filename,statusand the unifiedpatch. The tool takes the diff you give it and nothing else; it does not read your repository or GitHub. - Run inline verification
{ "method": "tools/call", "params": { "name": "spectrace_pr_verifications_create", "arguments": { "requirementId": "…", "mode": "inline", "prNumber": 0, "prUrl": "local:feat/sss-050-login-rate-limit", "headSha": "3f2c1a9e5b7d…", "prTitle": "Rate-limit login attempts", "prDiff": [ { "filename": "src/auth/login.ts", "status": "modified", "patch": "@@ -10,6 +10,12 @@ …" } ] } } }The call runs the verifier synchronously and returns
Verification complete: <score>/100 (<status>)followed by the structured result. Each call counts one agent call against the plan allowance and is subject to the tool timeout (30 seconds by default; the hosted endpoint allows up to 60 seconds per request). - Read acResults
acResultshas one entry per acceptance criterion:Field Meaning criterionId,criterionTextWhich criterion. statusOne of satisfied,partial,not_found,contradicted,unclear.confidence0–1. reasoningWhy the verifier reached that status. evidenceCited hunks: type(code_added,code_modified,test_added,config_change),file,lines,snippet,explanation.suggestionsWhat is missing, when the status is not satisfied.overallStatusis one ofsatisfied,partial,not_addressed,unclear, andrecommendationslists overall follow-ups. Treat anything other thansatisfiedas work still to do, and usesuggestionsto decide what to change next. - Update the requirement
For each criterion the diff satisfies, call
spectrace_acceptance_criteria_togglewithrequirementIdand thecriterionId(or passcompletedexplicitly). Mark the remaining subtasks withspectrace_tasks_update. These are bookkeeping calls: verification does not toggle criteria for you. - Commit and open the PR
Put the requirement reference in the branch name — the VS Code extension's convention is
feat/{refNumber}-{slug}, for examplefeat/sss-050-login-rate-limit— or in the PR title or body. When the pull request opens, Spectrace resolves the requirement from that reference and runs the webhook-driven verification on GitHub. Alternatively, once the PR number is known, call the tool again withmode: "register"and the real number: the webhook then verifies against the registered requirement directly (rung 0), beating any conflicting reference. See Linking a PR to a requirement.
Later, fetch a run with spectrace_pr_verifications_get by verificationId or by projectId + prNumber + headSha, or read the resource spectrace://verification/{id}.
What done looks like
You are done when the inline call returns overallStatus: "satisfied" for the requirement, or when every non-satisfied criterion is one you have consciously deferred, and the acceptance criteria and subtasks in Spectrace reflect the state of the diff.
Failure cases:
- No score,
verificationRan: false— you omittedmodeor passedregister. Call again withmode: "inline"andprDiff. MISSING_REQUIRED_FIELD: prDiff is required for mode='inline'— pass a non-emptyprDiffarray.- The same result comes back after new commits — the
prDiffyou passed did not change; inline mode verifies exactly the diff you supply. Rebuild the diff from the current commit and pass itsheadShaso the run is recorded against the new commit. INSUFFICIENT_PERMISSIONS— the key does not carryverifications:write. Every organization role has it, so this means the key was created with narrowed scopes outside the UI; create a new key under Settings → Developers.- An error about the plan — the organization is on the Free plan, or its monthly agent-call allowance is used up.
TIMEOUT_ERROR("Request timed out") — the diff is large or the model was slow. Retry, or split the diff by requirement. On stdio or self-hosted servers you can raiseSPECTRACE_TIMEOUT.
Related
- Connect an agent — hosted, stdio and self-hosted setup.
- Tool reference — full argument schemas for every tool.
- How PR verification works — the webhook-driven path that runs on GitHub.
- Reading a verification result — the same statuses as they appear in the app and on the PR.
- Linking a PR to a requirement — how the branch, title and body reference is resolved.