Reproducibility

This is an archived measurement under rubric 8. The current instrument uses different measurement rules. These files do not validate current scores; do not compare them with a new live run.

docs.stripe.com · audited 2026-09-30 · AgentFit v3.40.2-19-g3ff4d31 · rubric v8 · Claude Opus 5

A score you cannot repeat is not a measurement. So here is the test we owe you: we audited the same site six times in one day — three times by asking a language model to apply a documentation rubric, three times by running AgentFit — and we published what we recorded, including the parts that are inconvenient for us.

Ask a model · 3 runs

78 · 80 · 65 15 points of spread

Three independent agents, the same public prompt, the same model, the same day. None of them knew about the others, or about why they were being asked.

Run AgentFit · 3 runs

57 · 57 · 57 0 points of spread a2bc30e17d601ef21c9ec137a30302ecbff5ee4078e690be6bae670ddf583108 one sha256, three files

Three consecutive live audits, three JSON files, one checksum. Not a cache — each run went out to the site again.

Read the columns downwards, not across. The left rubric has 26 criteria; AgentFit has 28, and the two weight them differently — a machine-readable specification is worth 25 points on the left and 17 here. 57 is not "the right answer" and 78 is not "wrong". The claim on this page is narrower, and it is the only one the data supports: one of these two procedures returns the same number every time, and the other does not.


Where the runs disagreed

All three model runs did the work properly: they fetched live URLs, worked through the criteria one by one, and reported what they found. By our own count from the transcripts — which we did not publish — each run made between 36 and 47 tool calls, and none of them invented a fact. Take both of those as our reading of the runs, not as something the files below let you check. They still landed 15 points apart, and eleven of those points sit in a single category.

Category totals from the three model runs. Same site, same prompt, same day.
Category Max A B C Spread
A — Discovery181313121
B — Page artifacts221213121
C — Machine-readable spec2520211011
D — Content201819181
E — Rendering and hygiene151514132
Total10078806515

Two kinds of disagreement are mixed together there. The small ones — A5, B3, B5, B6, D1, D3, D6, a point here or there, in both directions — are what we would expect from three attentive readers of the same page: one found the SDK tabs in the DOM, the other two concluded they exist only inside a JavaScript payload. Whether that is ordinary measurement noise, three runs cannot tell you; that part is a guess. Only the D1 disagreement is visible in the published summaries — the rest comes from our own comparison of the three transcripts. The large disagreement is a different animal, and it is why this page exists.

The remaining criteria in category C scored exactly 10 points in each of the three runs. The entire eleven-point gap is two criteria.

C1a: the same facts, three different scores

Criterion C1a — from the model's 26-criterion rubric; AgentFit folds discovery and validity into a single C1 — asks whether the API has a machine-readable specification an agent can reach. All three runs established precisely the same two facts about docs.stripe.com:

Nobody was wrong. Nobody hallucinated. They scored it 0 of 8, 3 of 8 and 4 of 8.

The three criteria the runs diverged on most, as each run scored them.
CriterionABC
C1a · spec discoverable3/84/80/8
C1b · spec valid7/77/70/7
E5 · terms of use3/32/31/3

The disagreement is not about the site. It is about a question the rubric never asked: does a specification count as published if it lives on somebody else's domain and takes one more hop to reach? That is a genuine fork with no obvious answer, and each run walked up to it alone, in the middle of a long task, with no rule to consult. Three runs, three policies.

From there it cascades. C1b scores the quality of the specification you found. The run that decided GitHub does not count had nothing to validate and scored 0 of 7. The two that fetched it scored 7 of 7 — and then reported a different number of paths, 414 and 136, because Stripe's repository holds more than one specification file and they picked different ones (spec3.json and spec3.yaml). Two runs agreed on the score for opposite reasons.

E5 — "are the terms of use stated?" — came out 3/3, 2/3 and 1/3. One run found a footer link to stripe.com/legal/ssa. One rejected that link and credited the Content-Signal directive in robots.txt instead. One looked for /terms, /legal and /privacy on the documentation host, got three 404s, and scored what it saw. Three defensible readings of one line of rubric.

