Pull request review by X-Squad

Every finding is cross-examined before it's posted.

DevCops reviews pull requests with four specialists. Each finding quotes the line it's about, and a second pass tries to prove it wrong. Only what holds up reaches your pull request.

  • No workflow in your repository
  • Rules live in your repository
  • Cost shown on every review

Example review · app/accounts/statement.ts

Three findings proposed. One posted inline.

The specialists send what they suspect, each quoting a line of the diff. DevCops checks that the quote is really there, then a second pass tries to refute the claim.

app/accounts/statement.ts@@ -0,0 +1,25 @@
12+/** Totals for a statement. An empty statement has a count, total and average of 0. */
13+export function summarize(entries: readonly StatementEntry[]): StatementSummary {
14A+  const totalCents = entries.reduce((sum, entry) => sum + entry.amountCents, 0);
15+  return {
16+    count: entries.length,
17+    totalCents,
18B C+    averageCents: Math.round(totalCents / entries.length),
19+  };
20+}
  • Acorrectness · major · line 14

    reduce throws on an empty statement.

    Refuted. reduce starts from 0, so an empty statement totals 0.

    Refuted
  • Bcorrectness · major · line 18

    An empty statement gives 0 / 0, so averageCents is NaN. The doc comment promises 0.

    Verified. Posted on line 18.

    Verified
  • Ctests · nit · line 18

    No test pins down the empty-statement case.

    Verified. A nit, so it goes in the Report.

    Verified

What lands on the pull request

devcops-appbotcommented on line 18

major · correctness

An empty statement gives 0 / 0, so averageCents is NaN. The doc comment promises 0.

Fix: return 0 for an empty statement, with entries.length === 0 ? 0 : Math.round(totalCents / entries.length).

devcops-appbotupdated the Report

devcops review of 783dd73

1 new inline comment, 1 nit.

Nits

  • app/accounts/statement.ts:18 No test pins down the empty-statement case.

This run: 1 refuted and 0 unverified after checking · cost $0.19

Procedure

How a review runs

  1. You ask for a review

    Add the devcops label, mention DevCops in a comment, or request it as a reviewer. A repository can also have every pull request reviewed as it opens.

  2. Specialists read the diff

    Correctness and security always run. Architecture and tests run unless the repository turns them off. All four read one cached copy of the pull request.

  3. Quotes are checked

    Every finding quotes the line it's about. DevCops finds that line in the diff and pins the comment there. A quote that isn't in the diff is dropped.

  4. A second pass tries to refute it

    Each finding goes to a separate check with the same context, which is asked to prove it wrong. A refuted finding is never posted.

  5. The rules decide

    One comment per line, the most severe first. A finding already open in a thread isn't repeated, and one resolved in its thread stays resolved unless the new one is worse.

  6. One review is posted

    Inline comments for what needs a fix, and one Report comment, updated in place, with the nits and what the run cost.

The squad

Four specialists, one brief each

Always on

Correctness

Bugs a user or caller would hit: wrong values, crashes, races, lost data. Each finding names the input that triggers it.

Always on

Security

Untrusted input reaching a dangerous sink, missing or bypassable authorization, broken tenant isolation, leaked secrets.

On by default

Architecture

Your written Rules, and only those: layering, dependency direction, invariants kept in the domain.

On by default

Tests

Changed behaviour with no test that would fail without it, and tests that cannot fail.

Ground rules

Quiet, precise, hard to talk round

Comments land on the right line
DevCops places each comment on the line the finding quotes instead of trusting the model's line number. On the benchmark, 23 of 23 comments landed on the exact line.
Nothing it can't stand behind
A finding that fails the second pass, quotes code that isn't in the diff, or names a file the pull request didn't touch is dropped.
Re-runs stay quiet
Running a review again posts nothing new. The Report says what is still open and what was resolved.
A pull request can't weaken its own review
Rules come from the base branch. A skip label counts only when someone other than the author adds it. Required specialists can't be switched off or given instructions.
Safe to post
Model text is escaped before it's posted, so it can't add links, images, @mentions or issue cross-references.
Sealed reviews
The model runs without a shell, file edits or network access, and without the machine's own settings.
Lockfiles stay out
Files the organization ignores never reach the model and don't count toward the 1 MB diff limit.
Cost on every review
Each Report ends with what the run cost, so a busy week is never a surprise.

Your rules

Configure it from the repository

.devcops/config.ymlon the base branch
rules:
  - id: repo/no-infra-in-domain
    text: src/domain must not import from src/infrastructure.
    paths: ["src/domain/**"]
specialists:
  disable: [tests]          # optional specialists only
  instructions:
    architecture: Features live under src/features/<name>.
ignore:
  paths: ["drizzle/**"]
  labels: [wip]

Read from the base branch

A pull request is judged by the rules already on its base branch, so it can't change them for itself.

Add, never loosen

Add Rules, narrow what gets reviewed, or brief an optional specialist. Anything that would loosen a required check is rejected and reported on the pull request.

Organization defaults apply everywhere

Correctness and security, the organization's Rules, and ignored files such as lockfiles cover every repository before its own config.

Field report · 28 October 2026

Six planted bugs, four pull request sizes

Six small modules, each with one bug that its own doc comment contradicts, padded with real production code. One cold run per size.

Diff sizeBugs postedComments on the exact lineCost of the run
6 KBThe six modules alone6 of 66 of 6$0.19
102 KB6 of 66 of 6$0.48
293 KB5 of 65 of 5$0.99
506 KB6 of 66 of 6$1.51

At 293 KB the sixth bug was found, then dropped for citing a Rule that didn't cover its file. DevCops now drops the citation and keeps the finding, and a re-run posted all six. The 500 KB diff limit comes from this benchmark.

Get DevCops

Want it on your pull requests?

  1. DevCops is built and run by X-Squad. Tell us about your repositories and the rules your team holds them to.
  2. Ask for a review with the devcops label, a mention, or a review request, or have every pull request reviewed as it opens. Only people who can push to the repository can ask.
  3. Add .devcops/config.yml to give it your repository's Rules.

Asking for a review

@devcops-app review this, please

A comment like this on a pull request is enough. The review lands a few minutes later, its Report ending with what the run cost.