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).
Pull request review by X-Squad
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.
Example review · app/accounts/statement.ts
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.
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+}
reduce throws on an empty statement.
Refuted. reduce starts from 0, so an empty statement totals 0.
An empty statement gives 0 / 0, so averageCents is NaN. The doc comment promises 0.
Verified. Posted on line 18.
VerifiedNo test pins down the empty-statement case.
Verified. A nit, so it goes in the Report.
VerifiedWhat lands on the pull request
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).
783dd731 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
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.
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.
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.
Each finding goes to a separate check with the same context, which is asked to prove it wrong. A refuted finding is never posted.
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.
Inline comments for what needs a fix, and one Report comment, updated in place, with the nits and what the run cost.
The squad
Always on
Bugs a user or caller would hit: wrong values, crashes, races, lost data. Each finding names the input that triggers it.
Always on
Untrusted input reaching a dangerous sink, missing or bypassable authorization, broken tenant isolation, leaked secrets.
On by default
Your written Rules, and only those: layering, dependency direction, invariants kept in the domain.
On by default
Changed behaviour with no test that would fail without it, and tests that cannot fail.
Ground rules
Your rules
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]
A pull request is judged by the rules already on its base branch, so it can't change them for itself.
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.
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 small modules, each with one bug that its own doc comment contradicts, padded with real production code. One cold run per size.
| Diff size | Bugs posted | Comments on the exact line | Cost of the run |
|---|---|---|---|
| 6 KBThe six modules alone | 6 of 6 | 6 of 6 | $0.19 |
| 102 KB | 6 of 6 | 6 of 6 | $0.48 |
| 293 KB | 5 of 6 | 5 of 5 | $0.99 |
| 506 KB | 6 of 6 | 6 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
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..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.