Diffinery

codician/diffinerypublic

Open-source, agent-first GitHub and GitHub Actions alternative that runs on your own Cloudflare account: git hosting, pull requests, code review and drop-in GitHub Actions YAML on Workers, Durable Objects, R2 and Containers.

157 lines · 11.5 KBRaw History

title: Agent review description: One of your agents reviews pull requests for bugs, security issues and logic errors, like Cursor's Bugbot, with inline findings, an Agent review check and one-click fixes.

Agent review has one of your agents review pull requests, the way Cursor's Bugbot does. The agent runs Claude Code, Codex or a command of your own in a read-only sandbox, using a model key you bring. It reads the pull request's changes and looks for bugs, security issues and logic errors, not style. Diffinery then posts what it found as a review with inline comments, and reports an Agent review check that fails when a finding is blocking.

Agent review is off until a repository admin turns it on. Nothing changes for a repository that doesn't use it.

Turn it on

You need to be a repository admin, with an agent you manage that has write access (see Agent tasks) and your own model key under Settings → Model access.

  1. Open the repository's Settings → Agent review.
  2. Pick the agent and the runtime: Claude Code (your Anthropic key), Codex (your OpenAI key), or a custom command.
  3. Choose when to review:
    • Every pull request, when it opens and on every push (the default).
    • Once per pull request, when it opens or is marked ready for review.
    • Only when someone asks.
  4. Choose which pull requests to review: all of them, only ones from people, or only ones from agents. Drafts are skipped unless you tick Review draft pull requests too.
  5. Optionally turn on Autofix (see Fix it and autofix).
  6. Set the daily limit: the most reviews the repository runs in 24 hours (50 unless you change it; see Limits).
  7. Tick the confirmation and click Turn on agent review.

Every review on the repository uses your model key, automatic reviews and ones other people ask for alike. The settings page and every review's footer name whose key it is. Another admin who saves the settings becomes the one whose key is used. Turn off stops new reviews.

What a review does

  1. Diffinery re-checks that you can still run the agent and that your key is still saved. Otherwise the check reports why, and nothing runs.
  2. It starts a read-only sandbox as the agent, with the pull request's head checked out. The sandbox can clone and read, but its git credential can't push and can't write through the API.
  3. The runtime gets a prompt containing:
    • the pull request's title, description and changed files;
    • the base and head commits;
    • your project's review rules (below);
    • its own earlier findings on this pull request.
  4. It reports findings as a JSON block at the end of its final message. A block anywhere else, such as in a file the agent read, doesn't count. (A custom command's whole output is read.)
  5. Diffinery posts the findings as a Comment review by the agent:
    • Each finding becomes an inline comment marked 🔴 Blocking or 🟡 Not blocking, with the reasoning and, for a one-line fix, a suggestion block.
    • Findings outside the changed lines go in the review's summary.
    • At most 25 inline findings are posted per review.
  6. It completes the Agent review check on that commit:
ResultCheck
No blocking findingssuccess
One or more blocking findingsfailure
The agent produced no findings blockfailure: "The review didn't produce findings"
The review was stopped, or a newer push superseded itcancelled
The review ran past its time or model-request limitfailure: "The review didn't finish"
Your key or your access is gone, the author can't be reviewed automatically, or a daily limit was reachedaction required

The review and its findings show on the pull request like any review. The run, with its full transcript, is on the repository's Tasks tab, labelled Review. Reviews don't count toward required approvals, and an agent review never requests changes. Whether findings block a merge is up to the check.

Re-reviews

On the next push, the review covers what changed since its last review and checks its earlier findings:

  • When the code now fixes a finding, the agent replies Fixed in abc1234. and resolves its own thread.
  • It doesn't repeat a finding a person dismissed by resolving its thread.
  • It never resolves a person's thread.

Only one review of a pull request runs at a time. Pushes during a review queue one more review of the newest head. If the pull request changes while a review runs, that review's findings aren't posted, because their lines may be wrong, and the queued review covers the new head.

Ask for a review

People with write access can ask for a review at any time, whatever the trigger setting:

  • Request agent review in the pull request's Reviewers sidebar.
  • A comment starting with @<agent> review, for example @review-bot review.
  • Requesting the agent as a reviewer.
  • POST /repos/{owner}/{repo}/pulls/{number}/diffinery/agent-review, with any of your tokens.

Agents can't ask for reviews, so agents can't set off review loops.

Pull requests from people without write access aren't reviewed automatically. Their check says it is waiting for a request. Someone with write access asks for the review, much like approving a workflow run for an outside contributor.

Project rules: REVIEW.md

Write review rules in REVIEW.md files: what matters in this codebase, what to ignore, and conventions to enforce.

  • Diffinery reads REVIEW.md at the repository root and in every directory above a changed file. A file nearer a changed file wins for it.
  • It also reads .cursor/BUGBOT.md files, so rules written for Bugbot carry over.

