Home / How we measure
We tested our own tool against a linter and an AI assistant. Here is everything, limits included.
The honest question about any documentation reviewer in 2026 is whether a well-prompted AI assistant does the same job. We ran that test and published what it showed, including where it does not favour us.
The short version
- On a small specification, an AI assistant that simply reads the file finds almost everything our rules find.
- On very large specifications, reading stops working. Computation does not. An assistant matches the reviewer only when it is told exactly what to compute.
- Our rule list is not a secret. Handed only the rule titles, an AI agent agreed with the reviewer on 73 to 88 percent of rules per run.
- Where the reviewer is different: it gives the same answer every time, finishes large files in seconds without a model, and says what it did not check.
What we ran
| Test | Result |
|---|---|
| 35 faults seeded into one small specification, each written to be caught by one rule | Rules: 35 of 35 caught, 27 of them pointing at the changed place. A popular linter: 8 reported for the same reason, 8 reported something else, 19 reported nothing. An AI assistant reading the file: 34 of 35. Each assistant run used a fresh copy of the file and the same prompt. |
| Invalid examples across 16 real public specifications, checked by an independent script | The script found 99 examples that break their own schema. The reviewer flags 95, all confirmed; the linter's example claims about 88. Four are missed by both. |
| Two very large specifications, an assistant that only reads | Found 6 of 78 invalid examples (6 of 48 and 0 of 30). It said which parts it had not read. |
| The same two, with an assistant told to validate every example with a script | Found all 78, twice each. Without that instruction, but with tools, it found 19 of 48 and 0 of 30. |
| Three real specifications, an AI agent given only our rule titles as a checklist | Agreed with the reviewer on 30 to 36 of 41 rules per run. Closest on structural rules, furthest on judgement calls. |
| About 1,800 assistant findings, mechanically checked | Pointers to the file were almost always real. Few claims could be checked by a script (under 5 percent), and those that could were not clearly wrong, except where the assistant had read instead of computed. |
What these numbers do not show
- The faults are ours. We wrote them to be found by our rules, on one small specification. Treat 35 of 35 as a floor on a test we designed, not as recall on faults documentation really has.
- Precision was not measured for the assistant. On a clean copy it raised 21 to 24 findings where the reviewer raised 6. How many of those were real and worth fixing needs a second person, and we have not done that.
- One model, small runs. Mostly one run per cell, one AI model, one prompt. The open-ended part of an assistant's answer varied from run to run.
- One labeller. The person who built the scorer also did the labelling. The agreement figures are agreement, not accuracy: there is no ground truth for judgement calls.
- Possible leakage. The assistants ran inside the project that builds the reviewer and could in principle have picked up context about it. They were told to read only their file.
- The example check is the only computed check we tested at scale. Other computed checks (references, structure, consistency across schemas) were not tested the same way.
What follows from it
The finding that a prompt can reproduce most of our rules is the useful one, and it shaped what we are building. Recall on a small file is not a moat. What an assistant cannot cheaply give you is repeatability, a complete pass over a very large file, and an explicit list of what was not checked. Use both if you like. Just ask whichever you use to tell you what it did not read.
The write-up, in plain language, is in our notes.
How far each rule has been measured
People judged samples of each rule's findings as right, wrong or unsure. These are counts from one labeller on public specifications and guide folders, not a precision claim. A rule with fewer than 10 judged findings is marked as too few to rely on, and a rule nobody has judged says "not measured". Labels that no longer match any finding because a rule changed are shown as out of date.
| Rule | What it looks for | Judged | Right | Wrong |
|---|---|---|---|---|
CC-REF-01 | Internal $ref that does not resolve | Not measured | ||
CC-DESC-01 | Operation has neither summary nor description | Not measured | ||
CC-PARAM-01 | Required parameter or required request property has no description | 10 | 10 | 0 |
CC-RESP-01 | Response has no description | Not measured | ||
CC-ERR-01 | Operation documents no error response | 10 | 10 | 0 |
CC-EX-01 | Operation with a body has no example request or response | 10 | 10 | 0 |
CC-EX-02 | Request or success-response example does not validate against its own schema | 10 | 10 | 0 |
ERR-05 | Error response example does not validate against its own schema | 4 | 4 | 0 too few to rely on |
CC-CONFLICT-01 | The API description and a guide state different maximums for the same parameter | Not measured | ||
CC-PATH-01 | Path placeholder has no path parameter definition | Not measured | ||
CC-SCHEMA-01 | Request or response declares a structured content type but no schema | 2 | 2 | 0 too few to rely on |
CC-TYPE-01 | Path or query parameter has no type information | Not measured | ||
CC-CONSIST-01 | The same property has incompatible types in different schemas | 3 | 2 | 1 too few to rely on |
RATE-02 | 429 is documented without telling clients when to retry | 1 | 1 | 0 too few to rely on |
WH-01 | Webhook or callback has no payload schema | Not measured | ||
WH-02 | Webhook signature verification is not described | 3 | 3 | 0 too few to rely on |
WH-03 | Webhook delivery retries and acknowledgement are not described | 3 | 3 | 0 too few to rely on |
AUTH-03 | Where credentials come from is not described | 2 | 0 | 1 too few to rely on |
IDEM-02 | Idempotency key lifetime and reuse are not described | Not measured | ||
ERR-04 | Which failures are worth retrying is not described | 4 | 4 | 0 too few to rely on |
WF-04 | 202 Accepted response does not say how to learn the outcome | 10 | 10 | 0 |
DATA-02 | Date/time property has no format or timezone information | 3 | 3 | 0 too few to rely on |
DATA-03 | Date/time example has no timezone although the contract says it has one | Not measured | ||
CC-ENV-01 | Server description and address point to different environments | Not measured | ||
AUTH-04 | OAuth2 scopes are not described or not tied to operations | 1 | 1 | 0 too few to rely on |
AUTH-01 | No usable authentication described | 2 | 2 | 0 too few to rely on |
AUTH-02 | Security scheme has no description | 8 | 8 | 0 too few to rely on |
CC-SEC-01 | Operation requires a security scheme that is not defined | Not measured | ||
NAME-01 | Inconsistent casing of paths or query parameters, or verbs in some paths | 3 | 3 | 0 too few to rely on |
PAG-01 | List operation does not document how to page through results | 10 | 10 | 0 |
PAG-02 | List operations use different pagination styles | 3 | 0 | 3 too few to rely on |
RATE-01 | API documents no rate limiting | 2 | 2 | 0 too few to rely on |
ERR-02 | Error responses lack a shared, machine-readable shape | 1 | 1 | 0 (+1 out of date) too few to rely on |
IDEM-01 | Resource-creating POST has no idempotency key | 7 | 7 | 0 too few to rely on |
CC-DEP-01 | Deprecated operation does not say what to use instead | 10 | 10 | 0 |
CC-DESC-02 | Description is a placeholder, only repeats the name, or is too short to help | 25 | 18 | 7 |
CC-DESC-03 | Description uses vague wording (etc., various, as needed) | 5 | 2 | 3 (+20 out of date) too few to rely on |
CC-DESC-04 | Several operations share the same description | 23 | 23 | 0 |
LINK-01 | In-scope documentation link returns 404/410, points to a missing anchor, or names a file that is not in the supplied documents | 8 | 8 | 0 (+18 out of date) too few to rely on |
ON-ENV-01 | Code sample uses a placeholder that no text explains | 17 | 17 | 0 (+1 out of date) |
DOC-CODE-01 | A JSON code sample is not valid JSON | 31 | 31 | 0 |
Want to see it on your own API?
We would rather you judge it on your documentation than on our test.