@agentskit/doc-bridge 1.7.44 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (223) hide show
  1. package/CHANGELOG.md +471 -0
  2. package/CONTRIBUTING.md +29 -4
  3. package/README.md +87 -40
  4. package/SECURITY.md +7 -0
  5. package/action.yml +1 -1
  6. package/bin/ak-docs.js +2 -2
  7. package/bin/ak-verify.js +13 -7
  8. package/dist/cli/program.d.ts +3 -1
  9. package/dist/cli/program.js +15888 -6061
  10. package/dist/cli/program.js.map +1 -1
  11. package/dist/config/index.d.ts +1 -1
  12. package/dist/config/index.js +91 -9
  13. package/dist/config/index.js.map +1 -1
  14. package/dist/index-Beor6Yhi.d.ts +792 -0
  15. package/dist/index.d.ts +9979 -3257
  16. package/dist/index.js +15954 -5774
  17. package/dist/index.js.map +1 -1
  18. package/docs/MARKETPLACE.md +1 -1
  19. package/docs/PRD-documentation-efficiency-study.md +406 -0
  20. package/docs/PRD-knowledge-retrieval-and-enrichment.md +466 -0
  21. package/docs/RELEASE.md +22 -8
  22. package/docs/adr/0002-documentation-audit-boundary.md +22 -0
  23. package/docs/adr/0003-study-protocol-and-historical-evidence.md +40 -0
  24. package/docs/adr/0004-controlled-study-runner.md +25 -0
  25. package/docs/adr/0005-documentation-quality-and-criticality.md +20 -0
  26. package/docs/adr/0006-registry-semantic-grounding.md +20 -0
  27. package/docs/adr/0007-longitudinal-study-metrics.md +21 -0
  28. package/docs/adr/0008-study-verification-boundary.md +21 -0
  29. package/docs/adr/0009-study-provider-cli-adapter.md +25 -0
  30. package/docs/agent-corpus/INDEX.md +14 -3
  31. package/docs/agent-corpus/OVERVIEW.md +25 -0
  32. package/docs/agent-corpus/chat.md +7 -3
  33. package/docs/agent-corpus/cli.md +18 -2
  34. package/docs/agent-corpus/conformance.md +14 -2
  35. package/docs/agent-corpus/doc-bridge.md +48 -1
  36. package/docs/agent-corpus/doctor.md +10 -2
  37. package/docs/agent-corpus/gates.md +6 -2
  38. package/docs/agent-corpus/mcp.md +15 -2
  39. package/docs/agent-corpus/memory.md +6 -2
  40. package/docs/agent-corpus/query.md +35 -2
  41. package/docs/bench/README.md +122 -0
  42. package/docs/bench/retrieval-baseline-v1.json +28 -0
  43. package/docs/bench/retrieval-suite-v1.json +1033 -0
  44. package/docs/chat-and-rag.md +3 -2
  45. package/docs/for-agents.md +9 -1
  46. package/docs/getting-started.md +4 -11
  47. package/docs/guides/gate-ci.md +11 -1
  48. package/docs/guides/install-and-run.md +9 -65
  49. package/docs/index.md +22 -1
  50. package/docs/knowledge-engine-runbook.md +51 -4
  51. package/docs/landing/assets/context-payload-reduction.svg +21 -0
  52. package/docs/landing/assets/controlled-ab-comparison.svg +30 -0
  53. package/docs/landing/index.html +119 -5
  54. package/docs/loop-workflow.md +117 -0
  55. package/docs/mcp.md +6 -1
  56. package/docs/parity/public-claims-v1.json +145 -0
  57. package/docs/playbook/doc-bridge-pattern.md +1 -1
  58. package/docs/query.md +90 -2
  59. package/docs/recipes/index-pipeline.md +1 -1
  60. package/docs/schemas/agent-handoff-v1.md +15 -0
  61. package/docs/schemas/doc-bridge-index-v1.md +65 -0
  62. package/docs/spec/benchmark-v1.md +39 -1
  63. package/docs/spec/cli.md +30 -10
  64. package/docs/spec/config-v1.md +192 -8
  65. package/docs/spec/documentation-audit-v1.md +61 -0
  66. package/docs/spec/enrichment-overlay-v1.md +241 -0
  67. package/docs/spec/graph-signals-v1.md +92 -0
  68. package/docs/spec/incremental-scan-v1.md +102 -0
  69. package/docs/spec/markdown-analyzer-v1.md +73 -0
  70. package/docs/spec/mcp-knowledge-tools-v1.md +147 -0
  71. package/docs/spec/measured-enrichment-v1.md +229 -0
  72. package/docs/spec/public-parity-v1.md +119 -0
  73. package/docs/spec/registry-agents.md +6 -0
  74. package/docs/spec/render-v1.md +122 -0
  75. package/docs/spec/retrieval-index-v1.md +164 -0
  76. package/docs/spec/study-metrics-v1.md +58 -0
  77. package/docs/spec/study-protocol-v1.md +46 -0
  78. package/docs/spec/study-provider-cli-v1.md +116 -0
  79. package/docs/spec/study-runner-v1.md +35 -0
  80. package/docs/spec/study-task-suite-v1.md +41 -0
  81. package/docs/spec/study-verification-v1.md +40 -0
  82. package/docs/study/README.md +84 -0
  83. package/docs/study/ab-adjudicated-cost-analysis-v1.md +29 -0
  84. package/docs/study/ab-adjudicated-cost-plan-v1.json +33 -0
  85. package/docs/study/ab-adjudicated-cost-plan-v2-v1.json +33 -0
  86. package/docs/study/ab-adjudicated-cost-result-v1.json +80 -0
  87. package/docs/study/ab-baseline-analysis-v1.md +21 -0
  88. package/docs/study/ab-baseline-plan-v1.json +33 -0
  89. package/docs/study/ab-baseline-recovery-plan-v1.json +33 -0
  90. package/docs/study/ab-baseline-result-v1.json +79 -0
  91. package/docs/study/documentation-audit-round-2026-08-31.json +183 -0
  92. package/docs/study/historical-evidence-v1.json +252 -0
  93. package/docs/study/observation-ledger-v1.json +30632 -0
  94. package/docs/study/phase3-task-coverage-v1.json +34 -0
  95. package/docs/study/phase4-public-pilot-ledger-v1.json +1344 -0
  96. package/docs/study/phase4-public-pilot-result-v1.json +52 -0
  97. package/docs/study/phase4-public-pilot-run-plan-v1.json +26 -0
  98. package/docs/study/phase4-public-pilot-task-suite-v1.json +71 -0
  99. package/docs/study/pilot-round-2026-08-31.json +46 -0
  100. package/docs/study/protocol-v1.json +90 -0
  101. package/docs/study/publication-gate-v1.md +45 -0
  102. package/docs/study/quality-scorecard-cycle-plan.md +545 -0
  103. package/docs/study/quality-scorecard-v1.json +38 -0
  104. package/docs/study/round-1-adjudicated-smoke-v1.json +30642 -0
  105. package/docs/study/round-1-instrumentation-plan-v1.md +39 -0
  106. package/docs/study/round-2-expanded-adjudication-v1.json +91 -0
  107. package/docs/study/round-2-expanded-validation-v1.md +58 -0
  108. package/docs/study/round-3-evidence-contract-v1.json +75 -0
  109. package/docs/study/round-3-evidence-contract-v1.md +57 -0
  110. package/docs/study/round-4-confirmation-v1.json +75 -0
  111. package/docs/study/round-4-confirmation-v1.md +55 -0
  112. package/docs/study/run-plan-v1.json +33 -0
  113. package/docs/study/semantic-adjudication-cycle-8.md +20 -0
  114. package/docs/study/task-suite-v1.json +96 -0
  115. package/docs/study/token-efficiency-plan-v1.md +337 -0
  116. package/docs/study/token-efficiency-protocol-v2.json +62 -0
  117. package/docs/study/verification-binding-v1.json +27 -0
  118. package/docs/validation-cycle-plan.md +33 -0
  119. package/docs/verification-harness.md +15 -6
  120. package/ecosystem-claims.json +2 -2
  121. package/ecosystem-upstream.json +2 -2
  122. package/ecosystem.json +4 -4
  123. package/mcpb/manifest.json +9 -1
  124. package/package.json +89 -72
  125. package/scripts/check-ecosystem-upstream.mjs +36 -7
  126. package/scripts/report-visual-check.mjs +20 -3
  127. package/skills/doc-bridge-handoff/fixtures/synthetic-repo/docs/for-agents/packages/payments.md +7 -0
  128. package/skills/doc-bridge-handoff/scripts/resolve-handoff.mjs +1 -1
  129. package/src/agents/registry-adapter.ts +192 -24
  130. package/src/audit/documentation.ts +513 -0
  131. package/src/bench/baseline.ts +198 -0
  132. package/src/bench/overlay-delta.ts +139 -0
  133. package/src/bench/retrieval.ts +319 -0
  134. package/src/budget/compile.ts +91 -0
  135. package/src/budget/sections.ts +70 -0
  136. package/src/cli/demo.ts +2 -2
  137. package/src/cli/program.ts +699 -79
  138. package/src/cli/usage.ts +71 -0
  139. package/src/config/defaults.ts +1 -0
  140. package/src/config/index.ts +4 -0
  141. package/src/config/load-config.ts +7 -1
  142. package/src/config/schema.ts +121 -4
  143. package/src/conformance/documentation-standard-v1.ts +22 -14
  144. package/src/discovery/areas.ts +182 -0
  145. package/src/discovery/documentation.ts +255 -23
  146. package/src/discovery/identity.ts +24 -0
  147. package/src/discovery/incremental.ts +314 -0
  148. package/src/discovery/inputs.ts +110 -0
  149. package/src/discovery/markdown.ts +481 -0
  150. package/src/discovery/repository.ts +557 -125
  151. package/src/doctor/run-doctor.ts +246 -27
  152. package/src/enrich/approvals.ts +190 -0
  153. package/src/enrich/cache.ts +93 -0
  154. package/src/enrich/context-pack.ts +272 -0
  155. package/src/enrich/overlay.ts +255 -0
  156. package/src/enrich/review.ts +106 -0
  157. package/src/enrich/stage.ts +374 -0
  158. package/src/enrich/stats.ts +100 -0
  159. package/src/enrich/validate.ts +410 -0
  160. package/src/federation/llms.ts +74 -24
  161. package/src/findings/report.ts +103 -0
  162. package/src/fixes/proposals.ts +4 -3
  163. package/src/graph/build.ts +356 -0
  164. package/src/graph/memory.ts +208 -0
  165. package/src/index-builder/build-handoffs.ts +22 -11
  166. package/src/index-builder/build-index.ts +132 -3
  167. package/src/index-builder/human-adapters/fumadocs.ts +1 -1
  168. package/src/index-builder/llms-txt.ts +48 -8
  169. package/src/index-builder/project-corpus.ts +111 -0
  170. package/src/index-builder/watch-index.ts +1 -1
  171. package/src/index.ts +630 -2
  172. package/src/lib/bounded-text.ts +15 -10
  173. package/src/lib/fuzzy-match.ts +235 -0
  174. package/src/mcp/knowledge.ts +554 -0
  175. package/src/mcp/server.ts +113 -18
  176. package/src/metrics/benchmark.ts +21 -0
  177. package/src/parity/check.ts +309 -0
  178. package/src/parity/claims.ts +259 -0
  179. package/src/parity/resolve.ts +160 -0
  180. package/src/query/handoff.ts +326 -0
  181. package/src/query/load-index.ts +53 -1
  182. package/src/query/query.ts +92 -59
  183. package/src/query/search.ts +289 -92
  184. package/src/query/text.ts +155 -0
  185. package/src/reconciliation/reconcile.ts +148 -15
  186. package/src/render/data.ts +356 -0
  187. package/src/render/engine.ts +398 -0
  188. package/src/render/generated.ts +77 -0
  189. package/src/render/render.ts +209 -0
  190. package/src/render/template-source.ts +52 -0
  191. package/src/render/templates.ts +289 -0
  192. package/src/report/html.ts +23 -17
  193. package/src/retrieval/bm25.ts +161 -0
  194. package/src/retrieval/project.ts +495 -0
  195. package/src/retrieval/rank.ts +383 -0
  196. package/src/retrieval/weights.ts +39 -0
  197. package/src/retriever/doc-bridge-retriever.ts +100 -15
  198. package/src/rules/engine.ts +45 -12
  199. package/src/safety/repository.ts +1 -1
  200. package/src/schemas/agent-handoff.ts +56 -0
  201. package/src/schemas/budget.ts +37 -0
  202. package/src/schemas/doc-bridge-index.ts +53 -2
  203. package/src/schemas/enrichment.ts +369 -0
  204. package/src/schemas/json-schemas.ts +39 -2
  205. package/src/schemas/knowledge.ts +19 -3
  206. package/src/schemas/retrieval-index.ts +152 -0
  207. package/src/shims/graphology.d.ts +91 -0
  208. package/src/study/adjudication.ts +196 -0
  209. package/src/study/execution.ts +350 -0
  210. package/src/study/expectations.ts +219 -0
  211. package/src/study/metrics.ts +467 -0
  212. package/src/study/protocol.ts +271 -0
  213. package/src/study/provider-cli.ts +115 -0
  214. package/src/study/provider-telemetry.ts +47 -0
  215. package/src/study/quality-scorecard.ts +164 -0
  216. package/src/study/runner.ts +461 -0
  217. package/src/study/task-suite.ts +321 -0
  218. package/src/study/verification.ts +134 -0
  219. package/src/validate.ts +8 -5
  220. package/src/version.ts +1 -1
  221. package/src/workflow/engine.ts +36 -11
  222. package/dist/index-C2PCQSrB.d.ts +0 -2251
  223. package/scripts/verification-harness.mjs +0 -483
