Skip to content

Commit 6428a08

Browse files
authored
Merge pull request #10 from agent-ecosystem/add-scoring-module
Updates for spec v0.3.0
2 parents c9eade8 + a19e05f commit 6428a08

57 files changed

Lines changed: 4846 additions & 148 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 100 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@ Test your documentation site against the [Agent-Friendly Documentation Spec](htt
77

88
Agents don't use docs like humans. They hit truncation limits, get walls of CSS instead of content, can't follow cross-host redirects, and don't know about quality-of-life improvements like `llms.txt` or `.md` docs pages that would make life swell. Maybe this is because the industry has lacked guidance - until now.
99

10-
afdocs runs 22 checks across 8 categories to evaluate how well your docs serve agent consumers.
10+
afdocs runs 22 checks across 7 categories to evaluate how well your docs serve agent consumers.
1111

1212
> **Status: Early development (0.x)**
1313
> This project is under active development. Check IDs, CLI flags, and output formats may change between minor versions. Feel free to try it out, but don't build automation against specific output until 1.0.
1414
>
15-
> Implements [spec v0.2.1](https://agentdocsspec.com/spec) (2026-03-15).
15+
> Implements [spec v0.3.0](https://agentdocsspec.com/spec) (2026-03-31).
1616
1717
## Quick start
1818

@@ -25,7 +25,7 @@ Example output:
2525
```
2626
Agent-Friendly Docs Check: https://react.dev
2727
28-
llms-txt
28+
content-discoverability
2929
✓ llms-txt-exists: llms.txt found at 1 location(s)
3030
✓ llms-txt-valid: llms.txt follows the proposed structure
3131
✓ llms-txt-size: llms.txt is 14,347 characters (under 50,000 threshold)
@@ -64,23 +64,34 @@ afdocs check https://docs.example.com --checks llms-txt-exists,llms-txt-valid,ll
6464
# JSON output
6565
afdocs check https://docs.example.com --format json
6666

67+
# Scorecard with overall score, category scores, and fix suggestions
68+
afdocs check https://docs.example.com --format scorecard
69+
70+
# Add fix suggestions to the standard text output
71+
afdocs check https://docs.example.com --fixes
72+
73+
# JSON output with scoring data
74+
afdocs check https://docs.example.com --format json --score
75+
6776
# Adjust thresholds
6877
afdocs check https://docs.example.com --pass-threshold 30000 --fail-threshold 80000
6978
```
7079

7180
### Options
7281

73-
| Option | Default | Description |
74-
| ----------------------- | -------- | -------------------------------------------- |
75-
| `--format <format>` | `text` | Output format: `text` or `json` |
76-
| `-v, --verbose` | | Show per-page details for checks with issues |
77-
| `--checks <ids>` | all | Comma-separated list of check IDs |
78-
| `--sampling <strategy>` | `random` | URL sampling strategy (see below) |
79-
| `--max-concurrency <n>` | `3` | Maximum concurrent HTTP requests |
80-
| `--request-delay <ms>` | `200` | Delay between requests |
81-
| `--max-links <n>` | `50` | Maximum links to test in link checks |
82-
| `--pass-threshold <n>` | `50000` | Size pass threshold (characters) |
83-
| `--fail-threshold <n>` | `100000` | Size fail threshold (characters) |
82+
| Option | Default | Description |
83+
| ----------------------- | -------- | ----------------------------------------------------- |
84+
| `--format <format>` | `text` | Output format: `text`, `json`, or `scorecard` |
85+
| `-v, --verbose` | | Show per-page details for checks with issues |
86+
| `--fixes` | | Show fix suggestions for warn/fail checks (text mode) |
87+
| `--score` | | Include scoring data in JSON output |
88+
| `--checks <ids>` | all | Comma-separated list of check IDs |
89+
| `--sampling <strategy>` | `random` | URL sampling strategy (see below) |
90+
| `--max-concurrency <n>` | `3` | Maximum concurrent HTTP requests |
91+
| `--request-delay <ms>` | `200` | Delay between requests |
92+
| `--max-links <n>` | `50` | Maximum links to test in link checks |
93+
| `--pass-threshold <n>` | `50000` | Size pass threshold (characters) |
94+
| `--fail-threshold <n>` | `100000` | Size fail threshold (characters) |
8495

8596
### Sampling strategies
8697

@@ -122,6 +133,76 @@ const check = getCheck('llms-txt-exists')!;
122133
const result = await check.run(ctx);
123134
```
124135

136+
## Scoring
137+
138+
afdocs includes a scoring module that assigns a 0-100 numerical score to a documentation site's agent-friendliness. The score reflects how well agents can actually use the documentation, not just how many boxes are ticked: checks are weighted by impact, multi-page checks use proportional scoring (3/50 pages failing is different from 48/50), and interaction effects between checks are modeled as coefficients.
139+
140+
For a full explanation of how scores are calculated, including check weights, warn coefficients, score caps, and interaction diagnostics, see [How the Agent-Friendly Docs Score Works](SCORING.md).
141+
142+
### Scorecard output
143+
144+
`--format scorecard` renders the full scorecard: overall score with letter grade, per-category scores, interaction diagnostics (system-level findings that emerge from combinations of check results), and per-check results with fix suggestions.
145+
146+
```
147+
Agent-Friendly Docs Scorecard
148+
==============================
149+
150+
Overall Score: 72 / 100 (C)
151+
152+
Category Scores:
153+
Content Discoverability 72 / 100 (C)
154+
Markdown Availability 60 / 100 (C)
155+
Page Size and Truncation Risk 45 / 100 (D)
156+
...
157+
158+
Interaction Diagnostics:
159+
[!] Markdown support is undiscoverable
160+
Your site serves markdown at .md URLs, but agents have no way to
161+
discover this. ...
162+
163+
Fix: Add a blockquote directive near the top of each docs page ...
164+
165+
Check Results:
166+
Content Discoverability
167+
PASS llms-txt-exists llms.txt found at /llms.txt
168+
WARN llms-txt-size llms.txt is 65,000 characters
169+
Fix: If it grows further, split into nested llms.txt files ...
170+
FAIL llms-txt-directive No directive detected on any tested page
171+
Fix: Add a blockquote near the top of each page ...
172+
```
173+
174+
### Letter grades
175+
176+
| Grade | Score | Description |
177+
| ----- | ----- | --------------------------------------------------------------------------- |
178+
| A+ | 100 | Perfect. Every check passes. |
179+
| A | 90-99 | Excellent. Agents can effectively navigate and consume this documentation. |
180+
| B | 80-89 | Good. Minor improvements possible; agents can use most content. |
181+
| C | 70-79 | Functional but with notable gaps. Some content is inaccessible or degraded. |
182+
| D | 60-69 | Significant barriers. Agents struggle to use this documentation. |
183+
| F | 0-59 | Poor. Agents likely cannot use this documentation in a meaningful way. |
184+
185+
### Programmatic scoring
186+
187+
The scoring module is available as a pure function for programmatic consumers:
188+
189+
```ts
190+
import { computeScore } from 'afdocs';
191+
// or import from the dedicated subpath:
192+
// import { computeScore } from 'afdocs/scoring';
193+
194+
const report = await runChecks('https://docs.example.com');
195+
const score = computeScore(report);
196+
197+
console.log(score.overall); // 72
198+
console.log(score.grade); // 'C'
199+
console.log(score.categoryScores); // { 'content-discoverability': { score: 80, grade: 'B' }, ... }
200+
console.log(score.diagnostics); // [{ id: 'markdown-undiscoverable', severity: 'warning', ... }]
201+
console.log(score.resolutions); // { 'llms-txt-directive': 'Add a blockquote near the top...' }
202+
```
203+
204+
`computeScore` takes a `ReportResult` and returns a standalone `ScoreResult`. It does not modify the report. Composition is the consumer's responsibility: the CLI formatters compose them; external consumers call `computeScore()` directly.
205+
125206
## Test helpers
126207

127208
afdocs includes vitest helpers so you can add agent-friendliness checks to your docs site's CI pipeline. For a ready-to-copy setup with a GitHub Actions workflow, see the [`examples/`](examples/) directory.
@@ -224,9 +305,9 @@ describe('agent-friendliness', () => {
224305

225306
## Checks
226307

227-
22 checks across 8 categories.
308+
22 checks across 7 categories.
228309

229-
### Category 1: llms.txt
310+
### Category 1: Content Discoverability
230311

231312
| Check | Description |
232313
| ------------------------- | --------------------------------------------------------- |
@@ -235,6 +316,7 @@ describe('agent-friendliness', () => {
235316
| `llms-txt-size` | Whether `llms.txt` fits within agent truncation limits |
236317
| `llms-txt-links-resolve` | Whether URLs in `llms.txt` return 200 |
237318
| `llms-txt-links-markdown` | Whether URLs in `llms.txt` point to markdown content |
319+
| `llms-txt-directive` | Whether pages include a directive pointing to `llms.txt` |
238320

239321
### Category 2: Markdown Availability
240322

@@ -267,21 +349,15 @@ describe('agent-friendliness', () => {
267349
| `http-status-codes` | Whether error pages return correct status codes |
268350
| `redirect-behavior` | Whether redirects are same-host HTTP redirects |
269351

270-
### Category 6: Agent Discoverability Directives
271-
272-
| Check | Description |
273-
| -------------------- | -------------------------------------------------------- |
274-
| `llms-txt-directive` | Whether pages include a directive pointing to `llms.txt` |
275-
276-
### Category 7: Observability and Content Health
352+
### Category 6: Observability and Content Health
277353

278354
| Check | Description |
279355
| ------------------------- | ---------------------------------------------- |
280356
| `llms-txt-freshness` | Whether `llms.txt` reflects current site state |
281357
| `markdown-content-parity` | Whether markdown and HTML versions match |
282358
| `cache-header-hygiene` | Whether cache headers allow timely updates |
283359

284-
### Category 8: Authentication and Access
360+
### Category 7: Authentication and Access
285361

286362
| Check | Description |
287363
| ------------------------- | -------------------------------------------------------------------- |

0 commit comments

Comments
 (0)