agentic reviews
for autonomous ci/cd
Push review into the agent's commit loop, not the pull request. Reviewer-agents you control return structured verdicts on every diff — and an approval is a cryptographic attestation, bound to the diff, that anything downstream can verify by signature alone. In the trusted shapes the verdict itself is signed by a stamp server you deploy, so forging a review means forging a server signature. Accuracy is settled in the loop, so the PR is free to be about alignment — the part that actually needs a human.
stamp · ed25519 signing · three deployment shapes, one review flow// the review cycle
// backpressure, not a bigger PR
The expensive part — an AI actually reading the change — runs in the agent's loop, scoped to the diff, not in a git hook. Put a model call in a hook and you've blocked git on a slow review: that's the crawl. Instead the agent calls the reviewers on the diff, gets structured verdicts, fixes, and re-runs — a pass takes ~5–30 seconds on a small change, so it cycles against the reviewer in real time. And re-reviews get cheaper as you converge: identical (diff, prompt) pairs are served from a verdict cache, and a reviewer that already weighed in re-reads only the delta since its last look.
What sits at the git boundary is cheap: a signature check. The reviewer signs an attestation over the diff when it approves; the pre-receive hook (or a CI check) just verifies that signature — milliseconds, no model call, no test run. The precommit gate is fast because the thinking already happened upstream, on a tiny diff.
// AI code review, minus the burden
The human attention that used to go to re-reading diffs is freed for the judgment only a human can make. And because review is cheap per-diff, the agent decomposes into tiny commits on purpose — so what arrives for alignment is a clean, scoped change, not a giant unreadable AI PR.
All the questions that make agent PRs exhausting — did it skip an edge case, did it really run the tests it claimed, did it touch files it had no reason to — are accuracy questions. They get answered upstream, by reviewers built to look for exactly that, before anything becomes a PR. So the PR stops being where you play detective: the attestation already says the review happened, and you're left with the one question worth a human — is this the right change? — on a diff small enough to actually answer it.
// get started
Pick a deployment shape — self-hosted gate, GitHub PR check, or local-only — or read the concepts first to understand attestations and the gate.
// concepts
Reviewers are AI personas you control.
An attestation is their signed verdict on the diff.
The gate stays closed until the attestation exists.
Verification re-checks it anywhere, anytime.
A stamp server signs the verdicts, so trust never rests on the operator.
reviewers
AI review personas, defined as plain markdown prompt files at .stamp/reviewers/<name>.md. stamp init scaffolds three — security, standards, product — and you edit them to fit your stack and domain. The whole machine contract is one trailing line: VERDICT: approved (or changes_requested / denied). Everything else is prompt engineering you own.
attestation
A reviewer verdict is signed into a cryptographic attestation bound to the content of the diff (via git patch-id). It travels with the change — a commit trailer on a signed merge, or a refs/stamp/attestations/<patch-id> ref on a PR. Because it's keyed on content, it survives squash, rebase, and merge-commit: the same diff carries the same attestation.
the gate
The gate is the rule that a change can't land until the required reviewers approve. stamp status reports it; stamp merge enforces it before signing. Closed by default — unreviewed or rejected code simply doesn't have a valid attestation, so nothing downstream accepts it.
verification
Any party with the trusted-keys manifest can re-verify an attestation without re-running the reviewers — locally with stamp verify, server-side in a pre-receive hook, or in CI via the stamp/verify-attestation@v1 GitHub Action. The trust root is a manifest of ed25519 public keys you control; signatures are checked end-to-end.
server-attested verdicts
In the trusted shapes, the reviewer LLM runs on a stamp server that holds its own signing key and signs every verdict. The operator never constructs both sides of “what the LLM saw” and “what the LLM said” — forging a review means forging a server signature. And the trust anchors themselves — reviewer prompts, the trusted-keys manifest, path_rules — can't change without admin counter-signatures.
// deployment shapes
One review flow, three ways to enforce it — an explicit trust ladder. Pick deliberately; they make different guarantees.
server-gated — strongest
A stamp server you deployed (git + sshd) signs every verdict and runs a pre-receive hook that rejects unstamped pushes before main moves. Nothing unsigned reaches the remote. stamp provision <name> sets a repo up in one command — bare repo, clone, reviewers, optional locked GitHub mirror. The fastest iteration loop — sign locally, push, done — and the only shape with true server-side enforcement.
github-primary — PR + CI
For teams whose source of truth is GitHub. The reviewer flow stays local (full speed, full control); the attestation rides the PR and a required status check (stamp/verify-attestation@v1) verifies it before merge. Point reviewers at a stamp-server for server-signed verdicts without transferring your source to it. Unreviewed code can't go green.
local-only — fastest, no trust
No server, no server-side enforcement — pure iteration feedback when you haven't deployed a gate. stamp review --plan / --headless fan reviewers out for fast feedback with no signed verdict; stamp merge still signs the merge locally (and stamp verify validates it on any clone), but the remote rejects nothing. Discipline-only: anyone with write access can push. Use it to iterate, then graduate to a gated shape.
// how it fits together
+- author-agent ----------+ +- reviewer-agents --------+ +- gate + sign ------------+ | | | | | | | opens a diff on a | ───>| your personas run in | ───>| all approved? sign a | | feature branch | | parallel, each returns | | v4 attestation bound | | | | a VERDICT: line | | to the diff's patch-id | | stamp review | | .stamp/reviewers/*.md | | stamp merge / attest | +--------------------------+ +--------------------------+ +-----------+--------------+ | +- verify anywhere --------+ | rides the | pre-receive hook · CI |<──────────────────+ commit / PR | check · stamp verify | +---------------------------+
The reviewers are AI personas you author. In the trusted shapes the verdicts they return are signed by the stamp server, not the operator. The attestation is the only thing that needs to be trusted downstream — and it's verifiable by signature, so the verifier never re-runs the model.
// install
Install once, then pick the deployment shape that matches your trust model.
stamp init scaffolds .stamp/ (config + three starter reviewers), generates an ed25519 keypair, and writes an AGENTS.md at the repo root telling your agents how to use the flow. Reviewers run on the Claude Agent SDK — locally in the advisory shapes, on your stamp server in the trusted ones — and require a Claude subscription. Per-reviewer model defaults live in ~/.stamp/config.yml (stamp config reviewers show).
-
Shape A — server-gated (self-hosted, strongest)
$stamp provision myproject --org my-github-orgOne command: provisions the bare repo on your stamp server (
~/.stamp/server.yml), clones it, lands the three starter reviewers + trusted-keys manifest viastamp bootstrap, and optionally creates a GitHub mirror locked by a Ruleset (skip with--no-mirror). Per change:stamp review→stamp merge <branch> --into main→stamp push main. The pre-receive hook verifies the attestation server-side and rejects anything unsigned. Onboard teammate #2 withstamp invites mint <name>/stamp invites accept <url>. See the server quickstart for the Railway walkthrough. -
Shape B — github-primary (PR + CI check)
$cd myproject && stamp init # scaffolds .stamp/ + .github/workflows/stamp-verify.yml$git add .stamp .github && git commit -m "stamp: scaffold PR verification"$git push origin mainIn GitHub: Settings → Branches → Require status checks → add
stamp verify. Per change:stamp review --diff main..HEAD(the attestation auto-mints the moment the gate opens) →stamp attest --into main --push originto push branch + attestation ref → open the PR → the check goes green → a human clicks merge. For server-signed verdicts without code transfer, usestamp init --migrate-to-server-attested --server <host:port>. -
Shape C — local-only (fastest, no trust)
$cd myproject && stamp init --mode local-only --no-pr-checkNo server, no server-side enforcement.
stamp review --plan --diff <revspec>emits a structured plan a parent agent fans out to reviewer subagents (the stamp-review Claude Code skill ships in the repo) — no signed verdict. Merges are still signed locally for discipline, but the remote rejects nothing — graduate to Shape A or B when you want a real gate.
// docs
Reference, source, and where to find help.
// core commands
stamp init [--mode <shape>] Scaffold .stamp/ + keypair + AGENTS.md
stamp provision [name] One-command server-gated setup: bare repo + clone
+ bootstrap (+ GitHub mirror w/ locked Ruleset)
stamp bootstrap Replace placeholder reviewers on a fresh server repo
stamp review --diff <revspec> Run all reviewers in parallel (verdict cache +
delta-scoped re-reviews; auto-mints on gate-open)
stamp review --diff <rev> --only <name> Run a single reviewer
stamp review --plan --diff <rev> Emit a plan for local-only fan-out (no attestation)
stamp status --diff <revspec> Gate check (exit 0 open, 1 closed)
stamp merge <branch> --into <target> Confirm → merge → sign attestation (-y skips prompt)
stamp attest [<branch>] --into <t> --push <remote> Sign + push attestation ref (PR mode)
stamp push <target> Push to the stamp server; hook stderr forwarded
stamp verify <sha> Verify a merge commit's attestation locally
stamp verify-pr <head> --base <ref> --into <branch> Consumer side of the GH Action
stamp reviewers list|add|edit|test|show|remove|fetch|verify Manage review personas
stamp keys generate|list|export|trust ed25519 key management
stamp admin sign|add-key|revoke|list-keys Trust-anchor administration (server-gated)
stamp invites mint|accept Single-use teammate onboarding tokens
stamp users / stamp trust ... Membership + per-repo signing trust
stamp server / stamp server-repos ~/.stamp/server.yml + bare repos on the server
stamp config reviewers show|set Per-user reviewer model config (Sonnet defaults)
stamp manifest sign|verify Signed reviewer-persona manifests
stamp pr / stamp peer Opt-in peer-agentic review over GitHub PRs
stamp log [<sha>] First-parent history w/ attestation summary
stamp prune --older-than <30d> Trim review history from local state.db
stamp ui Interactive TUI: list → detail → review prose
stamp update Update to latest version
// where things live
- .stamp/config.ymlreviewers, branch rules, path rules
- .stamp/reviewers/*.mdyour review personas (prompt files)
- .stamp/trusted-keys/
manifest.yml+ pubkeys — the trust root - .git/stamp/state.dblocal SQLite: review verdicts, never committed
- .git/stamp/failed-runs/structured turn traces when a reviewer fails
- ~/.stamp/keys/
ed25519/ed25519.pub— your signing key - ~/.stamp/server.ymlyour stamp server endpoint (provision, server-repos)
- ~/.stamp/config.ymlper-user knobs: reviewer models, uncommitted
- .github/workflows/
stamp-verify.yml— PR-check verifier (Shape B) - AGENTS.mdshape-aware guidance written into the repo root
// links
- githubgithub.com/OpenThinkAi/stamp-cli
- npmnpmjs.com/package/@openthink/stamp
- designDESIGN.md — spec + security model
- personaswriting reviewer prompts
- threat modelwho attacks, how, what defends
- quickstartserver-gated from zero (Railway walkthrough)
- local-onlythe no-trust iteration mode's contract
- troubleshootingrunbook for when stamp blocks you
- roadmapwhat's shipped + what's next
- issuesgithub.com/OpenThinkAi/stamp-cli/issues
- licenseMIT