package/CHANGELOG.md CHANGED
@@ -1,5 +1,476 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.9.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 9a775a5: Add code areas — the unit of architecture between a package and a file — so reconciliation says
8
+ something useful about a single-package repository.
9
+
10
+ With `reconciliation.scope: "package"` and one package, every internal relation aggregated into a
11
+ self-loop the comparison skips: a thousand observed relations, zero diagnostics, and a health
12
+ score of 100 out of 100 that meant nothing. Most repositories are a single package. The ownership
13
+ configuration already named the missing unit (`path: "src/mcp"`); the graph had no entity for it.
14
+
15
+ `area:<dir>` entities are now derived from the first directory level under each package's source
16
+ roots, plus any path an ownership record names, with `contains` relations from the package, to
17
+ nested areas, and to each module. Each module belongs to exactly one area — the most specific —
18
+ so containment stays a tree and an aggregation has one answer per module. `analysis.areas.depth`
19
+ and `analysis.areas.roots` change what is derived without a code change.
20
+
21
+ `reconciliation.scope: "area"` compares at that level. On this repository it turns 0 diagnostics
22
+ into 177 `RELATION_UNDOCUMENTED` findings, each with file and line evidence.
23
+
24
+ An area that an ownership record names carries `metadata.ownershipId`, which makes two things
25
+ work that could not before. An ownership path no observed module or document lives under is now
26
+ reported as `OWNERSHIP_PATH_UNOBSERVED` with status `stale-or-unverified` — a renamed directory
27
+ was previously invisible, because the handoff still resolved. And an agent document declaring
28
+ `id` plus `editRoot` now resolves to the area it owns: that pair has always filled the ownership
29
+ map, but discovery never read it, so every such declaration became an unresolved reference.
30
+
31
+ The documentation audit measures coverage against areas when a repository has exactly one package.
32
+ It reported `Packages covered: 0/0` on this repository; it now reports `Areas covered: 9/36`, with
33
+ `metrics.coverageUnit` naming the unit and `AREA_DOCUMENTATION_MISSING` for an uncovered area.
34
+
35
+ A document naming a directory in inline code now produces a `mentions` relation to that area,
36
+ completing the part of the Markdown analyzer that was waiting for areas to exist.
37
+
38
+ `pipelineVersion` becomes `1.3.0` and the `repository` analyzer `1.2.0`. `DiscoverySnapshotV1`'s
39
+ schema version is unchanged: the new kind travels through the existing generic envelope.
40
+ - 9a775a5: Let a Registry agent enrich the knowledge graph without ever becoming an authority over it.
41
+
42
+ `EnrichmentProposalV1` is a discriminated union of eleven typed claims — classify a document,
43
+ summarize it, add an alias or an intent, mark it canonical for a scope, propose a relation, flag a
44
+ contradiction, a redundancy or a gap, hint at relevance, suggest an area — each with its own
45
+ deterministic validator and its own policy: low-risk kinds are accepted by policy, structural kinds
46
+ wait for a person, a gap is accepted as a finding and never as a fact, and an unknown kind is
47
+ rejected as `invalid-kind`. A proposal with no evidence, an unknown entity, an unknown diagnostic or
48
+ evidence outside the supplied artifacts is rejected at the boundary. `proposalId` is derived from
49
+ content, so re-running enrichment over an unchanged repository produces no duplicate entries.
50
+
51
+ `EnrichmentOverlayV1` at `.doc-bridge/enrich/overlay.json` stores what became of every proposal:
52
+ `accepted` with `acceptedAt` and `acceptedBy` (`policy` or a person, never the author), `pending`
53
+ with its approval id, `rejected` with a reason, and `stats` by kind. Each entry binds to the content
54
+ hash of the entity it describes: one changed file expires one entry at projection time, its siblings
55
+ survive, and a read never rewrites the file. Re-running the validators over a stored overlay
56
+ reproduces its partition.
57
+
58
+ A new workflow stage `enrich` sits between `reconcile` and `evaluate` and runs only from
59
+ `ak-docs enrich` or `check --enrich`. Agents receive context packs — one entity, its depth-one
60
+ neighbours, the open diagnostics that touch it and a redacted excerpt, under a 64 KB budget
61
+ (`intelligence.registry.maxPackBytes`) — over protocol `doc-bridge.registry-agent.v2`, batched by
62
+ area. Answers are cached under `.doc-bridge/enrich/cache/` keyed on task, agent identity and
63
+ version, prompt version and pack hash, so an unchanged repository makes zero agent calls and a
64
+ one-document change re-runs only the affected packs. Roles are configuration under
65
+ `intelligence.registry.roles` — curator for documents, reviewer for structure, adjudicator for
66
+ canonical conflicts and disputed contradictions, which must be a different identity and may never
67
+ judge its own proposals — and the default remains the existing corpus scanner as curator only.
68
+
69
+ Human approvals go through `createApprovalGate` from `@agentskit/core/hitl` over a file-backed
70
+ store under `.doc-bridge/approvals/`, shared by `ak-docs enrich approve|reject`, `ak-docs fix
71
+ approve` and MCP `docbridge.proposals` (`enrich-list`, `enrich-approve`, `enrich-reject`), bound to
72
+ both the proposal id and the target content hash. An approver equal to the author is refused.
73
+
74
+ Accepted entries enter the retrieval projection: aliases, summaries where a document has none,
75
+ intents and relations with `provenance: proposed` (drawn dashed in the HTML report), canonical
76
+ markers and rank hints as a per-entry signal worth at most 15 percent of the exact-id boost, so an
77
+ exact identifier match always outranks an overlay-boosted entry. With the Registry disabled, absent,
78
+ timing out or answering garbage, `check`, `index`, `search`, `query` and MCP are byte-identical to a
79
+ run with no overlay, and every observed entity and relation survives enrichment unchanged.
80
+ - 9a775a5: Compute graph signals with a graph library instead of ad-hoc counting, and expose the repository
81
+ graph through the ecosystem memory contract.
82
+
83
+ `centrality-risk` in the rules engine derived from the number of undocumented-relation findings
84
+ attached to an entity — documentation debt wearing the name of an architectural signal. A module
85
+ every import path runs through scored zero if it happened to be documented. It is now betweenness
86
+ over the import graph, and without a graph the rule reports nothing rather than reporting the wrong
87
+ thing under a name people act on. On this repository it flags `src/cli/program.ts` first, which is
88
+ the correct answer and one the old heuristic never gave.
89
+
90
+ `src/graph/build.ts` adds, on graphology:
91
+
92
+ - **canonicality** from PageRank over `links-to` and `covers`, so a documentation entry point
93
+ outranks a leaf page;
94
+ - **centrality** from normalized betweenness over `imports` and `re-exports`;
95
+ - **proximity** from bounded shortest paths, excluding `contains`, which is hierarchy and would put
96
+ every module in an area two hops from every other one;
97
+ - **import cycles** with every edge that forms them as evidence, reported as a new `IMPORT_CYCLE`
98
+ diagnostic — this repository has exactly one, between two `src/doctor` modules;
99
+ - **area suggestions** from seeded Louvain communities, emitted only as `coverage` with
100
+ `analyzer: graph` and `scope: area-suggestion:<path>`, status `not-analyzed`. A clustering
101
+ algorithm does not get to name the architecture.
102
+
103
+ `createDocBridgeGraphMemory(snapshot, overlay)` in `src/graph/memory.ts` projects the graph behind
104
+ `GraphMemory` from `@agentskit/memory`, so an agent built on AgentsKit walks repository structure
105
+ with the same `getNode`, `findEdges` and `neighbors` calls it uses for its own memory. Writes land
106
+ in a working layer above the projection and deletes mask rather than erase: the snapshot is an
107
+ observation, and nothing a caller writes should be mistaken for something the repository said.
108
+
109
+ The graph is never serialised and `DiscoverySnapshotV1` is unchanged. Insertion is sorted and every
110
+ score rounded, so metrics are identical across runs and after the input order is shuffled.
111
+ `pipelineVersion` becomes `1.4.0` with a `graph` analyzer version.
112
+ - 9a775a5: Give every file-backed entity its own content hash, and reuse unchanged entities between scans.
113
+
114
+ `EvidenceSchema.contentHash` had existed since the first schema and `discoverRepository` never
115
+ filled it: on this repository 0 of 369 entities carried one. Every cache and every overlay could
116
+ therefore be keyed only on "the whole repository changed", which is true between any two commits.
117
+ Now every `module`, `document` and `package` entity carries the hash of its file in its first
118
+ evidence item, and `external` entities carry none — a name in a manifest is not a file.
119
+
120
+ `discoverRepository({ previous })` accepts a snapshot from a previous scan and skips the TypeScript
121
+ and Markdown parses for files whose hash is unchanged. Reuse is only taken where it cannot change
122
+ the answer:
123
+
124
+ - an entity's own fields depend on its own bytes, so a hash match is enough for the entity;
125
+ - a relation depends on what else exists, so relation reuse also requires that the universe the
126
+ references resolve against is identical — module paths, packages and compiler options for a
127
+ module, and additionally document paths, area paths and which module declares each exported
128
+ symbol for a document. Both fingerprints are derived from the previous snapshot rather than
129
+ stored in it;
130
+ - the whole snapshot is refused unless it declares, and matches, this `pipelineVersion`, these
131
+ `analyzerVersions` and this `configurationHash`. An analyzer that learns to read more produces
132
+ different entities from identical bytes.
133
+
134
+ A replayed edge whose internal target is gone is dropped rather than carried — a renamed file must
135
+ not leave a graph asserting something the repository no longer contains — while an external or
136
+ unresolved endpoint is re-added, because it is in the snapshot only because the reused entity
137
+ referenced it.
138
+
139
+ Two `js-ts` facts only ever lived in a local variable, which made the aggregate `dynamic-imports`
140
+ and `runtime-wiring` entries unreproducible from the per-file ones — and a reused scan replays the
141
+ per-file ones. A literal `require` now sets the resolved-dynamic-import flag it always recorded
142
+ evidence for, and every observed runtime-wiring call leaves a per-file entry: `complete` when its
143
+ target is statically known, `not-analyzed` when it is not, where before a resolved call left no
144
+ record at all. Both make the aggregate derivable from what the snapshot actually carries.
145
+
146
+ One `coverage` entry with `scope: reused-entities` reports what a run reused and what it re-parsed,
147
+ so a fast run is explainable rather than suspicious. It is the only part of a snapshot that
148
+ describes the run rather than the repository: the entities, the relations and every other coverage
149
+ entry are byte-identical to a cold scan's. The CLI still scans cold, so its artifacts are unchanged
150
+ apart from the new entry. `pipelineVersion` becomes `1.5.0`, the `repository` analyzer `1.3.0` and `js-ts` `1.3.5`.
151
+ - 9a775a5: Read documentation with a real Markdown parser, and turn its prose into evidence-backed graph
152
+ edges.
153
+
154
+ Documentation used to be read with regular expressions: frontmatter by one, the `docbridge` block
155
+ by a hand-written YAML subset, and the prose not at all. Headings, links and inline code were
156
+ discarded — so on this repository, where 23 documents link to other documents and 14 cite source
157
+ paths, none of it produced a single edge.
158
+
159
+ A new `markdown` analyzer parses documents with remark (CommonMark plus GFM) and emits `observed`
160
+ relations with the file and line each claim was made on: `links-to` between documents,
161
+ `mentions` from a document to a module or package, and `mentions-symbol` from an inline code token
162
+ to the module that exports it. On this repository that is 154 `links-to`, 93 `mentions` and 50
163
+ `mentions-symbol` where there were none, and 55 of 104 documents now have an outgoing edge.
164
+
165
+ A symbol resolves to the module that declares it rather than a barrel that re-exports it, and a
166
+ name declared by two modules resolves to neither — the reference and its lines are reported as a
167
+ coverage note, because sending an agent to one of two possible definitions is worse than sending
168
+ it nowhere. Unresolved path-shaped references are matched with Jaro-Winkler and accepted only at
169
+ 0.92 or above with a single candidate, recorded as `confidence: 'fuzzy'`. Mentions inside a
170
+ `<!-- doc-bridge:generated -->` region are ignored, so Doc Bridge never reads its own output back
171
+ in as evidence. A document referencing more than 64 entities records `evidenceTruncated`.
172
+
173
+ Document entities now carry `title`, headings to depth three with their lines, a bounded
174
+ `summary`, `wordCount`, the frontmatter subset (`type`, `audience`, `owner`, `lifecycle`, `tier`),
175
+ any generated regions, and the file's content hash on its evidence. A document declaring
176
+ `audience` overrides the path heuristic that classifies it.
177
+
178
+ The `docbridge` block is now real YAML validated by a schema, so quoted lists, flow mappings,
179
+ anchors and multi-line strings work as they do everywhere else, and a schema violation names the
180
+ field. Every `DOCBRIDGE_*` diagnostic code is preserved, and a block YAML cannot read at all falls
181
+ back to the previous line-oriented scanner, which reports per line.
182
+
183
+ `pipelineVersion` becomes `1.2.0` and `analyzerVersions` gains `markdown`. The
184
+ `DiscoverySnapshotV1` envelope is unchanged.
185
+
186
+ Entity identity is consolidated into one module: `entityId` and `relationId` in
187
+ `src/discovery/identity.ts`, shared by the discovery analyzers and the retrieval projection, which
188
+ had grown a second copy. `projectedEntityId` (added in the unreleased corpus projection and never
189
+ published) is gone in favour of `entityId`.
190
+ - 9a775a5: Render the canonical artifacts as Markdown people can read, from templates rather than string
191
+ concatenation, and close the loop between what Doc Bridge writes and what it reads.
192
+
193
+ `ak-docs render <template> [--data <artifact>] [--output <path>]` ships five templates: `llms.txt`,
194
+ replacing the concatenation in the index builder byte for byte; `area`, one page per code area
195
+ with its purpose, modules, documents, related areas, checks and open findings; `ownership`, one
196
+ sidecar per ownership record; `change-digest`, the entities and documents whose content hash
197
+ moved since the last scan and the documents that should have moved with them; and
198
+ `overlay-review`, the pending agent proposals with their evidence links, with an explicit empty
199
+ state when no overlay exists. A project replaces any of them under `render.templates` without a
200
+ code change; `--print-template` prints the bundled source to start from.
201
+
202
+ Templates are `knap` 0.5 templates: parsed to an AST, interpreted without `eval`, and fed only
203
+ the variables Doc Bridge computes. The index pipeline is synchronous and knap's renderer is not,
204
+ so the AST is walked by a synchronous evaluator of Doc Bridge's own; a test renders every bundled
205
+ template through knap's engine as well and holds the two to identical bytes. Every bundled
206
+ template has a golden file, and rendering never calls an agent or reads the Registry.
207
+
208
+ Every generated Markdown region carries `<!-- doc-bridge:generated hash=… -->`. The Markdown
209
+ analyzer already skips mentions inside one; the documentation audit now recomputes the hash and
210
+ reports a region a person edited by hand as `GENERATED_REGION_EDITED` under
211
+ `generated-freshness`, so a regeneration never silently discards the edit. `llms.txt` carries no
212
+ marker and its bytes are unchanged for its existing consumers.
213
+ - 9a775a5: Answer an agent's question in one bounded MCP call, report findings in the shape the ecosystem
214
+ consumes, and stop the doctor from grading what it did not measure.
215
+
216
+ `knowledge.search { query, kinds?, limit?, explain?, budgetTokens? }` ranks the retrieval
217
+ projection with the same `searchIndex` the CLI uses — its results are what `ak-docs search`
218
+ prints for the same query and index, which a test compares — and adds a title and a body excerpt
219
+ to each. `knowledge.lookup { id | path, depth?, budgetTokens? }` returns, in one response, the
220
+ entity, its neighbours by relation kind (hierarchy included, up to three hops), the documents that
221
+ cover or mention it, the handoff `handoff.resolve` would return, the open diagnostics of the
222
+ latest reconciliation report that name it, and its evidence with excerpts. `format: 'text'` on
223
+ either renders the same payload through `formatRetrievedDocuments`.
224
+
225
+ When `budgetTokens` is present, both tools and `handoff.resolve` trim through `compileBudget`
226
+ (mirrored from `@agentskit/core`, which is an optional peer, and asserted identical to the real
227
+ function by test) in the declared order: evidence excerpts, then `related`, then neighbours, then
228
+ summaries. The response reports `tokens.total`, `fits`, the sections kept and dropped and
229
+ `tokenMethod: 'approximate'`. The entity, the evidence paths and hashes, the handoff fields and the
230
+ diagnostics are never dropped; a payload whose core exceeds the budget says `fits: false` rather
231
+ than truncating them. `AgentHandoffV1` gains an optional `budget` field. Every pre-existing tool
232
+ name, argument and payload is unchanged.
233
+
234
+ `ak-docs check --json --format finding` and `docbridge.diagnostics { format: 'finding' }` emit
235
+ every reconciliation diagnostic as a `Finding` from `@agentskit/core/finding` with severities from
236
+ `SEVERITY_ORDER` (`error → high`, `warn → medium`, `info → low`, nothing `critical`). The internal
237
+ diagnostic shapes do not change; this is a reporter.
238
+
239
+ The doctor measures three new dimensions and can lower the grade for them: reachability (the
240
+ share of the snapshot's document entities in the retrieval projection, 15 points), connectivity
241
+ (areas with a covering or mentioning document and documents with an edge into code, 15 points)
242
+ and the retrieval benchmark hit@3 over the golden suite at `retrieval.benchmark.suite` (10
243
+ points, `not-analyzed` and zero when no suite exists). The existing dimensions are rebalanced to
244
+ the remaining sixty. An A requires reachability at 100%, connectivity at 80% or more and a measured
245
+ hit@3 of 80% or more; on this repository the grade falls from 100/100 (A) to 91/100 (B), because
246
+ 20 of 39 areas have no document about them and 55 of 100 documents do not point at code. The
247
+ doctor's `ok` and exit code are unchanged.
248
+ - 9a775a5: Measure enrichment: what a run cost, what it invented, whether it improved retrieval at all — and
249
+ give the controlled study mechanical expectations, a third arm that reports its own readiness, and
250
+ tokens to first evidence.
251
+
252
+ The overlay reported what it accepted, which is the one number an agent cannot fail: a curator that
253
+ proposes a hundred things and has ninety rejected looked exactly like one that proposes ten good
254
+ ones. Nothing said whether any of it helped retrieval. And the study could not answer the question
255
+ either — its last round recorded zero semantic successes in both arms, because a task whose only
256
+ success criterion is a model's opinion produces no signal, and `registry-assisted` had been reserved
257
+ since the first suite without ever running.
258
+
259
+ `EnrichmentStats` now carries the whole shape of a run: counts per kind, a rejection histogram over
260
+ the closed reason list, cost as agent runs, input and output bytes, cache hit rate and measured wall
261
+ time, and `inventedReferences` — rejections that named something the repository does not contain,
262
+ counted apart from the rejection total because a curator wrong about a judgement and one making
263
+ things up are different problems. `enrichmentStability` compares a run with the previous one:
264
+ identical overlay hashes for a deterministic agent, and for a live model the share of proposal
265
+ identifiers present in both runs, over the union, so proposing fewer things does not read as more
266
+ stable. `stats` stays outside the overlay's content hash.
267
+
268
+ `ak-docs bench retrieval <suite> --overlay` and `ak-docs enrich --retrieval-delta` run the golden
269
+ suite twice over one snapshot — once with the accepted overlay projected, once without — and report
270
+ the delta in both text and JSON, with the case ids gained and lost at hit@3. Both project their own
271
+ indexes, so neither needs an index on disk. An overlay may leave retrieval unchanged and it may
272
+ improve it; if it lowers hit@3 the run exits 1 and says so, as a finding about the agent rather than
273
+ a new baseline.
274
+
275
+ A study task may declare `expectedEntities`, `expectedDocuments` and `retrievalQueries` as opaque
276
+ references, resolved to concrete entities and documents by a local `StudyExpectationsV1` file that
277
+ declares `scope: 'local'`, binds to the suite hash and is never published. `ak-docs study
278
+ expectations` turns the pair into an Open Eval Format suite and checks it with the same benchmark
279
+ that gates this repository's retrieval: an unresolved reference fails, and a task with no
280
+ expectations is reported unchecked rather than counted as a pass. A rubric item may now name the
281
+ mechanical check that decides it, and the model adjudicator receives only the items no checker can
282
+ settle — the settled ones travel beside them as context, not for review.
283
+
284
+ The assisted arm reports its own readiness. Missing provider, missing scenario or missing agent
285
+ identity make it unavailable, and its executions are then recorded as unavailable observations with
286
+ `errorCode: 'registry-unavailable'` rather than skipped or failed: a scenario absent from a ledger
287
+ is indistinguishable from one that was never planned. A missing `promptVersion` or `agentBudget` does
288
+ not cost the arm its run; it is reported as undeclared. `tokensToFirstEvidence` is a primary metric
289
+ per scenario, and the enrichment agent's own tokens, runs and cost are recorded apart from the
290
+ model's while still landing in the total.
291
+
292
+ The committed 24-task suite, run plan and ledgers are deliberately unchanged: the suite's hash is
293
+ bound to published artifacts, and the targets an expectations file would resolve belong to study
294
+ repositories that are not in this one.
295
+ - 6409c68: Add `ak-docs parity`: a registry of the claims this repository makes in public, the repository facts
296
+ they stand for, and a gate that fails when a public surface states something the repository has
297
+ moved past.
298
+
299
+ Four figures from the published A/B round appear in `README.md` and again in `docs/study/README.md`.
300
+ They agree today, and nothing made them agree: an edit to one, or a new round replacing the artifact
301
+ both quote, would leave two public surfaces stating a number the repository no longer measures, with
302
+ no mechanism for noticing but a person reading both pages on the same day.
303
+
304
+ `docs/parity/public-claims-v1.json` is a sealed registry. A claim names what it asserts, who owns
305
+ it, how it appears in prose (`{value}` inside a template, optionally worded differently per
306
+ surface), which surfaces must carry it, and where the canonical value comes from: a field in
307
+ `package.json`, a dotted path into a committed artifact, a sum across an array in one, a count over
308
+ the snapshot, a figure the doctor measured, or the presence of a CLI command. Numbers render the way
309
+ prose states them, and two transforms are signed on purpose — "18.46% fewer" and "39.75 seconds
310
+ lower" carry their direction in a word the checker cannot read, so a measurement that turns positive
311
+ stops resolving instead of matching the same digits for the opposite result.
312
+
313
+ The four outcomes stay apart because they need different actions: `PARITY_STALE` (a surface states a
314
+ value the repository moved past), `PARITY_MISSING` (a required surface omits the claim),
315
+ `PARITY_CONTRADICTION` (two public surfaces disagree — always blocking, and the one an agent cannot
316
+ resolve for itself) and `PARITY_NOT_ANALYZED` (the value could not be resolved: reported, never
317
+ counted as a pass). Every finding carries the claim's owner, the exact surface and line, both
318
+ values, a bounded redacted excerpt and a remediation. An exception accepts one finding on one
319
+ surface and requires a reason and an approver; it stays visible in the report rather than silencing
320
+ the claim.
321
+
322
+ `ak-docs parity [--claims <file>] [--json|--text]` exits 1 on a blocking finding, and CI runs it in
323
+ the dogfood step next to the index, the gate, the doctor and the retrieval benchmark. On this
324
+ repository the registry starts with seven claims over three surfaces, and the run that introduced it
325
+ found two real problems: a claim of mine pointed at the wrong field, and the command was not yet in
326
+ the CLI reference.
327
+
328
+ The report is publication-safe by construction — repository-relative paths, bounded excerpts,
329
+ secrets redacted, no document contents — and a test asserts that against a fixture containing a
330
+ secret-shaped string.
331
+ - 9a775a5: Project the repository's documents and modules into the index retrieval reads, and rank them with
332
+ field-weighted BM25.
333
+
334
+ `index.knowledge` previously held only the curated agent sidecars, while the discovery snapshot
335
+ held hundreds of documents and modules, so a query for an exported symbol or a file path had
336
+ nothing to resolve against — on the retrieval benchmark, none of the twenty exported-symbol
337
+ queries found its module and 47% of all queries returned nothing at all.
338
+
339
+ Every documentation file and source module is now an entry carrying its own content hash, its
340
+ tags, and (for a module) its exported symbols, projected from the same repository walk as the
341
+ discovery snapshot so the two cannot disagree about what exists. Ranking is field-weighted BM25
342
+ plus boosts for exact identity and multiplicative priors for query shape, over one tokenizer
343
+ shared by indexing and querying: English and Portuguese stopwords, accent folding, plural
344
+ collapsing, identifier and path expansion, and CJK bigrams. Weights and BM25 parameters are
345
+ configurable under `retrieval` and recorded in `index.retrieval`, so a retuned ranking is a
346
+ visibly different artifact.
347
+
348
+ Measured against the committed benchmark: hit@1 21.7% → 76.7%, hit@3 23.3% → 83.3%, mean
349
+ reciprocal rank 0.228 → 0.812, zero-result rate 46.7% → 5.0%, exported-symbol queries 0% → 100%.
350
+
351
+ Queries also stop rebuilding the index to check freshness. The index records an `inputs`
352
+ fingerprint of the files and configuration it was built from, so a query re-hashes the inputs
353
+ instead — `loadFreshDocBridgeIndex` on this repository went from over a second to about 170 ms. An
354
+ index written before `inputs` existed is still validated by the previous rebuild-and-compare.
355
+ - 9a775a5: Make the retrieval index a projection of the snapshot, explain every ranking, and derive handoffs
356
+ for any entity from the graph.
357
+
358
+ `buildDocBridgeIndex` used to run a scanner of its own: it walked the repository a second time,
359
+ parsed every module and document again, and produced records that shared nothing with the
360
+ snapshot but a file path — two views of one repository, built by two pipelines, free to disagree.
361
+ The index now carries `projection`, a `RetrievalIndexV1` built by `projectRetrievalIndex` as a pure
362
+ function of the snapshot, the accepted overlay and the configuration. Every entry is a snapshot
363
+ entity (or a route the configuration declares) with the entity's own content hash, provenance and
364
+ confidence, its graph position (PageRank, covered-by, mentioned-by, area, package, edges) and the
365
+ text the lexical ranker indexes. The projection's content hash is over its three input hashes, so
366
+ `IndexStaleError` keeps working; `knowledge[]` is still written and stays in step, without body
367
+ text, which now lives once. The index has no scanner of its own; `projectRepositoryCorpus` is gone
368
+ and `repositoryInputs` remains as the freshness fingerprint.
369
+
370
+ `searchIndex` keeps its signature and gains `{ explain, agent }`. Ranking (`src/retrieval/rank.ts`)
371
+ is BM25 over `title`, `headings`, `symbols`, `path`, `aliases`, `summary` and `body`, times the
372
+ query-shape prior, plus exact-identity boosts, graph proximity (scaled by the anchor's strength),
373
+ log-scaled canonicality, the `--agent` audience prior, and a zero-weighted hook for accepted agent
374
+ signals. `ak-docs search <term> --explain` names every component's contribution and the matched
375
+ terms per field; explaining never changes the ranking. Every result carries evidence, provenance
376
+ and confidence, where confidence is the entry's own for a direct match and the weaker of the entry
377
+ and the surfacing relation when a relation alone surfaced it. Per-token identity boosts apply only
378
+ to queries of at most two tokens: a sentence does not name a thing by containing one of its tokens.
379
+ On this repository's golden suite hit@3 rises from 83.3% to 88.3%, hit@1 from 76.7% to 78.3% and
380
+ MRR from 0.812 to 0.829.
381
+
382
+ `handoffForEntity(index, id, config, { root })` replaces `handoffForPackage` and answers for a
383
+ package, an area, a module or a document, by entity id, ownership id, alias or path. `editRoots` is
384
+ the unit itself or a module's area; `startHere` is the ownership agent document, then a document
385
+ that covers the target, then one that mentions it, then one links-to hop away, most canonical
386
+ first; `readBeforeEditing` adds the next two and `AGENTS.md`; `checks` report their origin in
387
+ `metadata.checksSource`, which the index builder now records where the decision is made;
388
+ `related` lists the strongest importing and imported areas with the import that proves each;
389
+ `explain` names the relation behind every field. `AgentHandoffV1` stays byte-compatible:
390
+ `related`, `explain`, `evidence` and `metadata` are optional additions and `target.type` gains
391
+ `area` and `document`. A `covers` declaration now also resolves by an area, module or document
392
+ path.
393
+
394
+ `createDocBridgeRetriever` returns `RetrievedDocument[]` from `@agentskit/core` with
395
+ `metadata: { kind, path, evidence, explain, confidence }`, so `createHybridRetriever` and
396
+ `formatRetrievedDocuments` consume Doc Bridge with no adapter — exercised against the real
397
+ packages. The original `retrieve('query', { limit })` still works.
398
+
399
+ The default field weights change with the field set (`id`, `tags` and `description` no longer
400
+ exist as fields; `headings`, `aliases` and `summary` do), `CORPUS_PROJECTION_VERSION` becomes 2 so
401
+ an index built by older code is stale by version, and a projected index is about three times the
402
+ size of the old one on this repository, because it now carries every entry's graph edges.
403
+
404
+ ### Patch Changes
405
+
406
+ - 93bc2ad: Stop writing an index that Doc Bridge's own reader refuses.
407
+
408
+ `knowledge[]` and `projection.entries` in `doc-bridge-index-v1` describe the same entries, and
409
+ their bounds disagreed: 10 000 against 50 000. A monorepo that projects 10 909 entries therefore
410
+ got an index `ak-docs index` reported building successfully and every reader rejected — `doctor`,
411
+ `search` and the MCP server all failed with a schema dump naming an array, on a repository whose
412
+ index was sitting on disk.
413
+
414
+ Both bounds are now one exported constant, `RETRIEVAL_MAX_ENTRIES`, shared by the Zod schema, the
415
+ published JSON Schema and the builder, and a test asserts the two agree rather than asserting the
416
+ number. The builder checks the bound before it writes, so a corpus that genuinely exceeds it is
417
+ reported where the count and the remedy are both known — narrow `corpus.*.include`, or split the
418
+ repository across more than one index — instead of becoming an unreadable file.
419
+ - 93bc2ad: Make Markdown reference resolution scale, so a large repository can be indexed at all.
420
+
421
+ Dogfooding Doc Bridge on a monorepo of 4 100 documents, 9 240 TypeScript files and 102 packages
422
+ found that `ak-docs scan` and `ak-docs index` did not complete — not slowly, but not at all within
423
+ fifteen minutes. The cost was superlinear in corpus size and concentrated in one place: a CPU
424
+ profile of a 401-document corpus put 56.5% of samples in `fuzzyMatchList`, the near-miss resolver
425
+ for path-shaped references.
426
+
427
+ Two things were wrong. The analyzer rebuilt the candidate universe — every document, module and
428
+ area path — once per document, which on that monorepo is tens of millions of string copies before
429
+ any analysis happens; the universe is now built once per run and passed in as
430
+ `MarkdownResolution.pathIndex`. And every unresolved reference ran a full Jaro-Winkler scan over
431
+ that universe, where almost every candidate cannot reach the 0.92 threshold for reasons that cost
432
+ far less to check than a similarity computation.
433
+
434
+ `createFuzzyCandidateIndex` precomputes, per candidate, its length and its character counts over a
435
+ fixed alphabet. A query then visits only the lengths that can pass, and within those skips any
436
+ candidate whose shared-character count is too low. Both tests are upper bounds on Jaro's match
437
+ count — `m` cannot exceed the shorter string, and cannot exceed the multiset intersection — so a
438
+ candidate they drop provably could not have matched. The filter is behaviour-preserving including
439
+ the order of tied scores, and a test asserts that a list universe and an index universe return
440
+ identical results over 646 candidates at four thresholds.
441
+
442
+ Measured on the same corpora: 908 documents went from 151 to 25 seconds, and the monorepo that
443
+ did not finish in fifteen minutes now scans in 100 seconds. `fuzzyMatchList` and
444
+ `resolveFuzzyReference` still accept a plain array, so the public contract and the mirror of
445
+ `@agentskit/core/fuzzy-match` are unchanged.
446
+
447
+ ## 1.8.0
448
+
449
+ ### Minor Changes
450
+
451
+ - 4ed42e3: Add configurable documentation tiers, criticality metadata checks, and independent quality-dimension assessments to the documentation audit.
452
+ - ee756a1: Add a bounded, shell-free generic CLI adapter for AgentsKit Registry proposals.
453
+ - ee756a1: Add a configurable documentation audit command with measurable quality, coverage, structure-gap, stale, contradiction, redundancy, and generated-document freshness-boundary findings.
454
+ - 4ed42e3: Add deterministic longitudinal study metrics with subgroup comparisons, uncertainty, missing-data handling, quality guardrails, and anonymization-safe cost measurements.
455
+ - 4ed42e3: Add versioned, anonymization-safe study protocol and historical evidence registry contracts with CLI validation and summaries.
456
+ - 4ed42e3: Add bounded controlled-study run plans, isolated command execution, provenance-safe observations, and idempotent observation ledgers.
457
+ - 4ed42e3: Add a versioned controlled-study task suite with deterministic variant assignment and outcome adjudication contracts.
458
+ - 4ed42e3: Add content-addressed controlled-study verification bindings for provenance, privacy, budget, recovery, and publication-safe evidence.
459
+
460
+ ### Patch Changes
461
+
462
+ - 5656632: Adopt the provider-neutral `@agentskit/harness@0.9.0` for fail-closed verification, YOLO intermediate execution, immutable evidence, and explicit UI and tracking gates.
463
+ - c1fed28: Refresh supported runtime and documentation dependencies, harden GitHub Actions pins, and keep the README freshness contract synchronized.
464
+ - 4ed42e3: Reject Registry-agent proposals that reference unknown diagnostics or evidence outside the supplied artifacts, and document alternate-agent and human-approval boundaries.
465
+ - ee756a1: Allow failed or cancelled workflow runs with changed inputs to be invalidated and retried, and bump the discovery pipeline identity when report artifacts change.
466
+ - 4ed42e3: Add a generic bounded CLI adapter and resumable `study run` execution for hosted model CLIs and AgentsKit Registry agents without requiring Ollama.
467
+
468
+ ## 1.7.45
469
+
470
+ ### Patch Changes
471
+
472
+ - 9929eb0: Harden dependency resolution, filesystem and URL handling, reconciliation schema compatibility, generated-code boundaries, CI permissions, and npm publishing without long-lived npm tokens.
473
+
3
474
  ## 1.7.44
4
475
 
5
476
  - Precompute module-to-package ownership during package-scope reconciliation to reduce repeated entity scans on large repositories.
package/CONTRIBUTING.md CHANGED
@@ -1,3 +1,10 @@
1
+ ---
2
+ owner: maintainers
3
+ lifecycle: active
4
+ sourceOfTruth: CONTRIBUTING.md
5
+ validationPath: pnpm typecheck && pnpm test
6
+ ---
7
+
1
8
  # Contributing
2
9
 
3
10
  Thanks for helping improve `@agentskit/doc-bridge`.
@@ -28,17 +35,35 @@ pnpm build
28
35
  - Update docs and `CHANGELOG.md` when behavior changes.
29
36
  - Keep examples public and reproducible.
30
37
 
38
+ ## Why contribute?
39
+
40
+ Doc Bridge helps humans and coding agents navigate large repositories with less context and stronger evidence. The study is intentionally open and anonymized so contributors can improve the measurement surface as well as the product.
41
+
42
+ High-impact contribution areas:
43
+
44
+ - language and framework analyzers;
45
+ - documentation quality rules and contradiction detectors;
46
+ - architecture relation extraction;
47
+ - CLI, MCP, and documentation adapters;
48
+ - executable acceptance checks;
49
+ - anonymized benchmark tasks and replications;
50
+ - accessibility and report improvements.
51
+
52
+ Start with the [study overview](docs/study/README.md), run the chart check, and use the smallest reproducible example for a proposed change.
53
+
31
54
  ## Releases
32
55
 
33
- Use Changesets for versioned changes:
56
+ Use Changesets for versioned changes. A merged changeset on `master` starts the
57
+ version workflow, which opens a version PR and publishes the merged version
58
+ through npm Trusted Publishing (GitHub OIDC). No npm token is stored in GitHub.
34
59
 
35
60
  ```bash
36
61
  pnpm changeset
37
- pnpm version-packages
38
- pnpm release
39
62
  ```
40
63
 
41
- Do not publish from a dirty worktree.
64
+ The npm package must have a GitHub Actions trusted publisher configured for
65
+ `AgentsKit-io/doc-bridge`, workflow `changesets.yml`, and environment `npm`.
66
+ Do not publish from a dirty worktree or run `pnpm release` locally.
42
67
 
43
68
  Project decisions and maintainer responsibilities are documented in
44
69
  [GOVERNANCE.md](GOVERNANCE.md). By participating, you agree to follow the