Skip to content

Commit 5a19aa1

Browse files
authored
docs(fairness): write down what the automation rate actually counts (#10066)
#9726's second sub-issue asked to publish the series WITH a methodology note. The series shipped and the note did not, so the metric the 97% target is stated against was the one figure on /fairness whose definition existed only in a source comment. Its definition contains three choices a reader cannot guess, and would plausibly assume the other way round: Non-deciding verdicts are excluded from BOTH halves rather than counted as automated. `action` also carries label, update_branch, approve and the error classes; counting those would let work the gate never ruled on read as an automated decision. A PR that was held and later merged is MANUAL. The question is whether a human had to act, not how it ended -- scoring the final disposition would let the rate be inflated by holding everything and then merging it by hand. Three human signals count, not just `hold`: a named reevaluation_actor, and a reevaluation_reason of maintainer_request, each make a PR manual. The backfill horizon gets its own section, because the page already surfaces a per-week `basis` field that nothing explained. The provenance fields arrived in migration 0204 on 2026-07-29; earlier weeks can only observe `hold`, so they can only under-count manual work and therefore only OVER-state automation. Those weeks are published as `holds_only` rather than mixed in, and the horizon is a stated constant rather than inferred -- "the column did not exist yet" and "this was a first evaluation" both read as NULL, so guessing it from the rows would be a fabrication dressed as a derivation. Every number and date here was read out of automation-rate.ts and the migrations rather than recalled, including which migration added the fields. /fairness's automation section now links to the definition, as its sibling sections already do, and the code pointer joins the list at the foot of the methodology page. Closes #10065
1 parent a7673e2 commit 5a19aa1

2 files changed

Lines changed: 60 additions & 0 deletions

File tree

apps/loopover-ui/content/docs/fairness-methodology.mdx

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,56 @@ because a methodology page that omitted them would be marketing.
188188
recorded gets its own row rather than being bucketed into maintainer or contributor — bucketing it
189189
would bias exactly the comparison the block exists to make.
190190

191+
## Automation rate: what counts as automated
192+
193+
The share of pull requests decided with no human in the path. It is the metric every claim about the
194+
gate ultimately rests on, so its definition is stated here rather than left to the label on the chart.
195+
196+
Computed from `decision_records` — the anchored ledger — **and nothing else**, so anyone holding the
197+
export recomputes the same numbers. A pull request is counted once per week, by the week of its
198+
**first** verdict.
199+
200+
| Bucket | Definition |
201+
| --- | --- |
202+
| **decided** | The PR reached a disposition at all: at least one verdict whose action *enacts* one (`merge` / `close`), or one that `hold`s. |
203+
| **manual** | A decided PR where **any** verdict shows a human in the decision path. |
204+
| **automated** | A decided PR that reached `merge` or `close` with none of those signals. |
205+
206+
Three things about that definition are deliberate, and each one closes a way the number could be
207+
made to look better than it is.
208+
209+
**Non-deciding verdicts are excluded from both halves, not counted as automated.** `action` also
210+
carries `label`, `update_branch`, `approve` and the error/no-op classes. A PR that only ever drew
211+
those was never *decided*, so counting it would let work the gate never ruled on read as an
212+
automated decision.
213+
214+
**A PR that was held and later merged is manual.** The question is whether a human had to act, not
215+
what the end state was. Scoring the final disposition instead would let the rate be inflated by
216+
holding everything and then merging it by hand.
217+
218+
**Three distinct human signals count, not just one.** A `hold` is the gate declining to decide and
219+
handing the PR to a person. A named `reevaluation_actor` is a person who caused a re-evaluation. A
220+
`reevaluation_reason` of `maintainer_request` is a human asking for the re-run. Counting only holds
221+
would miss the last two entirely.
222+
223+
A bot action alongside a decision does **not** make it manual — a `label` or an `update_branch` is
224+
the bot acting, not a person.
225+
226+
### The backfill horizon
227+
228+
The two re-evaluation fields arrived with migration 0204, on **2026-07-29**. Weeks starting before
229+
that date can only observe `hold`, so they can only **under-count** manual work — which means they
230+
can only over-state automation.
231+
232+
Those weeks are published with `basis: "holds_only"` rather than being quietly mixed in with
233+
complete ones. A series whose definition changes partway along, without saying where, is worse than
234+
one that is explicit about it: the earlier points are not wrong, they are measuring something
235+
narrower, and a reader comparing this quarter to last needs to know which.
236+
237+
The horizon is a stated constant rather than something inferred from the rows, because it cannot be
238+
inferred: "the column did not exist yet" and "this was a first evaluation" both read as `NULL`.
239+
Guessing the date from the data would be a fabrication dressed as a derivation.
240+
191241
## Where this lives in the code
192242

193243
Kept adjacent to the scoring code it describes, so a change to a definition and a change to this page
@@ -199,3 +249,4 @@ show up in the same review:
199249
- Wilson intervals and the fleet fold — `src/orb/analytics.ts`
200250
- Review-parity rollups — `src/review/review-parity-rollups.ts`
201251
- The published corpus and its checksum — `src/review/public-eval-corpus.ts`
252+
- The automation rate, its buckets and the provenance horizon — `src/review/automation-rate.ts`

apps/loopover-ui/src/components/site/fairness-report-page.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,15 @@ export function FairnessReportPage() {
462462
>
463463
verify this review
464464
</Link>
465+
. For the full definition — which verdicts count, why a held-then-merged PR is
466+
manual, and what the pre-2026-07-29 weeks can and cannot measure — see the{" "}
467+
<Link
468+
to="/docs/$slug"
469+
params={{ slug: "fairness-methodology" }}
470+
className="underline underline-offset-2"
471+
>
472+
fairness methodology
473+
</Link>
465474
.
466475
</p>
467476

0 commit comments

Comments
 (0)