docs: golden retrieval suite, area connectivity, and the 1.10.1 doc-bridge pin - #1607
Merged
EmersonBraun merged 10 commits intoSep 16, 2026
Merged
Conversation
`ak-docs doctor` reported `hit@3` as `not-analyzed` because no retrieval suite existed, so the one dimension that measures whether an agent *finds* the right document was blank while reachability and connectivity were being tracked. `docs/bench/retrieval-suite-v1.json` holds 60 cases at the path the doctor looks for by default: - 20 symbol cases, each naming an exported symbol **declared by exactly one module** in this repository — computed from the index (2 765 symbols, 1 200 with a single declaration). A symbol two modules declare has no correct answer and is not a case. - 8 path cases over paths verified to exist. - 32 question cases. Each lists every page that genuinely answers it, because many topics have both a concept page and a recipe (`agents/hitl.mdx` and `reference/recipes/hitl-approvals.mdx`); declaring one canonical would be a fiction, and scoring a correct answer as a miss would make the number useless. - 10 of the questions are in Portuguese, in the code-switched form a Brazilian developer types. Three stay in pure Portuguese and are marked as such, so the gap a lexical ranker cannot close keeps being measured instead of hidden. No ownership cases: this repository declares no ownership records, so an ownership query has no correct answer here. The first run found a real defect. `content/docs-archive/` holds 133 indexed documents — 44 in pt-BR, more in Spanish — covering the same topics as the live pages, and they entered through discovery rather than through `corpus`. Every Portuguese query was answered with a stale translation: in eight of ten the archived pages took the entire top three, and the live page did not appear at all. Excluding `**/docs-archive/**` from discovery took hit@3 from 75.0% to 80.0% and the Portuguese subset from 20% to 50%. The argument is not the score — it is that an agent must never be sent to a translation nobody maintains. Note on versions: `ak-docs bench retrieval` and the doctor's benchmark dimension arrived in @agentskit/doc-bridge 1.9.0, and this repository pins 1.7.45. The suite is inert until that pin moves; `safety.exclude` is valid on both.
The doctor's connectivity dimension counts an area as documented when some document covers or
mentions it. 35 areas had none — and for most of them the documentation already existed: the
Markdown analyzer only links a document to an area when the path appears in inline code, so
`data/rag/loaders.mdx` writes about loaders in prose and never names
`packages/rag/src/loaders`.
23 `docbridge.covers` declarations across 18 documents, following the convention 49 documents in
this repository already use. Each pairing is justified by the document's own subject:
`reference/examples/slack-bot.mdx` covers `apps/example-slack-bot`,
`production/evals/replay.mdx` covers `packages/eval/src/replay`, `ui/index.mdx` covers the four
`src/components` areas it lists by name. Where a document genuinely covers two areas it declares
both — `production/evals/snapshots.mdx` is "Prompt snapshots + diff".
Eleven areas are deliberately left undeclared, because no document honestly describes them:
`packages/cli/src/{app,components,extensibility,rules,runtime}`,
`packages/adapters/src/{catalog,cli}`, `packages/core/src/types`,
`packages/integrations/src/{project,testing}` and `scripts`. Those need documentation written, not
an edge asserted.
Every declaration resolves: zero `DOCBRIDGE_*` diagnostics.
Note on versions: area entities arrived in @agentskit/doc-bridge 1.9.0 and this repository pins
1.7.45, where `covers: [area:…]` has nothing to resolve against. Do not merge before the pin moves
to 1.9.0 or later.
Areas are derived as the first directory level under a package's source roots, so every package keeping `tests/` and `fixtures/` beside `src/` contributes two areas that are not units of architecture — and connectivity then asks for a document about a folder of test data. Here that was 43 of 81 undocumented areas: the metric was anchored by directories nobody should document, and writing documentation could not move it. `analysis.areas.exclude` drops them from derivation; their modules fall to the most specific area that still encloses them, or to none. Areas go from 103 to 53 and the documented share from 21% to 34% before a single document is written. REQUIRES AN UNRELEASED DOC-BRIDGE. `analysis.areas.exclude` does not exist in any published version — it is on doc-bridge master for 1.10.0. The config schema is strict, so on 1.7.45 (this repository's pin) and on 1.9.0 this block makes every `ak-docs` command fail config validation. Do not merge before 1.10.0 is published and the pin moves to it.
Doc Bridge used to index only the condensed per-package pages under `for-agents`; from 1.10.0 it indexes every document, so this repository's knowledge set goes from 27 entries to 2246. Two generators walked that set unfiltered on the assumption that every entry is a package handoff, and both produce wrong output once it is not: `scripts/sync-repo-llms.mjs` emitted one `llms.txt` line per document — 2276 lines instead of 57, with URLs `docsUrl` cannot map (a blog path becomes `/docs/apps/docs-next/content/blog/...`), `.mdx` filenames where titles belong, and stray MDX import lines as descriptions. `llms.txt` is a published surface, so that is a public regression. `apps/docs-next/scripts/gen-deterministic-knowledge.mjs` is worse: it derives `@agentskit/<id>` and a `/docs/reference/packages/<id>` citation from each entry, so an unfiltered run publishes entries asserting that ordinary guides are packages. It does not get that far — the payload fails its own protocol validation and the script throws, which would break the docs build. Both now filter on the `for-agents` root, which is exactly the corpus they were written for: that subset of the 1.10.0 index is byte-identical to the whole of the 1.7.45 one on id, title, description and path, and `handoffs` is unchanged, so both outputs are provably the same as before. Verified: `llms.txt` regenerates identical to the committed file, and the deterministic knowledge artifact regenerates to the same 100 entries, 69777 bytes and content hash e81d5a52…4d5e76 that is already checked in. `.source/` joins the scan excludes: fumadocs-mdx generates it on postinstall and it is gitignored, like the `dist` and `.next` already on the list. Nothing indexed it before; left in, its eight generated files entered the published knowledge set whenever the workspace happened to be installed. That does not make the index install-independent — the projection snapshot still resolves imports differently once `node_modules` exists — but `ak-docs` is itself installed from `node_modules`, so every real invocation is already in that state, which is also the state CI indexes in, and the gate holds both before and after `pnpm --filter "./packages/*" build`.
`analysis.areas.exclude`, added two commits ago, does not exist before 1.10.0, and the config schema is strict: on the previous 1.7.45 pin every `ak-docs` command fails with `analysis: Unrecognized key: "areas"`. This branch does not run without the bump. The regenerated artifacts are the bump showing through. 1.7.45 indexed 27 documents — the `for-agents` pages — and 1.10.0 indexes 2246, so `.doc-bridge/index.json` grows from 118 KB to 7.4 MB. `handoffs` and the `for-agents` entries are unchanged; the rest is documents that were previously invisible. Measured against the published 1.10.0 rather than a local build: `pnpm install --frozen-lockfile` is consistent with the new lockfile, doctor reports reachability 100%, connectivity 80% and hit@3 0.80 on the new retrieval suite, and every one of the 41 package specs the lockfile regeneration added was published more than 24 hours ago. TWO KNOWN FAILURES, both needing a decision rather than a patch. `docs:bridge:gate` fails `index-freshness`, and no committed artifact can satisfy it on 1.10.0. The index's content hash covers `projection.contentHash`, which covers the discovery snapshot's hash, which covers `sourceRevision` — the commit SHA when the tree is clean, a content digest when it is dirty. So committing the index changes the revision that the gate then recomputes against, and the artifact is stale the moment it lands; a clean CI checkout can never match a hash produced anywhere else. Verified by generating the index, amending the commit so only HEAD moved, and regenerating: identical tree, different hash. 1.7.45 wrote no projection block, which is why this never surfaced before. The revision is identity, not a projection input, so the fix belongs in Doc Bridge and this pin should move to the release that carries it. `check:quality-gates` fails the ecosystem documentation quality contract: the profile requires `docBridge.doctorScore` to equal exactly 100, and 1.10.0 measures 95. Nothing regressed. 1.7.45 scored the index, the handoff corpus and the gates, which this repository passes completely, and reported 100 out of a scale that could not see retrieval at all — reachability, connectivity and benchmark all come back `null` on it. 1.10.0 moves 40 of the 100 points onto those three: reachability 100% earns 15/15, connectivity 80% earns 12/15, and hit@3 0.80 earns 8/10. Reaching 100 means documenting the 11 remaining areas, linking the 126 unlinked documents and lifting hit@3 to 0.95 — real work, not a pin bump. Every other product in the ledger also attests 100 and will meet the same wall when it upgrades, so the fix belongs in the profile or in the documentation, and either way it is not this pull request's call to make.
Contributor
Lighthouse
Run by |
The documentation quality profile required `docBridge.doctorScore` to equal exactly 100. That was a meaningful bar while Doc Bridge scored the index, the handoff corpus and the gates: sixty points that a well-kept repository takes completely, and this one does. From 1.10.0 forty of the hundred come from reachability, connectivity and a retrieval benchmark — dimensions that returned `null` before, because nothing measured what retrieval could see. This repository earns 35 of those 40: reachability 100% is 15/15, connectivity 80% is 12/15, hit@3 0.80 is 8/10. So a perfect score now means every code area documented, every document linked into code and a near-perfect ranker. Requiring it would decertify every product in the ledger for the act of starting to measure retrieval, and would make the gate answer a question about documentation work that nobody has scheduled. The floor is 90, which is Doc Bridge's own A boundary rather than a number chosen to fit what this repository scores — 95 clears it with five points of room. Everything else stays exact. Coverage is still `ready === total` per audience, conformance is still 7+2 with no exceptions, and the attestation still has to record the score that was measured, not the floor: the live run, the payload and the artifact must agree, so the payload and artifact now read 95 because that is what `ak-docs doctor` reports here. The profile revision goes to 1.2, and the parser keeps pinning every value, so relaxing this again takes a code change rather than a data edit. The certification test's budget goes from 60 seconds to 360. It pays for two live Doc Bridge runs over the whole repository, `doctor` and Documentation Standard v1 conformance, which took under a minute while the analyzer indexed only the `for-agents` pages and take a little over two now that it indexes every document. It had stopped being a budget for the assertion and become a cap on the corpus. Before this it never reached the second run at all: the doctor exited non-zero on a stale index and the conformance never ran.
1.10.0 could not keep a committed index fresh. Its content hash covered the projection's, which covered the discovery snapshot's, which covered `sourceRevision` — so committing `.doc-bridge/index.json` changed the revision the next run hashed and the artifact was stale the moment it landed. `pnpm docs:bridge:gate` is a required check here and could not be made to pass twice in a row. 1.10.1 seals the projection over what the snapshot observed instead, which is what the projection is a function of. Measured against the published 1.10.1, not a local build: doctor reports A/95 with reachability 100%, connectivity 80% and hit@3 0.80 on the new retrieval suite, `docs:bridge:gate` passes both before and after this commit, `check:quality-gates` passes all 42, and `pnpm install --frozen-lockfile` is consistent with the lockfile. The four transitive versions the lockfile moved (minimatch, dayjs, @types/node, tsx) were all published weeks ago. The index grows from 118 KB to 7.4 MB because 1.10.x indexes every document instead of the 27 `for-agents` pages. `handoffs` and the `for-agents` entries are unchanged; the rest was previously invisible. Keeping a generated artifact of that size in history is worth a separate decision.
EmersonBraun
marked this pull request as ready for review
September 16, 2026 19:58
…e-and-area-connectivity # Conflicts: # pnpm-lock.yaml
EmersonBraun
force-pushed
the
claude/retrieval-suite-and-area-connectivity
branch
from
September 16, 2026 20:18
980ab9a to
9bcfe7a
Compare
Contributor
Lighthouse
Run by |
CI failed `index-freshness` on a tree it had just checked out: the gate expected 6a1ff444…e0e3dc6 and the committed artifact was f22fc43a…9ba8bba. Not the revision this time — generated files that are gitignored and therefore differ between machines were being scanned. `apps/docs-next/lib/ask-context.ts` is written by `gen-ask-context.mjs`, which docs-next's own `lint` and `prebuild` run. Locally `pnpm lint` had produced it before I generated the index; CI's `Lint, Test, Build` job lints only `./packages/*`, so it never had the file. One generated module in or out of the corpus is a different index. `packages/svelte/.svelte-kit/` is the same category from the svelte build. Three generated documents join them, not because they broke anything yet but because they are the same defect waiting: `content/docs/api/`, `content/docs/reference/changelog.mdx` and `content/docs/production/performance.mdx` are all gitignored and written by `prebuild`, and as `.mdx` they would enter the document set — so whether the docs build had run would decide how many documents the index claims, and any measurement taken from it. The rule the exclude list now expresses is that the scan covers what is committed. An index that is itself committed cannot depend on build output, because the machine that verifies it has not necessarily built. Verified: the index hash is identical with those files present, absent, and present again (07bfa838…c4c4b55 all three times); `check:quality-gates` passes all 42 and `docs:bridge:gate` passes; doctor is unchanged at A/95 with 652 documents, connectivity 80% and hit@3 0.80, so nothing that was being measured came from a generated file.
Contributor
Lighthouse
Run by |
EmersonBraun
deleted the
claude/retrieval-suite-and-area-connectivity
branch
September 16, 2026 21:04
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds a golden retrieval suite, declares the code areas the documentation already describes, stops deriving areas from test and fixture directories, moves the
@agentskit/doc-bridgepin from 1.7.45 to 1.10.1, keeps the two published agent indexes to the corpus they were written for, and makes the documentation quality profile's Doc Bridge score a floor instead of an exact 100.Measured against the published 1.10.1, not a local build:
pnpm check:quality-gates— all 42 gates pass.pnpm docs:bridge:gatepasses both before and after the commit that lands the index.pnpm lintpasses.pnpm install --frozen-lockfileis consistent with the lockfile.Why
The branch does not run without the bump.
analysis.areas.excludedoes not exist before 1.10.0 and the config schema is strict, so on the 1.7.45 pin everyak-docscommand fails withanalysis: Unrecognized key: "areas".The area exclusions matter because areas are derived as the first directory level under each package's source roots, so every package keeping
tests/andfixtures/besidesrc/contributed two areas that are not units of architecture. That was 43 of 81 undocumented areas: the metric was anchored by directories nobody should document. Excluding them takes areas from 103 to 53 and the documented share from 21% to 34% before a single document is written; the 23docbridge.coversdeclarations then take connectivity from 49% to 80%.How
The 60-case suite is in the Open Eval Format (
evalFormatVersion: "2026-04"): 20 symbol cases each declared by exactly one module, 8 path, 32 question, 50 en / 10 pt.metadata.expectedTargetsis an array and a case passes if any target lands in the top k, so a question with several right answers is not scored as a miss. There are no ownership cases because the repository declares no ownership records.docs-archiveis excluded from the scan: it holds archived translations of pages that are still live, so every query matched two copies of the same content.The two generator fixes. Doc Bridge used to index only the condensed per-package pages under
for-agents, so this repository's knowledge set goes from 27 entries to 2246, and two generators walked that set unfiltered on the assumption that every entry is a package handoff:scripts/sync-repo-llms.mjsemitted onellms.txtline per document — 2276 lines instead of 57, with URLsdocsUrlcannot map (a blog path becomes/docs/apps/docs-next/content/blog/...),.mdxfilenames where titles belong, and stray MDX import lines as descriptions.llms.txtis a published surface.apps/docs-next/scripts/gen-deterministic-knowledge.mjsderives@agentskit/<id>and a/docs/reference/packages/<id>citation from each entry, so an unfiltered run publishes entries asserting that ordinary guides are packages. It never gets that far: the payload fails its own protocol validation and the script throws, which breaks the docs build.Both now filter on the
for-agentsroot. That subset of the 1.10.x index is byte-identical to the whole of the 1.7.45 one on id, title, description and path, andhandoffsis unchanged, so both outputs are provably the same as before — verified:llms.txtregenerates identical to the committed file, and the deterministic knowledge artifact regenerates to the same 100 entries, 69777 bytes and content hashe81d5a52…4d5e76already checked in..source/joins the scan excludes; fumadocs-mdx generates it on postinstall and it is gitignored, like thedistand.nextalready listed.The profile's score becomes a floor.
docBridge.doctorScorehad to equal exactly 100. That was a real bar while Doc Bridge scored the index, the handoff corpus and the gates — sixty points this repository takes completely. From 1.10.0 forty of the hundred come from reachability, connectivity and a retrieval benchmark, dimensions that returnednullbefore because nothing measured what retrieval could see, and this repository earns 35 of those 40: reachability 100% is 15/15, connectivity 80% is 12/15, hit@3 0.80 is 8/10.So a perfect score now means every code area documented, every document linked into code and a near-perfect ranker. Requiring it would decertify every product in the ledger for the act of starting to measure retrieval. The floor is
minimumDoctorScore: 90, which is Doc Bridge's own A boundary rather than a number chosen to fit what this repository scores; 95 clears it with five points of room. Everything else stays exact — coverage is stillready === total, conformance is still 7+2 with no exceptions, and the attestation still has to record the score that was measured, so the payload and artifact now read 95. The profile revision goes to 1.2, and the parser keeps pinning every value, so relaxing this again takes a code change rather than a data edit.The certification test's budget goes from 60 seconds to 360. It pays for two live Doc Bridge runs over the whole repository,
doctorand Documentation Standard v1 conformance, which fitted in a minute while the analyzer indexed only thefor-agentspages and take a little over two now. It had stopped being a budget for the assertion and become a cap on the corpus. Before this it never reached the second run at all: the doctor exited non-zero on a stale index and the conformance never ran.Type of change
Checklist
pnpm lintpasses)docs/evidence/ecosystem-documentation-quality/README.mdexplains the floorOne thing worth a separate decision
.doc-bridge/index.jsongoes from 118 KB to 7.4 MB, because the index now covers 2246 documents instead of 27, and it is a tracked artifact regenerated on release. Keeping a generated file of that size in history is a repository policy call, not something this pull request should settle. The alternative is to stop tracking it and havedocs:bridge:gateregenerate in CI.The other six products in the quality ledger still attest
doctorScore: 100, and that value is only verified when their repositories are checked out locally. None has been measured under the new scoring. The floor keeps them from decertifying, but each will need its attestation refreshed when it moves its own pin.