# How I put AI agents to work: evidence

By Alex Bouchard · October 15, 2026

Companion to [Let the agents work](https://midnightdev.dev/writing/learning-by-building), the [technical notes](https://midnightdev.dev/writing/learning-by-building-technical-notes.md), the [threat model](https://midnightdev.dev/writing/learning-by-building-threat-model.md) and the [failure catalog](https://midnightdev.dev/writing/agent-failure-catalog.md).

You cannot tell from a diagram whether an agent workflow merges thirty changes a month or none, or how often a change it held was a real problem. A reviewer of the essay said exactly that, and was right: the page had one anecdote and no counts.

This note has the counts I can measure today. Each one names the day it was measured and the thing that measured it. One box at the end says what the numbers cannot show.

## 01 / Pull requests that merged without me

<!-- auto-merged:start -->
Counted 2026-10-22 from GitHub and merge receipts. 151 pull requests across 6 repositories, merged 2026-06-29 to 2026-10-22. This is a floor: some agent merges left no record.

| How it merged | Pull requests |
| --- | ---: |
| Dependabot updates merged by the repository's workflow | 38 |
| Merged by GitHub auto-merge once the checks passed | 89 |
| Merged by an agent through the ship gate, no go-ahead on the receipt | 7 |
| Merged by an agent through the ship gate, with my go-ahead on the receipt | 17 |
| Total | 151 |

89 of the 151 (59%) merged through GitHub auto-merge that was switched on under my account, by me or by an agent, and merged once the checks passed.
<!-- auto-merged:end -->

A pull request counts here when it was merged in one of my own GitHub repositories without me pressing merge. Every merge runs under my account, so each one needs a machine record of how it merged: a Dependabot update merged by the repository's workflow, a GitHub auto-merge request, or a ship receipt left by an agent. Each pull request is counted once, under the first record that applies. A review on record shows who reviewed a change, not who merged it, so it is not a source. What this shows is how much merging the gates handle. It does not show whether the merged changes were good beyond what the gates check.

## 02 / The merge gate, counted

The gate is a required check that fails unless a review of record exists for the exact commit being merged, written by a name other than the author. It exists because of the first entry in the failure catalog. Two measurements.

**Before the gate.** Measured October 15 with a GitHub GraphQL search over merged pull requests across my repositories, June 10 to October 8, 2026, reading the first forty comments on each.

| Measure | Result |
| --- | ---: |
| Merged pull requests in the window | 934 |
| Carrying a usage-limit message where a review should be | 792 |
| Merged with zero reviews | 872 |
| Both | 741 |

**With the gate.** Measured October 15 with the GitHub Actions API: every failed workflow run created October 8 to 15 across the 112 repositories I own that are neither forks nor archived.

| Measure | Result |
| --- | ---: |
| Repositories scanned | 112 |
| Repositories with at least one failed run | 17 |
| Failed runs | 313 |
| Of which: the review gate refusing an unreviewed head | 138 |
| Of which: dependency-update checks opened by a bot | 86 |
| Of which: an inherited contributor-license workflow that fails by misconfiguration | 44 |
| Remainder: CI and smoke checks on branches | 45 |

A gate refusal is the control doing its job. In the previous week's triage, written October 11, every pull request the gate refused later merged after a review landed. I have not re-checked that for this week.

## 03 / Throughput, one day

Measured October 14 for commits dated October 13, method and limits in [Tuesday's count](https://midnightdev.dev/writing/a-very-crowded-tuesday-technical-notes.md).

| Measure | Result |
| --- | ---: |
| Distinct commits by the selected identities | 520 |
| Repository identities | 39 |
| Workflow runs matched to those commits | 375 |
| Successful · failed · cancelled | 305 · 46 · 21 |

Those are runs, not a pass rate. One commit triggers several workflows, and a failed run is often followed by a fixed commit.

## 04 / Decisions that went to a council

The council is the multi-model path: independent drafts from seats on different model families, anonymized cross-examination, dissent kept. Its ledger moves only when I settle a run against what actually happened. Read October 15 from the ledger database.

| Measure | Result |
| --- | ---: |
| Council runs since August 19 | 47 |
| Settled against reality | 41 |
| Outcome rows scored (win · mixed · loss) | 24 (13 · 7 · 4) |
| Outcome rows where the advice was never acted on | 63 |
| Rows voided | 17 |

Most advice goes unexecuted. That number stays on the page because the ledger's rule is that unsettled advice never improves it, and a council that is mostly ignored is a fact about how I use it.

## 05 / The report format

Each agent run leaves one report. These are its fields, in order. Copy them.

```
run:        <run name> · <start time, local>
scope:      one repository at a time; max pull requests; stop after N failed fixes
not allowed: money · messages to people · deletion · credentials · legal terms · public numbers
assessed:   <repo> · tests <pass/total> · open PRs <n> · branches ahead <n>
candidate:  <PR or change> · gate <pass/fail> · review <state> · preview <state> · held because <reason>
parked:     <decision id> · class <secret | published-number | sale-legal | other> · recommended <one line>
merged:     <n> · reverted <n>
notes:      <what changed in the project notes for the next session>
next:       <the first thing a person should look at>
```

Every line is something a reader can check against the repository after the run ends. The parked block is the one that matters: it is where the run says what it was not allowed to decide.

## The thing this page is not

It is not a benchmark. There are no cost figures here, by a standing rule for my public copy. There is no time-to-merge. There is no baseline against a single agent or against a human-only week. The auto-merged count includes only merges with a machine record, so it is a floor for what agents merged under my account. The weekly failure count mixes repositories with different gates. Run counts are runs, not changes.

## 06 / Count your gate before you count your merges

Pull the merged pull requests from your last three months and read the reviews on the first thirty. If the number with zero reviews surprises you, the gate is the first thing to build, and the merge count can wait.
