@agentskit/doc-bridge 1.7.45 → 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.
- package/CHANGELOG.md +465 -0
- package/CONTRIBUTING.md +23 -0
- package/README.md +87 -40
- package/SECURITY.md +7 -0
- package/action.yml +1 -1
- package/bin/ak-docs.js +2 -2
- package/bin/ak-verify.js +13 -7
- package/dist/cli/program.d.ts +3 -1
- package/dist/cli/program.js +15861 -6223
- package/dist/cli/program.js.map +1 -1
- package/dist/config/index.d.ts +1 -1
- package/dist/config/index.js +86 -6
- package/dist/config/index.js.map +1 -1
- package/dist/{index-BUL0q7s8.d.ts → index-Beor6Yhi.d.ts} +133 -1
- package/dist/index.d.ts +9871 -1062
- package/dist/index.js +16126 -6125
- package/dist/index.js.map +1 -1
- package/docs/MARKETPLACE.md +1 -1
- package/docs/PRD-documentation-efficiency-study.md +406 -0
- package/docs/PRD-knowledge-retrieval-and-enrichment.md +466 -0
- package/docs/adr/0002-documentation-audit-boundary.md +22 -0
- package/docs/adr/0003-study-protocol-and-historical-evidence.md +40 -0
- package/docs/adr/0004-controlled-study-runner.md +25 -0
- package/docs/adr/0005-documentation-quality-and-criticality.md +20 -0
- package/docs/adr/0006-registry-semantic-grounding.md +20 -0
- package/docs/adr/0007-longitudinal-study-metrics.md +21 -0
- package/docs/adr/0008-study-verification-boundary.md +21 -0
- package/docs/adr/0009-study-provider-cli-adapter.md +25 -0
- package/docs/agent-corpus/INDEX.md +12 -1
- package/docs/agent-corpus/OVERVIEW.md +25 -0
- package/docs/agent-corpus/chat.md +5 -1
- package/docs/agent-corpus/cli.md +16 -0
- package/docs/agent-corpus/conformance.md +12 -0
- package/docs/agent-corpus/doc-bridge.md +47 -0
- package/docs/agent-corpus/doctor.md +8 -0
- package/docs/agent-corpus/gates.md +4 -0
- package/docs/agent-corpus/mcp.md +13 -0
- package/docs/agent-corpus/memory.md +4 -0
- package/docs/agent-corpus/query.md +33 -0
- package/docs/bench/README.md +122 -0
- package/docs/bench/retrieval-baseline-v1.json +28 -0
- package/docs/bench/retrieval-suite-v1.json +1033 -0
- package/docs/chat-and-rag.md +3 -2
- package/docs/for-agents.md +9 -1
- package/docs/getting-started.md +4 -11
- package/docs/guides/gate-ci.md +11 -1
- package/docs/guides/install-and-run.md +9 -65
- package/docs/index.md +22 -1
- package/docs/knowledge-engine-runbook.md +38 -3
- package/docs/landing/assets/context-payload-reduction.svg +21 -0
- package/docs/landing/assets/controlled-ab-comparison.svg +30 -0
- package/docs/landing/index.html +119 -5
- package/docs/loop-workflow.md +117 -0
- package/docs/mcp.md +6 -1
- package/docs/parity/public-claims-v1.json +145 -0
- package/docs/playbook/doc-bridge-pattern.md +1 -1
- package/docs/query.md +90 -2
- package/docs/recipes/index-pipeline.md +1 -1
- package/docs/schemas/agent-handoff-v1.md +15 -0
- package/docs/schemas/doc-bridge-index-v1.md +65 -0
- package/docs/spec/benchmark-v1.md +33 -1
- package/docs/spec/cli.md +30 -10
- package/docs/spec/config-v1.md +147 -8
- package/docs/spec/documentation-audit-v1.md +61 -0
- package/docs/spec/enrichment-overlay-v1.md +241 -0
- package/docs/spec/graph-signals-v1.md +92 -0
- package/docs/spec/incremental-scan-v1.md +102 -0
- package/docs/spec/markdown-analyzer-v1.md +73 -0
- package/docs/spec/mcp-knowledge-tools-v1.md +147 -0
- package/docs/spec/measured-enrichment-v1.md +229 -0
- package/docs/spec/public-parity-v1.md +119 -0
- package/docs/spec/registry-agents.md +6 -0
- package/docs/spec/render-v1.md +122 -0
- package/docs/spec/retrieval-index-v1.md +164 -0
- package/docs/spec/study-metrics-v1.md +58 -0
- package/docs/spec/study-protocol-v1.md +46 -0
- package/docs/spec/study-provider-cli-v1.md +116 -0
- package/docs/spec/study-runner-v1.md +35 -0
- package/docs/spec/study-task-suite-v1.md +41 -0
- package/docs/spec/study-verification-v1.md +40 -0
- package/docs/study/README.md +84 -0
- package/docs/study/ab-adjudicated-cost-analysis-v1.md +29 -0
- package/docs/study/ab-adjudicated-cost-plan-v1.json +33 -0
- package/docs/study/ab-adjudicated-cost-plan-v2-v1.json +33 -0
- package/docs/study/ab-adjudicated-cost-result-v1.json +80 -0
- package/docs/study/ab-baseline-analysis-v1.md +21 -0
- package/docs/study/ab-baseline-plan-v1.json +33 -0
- package/docs/study/ab-baseline-recovery-plan-v1.json +33 -0
- package/docs/study/ab-baseline-result-v1.json +79 -0
- package/docs/study/documentation-audit-round-2026-08-31.json +183 -0
- package/docs/study/historical-evidence-v1.json +252 -0
- package/docs/study/observation-ledger-v1.json +30632 -0
- package/docs/study/phase3-task-coverage-v1.json +34 -0
- package/docs/study/phase4-public-pilot-ledger-v1.json +1344 -0
- package/docs/study/phase4-public-pilot-result-v1.json +52 -0
- package/docs/study/phase4-public-pilot-run-plan-v1.json +26 -0
- package/docs/study/phase4-public-pilot-task-suite-v1.json +71 -0
- package/docs/study/pilot-round-2026-08-31.json +46 -0
- package/docs/study/protocol-v1.json +90 -0
- package/docs/study/publication-gate-v1.md +45 -0
- package/docs/study/quality-scorecard-cycle-plan.md +545 -0
- package/docs/study/quality-scorecard-v1.json +38 -0
- package/docs/study/round-1-adjudicated-smoke-v1.json +30642 -0
- package/docs/study/round-1-instrumentation-plan-v1.md +39 -0
- package/docs/study/round-2-expanded-adjudication-v1.json +91 -0
- package/docs/study/round-2-expanded-validation-v1.md +58 -0
- package/docs/study/round-3-evidence-contract-v1.json +75 -0
- package/docs/study/round-3-evidence-contract-v1.md +57 -0
- package/docs/study/round-4-confirmation-v1.json +75 -0
- package/docs/study/round-4-confirmation-v1.md +55 -0
- package/docs/study/run-plan-v1.json +33 -0
- package/docs/study/semantic-adjudication-cycle-8.md +20 -0
- package/docs/study/task-suite-v1.json +96 -0
- package/docs/study/token-efficiency-plan-v1.md +337 -0
- package/docs/study/token-efficiency-protocol-v2.json +62 -0
- package/docs/study/verification-binding-v1.json +27 -0
- package/docs/validation-cycle-plan.md +14 -0
- package/docs/verification-harness.md +11 -6
- package/ecosystem-claims.json +2 -2
- package/ecosystem-upstream.json +2 -2
- package/ecosystem.json +4 -4
- package/mcpb/manifest.json +9 -1
- package/package.json +25 -6
- package/scripts/check-ecosystem-upstream.mjs +34 -6
- package/skills/doc-bridge-handoff/fixtures/synthetic-repo/docs/for-agents/packages/payments.md +7 -0
- package/skills/doc-bridge-handoff/scripts/resolve-handoff.mjs +1 -1
- package/src/agents/registry-adapter.ts +192 -24
- package/src/audit/documentation.ts +513 -0
- package/src/bench/baseline.ts +198 -0
- package/src/bench/overlay-delta.ts +139 -0
- package/src/bench/retrieval.ts +319 -0
- package/src/budget/compile.ts +91 -0
- package/src/budget/sections.ts +70 -0
- package/src/cli/program.ts +684 -74
- package/src/cli/usage.ts +71 -0
- package/src/config/defaults.ts +1 -0
- package/src/config/index.ts +4 -0
- package/src/config/schema.ts +117 -2
- package/src/conformance/documentation-standard-v1.ts +8 -6
- package/src/discovery/areas.ts +182 -0
- package/src/discovery/documentation.ts +211 -5
- package/src/discovery/identity.ts +24 -0
- package/src/discovery/incremental.ts +314 -0
- package/src/discovery/inputs.ts +110 -0
- package/src/discovery/markdown.ts +481 -0
- package/src/discovery/repository.ts +484 -101
- package/src/doctor/run-doctor.ts +244 -12
- package/src/enrich/approvals.ts +190 -0
- package/src/enrich/cache.ts +93 -0
- package/src/enrich/context-pack.ts +272 -0
- package/src/enrich/overlay.ts +255 -0
- package/src/enrich/review.ts +106 -0
- package/src/enrich/stage.ts +374 -0
- package/src/enrich/stats.ts +100 -0
- package/src/enrich/validate.ts +410 -0
- package/src/federation/llms.ts +2 -4
- package/src/findings/report.ts +103 -0
- package/src/graph/build.ts +356 -0
- package/src/graph/memory.ts +208 -0
- package/src/index-builder/build-handoffs.ts +22 -11
- package/src/index-builder/build-index.ts +132 -3
- package/src/index-builder/llms-txt.ts +48 -8
- package/src/index-builder/project-corpus.ts +111 -0
- package/src/index.ts +630 -2
- package/src/lib/fuzzy-match.ts +235 -0
- package/src/mcp/knowledge.ts +554 -0
- package/src/mcp/server.ts +113 -18
- package/src/metrics/benchmark.ts +21 -0
- package/src/parity/check.ts +309 -0
- package/src/parity/claims.ts +259 -0
- package/src/parity/resolve.ts +160 -0
- package/src/query/handoff.ts +326 -0
- package/src/query/load-index.ts +53 -1
- package/src/query/query.ts +92 -59
- package/src/query/search.ts +289 -92
- package/src/query/text.ts +155 -0
- package/src/reconciliation/reconcile.ts +101 -10
- package/src/render/data.ts +356 -0
- package/src/render/engine.ts +398 -0
- package/src/render/generated.ts +77 -0
- package/src/render/render.ts +209 -0
- package/src/render/template-source.ts +52 -0
- package/src/render/templates.ts +289 -0
- package/src/report/html.ts +2 -2
- package/src/retrieval/bm25.ts +161 -0
- package/src/retrieval/project.ts +495 -0
- package/src/retrieval/rank.ts +383 -0
- package/src/retrieval/weights.ts +39 -0
- package/src/retriever/doc-bridge-retriever.ts +100 -15
- package/src/rules/engine.ts +30 -10
- package/src/schemas/agent-handoff.ts +56 -0
- package/src/schemas/budget.ts +37 -0
- package/src/schemas/doc-bridge-index.ts +53 -2
- package/src/schemas/enrichment.ts +369 -0
- package/src/schemas/json-schemas.ts +39 -2
- package/src/schemas/knowledge.ts +14 -1
- package/src/schemas/retrieval-index.ts +152 -0
- package/src/shims/graphology.d.ts +91 -0
- package/src/study/adjudication.ts +196 -0
- package/src/study/execution.ts +350 -0
- package/src/study/expectations.ts +219 -0
- package/src/study/metrics.ts +467 -0
- package/src/study/protocol.ts +271 -0
- package/src/study/provider-cli.ts +115 -0
- package/src/study/provider-telemetry.ts +47 -0
- package/src/study/quality-scorecard.ts +164 -0
- package/src/study/runner.ts +461 -0
- package/src/study/task-suite.ts +321 -0
- package/src/study/verification.ts +134 -0
- package/src/validate.ts +1 -4
- package/src/version.ts +1 -1
- package/src/workflow/engine.ts +36 -11
- package/scripts/verification-harness.mjs +0 -482
package/docs/spec/cli.md
CHANGED
|
@@ -5,7 +5,7 @@ description: Complete command reference for indexing, querying, gates, doctor, m
|
|
|
5
5
|
|
|
6
6
|
# ak-docs CLI
|
|
7
7
|
|
|
8
|
-
Command-line interface for **`@agentskit/doc-bridge`**. The
|
|
8
|
+
Command-line interface for **`@agentskit/doc-bridge`**. The package publishes two executables: `ak-docs` is the product CLI and `ak-verify` is the verification-harness wrapper.
|
|
9
9
|
|
|
10
10
|
## Naming
|
|
11
11
|
|
|
@@ -13,11 +13,17 @@ Command-line interface for **`@agentskit/doc-bridge`**. The npm package is scope
|
|
|
13
13
|
|------|------|
|
|
14
14
|
| npm package | `@agentskit/doc-bridge` |
|
|
15
15
|
| CLI binary | `ak-docs` |
|
|
16
|
-
|
|
|
16
|
+
| Verification binary | `ak-verify` |
|
|
17
|
+
| Primary config filename | `doc-bridge.config.ts` |
|
|
17
18
|
| GitHub repo | `AgentsKit-io/doc-bridge` |
|
|
18
19
|
|
|
19
20
|
Install the package, run `ak-docs` — not `doc-bridge` on the shell.
|
|
20
21
|
|
|
22
|
+
The primary filename is shown for readability. Discovery also accepts
|
|
23
|
+
`doc-bridge.config.mts`, `.js`, `.mjs`, `.json`, and the `docBridge` field in
|
|
24
|
+
`package.json`; see the [configuration contract](./config-v1.md#discovery-order)
|
|
25
|
+
for the authoritative order.
|
|
26
|
+
|
|
21
27
|
## Why a separate binary
|
|
22
28
|
|
|
23
29
|
| Choice | Rationale |
|
|
@@ -39,7 +45,8 @@ pnpm add -D @agentskit/doc-bridge
|
|
|
39
45
|
{
|
|
40
46
|
"name": "@agentskit/doc-bridge",
|
|
41
47
|
"bin": {
|
|
42
|
-
"ak-docs": "./bin/ak-docs.js"
|
|
48
|
+
"ak-docs": "./bin/ak-docs.js",
|
|
49
|
+
"ak-verify": "./bin/ak-verify.js"
|
|
43
50
|
}
|
|
44
51
|
}
|
|
45
52
|
```
|
|
@@ -58,8 +65,8 @@ pnpm add -D @agentskit/doc-bridge
|
|
|
58
65
|
| `ak-docs doctor [--text] [--badge] [--write-badge]` | Coverage score, gaps, gates, shields.io badge |
|
|
59
66
|
| `ak-docs index` | Build `DocBridgeIndex` + optional `llms.txt` |
|
|
60
67
|
| `ak-docs index --watch` | Debounced rebuild on agent/human doc changes |
|
|
61
|
-
| `ak-docs query <target> [--agent] [--text]` | Resolve package/module/intent/change → handoff JSON or text |
|
|
62
|
-
| `ak-docs search <term> [--agent] [--text]` |
|
|
68
|
+
| `ak-docs query <target> [--agent] [--text]` | Resolve package/area/module/document/intent/change → handoff JSON or text |
|
|
69
|
+
| `ak-docs search <term> [--agent] [--explain] [--mode=<mode>] [--context-budget=<tokens>] [--text]` | Ranked search over the retrieval projection; `--explain` names every scoring component and the matched terms, and agent mode bounds the context it returns to a task-specific budget |
|
|
63
70
|
| `ak-docs ask <question>` | Human-readable local consult mode: search + best match + next handoff commands; no LLM |
|
|
64
71
|
| `ak-docs ask` | Interactive local REPL in a TTY; commands: `search <term>`, `read <id-or-path>`, `open <id-or-path>`, `resolve <id>`, `gate [id]`, `exit` |
|
|
65
72
|
| `ak-docs retrieve <query>` | Hybrid local/federated retriever chunks; deterministic local first |
|
|
@@ -68,13 +75,26 @@ pnpm add -D @agentskit/doc-bridge
|
|
|
68
75
|
| `ak-docs memory ingest` | Normalize local memory files (`.agent-memory/**/*.md`, `.cursor/rules/*.mdc`) into `MemoryCandidate[]` |
|
|
69
76
|
| `ak-docs memory classify` | Deterministically route candidates to agent/human/playbook/discard |
|
|
70
77
|
| `ak-docs memory promote` | Build draft-only promotion body with safety scan; never auto-merges |
|
|
71
|
-
| `ak-docs memory promote --pr
|
|
78
|
+
| `ak-docs memory promote --pr --dry-run [--force]` | Write a local draft and print the `git`/`gh` commands; does not execute them |
|
|
79
|
+
| `ak-docs memory promote --pr [--force]` | Write the draft, commit/push it, and open a GitHub draft PR via `gh` |
|
|
72
80
|
| `ak-docs registry topology` | Print the `doc-curator` topology for AgentsKit/Registry composition |
|
|
81
|
+
| `ak-docs suggest [--documentation] --json` | Run the configured Registry agent module or CLI and persist its typed proposal; optionally include the bounded documentation-audit context |
|
|
82
|
+
| `ak-docs enrich [--json\|--text]` | Run the enrichment stage: context packs to the configured Registry roles, deterministic validators, the overlay at `.doc-bridge/enrich/overlay.json`. Zero agent calls over an unchanged repository |
|
|
83
|
+
| `ak-docs enrich list \| approve <proposalId> --by <name> \| reject <proposalId> --by <name> [--reason <text>]` | Review pending enrichment proposals; a decision is recorded through the ecosystem approval gate under `.doc-bridge/approvals/`, bound to the proposal id and the target content hash |
|
|
84
|
+
| `ak-docs check --enrich` | `check` with the `enrich` stage between `reconcile` and `evaluate`; a failed enrichment is reported in `enrichment` and never changes the check result |
|
|
85
|
+
| `ak-docs enrich --retrieval-delta [--json\|--text]` | `enrich`, then the golden suite with and without the accepted overlay on the same snapshot. Exits 1 when the overlay lowers hit@3 |
|
|
86
|
+
| `ak-docs bench retrieval <suite.json> --overlay [--json\|--text]` | The overlay on disk measured against a suite: both indexes projected from one snapshot, no index on disk required. Exits 1 on a hit@3 regression |
|
|
87
|
+
| `ak-docs study expectations <task-suite.json> --expectations <local.json> [--index <index.json>] [--repository <id>]` | Check a study round's mechanical retrieval expectations through the benchmark. Exits 1 when a reference does not resolve or a case misses |
|
|
73
88
|
| `ak-docs playbook draft` | Build a draft Playbook feedback payload from local memory candidates |
|
|
74
89
|
| `ak-docs playbook pattern [--text]` | Export published Doc Bridge Playbook pattern (OKF markdown / JSON) |
|
|
75
90
|
| `ak-docs list <kind> [--text]` | List packages, apps, intents, … |
|
|
76
|
-
| `ak-docs gate run [
|
|
91
|
+
| `ak-docs gate run [gate-id]` | Run resolved configured documentation gates; an optional id narrows the run to one gate |
|
|
77
92
|
| `ak-docs conformance run documentation-standard-v1 [--text\|--json]` | Run the stable ecosystem documentation profile with evidence and remediation |
|
|
93
|
+
| `ak-docs audit documentation [--text\|--json]` | Measure documentation quality and compare documentation claims with the observed project graph |
|
|
94
|
+
| `ak-docs parity [--claims <file>] [--json\|--text]` | Check the public claim registry against what the repository can prove: stale, missing, contradictory and not-analyzed claims, each with an owner, an exact source and a remediation. Exits 1 on a blocking finding |
|
|
95
|
+
| `ak-docs render <llms.txt\|area\|ownership\|change-digest\|overlay-review> [--data <artifact>] [--output <path>] [--print-template] [--json]` | Render the canonical artifacts as Markdown from bundled or project templates (`render.templates`); deterministic, no agent. See [Render v1](./render-v1.md) |
|
|
96
|
+
| `ak-docs bench retrieval <suite.json> [--index <file>] [--baseline <file>] [--limit <n>] [--text\|--json]` | Measure retrieval quality against a golden query suite: hit@1, hit@3, mean reciprocal rank, context bytes and approximate tokens. Exits non-zero on a hit@3 regression against the baseline. No model, no network |
|
|
97
|
+
| `ak-docs bench retrieval <suite.json> --baseline <file> --update-baseline --by <name> [--reason <text>]` | Record the measured figures as the approved baseline. A normal run never writes one |
|
|
78
98
|
| `ak-docs mcp` | Start MCP server (stdio default) |
|
|
79
99
|
| `ak-docs mcp install --cursor \| --claude` | Write MCP server config for Cursor or Claude Desktop |
|
|
80
100
|
|
|
@@ -94,7 +114,7 @@ Peers: `@agentskit/rag`, `@agentskit/ink`, `@agentskit/adapters`, `@agentskit/me
|
|
|
94
114
|
| Flag | Description |
|
|
95
115
|
|------|-------------|
|
|
96
116
|
| `--config <path>` | Config file (default: auto-discover) |
|
|
97
|
-
| `--json` / `--text` | Output format for non-agent commands (default: json); `--agent`
|
|
117
|
+
| `--json` / `--text` | Output format for non-agent commands (default: formatted json); `--agent` emits compact machine-readable JSON, while `--text` remains human-readable |
|
|
98
118
|
| `--chat` | Request planned intelligence-backed ask mode; errors clearly until `intelligence.adapter` and RAG/chat support are configured |
|
|
99
119
|
| `--help` | Command help |
|
|
100
120
|
|
|
@@ -104,7 +124,7 @@ Peers: `@agentskit/rag`, `@agentskit/ink`, `@agentskit/adapters`, `@agentskit/me
|
|
|
104
124
|
ak-docs index
|
|
105
125
|
ak-docs query ownership auth --agent
|
|
106
126
|
ak-docs query ownership auth --text
|
|
107
|
-
ak-docs search "sidecar transport" --agent
|
|
127
|
+
ak-docs search "sidecar transport" --agent --mode=discovery --context-budget=256
|
|
108
128
|
ak-docs list packages --text
|
|
109
129
|
ak-docs gate run
|
|
110
130
|
ak-docs mcp
|
|
@@ -141,7 +161,7 @@ CLI is a thin wrapper over the same exports.
|
|
|
141
161
|
pnpm docs:internal:query … # private dogfood wrapper → ak-docs query …
|
|
142
162
|
```
|
|
143
163
|
|
|
144
|
-
|
|
164
|
+
`ak-docs` is the primary product CLI. `ak-verify` is the portable verification-harness entry point used to prove repository work against a declared contract.
|
|
145
165
|
|
|
146
166
|
## See also
|
|
147
167
|
|
package/docs/spec/config-v1.md
CHANGED
|
@@ -5,7 +5,7 @@ description: Configure documentation corpora, ownership routing, conformance, an
|
|
|
5
5
|
|
|
6
6
|
# doc-bridge config contract v1
|
|
7
7
|
|
|
8
|
-
`doc-bridge.config.ts` (or `.js`, `.mjs`, `.json`, or `package.json` → `docBridge`) is the
|
|
8
|
+
`doc-bridge.config.ts` (or `.js`, `.mjs`, `.json`, or `package.json` → `docBridge`) is the v1 integration point for any project. Layer 0 fields are sufficient to run `index`, `query`, and MCP without an LLM.
|
|
9
9
|
|
|
10
10
|
Reconciliation summaries also expose deterministic `diagnosticsByCode` and
|
|
11
11
|
`diagnosticsByStatus` maps. They are additive rollups for agents and dashboards;
|
|
@@ -36,7 +36,7 @@ doc-bridge.config.json
|
|
|
36
36
|
package.json → "docBridge" field (subset, JSON only)
|
|
37
37
|
```
|
|
38
38
|
|
|
39
|
-
TypeScript/JavaScript configs are static in
|
|
39
|
+
TypeScript/JavaScript configs are static in v1: `defineConfig` imports are supported, but arbitrary imports are not. YAML config files are planned.
|
|
40
40
|
|
|
41
41
|
Dynamic-loading coverage is evidence-backed. Literal strings, constant aliases,
|
|
42
42
|
parenthesized strings, and string concatenations are resolved without executing
|
|
@@ -88,9 +88,15 @@ export default {
|
|
|
88
88
|
/** Optional reconciliation scope and orphan-document policy */
|
|
89
89
|
reconciliation?: ReconciliationConfig
|
|
90
90
|
|
|
91
|
+
/** Optional retrieval tuning: corpus projection, field weights, BM25 parameters */
|
|
92
|
+
retrieval?: RetrievalConfig
|
|
93
|
+
|
|
91
94
|
/** Optional resumable workflow state */
|
|
92
95
|
workflow?: WorkflowConfig
|
|
93
96
|
|
|
97
|
+
/** Optional project templates for `ak-docs render`, by template name */
|
|
98
|
+
render?: RenderConfig
|
|
99
|
+
|
|
94
100
|
/** Optional report publication privacy; private is the default */
|
|
95
101
|
report?: { privacy?: 'private' | 'anonymized' }
|
|
96
102
|
} satisfies DocBridgeConfigV1
|
|
@@ -301,7 +307,9 @@ by Nx plugins are intentionally not inferred by this read-only adapter.
|
|
|
301
307
|
| Screen / feature | `id` in `screens/` or `features/` | MDX slug |
|
|
302
308
|
| Flow / recipe | `id` in `flows/` | docs slug |
|
|
303
309
|
|
|
304
|
-
Plugins document their join convention
|
|
310
|
+
Plugins document their join convention. The orphan-link gate only runs when the
|
|
311
|
+
corresponding gate is enabled (for example, `human-guide-links`); the `minimal`
|
|
312
|
+
preset does not enable that gate.
|
|
305
313
|
|
|
306
314
|
---
|
|
307
315
|
|
|
@@ -347,14 +355,14 @@ type GateId =
|
|
|
347
355
|
| Preset | Gates |
|
|
348
356
|
|--------|-------|
|
|
349
357
|
| `minimal` | `index-freshness` |
|
|
350
|
-
| `standard` | + `human-guide-links` in
|
|
351
|
-
| `strict` | + `okf-type` in
|
|
358
|
+
| `standard` | + `human-guide-links` in v1 |
|
|
359
|
+
| `strict` | + `okf-type` in v1 |
|
|
352
360
|
|
|
353
361
|
Implemented gates include `index-freshness`, `human-guide-links`, `okf-type`, `docs-style`, and the opt-in `documentation-standard-v1`. For v1 compatibility, `link-rot`, `routing-currency`, and `bootstrap-size` remain accepted as reserved IDs; including one emits `AK_DOCS_RESERVED_GATE` and does not claim that the gate ran. Unknown IDs are rejected.
|
|
354
362
|
|
|
355
363
|
### Structural vs style validation
|
|
356
364
|
|
|
357
|
-
|
|
365
|
+
These gates are deterministic lint checks, not editorial grading:
|
|
358
366
|
|
|
359
367
|
| Gate | Kind | What it proves |
|
|
360
368
|
|------|------|----------------|
|
|
@@ -363,7 +371,7 @@ Alpha gates are deterministic lint checks, not editorial grading:
|
|
|
363
371
|
| `okf-type` | OKF lint | Agent docs have required `type:` frontmatter when strict/required |
|
|
364
372
|
| `docs-style` | style lint | Opt-in deterministic profile checks for title, purpose, audience, examples, owner/source, task orientation, and stale wording |
|
|
365
373
|
|
|
366
|
-
`docs-style` supports `google-dev-docs`, `playbook-okf`, and `custom` profiles. It is not part of the default
|
|
374
|
+
`docs-style` supports `google-dev-docs`, `playbook-okf`, and `custom` profiles. It is not part of the default path and does not grade prose quality; it checks for explicit structural signals. LLM critique remains planned optional behavior.
|
|
367
375
|
|
|
368
376
|
---
|
|
369
377
|
|
|
@@ -413,7 +421,7 @@ report status, commands, and the recorded stable-publication HITL decision.
|
|
|
413
421
|
```ts
|
|
414
422
|
type ReconciliationConfig = {
|
|
415
423
|
/** Semantic comparison level; discovery still preserves raw file relations. */
|
|
416
|
-
scope?: 'file' | 'module' | 'package'
|
|
424
|
+
scope?: 'file' | 'module' | 'area' | 'package'
|
|
417
425
|
/** Observed relation kinds that require documentation declarations. */
|
|
418
426
|
requiredRelationKinds?: string[]
|
|
419
427
|
/** Limit missing-declaration findings to relations between internal project entities. */
|
|
@@ -425,6 +433,12 @@ type ReconciliationConfig = {
|
|
|
425
433
|
|
|
426
434
|
Use `scope: 'package'` for monorepos where file imports should be compared as package-level architecture evidence. Omit `requiredRelationKinds` to require all observed kinds; an empty array intentionally disables undocumented-relation findings and must be treated as an explicit exemption.
|
|
427
435
|
|
|
436
|
+
Use `scope: 'area'` for a single-package repository. At package scope such a repository aggregates
|
|
437
|
+
every internal relation into one self-loop, which the comparison skips — a thousand observed
|
|
438
|
+
relations and nothing to report. At area scope the same relations become edges between
|
|
439
|
+
directories, which a declaration can confirm or fail to. On this repository that is the difference
|
|
440
|
+
between zero diagnostics and 177.
|
|
441
|
+
|
|
428
442
|
Use `requiredRelationTargets: 'internal'` when the repository wants package or module architecture declarations without requiring Markdown to enumerate every external library import. External relations remain in the raw snapshot and report as evidence; they simply do not generate missing-declaration findings.
|
|
429
443
|
|
|
430
444
|
The reconciliation documentation summary reports package health separately from
|
|
@@ -456,6 +470,107 @@ report?: {
|
|
|
456
470
|
|
|
457
471
|
`private` is the default and keeps local evidence useful for debugging. `anonymized` is intended for reports shared outside the repository: it preserves counts, relation kinds, topology, and coverage status while removing project-specific identity and evidence content. The generated HTML and every lazy chunk use the same mode.
|
|
458
472
|
|
|
473
|
+
## `analysis.areas` (optional)
|
|
474
|
+
|
|
475
|
+
```ts
|
|
476
|
+
areas?: {
|
|
477
|
+
/** Directory levels below a source root that form an area. Default 1. */
|
|
478
|
+
depth?: number
|
|
479
|
+
/** Directories that contain areas rather than being one. */
|
|
480
|
+
roots?: string[]
|
|
481
|
+
}
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
An **area** is the unit of architecture between a package and a file: a directory that groups
|
|
485
|
+
modules. `src` is not an area in any useful sense; `src/query` is. So `roots` names the
|
|
486
|
+
directories that hold areas — by default `src`, `lib`, `app`, `source`, `server`, `client`,
|
|
487
|
+
`packages`, `apps` — and `depth` says how many levels below such a root an area sits.
|
|
488
|
+
|
|
489
|
+
Areas are derived, never declared, with one exception that matters: **any path an ownership record
|
|
490
|
+
names becomes an area**, whatever the convention says. A configuration that reads
|
|
491
|
+
`path: "src/mcp"` is a human stating that the directory is a unit, and the graph should have an
|
|
492
|
+
entity for it. Such an area carries `metadata.ownershipId`, which is what lets an agent document
|
|
493
|
+
declaring `id` plus `editRoot` resolve to the thing it owns.
|
|
494
|
+
|
|
495
|
+
Each module belongs to exactly one area — the most specific one containing it — so containment
|
|
496
|
+
stays a tree and an aggregation at area scope has one answer per module. Nested areas keep their
|
|
497
|
+
shape: `area:src` holds what sits directly in `src`, with `area:src/query` recorded as its child.
|
|
498
|
+
|
|
499
|
+
An ownership path that no observed module or document lives under is reported as
|
|
500
|
+
`OWNERSHIP_PATH_UNOBSERVED` with status `stale-or-unverified`. A renamed directory is otherwise
|
|
501
|
+
invisible: the handoff still resolves, it just points an agent somewhere that no longer holds what
|
|
502
|
+
it claims.
|
|
503
|
+
|
|
504
|
+
## `retrieval` (optional)
|
|
505
|
+
|
|
506
|
+
```ts
|
|
507
|
+
type RetrievalConfig = {
|
|
508
|
+
corpus?: {
|
|
509
|
+
/** Project repository documents and modules into `index.knowledge`. Default: true. */
|
|
510
|
+
enabled?: boolean
|
|
511
|
+
}
|
|
512
|
+
/** Per-field BM25 multipliers. Unknown field names are ignored. */
|
|
513
|
+
weights?: {
|
|
514
|
+
id?: number
|
|
515
|
+
symbols?: number
|
|
516
|
+
title?: number
|
|
517
|
+
path?: number
|
|
518
|
+
tags?: number
|
|
519
|
+
description?: number
|
|
520
|
+
body?: number
|
|
521
|
+
}
|
|
522
|
+
/** BM25 parameters: `k1` term-frequency saturation, `b` length-normalization strength (0–1). */
|
|
523
|
+
params?: { k1?: number; b?: number }
|
|
524
|
+
}
|
|
525
|
+
```
|
|
526
|
+
|
|
527
|
+
Search ranks records with field-weighted BM25 plus boosts for exact identity, so an agent that
|
|
528
|
+
types an exported symbol, a file path or a package name lands on that thing rather than on
|
|
529
|
+
whatever mentions it most. The defaults are:
|
|
530
|
+
|
|
531
|
+
| Field | Weight | Why |
|
|
532
|
+
| --- | --- | --- |
|
|
533
|
+
| `id` | 8 | The query names the record |
|
|
534
|
+
| `symbols` | 7 | An agent that types an exported name wants the module that defines it |
|
|
535
|
+
| `title` | 6 | A heading is what a document is about |
|
|
536
|
+
| `path` | 4 | Location is identity for a module |
|
|
537
|
+
| `tags` | 3 | Audience and kind |
|
|
538
|
+
| `description` | 2 | A summary a human wrote |
|
|
539
|
+
| `body` | 1 | A passing mention is the weakest evidence |
|
|
540
|
+
|
|
541
|
+
Tuning is configuration, not code: the resolved weights, parameters and stopword-lexicon version
|
|
542
|
+
are recorded in `index.retrieval`, so a retuned ranking is a different artifact with a different
|
|
543
|
+
content hash rather than a silent behaviour change. Re-run `ak-docs index` after changing them,
|
|
544
|
+
and re-approve the [retrieval benchmark](../bench/README.md) baseline if you gate on it.
|
|
545
|
+
|
|
546
|
+
`corpus.enabled: false` keeps the index to the curated agent corpus only. The index is then
|
|
547
|
+
smaller and builds faster, at the cost of the retrieval it exists for: an exported-symbol or
|
|
548
|
+
file-path query has nothing to resolve against. Turn it off only for a repository whose source is
|
|
549
|
+
not the thing agents ask about.
|
|
550
|
+
|
|
551
|
+
## `render` (optional)
|
|
552
|
+
|
|
553
|
+
```ts
|
|
554
|
+
type RenderConfig = {
|
|
555
|
+
/** Project templates that replace the bundled ones, by name, as paths relative to the project root. */
|
|
556
|
+
templates?: Partial<Record<'llms.txt' | 'area' | 'ownership' | 'change-digest' | 'overlay-review', string>>
|
|
557
|
+
}
|
|
558
|
+
```
|
|
559
|
+
|
|
560
|
+
`ak-docs render <name>` renders the canonical artifacts as Markdown from a bundled template; a
|
|
561
|
+
path under `templates` replaces that template entirely, without a code change. Templates use
|
|
562
|
+
knap syntax and see only the variables Doc Bridge computes — see [Render v1](./render-v1.md) for
|
|
563
|
+
each template's variables and `ak-docs render <name> --print-template` for the bundled source.
|
|
564
|
+
The `llms.txt` override is also what `ak-docs index` writes.
|
|
565
|
+
|
|
566
|
+
```json
|
|
567
|
+
{
|
|
568
|
+
"render": {
|
|
569
|
+
"templates": { "area": "templates/area.md" }
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
```
|
|
573
|
+
|
|
459
574
|
## `safety` (optional)
|
|
460
575
|
|
|
461
576
|
```ts
|
|
@@ -610,14 +725,38 @@ type IntelligenceConfig = {
|
|
|
610
725
|
agentId?: string
|
|
611
726
|
agentRoot?: string
|
|
612
727
|
runnerModule?: string
|
|
728
|
+
cli?: {
|
|
729
|
+
/** Executable name or absolute path; arguments are passed without a shell. */
|
|
730
|
+
command: string
|
|
731
|
+
args?: string[]
|
|
732
|
+
}
|
|
613
733
|
deterministic?: boolean
|
|
734
|
+
maxInputBytes?: number
|
|
614
735
|
timeoutMs?: number
|
|
615
736
|
maxTokens?: number
|
|
616
737
|
maxResponseBytes?: number
|
|
617
738
|
maxConcurrency?: number
|
|
739
|
+
/** Byte budget of one enrichment context pack. Default 65536 (4096..4000000). */
|
|
740
|
+
maxPackBytes?: number
|
|
741
|
+
/**
|
|
742
|
+
* Which installed agent plays which enrichment role (see Enrichment overlay v1).
|
|
743
|
+
* Default: the configured agent as curator only. The adjudicator must be a
|
|
744
|
+
* different identity from the curator and the reviewer.
|
|
745
|
+
*/
|
|
746
|
+
roles?: {
|
|
747
|
+
curator?: EnrichmentRole
|
|
748
|
+
reviewer?: EnrichmentRole
|
|
749
|
+
adjudicator?: EnrichmentRole
|
|
750
|
+
}
|
|
618
751
|
}
|
|
619
752
|
}
|
|
620
753
|
|
|
754
|
+
type EnrichmentRole = {
|
|
755
|
+
enabled?: boolean // default: true when the role is declared; curator on by default
|
|
756
|
+
agentId?: string // default: intelligence.registry.agentId
|
|
757
|
+
promptVersion?: string // default: '1'; part of every proposal id and cache key
|
|
758
|
+
}
|
|
759
|
+
|
|
621
760
|
type MemoryAdapterId =
|
|
622
761
|
| 'playbook-memory' // .agent-memory/MEMORY.md layout
|
|
623
762
|
| 'cursor-rules' // .cursor/rules/*.mdc
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Documentation audit v1
|
|
3
|
+
description: Configurable deterministic checks for documentation quality and agreement with repository structure.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Documentation audit v1
|
|
7
|
+
|
|
8
|
+
Run the repository audit after discovery and reconciliation:
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
ak-docs audit documentation --json
|
|
12
|
+
ak-docs audit documentation --text
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
The JSON report is versioned and content-hashed. It includes criterion-level evidence, metrics, blocking findings, generated-document freshness boundaries, and limitations.
|
|
16
|
+
|
|
17
|
+
## Configuration
|
|
18
|
+
|
|
19
|
+
Configure the optional `audit.documentation` block in `doc-bridge.config.json`:
|
|
20
|
+
|
|
21
|
+
```json
|
|
22
|
+
{
|
|
23
|
+
"audit": {
|
|
24
|
+
"documentation": {
|
|
25
|
+
"criticalPaths": ["src/cli/**", "src/mcp/**"],
|
|
26
|
+
"generatedPaths": ["docs/generated/**"],
|
|
27
|
+
"minWords": 20,
|
|
28
|
+
"requiredSections": ["Usage", "Examples"],
|
|
29
|
+
"requireExamples": true,
|
|
30
|
+
"exactDuplicates": true,
|
|
31
|
+
"defaultTier": "tier-2",
|
|
32
|
+
"tierRules": [
|
|
33
|
+
{ "pattern": "docs/agent-corpus/**", "tier": "tier-0", "critical": true },
|
|
34
|
+
{ "pattern": "docs/adr/**", "tier": "tier-1" }
|
|
35
|
+
],
|
|
36
|
+
"requiredCriticalMetadata": ["owner", "lifecycle", "sourceOfTruth", "validationPath"]
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
- `criticalPaths` makes high-confidence contradictions and missing structure documentation blocking.
|
|
43
|
+
- `generatedPaths` excludes generated documents from manual quality checks and reports freshness as `not-analyzed`; configure the generator's real check separately.
|
|
44
|
+
- `requiredSections`, `minWords`, and `requireExamples` are opt-in to avoid false positives for indexes and short reference files.
|
|
45
|
+
- `exactDuplicates` detects identical normalized bodies. It does not claim that similar prose is redundant.
|
|
46
|
+
- `defaultTier` and ordered `tierRules` classify every included document as `tier-0`, `tier-1`, or `tier-2`. A document may override the configured tier with `tier` frontmatter; `critical: true` frontmatter or a rule marks it critical.
|
|
47
|
+
- Critical documents are checked for `owner`, `lifecycle`, `sourceOfTruth`, and `validationPath` metadata. `requiredCriticalMetadata` can reduce this list for a declared project profile.
|
|
48
|
+
|
|
49
|
+
The audit reuses the canonical discovery snapshot and reconciliation report. A finding is not proof that prose is wrong unless its evidence and confidence say so. `not-analyzed` is intentional and includes semantic contradiction, unnecessary content, and agent-review boundaries. A document title is satisfied by a Markdown level-one heading, a `title` frontmatter field, or a visible HTML `<h1>` used by README-style documents.
|
|
50
|
+
|
|
51
|
+
## Independent quality dimensions
|
|
52
|
+
|
|
53
|
+
Each document receives an assessment instead of one opaque quality score. The machine-readable report exposes `documentAssessments` and independent status counts for:
|
|
54
|
+
|
|
55
|
+
- correctness: deterministic reconciliation can expose evidence, but semantic correctness remains `not-analyzed` until code, configuration, tests, and applicable runtime behavior are reviewed;
|
|
56
|
+
- completeness: structural signals such as title and configured required sections are reported as `partial`, never as semantic completeness;
|
|
57
|
+
- clarity: title and basic structure are measurable, while human readability remains `not-analyzed`;
|
|
58
|
+
- agent efficiency: title and example presence are signals only; retrieval usefulness and task success require the controlled study;
|
|
59
|
+
- maintainability: owner, lifecycle, source-of-truth, and validation-path metadata are directly measurable.
|
|
60
|
+
|
|
61
|
+
Example presence and example correctness are separate. The audit reports `example.present`; `example.validation` remains `not-analyzed` unless a real validation flow supplies evidence. Similar prose, unnecessary content, and document/document semantic contradictions are intentionally deferred to the Registry-agent and human-adjudication path.
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Enrichment overlay v1
|
|
3
|
+
description: Typed agent proposals, the deterministic validators that decide them, the overlay that stores the decisions, and how little of it the deterministic layer is allowed to feel.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Enrichment overlay v1
|
|
7
|
+
|
|
8
|
+
A Registry agent may enrich the knowledge graph. It may never become an authority over it.
|
|
9
|
+
|
|
10
|
+
`AgentProposalV1` could say "review this finding". It could not say that a document is canonical
|
|
11
|
+
for an area, that an alias should resolve to an entity, or that a relation exists with a given
|
|
12
|
+
confidence — and nothing stored what it said, nothing consumed it, the deterministic cache was an
|
|
13
|
+
in-process `Map`, and `ak-docs suggest` sent the whole redacted snapshot, 740 KB on this
|
|
14
|
+
repository, in one call. This document is the replacement: proposals typed per claim, decided by
|
|
15
|
+
validators that have no judgement to exercise, stored in an overlay bound to the content hash of
|
|
16
|
+
what each entry describes, and projected into retrieval with an influence that is bounded by
|
|
17
|
+
construction.
|
|
18
|
+
|
|
19
|
+
## Typed proposals
|
|
20
|
+
|
|
21
|
+
`EnrichmentProposalV1` in `src/schemas/enrichment.ts` is a discriminated union on `kind`. The
|
|
22
|
+
envelope is the same for every kind:
|
|
23
|
+
|
|
24
|
+
| Field | Meaning |
|
|
25
|
+
| --- | --- |
|
|
26
|
+
| `proposalId` | The hash of kind, entity, target content hash, agent identity, prompt version — and, for kinds one entity can carry several of, the payload field that tells them apart (`alias`, `phrase`, the relation's `to` and `kind`, `against`, `with`, `area` and `missing`, `directories`). A re-run over unchanged inputs produces the same id; a summary is a slot, an alias is a set. |
|
|
27
|
+
| `entity` | Must exist in the snapshot the proposal was made against. |
|
|
28
|
+
| `targetContentHash` | The entity's content hash at proposal time: the file hash for a file-backed entity, a hash of the entity as recorded for an area. The entry expires when it moves. |
|
|
29
|
+
| `confidence`, `reason` | 0..1, and up to 1 000 characters. |
|
|
30
|
+
| `evidence` | At least one item, and every item present — by source, path and lines — in the snapshot or the report. |
|
|
31
|
+
| `relatedDiagnosticIds` | Optional; every id must exist in the report. |
|
|
32
|
+
| `origin` | `agentId`, `agentVersion`, `promptVersion`, and optionally `model` and `provider`. |
|
|
33
|
+
| `baseSnapshotHash` | The snapshot it was made against. |
|
|
34
|
+
| `payload` | Per kind, below. |
|
|
35
|
+
|
|
36
|
+
| Kind | Payload | Deterministic validator | Policy |
|
|
37
|
+
| --- | --- | --- | --- |
|
|
38
|
+
| `classify-document` | `type`, `audience`, `lifecycle`, `criticality` | enumerated values; the entity is a document | accept by policy |
|
|
39
|
+
| `summarize` | `summary` ≤ 400 chars, `language` | length; redaction scan; differs from the current summary | accept by policy |
|
|
40
|
+
| `add-alias` | `alias` ≤ 64 chars | no collision with an id, name, title, filename stem or alias — exact, or Jaro-Winkler ≥ 0.95 | accept by policy |
|
|
41
|
+
| `add-intent` | `phrase` ≤ 120 chars, `language` | length; language tag present | accept by policy |
|
|
42
|
+
| `mark-canonical` | `scope` | the scope exists; the entity is a document; at most one canonical document per scope after the merge — a second one is a `canonical-conflict` | human approval |
|
|
43
|
+
| `propose-relation` | `from`, `to`, `kind`, `detection` | both endpoints exist; the kind is one of `covers`, `mentions`, `links-to`, `depends-on`, `related-to`, `documents`; not already observed; every evidence item lies inside one endpoint | human approval |
|
|
44
|
+
| `flag-contradiction` | `against`, `claim`, `observed` | both entities exist; evidence inside both | human approval |
|
|
45
|
+
| `flag-redundancy` | `with` | both are documents; not already exact duplicates | human approval |
|
|
46
|
+
| `flag-gap` | `area`, `missing` | the area exists; not already flagged with the same text | accepted as a finding, never as a fact |
|
|
47
|
+
| `rank-hint` | `relevance`: `strong` or `weak` | the entity exists | accept by policy, bounded weight |
|
|
48
|
+
| `suggest-area` | `directories`, `name` | every directory exists; no overlap with an existing area | human approval, then configuration, never an entity |
|
|
49
|
+
|
|
50
|
+
Any other kind is recorded as rejected with reason `invalid-kind`. The full reason list is
|
|
51
|
+
`ENRICHMENT_REJECTION_REASONS`; every rejection carries one of them, so a run's rejections are a
|
|
52
|
+
histogram and not a log.
|
|
53
|
+
|
|
54
|
+
Envelope checks run before the kind's own rule, in a fixed order: `invalid-kind`, `no-evidence`,
|
|
55
|
+
`schema`, `base-snapshot-mismatch`, `unknown-entity`, `stale-target`, `unknown-diagnostic`,
|
|
56
|
+
`evidence-outside-artifacts`, `proposal-id-mismatch`. A proposal that fails the envelope never
|
|
57
|
+
reaches a kind validator.
|
|
58
|
+
|
|
59
|
+
## The overlay
|
|
60
|
+
|
|
61
|
+
`EnrichmentOverlayV1` lives at `.doc-bridge/enrich/overlay.json`:
|
|
62
|
+
|
|
63
|
+
```json
|
|
64
|
+
{
|
|
65
|
+
"type": "enrichment-overlay",
|
|
66
|
+
"schemaVersion": 1,
|
|
67
|
+
"contentHash": "…",
|
|
68
|
+
"baseSnapshotHash": "…",
|
|
69
|
+
"accepted": [{ "proposal": { "…": "…" }, "acceptedAt": "2026-09-14T00:00:00.000Z", "acceptedBy": "policy" }],
|
|
70
|
+
"pending": [{ "proposal": { "…": "…" }, "approvalId": "…", "note": "canonical-conflict" }],
|
|
71
|
+
"rejected": [{ "proposalId": "…", "kind": "propose-relation", "entity": "…", "reason": "unknown-endpoint", "detail": "…" }],
|
|
72
|
+
"stats": { "byKind": { "summarize": { "proposed": 4, "accepted": 4, "pending": 0, "rejected": 0 } }, "rejectionReasons": {}, "agentRuns": 1, "cacheHits": 0, "packs": 4, "inputBytes": 0, "outputBytes": 0, "expired": 0 }
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
`acceptedBy` is `policy` for accept-by-policy kinds and a person's name otherwise; the schema
|
|
77
|
+
refuses `policy` on a human-approval kind and refuses an `acceptedBy` equal to the proposal's
|
|
78
|
+
`origin.agentId`. `contentHash` is over the decisions — every accepted, pending and rejected entry
|
|
79
|
+
and the hashes they bind to — and not over `acceptedAt` or `stats`, because two runs over one
|
|
80
|
+
unchanged repository must produce one overlay hash and a timestamp is not a fact about the
|
|
81
|
+
repository.
|
|
82
|
+
|
|
83
|
+
Reading never writes. `readEnrichmentOverlay` returns nothing for a missing, unreadable, malformed
|
|
84
|
+
or hash-mismatched file, and a reader that got nothing behaves as if there were no overlay.
|
|
85
|
+
|
|
86
|
+
**Staleness is per entry.** At projection time an accepted entry whose `targetContentHash` no
|
|
87
|
+
longer matches its entity — or whose other endpoint no longer exists — is expired in the result
|
|
88
|
+
and excluded from ranking; its siblings for unchanged entities survive. The file is untouched by a
|
|
89
|
+
read; the next `ak-docs enrich` moves the expired entries to `rejected` with reason `expired`.
|
|
90
|
+
|
|
91
|
+
**Reproducible acceptance.** `revalidateEnrichmentOverlay` re-runs the validators over the stored
|
|
92
|
+
proposals and returns the partition they produce; a test asserts it equals the stored one. An
|
|
93
|
+
overlay whose partition does not reproduce was edited by hand or outlived its validators, and
|
|
94
|
+
either way it is no longer evidence of a decision.
|
|
95
|
+
|
|
96
|
+
## The stage
|
|
97
|
+
|
|
98
|
+
`enrich` is a workflow stage between `reconcile` and `evaluate`, run only by `ak-docs enrich` or
|
|
99
|
+
`ak-docs check --enrich`. A plain `check` leaves its step pending and `evaluate` reads a null
|
|
100
|
+
previous output. A missing, failed, timed-out or stale enrichment never changes a `check` result:
|
|
101
|
+
`check --enrich` reports `enrichment.status: failed` with the error and carries on.
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
$ ak-docs enrich --text
|
|
105
|
+
Roles: curator=ecosystem-doc-bridge-corpus-scanner
|
|
106
|
+
Packs: 92 (agent calls 3, cache hits 89, re-run 3)
|
|
107
|
+
Accepted: 180 Pending: 4 Rejected: 7 Expired: 3
|
|
108
|
+
summarize: accepted 89, pending 0, rejected 1
|
|
109
|
+
…
|
|
110
|
+
Overlay: 7c1e… (overlay.json)
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
The stage:
|
|
114
|
+
|
|
115
|
+
1. builds one context pack per target entity for each configured role and batches them by area;
|
|
116
|
+
2. answers each pack from the cache or from the agent, caching what the agent said per pack —
|
|
117
|
+
including nothing, so silence is not asked for twice;
|
|
118
|
+
3. validates everything through the partition against the snapshot, the report and the overlay
|
|
119
|
+
already on disk; policy kinds are accepted, human kinds are requested from the approval gate;
|
|
120
|
+
4. adjudicates what two roles could not settle, if a third identity is configured;
|
|
121
|
+
5. merges with the stored overlay — decisions people made survive while their target does — and
|
|
122
|
+
writes it.
|
|
123
|
+
|
|
124
|
+
The step's workflow input names the overlay it attaches (`{ reportHash, overlayHash }`), because
|
|
125
|
+
an approval changes the overlay without changing the report, and the engine refuses a step whose
|
|
126
|
+
input did not move but whose output did.
|
|
127
|
+
|
|
128
|
+
## Context packs and the cache
|
|
129
|
+
|
|
130
|
+
Agents never receive the snapshot. `buildContextPacks` in `src/enrich/context-pack.ts` builds
|
|
131
|
+
one pack per target entity:
|
|
132
|
+
|
|
133
|
+
| Section | Content | Bound |
|
|
134
|
+
| --- | --- | --- |
|
|
135
|
+
| `target` | id, kind, name, path, content hash, aliases, its own evidence items, bounded metadata | — |
|
|
136
|
+
| `neighbours` | the other end of every relation touching the target, with kind, path, content hash, the relation and its direction; sorted by kind then id | 32 |
|
|
137
|
+
| `diagnostics` | open diagnostics naming the target or citing its file | 16 |
|
|
138
|
+
| `evidence` | the target's own file, redacted, read only if it still hashes to what the snapshot recorded | 12 KB |
|
|
139
|
+
| `budget` | `maxBytes`, `bytes`, `dropped` | 64 KB default, `intelligence.registry.maxPackBytes` |
|
|
140
|
+
|
|
141
|
+
Over budget, sections are dropped in a declared order — excerpt bytes (halved until it fits, then
|
|
142
|
+
dropped), then diagnostics from the end, then neighbours from the end — and the target is never
|
|
143
|
+
dropped. This mirrors `compileBudget` from `@agentskit/core` with a byte counter and the
|
|
144
|
+
`drop-oldest` strategy over sections ordered least-important-first; a test cross-checks the two,
|
|
145
|
+
and the mirror is what runs, because a pack must be the same pack whether or not an optional peer
|
|
146
|
+
is installed. Every string in a pack passes `redactSecrets`, asserted by test.
|
|
147
|
+
|
|
148
|
+
`packHash` covers the target's and every neighbour's content hash and nothing else. The cache key
|
|
149
|
+
is the hash of task, agent identity and version, prompt version and pack hash; entries live under
|
|
150
|
+
`.doc-bridge/enrich/cache/<key>.json`. An unchanged repository therefore makes zero agent calls,
|
|
151
|
+
and a one-document change re-runs only the packs whose hash moved — the changed document's, and
|
|
152
|
+
any pack it was a neighbour of.
|
|
153
|
+
|
|
154
|
+
## Protocol v2
|
|
155
|
+
|
|
156
|
+
The adapter (`src/agents/registry-adapter.ts`) keeps `run` for `AgentProposalV1` over protocol
|
|
157
|
+
`doc-bridge.registry-agent.v1` — `ak-docs suggest` still works — and gains `enrich(task, packs)`
|
|
158
|
+
over `doc-bridge.registry-agent.v2`:
|
|
159
|
+
|
|
160
|
+
```json
|
|
161
|
+
{ "protocol": "doc-bridge.registry-agent.v2", "task": "curate", "role": "curator", "promptVersion": "1", "packs": [ … ], "capabilities": ["pack.read", "proposal.write"], "network": false, "shell": false, "deterministic": true }
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
The answer is one JSON object `{ "proposals": [ … ] }`. `task` is `curate`, `review` or
|
|
165
|
+
`adjudicate`; for `adjudicate` the packs are followed by one `adjudication-request` item listing
|
|
166
|
+
the disputed proposals, and `proposals` carries `EnrichmentAdjudicationV1` values. The adapter
|
|
167
|
+
checks transport and budget and returns the raw array; grounding is the validators' job, and
|
|
168
|
+
keeping it there is what makes a stored overlay reproducible from its proposals. The same CLI or
|
|
169
|
+
local runner module serves both protocols and tells them apart by `protocol`.
|
|
170
|
+
|
|
171
|
+
## Roles
|
|
172
|
+
|
|
173
|
+
| Role | Task | Targets | Kinds it is for |
|
|
174
|
+
| --- | --- | --- | --- |
|
|
175
|
+
| curator | `curate` | documents | classification, summaries, aliases, intents, canonical markers, redundancy, gaps |
|
|
176
|
+
| reviewer | `review` | documents, areas | relations, contradictions, gaps, rank hints, area suggestions |
|
|
177
|
+
| adjudicator | `adjudicate` | the disputed entities | canonical conflicts and disputed contradictions only |
|
|
178
|
+
|
|
179
|
+
Roles are configuration under `intelligence.registry.roles`; the default is the configured agent
|
|
180
|
+
as curator only. The adjudicator must be a different agent identity from both others —
|
|
181
|
+
`resolveEnrichmentRoles` refuses the configuration otherwise — and the validator rejects any
|
|
182
|
+
adjudication whose origin matches a proposal it judges as `self-adjudication`. An adjudication
|
|
183
|
+
judges; it never approves: the losers are rejected as `adjudicated`, the winner stays pending for
|
|
184
|
+
the person the kind's policy requires, and a settled dispute is not reopened by the cache
|
|
185
|
+
replaying the proposals that caused it.
|
|
186
|
+
|
|
187
|
+
## Approvals
|
|
188
|
+
|
|
189
|
+
Human approval goes through `createApprovalGate` from `@agentskit/core/hitl` over a file-backed
|
|
190
|
+
`ApprovalStore` under `.doc-bridge/approvals/`, one JSON record per approval. The gate contract is
|
|
191
|
+
mirrored in-repo (`src/enrich/approvals.ts`) for the same reason every ecosystem contract is —
|
|
192
|
+
`@agentskit/core` is an optional peer — and the real gate is used through `importPeer` when it is
|
|
193
|
+
installed; a test writes through both over one store and reads the same records.
|
|
194
|
+
|
|
195
|
+
An approval id is the hash of `proposalId` and `targetContentHash`, so an approval given for one
|
|
196
|
+
version of a document cannot be replayed against the next. `ak-docs enrich approve <proposalId>
|
|
197
|
+
--by <name>`, MCP `docbridge.proposals { action: "enrich-approve" }` and a rendered review page
|
|
198
|
+
call the same `decideEnrichment`: the gate decides first, the overlay moves second, and if the
|
|
199
|
+
gate refuses — already decided, unknown — the overlay is untouched. An approver equal to the
|
|
200
|
+
proposal's author is refused; `policy` is not a person. `ak-docs fix approve` records its
|
|
201
|
+
approval through the same gate under `doc-bridge.fix`, bound to the fix proposal id and its
|
|
202
|
+
content hash.
|
|
203
|
+
|
|
204
|
+
## Projection and bounded influence
|
|
205
|
+
|
|
206
|
+
`projectEnrichmentOverlay(overlay, snapshot)` turns the live accepted set into what
|
|
207
|
+
`projectRetrievalIndex` reads:
|
|
208
|
+
|
|
209
|
+
| Accepted kind | Effect in the projection |
|
|
210
|
+
| --- | --- |
|
|
211
|
+
| `add-alias` | one more alias on the entry |
|
|
212
|
+
| `summarize` | the entry's summary, only when the entity has none of its own |
|
|
213
|
+
| `add-intent` | an `intent` entry with `provenance: proposed` |
|
|
214
|
+
| `mark-canonical` | the `canonical` tag, and 0.8 of the signal |
|
|
215
|
+
| `rank-hint` | 1 (strong) or 0.5 (weak) of the signal |
|
|
216
|
+
| `propose-relation` | one more edge with `confidence: proposed`; a `covers` edge counts toward `coveredBy` and canonicality |
|
|
217
|
+
| `flag-*`, `suggest-area` | nothing: findings and suggestions are for a reviewer, not for ranking |
|
|
218
|
+
|
|
219
|
+
The signal is a per-entry share in 0..1, carried on the entry as `agentSignal`, and the ranker
|
|
220
|
+
multiplies it by `ACCEPTED_SIGNALS_WEIGHT` = 15% of the exact-id boost (30 of 200). It applies to
|
|
221
|
+
lexical hits only, like every other tie-breaker. An accepted signal can therefore reorder near-ties
|
|
222
|
+
and can never lift an entry past one the query named exactly — asserted by test. Without an
|
|
223
|
+
overlay, `ACCEPTED_SIGNALS_WEIGHT × 0` is what it always was, and the projection is byte-identical.
|
|
224
|
+
|
|
225
|
+
The projection's `overlayHash` is the hash of the live accepted set — `EMPTY_OVERLAY_HASH` when
|
|
226
|
+
nothing is live — so it is part of the projection's identity and `IndexStaleError` sees a changed
|
|
227
|
+
overlay. `withAcceptedRelations` merges live proposed relations into a snapshot for the graph, the
|
|
228
|
+
HTML report and the memory view, and `assertObservedSurvive` checks that every observed entity and
|
|
229
|
+
relation is present and unchanged afterwards; the report draws a proposed edge dashed.
|
|
230
|
+
|
|
231
|
+
The index builder consults the overlay only while `intelligence.registry.enabled` is true:
|
|
232
|
+
switching the Registry off restores the deterministic baseline exactly.
|
|
233
|
+
|
|
234
|
+
## What never happens
|
|
235
|
+
|
|
236
|
+
- No overlay entry deletes or alters observed data. The projection asserts that every observed
|
|
237
|
+
entity and relation survives enrichment.
|
|
238
|
+
- No agent is called from `check`, `index`, `search`, `query`, `render` or MCP. The enrich stage
|
|
239
|
+
runs only on request, and nothing reachable from the query path imports `src/agents`.
|
|
240
|
+
- No agent approves anything — its own output, another agent's, or an adjudication's winner.
|
|
241
|
+
- No read writes. A corrupt overlay is no overlay.
|