How it works
Three roles, and only one of them is a sandbox:- Trigger — a GitHub Actions workflow fires on
pull_requestevents (opened,synchronize,reopened). No idle cron. - Orchestrator — a stateless script from the published
@superserve/loopspackage runs on the CI runner: it finds the repo’s loop sandbox by metadata, runs one tick inside it, then pauses it. - Worker sandbox — a Firecracker microVM booted from the
superserve/claude-codetemplate. The repo clone, the review state, and Claude Code all live here, warm between ticks.
- Warm checkout. The repo and its dependencies are cloned once, on the first tick. Every later tick resumes the same box and skips setup entirely.
- Isolation. A PR diff is untrusted code. It is reviewed — and your test suite runs against it — inside an isolated microVM, never on your runner or laptop.
- ~$0 idle. The box is paused between ticks; you pay for seconds of compute per review, plus your LLM tokens.
Prerequisites
| You need | Where to get it |
|---|---|
Superserve API key (ss_live_…) | console.superserve.ai |
| A Claude credential | claude setup-token (Pro/Max/Team/Enterprise subscription, mints a ~1-year token) — or a metered ANTHROPIC_API_KEY |
| bun | bun.sh — only to run the installer |
| GitHub access | Nothing extra — reviews post as github-actions[bot] via the workflow’s built-in token. A PAT or App is opt-in (below). |
Install
Run inside the repo you want reviewed:- Prompts for your Superserve API key (hidden input) and — when the
claudeCLI is installed — runsclaude setup-tokenfor you to mint the long-lived Claude token. - Stores that token as a Superserve secret (
claude-oauth) bound toapi.anthropic.com— it is swapped in at egress and never enters the sandbox. - Sets
SUPERSERVE_API_KEYas a GitHub Actions secret on the repo. - Writes
.github/workflows/loop-pr-loop.yml— the only file added to your repo — then commits it (scoped to just that file; anything else you had staged stays staged) and pushes it after you confirm (--yesis the non-interactive consent).
The push only ever publishes the installer’s own commit. If your branch is
already ahead of upstream with unpublished work, the installer refuses to
auto-push — and whenever it can’t or won’t push (no upstream, no write
access, confirmation declined), it prints the exact commands to run yourself.
The workflow runs the published package (
bunx @superserve/loops@stable run pr-loop …) — no loop source is vendored into your repo. @stable is a gated
release channel, so loop improvements roll out without you ever editing the
file.Try one tick locally
No install, no repo changes — good for seeing the resolved plan and one live review first:--pr to sweep every open PR in one tick, or add --watch=15m to re-tick on an interval.
Where your credentials live
| Credential | Where it lives | Does it enter the sandbox? |
|---|---|---|
| Superserve API key | GitHub Actions secret | No — only the orchestrator on the CI runner uses it |
| Claude token | Superserve secret claude-oauth | No — the box sees a stand-in value; the real token is attached at egress, only toward api.anthropic.com |
| GitHub token | Minted per run by GitHub Actions | Yes, but it is repo-scoped, least-privilege, and expires when the run ends |
Bring your own bot identity
By default reviews post asgithub-actions[bot] — zero GitHub credentials to create. Two opt-in upgrades:
A custom name — machine-user PAT
Create a dedicated GitHub account (e.g.acme-review-bot) and mint a fine-grained PAT on the target repo with Contents: Read, Pull requests: Read & write, Issues: Read & write. Classic repo-scope tokens are refused — repo includes push and merge rights, which would void the loop’s propose-only guarantee. Then install with:
loop-github-token and swapped at egress. This path is also how one repo’s workflow reviews a different repo.
A name and an avatar — your own GitHub App
A GitHub App gets you the[bot] badge, a profile picture, and short-lived per-repo tokens. The App — and its private key — stay yours, in your own repo’s (or org’s) secrets; nothing is shared.
- Create the App: GitHub → Settings → Developer settings → GitHub Apps → New GitHub App. The name becomes the handle (
acme-pr-loop→acme-pr-loop[bot]). Uncheck the webhook. Permissions:Contents: Read-only,Pull requests: Read & write,Issues: Read & write. - Upload a logo under Display information (this is the avatar), generate a private key, and install the App on the repo you’re reviewing.
- Store the App credentials as Actions secrets — repo-level, or org secrets so every repo inherits them:
- Install with
--github-app— the installer writes the App-token workflow for you, no YAML editing:
actions/create-github-app-token, scoped to that one repo and expiring within the hour, and posts reviews as your App. Because the credentials are referenced by secret name, setting LOOP_APP_ID / LOOP_APP_PRIVATE_KEY as org secrets once covers every future repo — install the loop into a new repo and it inherits the identity with no extra token setup.
Make it review your way
These work with the published loop as-is — nothing to fork:- Review norms and the merge bar. Each run the loop reads your repo’s
CLAUDE.md/AGENTS.md/README.mdfor the review conventions and what “ready to merge” means in your project. Write your team’s rules there and reviews follow them. - The verifier’s checks. The loop runs your project’s own tests, lint, and build — discovered from
CLAUDE.md,AGENTS.md,Makefile, or CI config on the default branch. Nothing loop-specific to define. - Your own skills. Commit them to your repo at
.claude/skills/<name>/SKILL.md. Claude Code runs inside your cloned repo, so it discovers project skills automatically.
Rotate, revoke, uninstall
- Rotate a credential by re-running the installer.
addis idempotent: it rotates the existing Superserve secrets in place and rewrites the same workflow file. The Claude token lasts about a year; when it expires, runclaude setup-tokenagain and re-run the installer. - Revoke independently. Revoke the Claude token in your Claude account, the PAT in GitHub settings, or the Superserve API key in the console — each kills its own half without touching the others.
- Uninstall by deleting the workflow file, then kill the warm sandbox (console → Sandboxes → the box named
pr-loop, orSandbox.killById) and delete theclaude-oauthsecret.
Safety model
- Never merges, force-pushes, or edits
.github/workflows. The strongest action it takes is a review plus aready-to-mergelabel — kept in bounds by the skill’s rules and, decisively, by the least-privilege token scope below: acontents: readtoken cannot merge or push, no matter what runs in the sandbox. - Prompt-injection firewall. PR content is treated as data, not instructions. The loop refuses instructions embedded in diffs or comments and only runs the project’s own checks, read from the default branch — never commands suggested by the PR.
- Least privilege. The workflow grants
contents: readandpull-requests: write, nothing else. Fork PRs are skipped by default (their token is read-only); review them via the PAT path if you want them covered. - Human gates. Security, auth, payments, or core-infra changes — and PRs stuck across several runs — get a
needs-humanlabel and an@-mention instead of silent action.
Two cost meters, don’t conflate them: pausing the sandbox makes sandbox
compute roughly free between ticks, but LLM tokens are billed separately by
Anthropic. A subscription token from
claude setup-token keeps ticks off
metered API billing.See also
Source and full install guide
The loop’s code, review rubric, and the step-by-step README — from “just try
it” to a branded bot with your own skills.
Secret binding
How credentials are swapped in at egress so they never enter the sandbox.
Claude Code sandboxes
Run Claude Code interactively in a Superserve sandbox.
Sandbox lifecycle
Pause, resume, and the warm-state model the loop is built on.