The self-check varied too

The prompt ships with a calibration anchor: a table of previously measured sites on which Stripe sits at 56, measured 13 May 2026. It is there precisely to catch drift. That table is also why the site here is docs.stripe.com — Stripe was already in somebody else's calibration anchor before we ran anything, so the site was picked for us, and picked before the experiment.

Every run used it. Every run noticed its own deviation — +22, +24, +9. Every run then re-examined its criteria, reasoned about what might have changed since May, and concluded that the anchor was stale and its own number was the better one. Three times, independently, in the same direction, with three different numbers.

This is the part we find most instructive. It is not carelessness — it is what conscientious work looks like when the procedure still has a free parameter in it. A self-check whose verdict changes between runs is not a self-check.

The anchor happens to sit one point from AgentFit's 57. Read nothing into that: it is a hand measurement, on a different rubric, from a different month, and it is not evidence that 57 is the true score.


Why the code answers the same

Nothing clever. Every criterion is a fetch plus a rule, and both are written down before the audit starts.

Four rows from the AgentFit report — byte-identical across the three runs.
Criterion Result Fetched Recorded
A1 · llms.txt index present 3/3 GET /llms.txt → 200 Stripe Documentation
C1 · spec discovery absent 0/8 fixed probe list, no response —
D2 · example realism present 5/5 sampled endpoint page → 200 placeholder_ratio = 0.00, 0/3 blocks
E6 · accessibility partial 1/4 homepage → 200 a11y: 3 violations (e.g. button-name)

D2 is the machine-learning one. Two small classifiers run inside the audit: one scores how realistic a code example is, the other judges endpoint-page completeness. They are ONNX graphs with frozen weights compiled into the binary. The same input gives the same tensor and the same float, every time. Determinism does not require avoiding models; it requires avoiding models whose output you cannot pin down.

C1 is the very fork the three runs walked differently, and AgentFit scores 0 of 8 on it. Our rule is not "GitHub does not count" — it is a fixed list of places to look: seventeen conventional paths on the host being audited, an RFC 9727 api-catalog link, and any specification link found on the homepage we fetched. On docs.stripe.com none of those paths returned a specification and that page carried no such link, so nothing was found. A rule that followed one more hop into a vendor's repository would not be less correct. Ours is simply fixed before the audit starts, applied identically to every site in the corpus, and its scoring published on the rubric page. That is the whole difference — not a better answer, a fixed one. How C1 is scored.

Historical record

This is an archived measurement under rubric 8. The current instrument uses different measurement rules. These files do not validate current scores; do not compare them with a new live run.

You can still verify the original files and their published SHA-256 checksum. The files and the numbers in this archive remain unchanged.

curl -fsS https://agentfit.dev/static/reproducibility/agentfit-run1.json -o agentfit-run1.json
shasum -a 256 agentfit-run1.json

What we are not claiming

What a model is genuinely good at here

None of this makes the model runs worthless — it makes them a different instrument. The diagnosis in each of the three runs is good on its own terms: why a missing specification hurts an agent, what to publish instead, which of Stripe's pages would survive being read without a browser. That is explanation, and a model explains beautifully.

A language model is excellent at explaining what to fix. It is a poor instrument for measuring whether you fixed it. We are about the second one. AgentFit is the instrument; take its number to a model and ask what to do about it. That is the right division of labour, and it is the one we use.

The data

All six runs are served from this site. The three AgentFit reports are the files the tool wrote, byte for byte — that is what the checksum is taken over. The three model files are ours:

The raw transcripts are not published. What you get for the model column are structured summaries we wrote afterwards from those transcripts: the final score, the category totals, and the criterion-level notes quoted above. The scores and totals are each run's own output; the wording of the notes is ours.

Nothing was filtered out — no run, and no site. Three model audits and three tool audits, on the one site the prompt's calibration table already named; we ran no others and discarded none. Had a fourth run come back at 57, we would have published that too, and this page would be shorter.


Audit your documentation →

Free, no sign-up, about 30 seconds. 28 criteria, HTTP evidence under every one, a shareable report link — and the same number tomorrow if nothing has changed.