Verdict splits code review into steps your agent runs on your machine: fetch, review, gate, post. It fetches the change, your agent writes the findings, and verdict post submits exactly one review. No remote servers, no accounts, no daemon; verdict serve is an opt-in, read-only surface, loopback by default.
- Evidence-graded findings. Every finding carries an evidence rung, from
saidtoreproduced, plus a severity. Unproven claims are labeled, never posted as fact. - Guarded posting. Anchors are validated before posting. One bad anchor never fails a post. Stale-SHA and duplicate-post guards refuse to post over a moved head or a repeat.
- Any model, any agent. The agent you run is the review model. Verdict pins no models.
- Your agent runs only when you ask.
verdict run --agent <name>launches one process against one bundle by default (with--rounds Nit repeats only the launch→check pair up to N rounds): no daemon, queue, scheduler, webhook, or model selection, and by default verdict never interprets what the model wrote (with--rounds Nit runs the shape checker to build the next round's fix list). - Machine-readable. Review verbs print one
--jsonenvelope.reportalso exports SARIF for scanners and CI. - No PR needed.
fetch-localreviews your working tree and never posts.
Pick the route that matches your tools.
npm i -g @stainless-code/verdictOther package managers and OS installers
pnpm add -g @stainless-code/verdict
bun add -g @stainless-code/verdict
yarn global add @stainless-code/verdict
brew install stainless-code/tap/verdictpnpm's release-age gate (minimumReleaseAge) can serve the previous release for
a day after a new one ships, so pin the exact version or add
--config.minimumReleaseAge=0 when you need the newest.
macOS and Linux:
curl -fsSL https://stainless-code.com/verdict/install.sh | shWindows (PowerShell):
irm https://stainless-code.com/verdict/install.ps1 | iexCheck it with verdict --version.
The skill is the review prompt. It ships inside the binary.
verdict skill install --detect--detect installs into every agent whose skills directory already exists and
is non-empty. To target one agent, run verdict skill install --agent claude. The agent names are in verdict skill --help. You can also use the registry: npx skills add stainless-code/verdict. Use one route per machine, or the skill loads twice. The registry route installs only the skill, so install the binary first: install.sh is not shipped in the npm tarball. After verdict upgrade, re-run the install to refresh the copy.
You need gh signed in with repo scope, and git. Run verdict doctor to check.
verdict fetch owner/repo 123 # writes .verdict/state/123/ (diff, metadata, threads)
verdict run owner/repo 123 --agent claude # launch your agent on the bundle; it writes review.json
verdict post owner/repo 123 --dry-run # validate anchors, post nothing
verdict post owner/repo 123 # post exactly one reviewrun knows claude, codex, cursor, and opencode. For any other agent CLI,
--print renders the exact command to run yourself, and everything after -- is
passed to the agent unchanged (verdict run owner/repo 123 --agent claude -- --model opus).
The agent authenticates with your key on your machine; verdict makes no network
calls itself and posts nothing.
No PR yet? Review your working tree instead. This never posts.
verdict fetch-local owner/repo work # writes .verdict/state/local-work/
verdict run owner/repo local-work --agent claude # launch your agent on the local bundle
verdict record owner/repo local-work # validate anchors, save the findings| You want | Run |
|---|---|
| Try it once | npx @stainless-code/verdict --help or bunx @stainless-code/verdict --help |
| Pin a version (npm) | npm i -g @stainless-code/verdict@X.Y.Z |
| Pin a version (shell) | curl -fsSL https://stainless-code.com/verdict/install.sh | VERDICT_VERSION=vX.Y.Z sh |
| Pin a version (PowerShell) | $env:VERDICT_VERSION = 'vX.Y.Z'; irm https://stainless-code.com/verdict/install.ps1 | iex |
| Update | verdict upgrade (add --dry-run to preview) |
| Uninstall | verdict uninstall --remove-path, or the owning manager: npm uninstall -g @stainless-code/verdict, brew uninstall stainless-code/tap/verdict |
The shell installer puts verdict in ~/.verdict/bin. VERDICT_INSTALL picks another directory. It adds that directory to your PATH only if it is missing. --no-modify-path skips the edit.
verdict upgrade detects how you installed and runs the matching update. It never runs in the background.
If the docs site is down, both installers are also release assets: https://github.com/stainless-code/verdict/releases/latest/download/install.sh and install.ps1.
Releases are built from tagged commits, and each release publishes commit.txt with the commit its signature was minted for. checksums.txt is signed with cosign (keyless), and the installers verify the signature — identity, issuer, push trigger, and the workflow-SHA pin to that commit — when cosign is on your PATH, then the archive SHA-256 always. A release without commit.txt is refused rather than installed unpinned. Set VERDICT_REQUIRE_SIGNATURE=1 to fail instead of falling back to checksum-only. To check by hand, use the cosign verify-blob command in Release train.
setup-verdict installs a pinned, verified binary on Ubuntu, macOS, and Windows runners.
- uses: stainless-code/verdict/setup-verdict@vX.Y.Z # pin a release tag or commit
id: verdict
with:
version: vX.Y.Z
- run: ${{ steps.verdict.outputs.path }} --versionInputs are version (default latest) and require-signature (default true). Outputs are path and version. A full workflow is in examples/verdict-review.yml and the CI recipe.
- Skill and CLI. The skill from step 2 drives the CLI. It works with Claude Code, Cursor, Codex, OpenCode, Copilot, Gemini, Goose, Qwen, Windsurf, and any agent that reads an
agentsskills directory. - MCP.
verdict mcpserves the review verbs as tools over stdio.verdict mcp config --agent claudeprints the config entry, and--writemerges it into the file. It supportsclaude,cursor, andcodex, and is experimental until 1.0. See the manual. - Go SDK.
pkg/verdictruns the verbs in-process for Go programs, with typed requests and responses — noverdictsubprocess, no--jsonparsing. - TypeScript client.
import { createClient } from "@stainless-code/verdict/client". It ships in the npm package. Seeclients/ts. - Other languages. Every
--jsonenvelope and store file has a JSON Schema inskills/verdict/schemas/. The Build a client guide covers exit codes and codegen, with a tested Python example.
fetch works on all six hosts. post submits to GitHub, GitLab, and Forgejo.
| Host | --provider |
Fetch uses | Post | Incremental re-review (--base-sha) |
|---|---|---|---|---|
| GitHub | github |
gh |
yes | yes |
| GitLab | gitlab |
glab (or GITLAB_TOKEN) |
yes | yes |
| GitCafe | gitcafe |
cafe (or CAFE_TOKEN) |
no | no |
| Forgejo | forgejo |
curl with FORGEJO_HOST and FORGEJO_TOKEN |
yes | no |
| Bitbucket | bitbucket |
curl with BITBUCKET_TOKEN |
no | no |
| Azure | azure |
az (login or AZURE_DEVOPS_EXT_PAT, AZURE_DEVOPS_ORG) |
no | no |
A GitLab post is not a GitHub post: GitLab has no REQUEST_CHANGES review event, so a --bind --request-changes run posts its discussions and summary as a comment, and post.json records the withheld capability in withheld[] (request_changes, no-request-changes-event). An approval is a real MR approval. The four hosts without a compare adapter accept --base-sha and write an incremental.diff.note instead of a delta.
Forgejo takes one atomic review over its REST API through curl, so it carries both binding verdicts like GitHub. Its comments anchor on file line numbers, the approval event is spelled APPROVED, and a comment the host cannot place — no numeric line, a deleted file — is withheld with a warning rather than sent as an unanchored comment.
On the other three hosts, record, report, show, next, triage, and threads work on the fetched bundle. post, live calibrate, ready, and adopt refuse with a typed error; calibrate --probe runs offline on any bundle. adopt reaches any host verdict can post to (GitHub, GitLab, Forgejo), while ready and live calibrate run on GitHub and GitLab. Details and per-host gaps are in the manual.
- The skill runs with your privileges.
verifyruns the agent'sverifyCmdthroughbash -cwith a 300 second limit. A pre-exec gate refuses destructive, networked, credential-reading, and repo-escaping commands before anything spawns. The gate is a tripwire, not a sandbox. For a hostile PR on Linux,verify --sandboxenforces the sandbox; elsewhere follow the recipe. - Review controls come from the base commit. A PR cannot edit the panel, budget, or knowledge-base rules it is judged by. See Review controls are base-owned.
- Diffs and comments are untrusted input. The prompts treat them as evidence, never as instructions.
- Secrets stay local.
GH_TOKENnever leaves your machine, and provider tokens go only to their own hosts. Nothing phones home: no telemetry, no background updater.
Report vulnerabilities through SECURITY.md.
- Docs site: quickstart, how it reviews, comparison, glossary.
docs/manual.md: the operator manual. Every verb, flag, store file, and exit code.docs/troubleshooting.md: every refusal code, its cause, and its fix.docs/vision.md: what Verdict is and where its craft comes from.CHANGELOG.md: release notes.
Build from source, run the evals, and ship a change: see CONTRIBUTING.md.
MIT. See LICENSE.