Pointing reviewers at what breaks: an evaluation of Alden on 150 seeded PRs and 33 real ones
Abstract
Code review tools show the lines a PR changed. The bugs that slip through are often somewhere else: in the code that calls those lines, in a dependency the PR moved a major version, or in the file a later PR has to fix. We evaluate Alden, a review companion that runs on the reviewer's machine, on two sets of PRs.
On 150 PRs we seeded into four real repositories, including forks of Laravel and Grafana, Alden 0.3.0 ranked and checked all 150 as expected, without a model. On 15 public PRs that a later PR had to fix, briefings with a model flagged 21 of the 29 files the fix changed, 10 times as many as the checks alone (2 of 29), and none of its 104 findings pointed at code outside the diff. A briefing without a model takes under 5 seconds on Grafana, and 0.3.0 builds a 146-PR review queue twice as fast as 0.2.2. The median model briefing cost $0.06.
1. Introduction
A reviewer's scarcest resource is attention. A diff view gives every changed line the same weight, and shows none of the unchanged code those lines affect. Alden does three things before the reviewer opens the diff: it ranks the PRs waiting on them, it runs checks with evidence (secrets, destructive migrations, dependency changes, changed public signatures and their callers, text aimed at AI reviewers), and it picks the few places that need the reviewer's eyes. Optionally, a model adds findings at diff lines.
We ask four questions:
- Correctness. Does Alden rank and flag PRs the way each scenario calls for, in real repositories?
- Recall on real regressions. Does a briefing point at the files that later turned out to break?
- Precision of locations. When the model points at a line, is that line in the PR?
- Speed and cost. Is it fast and cheap enough to run on every PR?
2. Method
2.1 Seeded PRs in four repositories
We opened 150 PRs of varying risk from a GitHub App and requested our own review on each: docs typos, tests-only
changes, patch and major dependency bumps, additive and destructive migrations, likely secrets, breaking and
compatible signature changes in four languages, renames, stacked PRs, team review requests, a hotfix label,
failing CI, merge conflicts, a prompt injection and terminal escape codes. Each scenario states what Alden should do:
its lane (Needs you or Fast-track), the reasons on its queue row and the checks it should flag.
pnpm e2e:verify then ranked the live queue, briefed every PR with checks and the code graph from a
local clone, without a model, and compared the result with the scenario.
| Repository | What it is | PRs |
|---|---|---|
| alden-e2e-sandbox | A small shop in TypeScript, Python, Go and PHP, made for this test | 46 |
| A production monorepo | Python and TypeScript; private, so not named | 39 |
| alden-e2e-laravel | A fork of laravel/framework (PHP) | 32 |
| alden-e2e-grafana | A fork of grafana/grafana, a Go and TypeScript monorepo | 33 |
2.2 Recorded public PRs that a later PR had to fix
pnpm eval replays 33 recorded public PRs from Django, Grafana, Hugo, Laravel, Next.js, the GitHub CLI
and Prometheus. Fifteen of them introduced a regression that a later PR fixed; the 29 files those fixes changed are
the ground truth. A file counts as flagged when a check or a model finding points at it, and as in
Needs your eyes when it's one of the three places the briefing puts first. Both conditions see the diff only,
with no clone for the code graph, so the comparison isolates what the model adds. The model was claude-sonnet-5 at
its default effort.
3. Results
3.1 Every seeded PR handled as expected
Alden 0.3.0 met every expectation on all 150 seeded PRs (5 October 2026). Alden 0.2.2 met 147 the day before; the three misses, and a fourth found by hand, were fixed in 0.3.0 and are listed in section 4.
| Repository | PRs | 0.2.2 | 0.3.0 |
|---|---|---|---|
| alden-e2e-sandbox | 46 | 46 | 46 |
| Production monorepo | 39 | 37 | 39 |
| alden-e2e-laravel | 32 | 32 | 32 |
| alden-e2e-grafana | 33 | 32 | 33 |
| All four | 150 | 147 | 150 |
Three results stand out:
- Callers outside the diff were found in all four languages, including a PHP method reached through a trait in Laravel and a Python function imported relatively in the production monorepo.
- Breaking dependency upgrades rise to the top of the queue. Major bumps (carbon 3 → 4, mermaid 11 → 12, laravel/framework 11 → 12) ranked 5th to 8th among each repository's 32–46 PRs, with the package and versions as the reason.
- Every prompt-injection PR was caught. The check for text aimed at AI reviewers flagged the injection in all four repositories, and when we reviewed it with Claude Code and with Alden's model, neither obeyed it. Every likely secret was flagged, and in our tests never shown or sent to a model.
3.2 Ten times as many regressions flagged with a model
With a model, briefings flagged 21 of the 29 files that later broke (72%), against 2 of 29 for the checks alone: 10.5 times as many. Half of them, 10 of 29, were among the three places the briefing put first, five times the checks alone (2 of 29). In the first run 6 of 33 briefings didn't finish, five because the model's answer was cut off; Alden now retries those at low effort, and the second figure uses the retried briefing where there is one. Counting the first run only, the model flagged 13 of 29: 6.5 times the checks.
| Language | PRs | Files | Checks only | With the model | In Needs your eyes |
|---|---|---|---|---|---|
| PHP | 4 | 6 | 0 | 6 | 4 |
| Python | 4 | 4 | 0 | 4 | 2 |
| TypeScript | 3 | 3 | 1 | 3 | 2 |
| Go | 4 | 16 | 1 | 8 | 2 |
| All | 15 | 29 | 2 | 21 | 10 |
In PHP, Python and TypeScript, the model flagged every file that later broke (13 of 13). Go is the weak spot: one GitHub CLI fix touched 11 files, and the briefing flagged 6.
Go with the code graph, checks only, no model (12 October 2026). We re-ran the four Go regression PRs with clones of the GitHub CLI and Prometheus, so the code graph ran, as it does in a real review. The 0.9 development build follows more of how Go code calls itself: package-internal helpers, interfaces, embedded structs and functions passed as values. It flagged 9 of the 16 files the fixes changed, against 6 for 0.8.0, all three Prometheus files among them; 2 of 16 were in Needs your eyes with both. The model runs above used 0.3.0 without clones.
| Go, checks only, with clones | Files | 0.8.0 flagged | 0.9 dev flagged | 0.8.0 in eyes | 0.9 dev in eyes |
|---|---|---|---|---|---|
| cli/cli#13009 | 11 | 6 | 6 | 2 | 2 |
| cli/cli#14136 | 1 | 0 | 0 | 0 | 0 |
| cli/cli#10513 | 1 | 0 | 0 | 0 | 0 |
| prometheus/prometheus#19183 | 3 | 0 | 3 | 0 | 0 |
| All Go | 16 | 6 | 9 | 2 | 2 |
3.3 No invented locations
Alden drops any model finding that points at a line outside the PR's diff, and counts it. Across both runs, 0 of the model's 104 findings had to be dropped. Asked whether each change does what its title says, the model answered yes or partly on all 32 briefings that finished.
3.4 Speed and cost
| Measurement | Result |
|---|---|
| A briefing on a Grafana PR, warm, checks and callers, no model (0.2.2) | 4.5 s |
| A briefing on a Laravel PR, same conditions (0.2.2) | 3.8 s |
| All 33 Grafana briefings, cold, including building the code graph index (0.2.2) | 125 s |
| The queue, 146 PRs in four repos, fresh from GitHub, 0.2.2 | 20–25 s |
| The same queue, 0.3.0 (median of three runs: 10.7, 10.9, 11.1 s) | 10.9 s |
| Median model cost of a finished briefing, recorded PRs | $0.06 |
| Model cost per briefing on large seeded PRs (46 briefings, $4.90) | $0.11 |
0.3.0 builds the queue twice as fast as 0.2.2 by fetching PR details, CODEOWNERS and stacked PRs side by side, and the web UI and desktop app show the last queue at once while a fresh one loads. Model calls are checked against the reviewer's caps ($0.50 a briefing and $10 a day by default) before they're sent; the model is optional and off until you add one.
4. Limitations
- We wrote the seeded scenarios. They give every check something to find, so 150 of 150 shows Alden does what it's built to do, not how useful it is in your repositories.
- The regression set is small. 15 PRs and 29 files, from one or two runs of a model that isn't deterministic; a single PR moves the percentages a lot. The model runs used a development build between 0.2.2 and 0.3.0.
- 0.2.2 missed four things that 0.3.0 fixes: callers of a Python function imported relatively, files still importing a module's old path after a move, "has conflicts" on one PR (GitHub reports conflicts lazily), and a dependency patch bump.
- We haven't measured review time. Whether reviewers finish faster, and find the flags useful, is what the open beta is for. Tell us in the Alden Community on Discord.
5. Reproducing these results
pnpm e2e:seed --repo owner/name --clone <path> # open the seeded PRs and request your review
pnpm e2e:verify --repo owner/name --clone <path> # rank and brief them, no model, and compare
pnpm eval --no-llm # the recorded PRs, checks only: free
pnpm eval --yes # with your model; without --yes it prints the cost
How each works, and what the seeding needs (a GitHub App to open the PRs), is in Evals.
The scripts are in Alden's repository, which opens with the source after the beta; the three public test
repositories are linked above. The raw results are eval/e2e/*.results.json (5 October),
eval/results/2026-10-05T07-10-23-596Z-checks-only.json, and the two model runs of 4 October,
2026-10-04T00-07-16-468Z and 2026-10-04T09-25-06-638Z.