Rules are read from the base branch, never from the pull request. A pull request can't rewrite the rules it is reviewed against. A change to REVIEW.md takes effect once it is merged.

Fix it and autofix

  • Fix it appears under every finding for people with write access. It opens a new agent task, prefilled with the finding, that works on the pull request's own branch. It runs as your agent with your key, and it pushes its fix to that branch under the branch's protection rules. The next review then checks the fix.
  • Autofix does this by itself when a review finds blocking problems: one task for all of them, as the agent and with the key of the admin who turned reviews on.
    • It runs at most 3 times per pull request.
    • It runs only for pull requests whose author has write access.

Require it before merging

Add Agent review to a branch's required checks under Settings → Branch protection. Diffinery binds a required "Agent review" to its own reviewer (diffinery-agent-review), so nobody else can post a passing check with that name, and a check an agent posts itself never counts.

A passing Agent review means the agent found nothing, not that the change is safe. Pull request content can try to trick the agent ("prompt injection") into reporting nothing. Keep people's approvals required as well.

Limits

Diffinery enforces these itself, so an agent misled by a pull request can't run past them:

LimitWhat happens
30 minutes per reviewThe review stops, and its check fails.
200 model requests per reviewThe model proxy refuses the next request and stops the review, and its check fails.
Tokens per review (default 2,000,000, from 100,000 to 50,000,000)The same, once the next request could take the review past its budget.
10 automatic reviews per pull request in 24 hoursLater pushes get an action-required "Waiting for a request" check. People with write access can still ask.
20 reviews per pull request in 24 hours, asked for or automaticThe check asks for action, and asking returns 429.
The repository's daily limit (default 50, from 1 to 1000)The check asks for action, asking returns 429, autofix waits, and the admin whose key reviews use gets an email, at most once a day.

Daily limits count the reviews and autofix runs started in the last 24 hours, so reviews run again as older ones fall out of that window.

Diffinery counts tokens itself, as requests pass through the model proxy:

  • Before a request goes to the provider, the proxy books the most it may cost: a token per 3 bytes of request, plus the output it allows (max_tokens, or 32,000 when it sets none). If that could take the review past its budget, the request is refused and the review stops. So requests sent at once can't overrun the budget together.
  • Once the response has streamed through, the booking is replaced by the usage the provider reports: input, output and cache writes in full, cache reads as a tenth, since providers bill them at about a tenth. A response that reports no usage, or whose usage can't be read, stays charged its booking. An error response costs nothing.
  • A review can't start background responses, use previous_response_id, conversation or prompt (they pull in context stored at the provider that the booking can't see), or ask for more than one answer (n). A review's request that sets no output cap is sent with one of 32,000 tokens, so its booking holds.

Every run's model requests and tokens show in its transcript and in the API's runs (model_requests, tokens).

Change the daily limit and the token budget under Settings → Agent review.

Who pays, and the risks

  • Every review spends the model key of the admin who turned reviews on. Use a dedicated key with a spending limit with your provider as well: Diffinery's limits count reviews, requests and tokens, not money.
  • While a review runs, anything in its sandbox, including code from the pull request, can use that key through the model proxy. The proxy forwards only the model endpoints, and the review's model token stops working when the agent exits (see How your key is protected).
  • The sandbox can't push or write repository content. Its credential acts as the agent with read access.

REST API

EndpointDoesWho
GET /repos/{owner}/{repo}/diffinery/agent-reviewThe repository's agent review settingsWrite access
PUT /repos/{owner}/{repo}/diffinery/agent-reviewTurn on, change (agent, runtime, command, trigger: push, open or request, authors: all, people or agents, drafts, autofix, daily_limit: 1 to 1000, tokens_per_review, accept_terms: true) or turn off (enabled: false)Repository admin, browser session only
GET /repos/{owner}/{repo}/pulls/{number}/diffinery/agent-reviewThe pull request's review task, the last reviewed head and every finding with its state (open, fixed, dismissed)Write access
POST /repos/{owner}/{repo}/pulls/{number}/diffinery/agent-reviewAsk for a review (429 past a daily limit)People with write access (not agents)
{
  "task": { "number": 12, "kind": "review", "state": "ready", "html_url": "https://diffinery.com/acme/website/tasks/12" },
  "reviewed_sha": "9f2c…",
  "findings": [
    { "id": "F1", "path": "src/math.js", "line": 2, "side": "RIGHT", "severity": "blocking", "title": "Divides by zero", "state": "fixed", "fixed_in": "4be1…" }
  ]
}

Moving from Bugbot

BugbotAgent review
Reviews on open and every pushWhen to review: every pull request
bugbot run comment@<agent> review, or Request agent review
.cursor/BUGBOT.mdRead as is, with REVIEW.md
Fix in Cursor / AutofixFix it / Autofix
Bugbot checkAgent review check