Upgrading to v0.22.0
v0.22.0 updates AFDocs from the Agent-Friendly Documentation Spec v0.5.0 to v0.6.0 and moves the scoring version from 0.1.0 to 0.2.0. No check IDs, flags, or output fields were renamed or removed, so nothing breaks on upgrade. Scores do change, and there is new output to know about.
What changed for CLI users
Five new checks
| Check | Weight | What it measures |
|---|---|---|
bot-protection-interference | High (7) | Whether bot protection challenged, stalled, or blocked requests during the run |
page-size-transfer | Medium (4) | How much an agent has to download to read one page, before anything in it is read |
single-fetch-completeness | Medium (4) | Whether a markdown page is complete in one fetch, or declares a working continuation where agents will see it |
markdown-link-portability | Medium (4) | Whether links in served markdown are absolute, and whether a sample resolves to what the link promises |
embedded-data-serialization | Medium (4) | Whether machine-generated bulk data (large tables, data blobs) is what makes a page oversized |
The check count goes from 23 to 28 and the maximum raw score from 130 to 153.
Your scores may be different
Scores from v0.21.0 and v0.22.0 are not comparable. If a CI step enforces a minimum score, re-run once after upgrading and set the threshold from the new number.
- Most sites score a few points higher. Four of the five new checks pass on ordinary prose sites (no pagination, no bulk data, under 1MB served, no interference), which adds easy points to the denominator.
- Sites behind aggressive bot protection may drop.
bot-protection-interferenceis a High check. A warn costs points in proportion to how much of the run was affected; a fail costs all seven. - Sites on platforms that emit root-relative links in markdown warn on portability. In the field run this was every VitePress, Mintlify, and Next.js site tested. The warn coefficient is 0.60 because it is a platform property; see the check page for what to ask your platform for.
- Pages of exactly the size threshold now warn. The pass band for
page-size-html,page-size-markdown, andpage-size-transferis strictly under the threshold, as the result tables have always said. A page of exactly 50,000 characters used to pass and now warns. In practice no real page lands on the boundary.
See the scoring version history for the full list.
New output
- Two new diagnostics. Dynamic content rendered statically fires when two or more of the markdown checks flag the same generated page. Bot protection degrading scan reliability fires when interference affected the run.
(partial sample)after a check in the scorecard means bot protection interfered and that check scored whatever pages survived. The score still counts; the marker says what it measures.- A "Scanned from ..." line reports whether the run came from a developer machine, CI, or cloud infrastructure, because bot protection often decides by where traffic comes from. No IP address is recorded.
- A new fetch error. A response whose body stops arriving for longer than the request timeout now fails with
Body read timed out after <n>ms (response stalled; ...). Before v0.22.0 such a response hung until the whole request timed out. Any check that fetches pages can report it.
New flags
| Flag | Default | For |
|---|---|---|
--transfer-pass-threshold <bytes> | 1000000 | page-size-transfer |
--transfer-fail-threshold <bytes> | 10000000 | page-size-transfer |
--bulk-table-rows <n> | 20 | embedded-data-serialization |
--bulk-blob-chars <n> | 2000 | embedded-data-serialization |
--bulk-dominant-share <pct> | 50 | embedded-data-serialization |
--network-context <class> | detected | bot-protection-interference |
No existing flags were removed or renamed. See the CLI reference.
Config file changes
New optional keys, all with the same defaults as the flags: transferThresholds.pass, transferThresholds.fail, bulkTableRows, bulkBlobChars, bulkDominantShare, and networkContext. See the config file reference.
Programmatic API changes
runChecksaccepts the same six options:transferThresholds,bulkTableRows,bulkBlobChars,bulkDominantShare, andnetworkContext.- The report gains
requestSummary(aggregate counts of every request the run made) andnetworkContext. CheckScoregains an optionalpartialSample: truewhen bot protection degraded the scan.- Requests now send
Accept-Encoding: gzip, deflate, brexplicitly, and response bodies are read as streams with a stall guard. Custom HTTP clients passed to the runner should expose a body stream to get byte counts; a client that only implementstext()still works, with byte sizes approximated from the text.
JSON output changes
If you parse JSON output from the CLI or programmatic API:
- Five new check IDs appear in
resultsandcheckScores(see the table above). report.requestSummaryandreport.networkContextare new top-level fields.checkScores[id].partialSampleis new and optional.markdown-content-paritydetails gain optionalitemCountsper page anditemCountDivergencesat the top level. The check's status logic is unchanged.- New diagnostic IDs in the
diagnosticsarray:dynamic-content-rendered-statically(warning) andbot-protection-scan-reliability(warning).
Documentation changes
The check pages for the new checks are written for documentation owners rather than platform engineers, with a "Who owns this" lead in each fix section, and a glossary now defines the terms the checks use (RAG, hydration payload, soft 404, tarpit, and others).