akm-cli 0.9.30 → 0.9.31

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 (161) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/README.md +10 -10
  3. package/ROADMAP.md +112 -0
  4. package/dist/commands/improve/improve-cli.js +33 -12
  5. package/dist/core/file-lock.js +10 -1
  6. package/dist/llm/client.js +33 -3
  7. package/dist/scripts/akm-migrate-node.js +5 -1
  8. package/dist/scripts/akm-migrate.js +5 -1
  9. package/docs/README.md +42 -41
  10. package/docs/agents/README.md +15 -0
  11. package/docs/agents/agent-install.md +14 -0
  12. package/docs/architecture/README.md +67 -0
  13. package/docs/architecture/adapters.md +272 -0
  14. package/docs/architecture/akm-architecture-decision-history.md +2055 -0
  15. package/docs/architecture/akm-core-principles.md +126 -0
  16. package/docs/architecture/architecture.md +579 -0
  17. package/docs/architecture/comparisons/claude-code-vs-akm-workflows-full.md +550 -0
  18. package/docs/architecture/decisions/0001-no-interpolation-attached-structured-context.md +72 -0
  19. package/docs/architecture/decisions/0002-unit-reuse-and-input-hash-scope.md +142 -0
  20. package/docs/architecture/decisions/0003-child-env-allowlist-and-provenance.md +189 -0
  21. package/docs/architecture/decisions/0004-task-input-contract-and-flag-coercion.md +97 -0
  22. package/docs/architecture/decisions/0005-task-result-vocabulary-and-legacy-read-mapping.md +108 -0
  23. package/docs/architecture/decisions/0006-task-source-version-routing.md +124 -0
  24. package/docs/architecture/decisions/0007-workflow-composition-bounds.md +83 -0
  25. package/docs/architecture/decisions/0008-task-binding-normalization.md +88 -0
  26. package/docs/architecture/decisions/0009-child-run-publication-column-parity.md +80 -0
  27. package/docs/architecture/decisions/0010-driver-protocol-cut.md +36 -0
  28. package/docs/architecture/decisions/0011-engine-run-loop-invariants.md +125 -0
  29. package/docs/architecture/decisions/README.md +62 -0
  30. package/docs/architecture/improvement.md +440 -0
  31. package/docs/architecture/internals/classification.md +154 -0
  32. package/docs/architecture/internals/fresh-host-rebuild-runbook.md +40 -0
  33. package/docs/architecture/internals/functional-contract-patterns.md +340 -0
  34. package/docs/architecture/internals/health-advisories.md +110 -0
  35. package/docs/architecture/internals/improve-workflow.md +713 -0
  36. package/docs/architecture/internals/indexing.md +498 -0
  37. package/docs/architecture/internals/registry-network-boundary.md +57 -0
  38. package/docs/architecture/internals/search.md +249 -0
  39. package/docs/architecture/internals/storage-locations.md +943 -0
  40. package/docs/architecture/persisted-data-compat.md +59 -0
  41. package/docs/architecture/reviews/env-secret-access.md +319 -0
  42. package/docs/architecture/runtime-boundary-design.md +153 -0
  43. package/docs/architecture/specs/0.9.0-close-out-plan.md +361 -0
  44. package/docs/architecture/specs/0.9.0-decisions.md +528 -0
  45. package/docs/architecture/specs/0.9.0-docs-code-drift-register.md +745 -0
  46. package/docs/architecture/specs/0.9.0-open-items-register.md +135 -0
  47. package/docs/architecture/specs/0.9.0-public-api-issue-backlog.md +740 -0
  48. package/docs/architecture/specs/0.9.0-release-surface-review.md +636 -0
  49. package/docs/architecture/specs/agent-command-engine-model-design.md +513 -0
  50. package/docs/architecture/specs/akm-0.9.0-bundle-adapter-spec.md +501 -0
  51. package/docs/architecture/specs/akm-0.9.0-ref-grammar-decision.md +291 -0
  52. package/docs/architecture/specs/akm-format-neutral-bundle-workspace-spec.md +2059 -0
  53. package/docs/architecture/specs/di-seams-plan.md +539 -0
  54. package/docs/architecture/specs/driver-protocol-keep-or-cut.md +275 -0
  55. package/docs/architecture/specs/fact-asset-type.md +142 -0
  56. package/docs/architecture/specs/improve-collapse-churn-detector-design.md +634 -0
  57. package/docs/architecture/specs/okf-support.md +148 -0
  58. package/docs/architecture/specs/ref.md +329 -0
  59. package/docs/architecture/specs/reviews/task-workflow-unification/README.md +72 -0
  60. package/docs/architecture/specs/reviews/task-workflow-unification/findings-consolidated.md +152 -0
  61. package/docs/architecture/specs/reviews/task-workflow-unification/library-eval-alternatives.md +352 -0
  62. package/docs/architecture/specs/reviews/task-workflow-unification/library-eval-bunqueue.md +300 -0
  63. package/docs/architecture/specs/reviews/task-workflow-unification/library-eval-openworkflow.md +402 -0
  64. package/docs/architecture/specs/reviews/task-workflow-unification/opus-review-1.md +758 -0
  65. package/docs/architecture/specs/reviews/task-workflow-unification/opus-review-2.md +645 -0
  66. package/docs/architecture/specs/reviews/task-workflow-unification/opus-review-3.md +602 -0
  67. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-adversarial.md +27 -0
  68. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-architecture.md +27 -0
  69. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-coverage.md +74 -0
  70. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-security.md +15 -0
  71. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r2-adversarial.md +132 -0
  72. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r2-verification.md +147 -0
  73. package/docs/architecture/specs/stash-conventions-code-spec.md +275 -0
  74. package/docs/architecture/specs/stash-organization-conventions.md +377 -0
  75. package/docs/architecture/specs/task-workflow-format-unification.md +721 -0
  76. package/docs/architecture/specs/workflow-engine-buy-vs-build.md +231 -0
  77. package/docs/architecture/specs/workflow-format-unification.md +437 -0
  78. package/docs/architecture/testing/manual-testing-checklist.md +3420 -0
  79. package/docs/architecture/testing/okf-v0.2-conformance-runbook.md +924 -0
  80. package/docs/architecture/testing/task-workflow-manual-tests.md +1817 -0
  81. package/docs/architecture/testing/testing-workflow.md +446 -0
  82. package/docs/architecture/workflow-engine.md +274 -0
  83. package/docs/guides/README.md +33 -0
  84. package/docs/guides/author-bundles.md +310 -0
  85. package/docs/guides/author-workflows.md +520 -0
  86. package/docs/guides/bundles.md +321 -0
  87. package/docs/guides/capture-knowledge.md +136 -0
  88. package/docs/guides/claude-code-vs-akm-workflows.md +30 -0
  89. package/docs/guides/concepts.md +93 -0
  90. package/docs/guides/discover-and-load.md +158 -0
  91. package/docs/guides/getting-started.md +240 -0
  92. package/docs/guides/improve-the-library.md +246 -0
  93. package/docs/guides/knowledge-management.md +18 -0
  94. package/docs/guides/recipes/headless-install.md +97 -0
  95. package/docs/guides/recipes/website-source.md +28 -0
  96. package/docs/guides/run-workflows.md +279 -0
  97. package/docs/guides/scheduling.md +123 -0
  98. package/docs/guides/use-with-any-agent.md +129 -0
  99. package/docs/guides/wikis.md +81 -0
  100. package/docs/maintainers/README.md +19 -0
  101. package/docs/maintainers/curate-workmap.md +336 -0
  102. package/docs/maintainers/eval.md +3 -0
  103. package/docs/maintainers/local-development.md +108 -0
  104. package/docs/maintainers/release-checklist.md +103 -0
  105. package/docs/migration/README.md +2 -2
  106. package/docs/migration/release-notes/0.0.13.md +1 -1
  107. package/docs/migration/release-notes/0.1.0.md +1 -1
  108. package/docs/migration/release-notes/0.2.0.md +1 -1
  109. package/docs/migration/release-notes/0.3.0.md +1 -1
  110. package/docs/migration/release-notes/0.5.0.md +1 -1
  111. package/docs/migration/release-notes/0.6.0.md +1 -1
  112. package/docs/migration/release-notes/0.7.0.md +1 -1
  113. package/docs/migration/release-notes/0.7.3.md +2 -2
  114. package/docs/migration/release-notes/0.7.4.md +1 -1
  115. package/docs/migration/release-notes/0.7.5.md +1 -1
  116. package/docs/migration/release-notes/0.8.0.md +1 -1
  117. package/docs/migration/release-notes/0.9.0.md +1 -1
  118. package/docs/migration/release-notes/0.9.14.md +1 -1
  119. package/docs/migration/release-notes/0.9.15.md +1 -1
  120. package/docs/migration/release-notes/0.9.16.md +1 -1
  121. package/docs/migration/release-notes/0.9.17.md +1 -1
  122. package/docs/migration/release-notes/0.9.19.md +1 -1
  123. package/docs/migration/release-notes/0.9.2.md +1 -1
  124. package/docs/migration/release-notes/README.md +27 -31
  125. package/docs/migration/v0.5-to-v0.6.md +759 -0
  126. package/docs/migration/v0.8-to-v0.9.md +1 -1
  127. package/docs/plans/0.9.2-agent-command-workflow-plan.md +423 -0
  128. package/docs/posts/README.md +30 -0
  129. package/docs/posts/akm-command-tour.md +495 -0
  130. package/docs/posts/akm-logo-sized.webp +0 -0
  131. package/docs/posts/belief-aware-memory-12.md +139 -0
  132. package/docs/posts/config-v2-lessons-16.md +191 -0
  133. package/docs/posts/improve-loop-autonomous-10.md +225 -0
  134. package/docs/posts/improve-pipeline-debugging-0803.md +179 -0
  135. package/docs/posts/intro-part-01.md +76 -0
  136. package/docs/posts/intro-part-02.md +221 -0
  137. package/docs/posts/intro-part-03.md +190 -0
  138. package/docs/posts/intro-part-04.md +221 -0
  139. package/docs/posts/llm-mode-reflect-13.md +166 -0
  140. package/docs/posts/openpalm-built-on-akm.md +86 -0
  141. package/docs/posts/progressive-disclosure-06.md +129 -0
  142. package/docs/posts/proposal-safety-net-15.md +112 -0
  143. package/docs/posts/release-0.5.0.md +247 -0
  144. package/docs/posts/release-0.6.0.md +117 -0
  145. package/docs/posts/release-0.7.0.md +159 -0
  146. package/docs/posts/release-0.8.0.md +332 -0
  147. package/docs/posts/scattered-skills-05.md +100 -0
  148. package/docs/posts/task-assets-persistent-workflows-11.md +222 -0
  149. package/docs/posts/team-skills-07.md +198 -0
  150. package/docs/posts/wiki-agent-knowledge-08.md +223 -0
  151. package/docs/posts/workflows-vaults-09.md +321 -0
  152. package/docs/product-surface.md +54 -0
  153. package/docs/reference/README.md +1 -2
  154. package/docs/reference/asset-types.md +168 -0
  155. package/docs/reference/cli.md +5 -6
  156. package/docs/reference/env-and-secrets.md +126 -0
  157. package/docs/reference/memory.md +124 -0
  158. package/docs/reference/refs.md +156 -0
  159. package/docs/reference/registry.md +489 -0
  160. package/docs/reference/website-sources.md +141 -0
  161. package/package.json +12 -15
@@ -0,0 +1,501 @@
1
+ # AKM 0.9.0 — Bundle Adapter Specification
2
+
3
+ **Status:** binding implementation spec, reconciled with `akm-format-neutral-bundle-workspace-spec.md` **v0.3** (the normative RFC, amended in place — the two documents agree; where wording differs the normative spec governs) and `akm-architecture-decision-history.md` (decision register, D1–D30). This doc is the concrete *how* for the adapter/index/ref core; it **defers to the normative spec** for activation (§18, Tier A staging), improve (§24), and memory (§25, deferred) rather than duplicate them. Grounded in code at HEAD as `file:line`, or **NEW** with the mandate. Amended 2026-07-13/14 after the review passes: adapter contract is recognize-required/index-optional over a core-owned walk; index persistence is a diff keyed on ref; query-time ranking/filter signals are first-class `IndexDocument` fields; `validate` receives a snapshot+overlay context; adapter selection has a deterministic probe order; native links do not feed the graph boost; `KNOWN_TYPES`-typed presentation tables; bindings Tier A / memory deferred / no new trust machinery (deviation §4.3a–3c).
4
+
5
+ **Reconciliation decisions applied (maintainer, 2026-07-13)** — resolving the plan/spec deviations:
6
+
7
+ 1. **OKF is the first-class Markdown baseline (DEV-1).** Every applicable conformance case passes. The built-in `okf` adapter provides generic path identity, open type, content, links, and heading fragments. AKM-authored Markdown is an OKF-compatible superset; native adapters progressively add behavior. Non-Markdown Claude/OpenCode/Agent-Skills/workflow/task/env formats retain native serialization. The normalized `type` field is open and **MAY** drive adapter-owned presentation/ranking/filtering but **MUST NOT** authorize execution, grant runtime authority, be part of identity, or select the core storage/write path.
8
+ 2. **Ref = adapter-owned concept ID + optional `bundle//` prefix (DEV-2).** Identity is the concept ID produced by the selected adapter; the workspace-qualified ref prepends an optional `<bundle>//`. Component is **absorbed into the path**, not a separate ref segment.
9
+ 3. **Final scope (2026-07-14 refinements, deviation §4.3a–3c — supersede the earlier "DEV-3/4/5 restore full"):** the third `consolidate` verb is IN SCOPE as vocabulary (DEV-5); **bindings ship at Tier A only** (consolidation of existing install≠activation enforcement into one activation-policy point; the persisted `Binding` record, digests, rebind, and bind CLI are Tier B, deferred indefinitely); **the memory lifecycle is deferred entirely** (0.9.0 = consolidate decomposition with behavior preserved); **no new trust/approval machinery ships**. Retained simplifications: renderer/action as a **data table** typed over `KNOWN_TYPES`, and adapter facets expressed as **optional methods** on one interface (History §8.3), not a rigid `extends` hierarchy.
10
+ 4. **LLM Wiki adapter restored (DEV-7).** The `wiki` *asset type* dies; the **LLM Wiki adapter** is a first-class built-in owning `schema.md`/`index.md`/`log.md`/raw/pages/citations/xrefs/ingest.
11
+
12
+ **Amendment (v0.4, 2026-07-21 — owner ruling).** Two §1.2 resolution steps are removed and one dispatch behavior is confirmed shipped: (a) the `akm.bundle.yaml` **manifest** step is removed entirely (it was never implemented and should never have been approved); (b) **sub-mount registration** is replaced by **adapter-owned file processing** — one bundle = one component = one adapter, and that adapter's `recognize` claims/abstains on its bundle's files and subdirectories as it sees fit (the core provides the walk and persistence). The consequent multi-component machinery (nested-root subtraction §9.3, cross-component collisions, manifest `exports:`) no longer applies to 0.9.0. (c) Adapter **dispatch is live**: the indexer's per-directory drain resolves `adapterForId(component.adapter)` and skips a component whose adapter id is unknown with a warning (§4).
13
+
14
+ ---
15
+
16
+ ## 0. OKF: first-class format support in a format-neutral kernel
17
+
18
+ OKF v0.1 (Google Cloud, June 2026 — [SPEC](https://github.com/GoogleCloudPlatform/knowledge-catalog/blob/main/okf/SPEC.md)) defines a bundle as a directory tree of markdown "concept" files (`--- frontmatter ---` + body) where **the file path is the concept's identity** and the only required field is an open **`type`**. AKM supports that format directly through the built-in `okf` adapter. An OKF bundle indexes without conversion. OKF is the generic Markdown behavior floor, not AKM's database representation or a serialization imposed on non-Markdown formats.
19
+
20
+ **v0.2 update (#730):** upstream OKF minor-versioned to v0.2, adding a trust/
21
+ provenance frontmatter family (`generated`/`verified`/`sources`), a lifecycle
22
+ family (`status`/`stale_after`), and an actor convention
23
+ (`<producer>/<version>` / `human:<id>` / `process:<id>`), with one
24
+ breaking-with-fallback change: `timestamp` is superseded by `generated.at`,
25
+ and consumers are expected to fall back to `timestamp` when absent. The `okf`
26
+ adapter parses the full v0.2 family (§0.1 below); it remains **consumer-only**
27
+ — see `okf-support.md`'s v0.2 note for the read/write split and the
28
+ namespacing rationale (`provenance`/`lifecycleStatus`/`staleAfter`/
29
+ `okfVersion`, chosen to avoid overloading the three AKM-native fields that
30
+ already occupy adjacent names: `sources?: string[]`, `generation?: number`,
31
+ `quality: "generated"`).
32
+
33
+ ### 0.1 OKF support mapping
34
+
35
+ | OKF v0.1 | AKM | Note |
36
+ |---|---|---|
37
+ | Bundle = directory tree of markdown concepts | AKM bundle selected with `adapter: okf` (§5) | Other AKM bundles retain their native formats |
38
+ | **Concept ID** = file path − `.md` (`tables/users.md` → `tables/users`) | The `okf` adapter emits that concept ID; the ref adds an optional `<bundle>//` prefix (§1.3) | Other adapters define their own concept IDs |
39
+ | Required **`type`** (open string) | The `okf` adapter maps it to AKM's open indexed `type` field | Other adapters derive `type` from native semantics |
40
+ | **`title`** | `name` (FTS 10) — read `title` first; write `title` | OKF-compat output |
41
+ | **`description`** | `description` (FTS 5) | direct |
42
+ | **`tags`** | `tags` (FTS 3) | direct |
43
+ | Optional **`timestamp`** (v0.1) | `updated` when present | absence is not an AKM freshness error; v0.2's `generated.at` takes precedence when present (see below) |
44
+ | **`resource`** (URI) | provenance (`sourceRef`) | carried |
45
+ | Reserved **`index.md`**/**`log.md`** | reserved, not indexed as concepts (§5) | |
46
+ | bundle-relative links = relationship | deterministic native link graph (§9) | replaces LLM graph extraction for OKF content |
47
+ | **`okf_version`** | `IndexDocument.okfVersion` | Upstream declares it only on a bundle-root `index.md` (never indexed as a concept); read defensively from any concept's frontmatter, best-effort |
48
+ | consumers MUST tolerate unknown fields + broken links | `okf` adapter `validate` is **lenient** (§5) | interop guarantee |
49
+ | **`generated`** (v0.2: `{by, at}`) | `IndexDocument.updated` ← `generated.at` (precedence over `timestamp`); `IndexDocument.provenance.generatedBy`/`.generatedAt` | breaking-with-fallback: `timestamp` remains a valid legacy reading when `generated`/`generated.at` is absent |
50
+ | **`verified`** (v0.2: a list, or a single mapping without the list dash) | `IndexDocument.provenance.verified: Array<{by, at?}>` | both forms normalize to a non-empty array; a malformed entry is dropped, never rejecting the document |
51
+ | **`sources`** (v0.2: object list — `resource` required, `id`/`title`/`author`/`usage_count`/`last_modified` optional) | `IndexDocument.provenance.sources` | NAMESPACED — landed under `provenance.sources`, never the bare `IndexDocument.sources: string[]` field (wiki citation strings; a naive fold would silently drop every object entry as non-string) |
52
+ | **`status`** (v0.2: `draft`\|`stable`\|`deprecated`) | `IndexDocument.lifecycleStatus` | strict whitelist; any other value is left unset, never guessed at |
53
+ | **`stale_after`** (v0.2: `YYYY-MM-DD`) | `IndexDocument.staleAfter` | read verbatim; read-only in 0.9.0 — no re-verification/trust-tier ranking is driven off it (0.9.x improve-tuning track) |
54
+ | AKM-native writes (proposal-path provenance stamping, D2) | `promoteProposal` stamps `generated`/`verified` BARE at the top level (OKF v0.2's own spelling) and `sources` alone NAMESPACED as `provenance: {sources}` (avoids the wiki-citation-string collision) onto accepted AKM-native assets — same `IndexDocument.provenance` shape either way | write-only path is proposal-mediated, never through the `okf` adapter (which stays consumer-only); projects the proposals system's own `source`/`sourceRun`/`gateDecision`/`review` provenance and `evidenceSources`; every AKM-native markdown type is stamped, `workflow` included (its closed frontmatter allowlist admits these keys) |
55
+
56
+ ### 0.2 The clean taxonomy — identity / type / adapter / component
57
+
58
+ The old `AkmAssetType` conflated five roles (source selection, classification, naming, routing, state keys — History §4.4); 0.9.0 separates them:
59
+
60
+ | Concept | Is | Source | Role | NOT |
61
+ |---|---|---|---|---|
62
+ | **identity** | the one name of an item | adapter-owned concept ID; ref `[<bundle>//]<concept-id>` (§1.3) | refs, addressing, links, state keys | not type/adapter/component |
63
+ | **`type`** | open descriptive label | supplied by the selected adapter | presentation, ranking, filtering | not identity; not an adapter; **never execution authority**; not a core storage switch |
64
+ | **adapter** | native format-family owner | static id, one per component root | recognize / place / validate; optional authoring/export/memory methods | not a type; never competes per-file |
65
+ | **component** | a materialized root under one adapter | the bundle's single configured component | provenance, write policy, adapter selection, git pathspecs | not a distinct ref segment; not identity; not type |
66
+
67
+ **Orthogonality:** (1) `type` ≠ adapter, many-to-many. (2) presentation/ranking key on `type`; validation keys on `(adapter, type)` via shared functions. (3) a "tool directory" (`.claude`) is a component; provenance, never identity/type. (4) identity is the adapter-owned concept ID; changing indexed metadata without moving or renaming the native item does not change it. (5) `type` **presents but never executes** — runtime authority comes only from a binding or explicit one-shot approval (normative §18, §28; History D8).
68
+
69
+ **OKF baseline vs AKM capabilities.** For an OKF bundle, the `okf` adapter preserves path identity, open `type`, `title`/`description`/`tags`/`timestamp`, content, links, and heading fragments. AKM Markdown emits conformant OKF frontmatter and its adapter adds native behavior based on the recognized AKM asset kind. Executable, sensitive, YAML, and tool-native formats remain adapter-native rather than being translated through Markdown.
70
+
71
+ ---
72
+
73
+ ## 1. Bundle / component / installation model
74
+
75
+ ### 1.1 Interfaces (replaces `AssetSpec`/`TYPE_DIRS`/`ConfiguredSource`)
76
+
77
+ ```ts
78
+ export type BundleId = string; // stable bundle name (workspace identity); the optional ref prefix
79
+ export type ComponentId = string; // a configured root under one adapter; PROVENANCE, not a ref segment (§1.3)
80
+ export type ItemRef = string; // "[<bundle>//]<concept-id>" (§1.3)
81
+
82
+ export interface BundleInstallation {
83
+ id: BundleId;
84
+ revision?: string; // resolved git sha / npm version+integrity / snapshot digest
85
+ source?: string; // transport locator, kept OUT of identity (normative §11.2)
86
+ components: BundleComponent[]; // exactly one entry in 0.9.0
87
+ trusted: boolean; // explicit trust; installation grants nothing (History D8)
88
+ }
89
+
90
+ export interface BundleComponent {
91
+ id: ComponentId;
92
+ adapter: string; // static adapter id, one per root — no per-file competition
93
+ root: string; // absolute materialized root; workspace state NEVER written here
94
+ writable: boolean;
95
+ }
96
+ ```
97
+
98
+ `BundleInstallation`, `BundleComponent`, `IndexDocument`, `FileChange`, `Proposal`, and `Diagnostic` are the minimal durable core set for 0.9.0 (`Binding` is Tier-B target vocabulary — History §5.2, §10).
99
+
100
+ ### 1.2 How a directory becomes a bundle
101
+
102
+ *(Amended v0.4, 2026-07-21 — owner ruling: the `akm.bundle.yaml` manifest step and the sub-mount proposal step are removed; a bundle maps to exactly one component/adapter.)*
103
+
104
+ 1. **Workspace config `bundles` map** (normative §10.1).
105
+ 2. **Deterministic install-time probe** (no config): `looksLikeRoot` probes run in a fixed, most-specific-first order. Specific native formats, LLM Wiki, and strong AKM layout evidence run before the broad OKF probe. A root OKF `index.md` or an index-less conformant typed Markdown tree selects `okf` when no stronger format claims it. First match wins; probes MUST be pure (stat/read only), and the result is persisted per normative §9.4 and never re-guessed. `generic-files` is **never auto-selected** — explicit configuration only.
106
+ 3. **Single-component default** — nothing else matched ⇒ one component using the `akm` adapter. OKF is selected by explicit configuration or its own deterministic probe, never merely as the generic fallback.
107
+
108
+ **One bundle = one component = one adapter** (owner ruling 2026-07-21). The component's adapter processes the files and subdirectories of its bundle as it sees fit: the core provides symlink-safe traversal and persistence, while adapter-specific walk policy determines whether ordinary dot/cache directories participate. The adapter's `recognize` decides which walked files it claims and which it abstains on. There is no `akm.bundle.yaml` manifest and no sub-mount registration. Intra-component conceptId collisions are `duplicate-concept-id` diagnostics with a deterministic extension-priority winner.
109
+
110
+ ### 1.3 Ref grammar — adapter-owned concept ID + optional `bundle//` prefix
111
+
112
+ **Identity = the adapter-owned concept ID.** For OKF this is the Markdown path minus `.md`; other adapters define the corresponding path for their native item. The workspace-qualified ref prepends an optional `<bundle>//` (the `//` echoes the old `origin//`, and disambiguates the bundle prefix from the `/`-separated path):
113
+
114
+ ```
115
+ ref := [ bundle "//" ] conceptId [ "#" fragment ]
116
+ bundle := slug # no "/", ":", ".", "#" ; workspace bundle name (not the upstream package name)
117
+ conceptId := adapter-owned path within bundle # MAY contain "/"; MUST NOT contain "#"; opaque to the core below the first "//"
118
+ ```
119
+
120
+ Normative §11.1 rules apply verbatim: **all durable state keys store the fully-qualified `bundle//conceptId` form** (the short form is CLI sugar only); **short refs inside bundle content resolve to the containing bundle**; conceptIds are NFC-normalized, `/`-separated, byte-wise case-sensitive, with `case-collision` diagnostics; body refs in prose use only the fully-qualified anchored form. `akm bundle rename` was specced as a first-class rekey transaction (normative §11.5), but the `bundle` command group itself was removed (D5, `0.9.0-decisions.md`) — no `akm bundle` subcommand exists in the shipped CLI. The startup guard that references it (`src/indexer/bundle-identity-guard.ts`) still points at a command that does not exist; see the drift register.
121
+
122
+ ```
123
+ personal//knowledge/http-caching # bundle-qualified; "knowledge" is part of the AKM concept path
124
+ team-catalog//workflows/release # component "workflows"
125
+ project-claude//commands/test # component root is .claude; type=command (derived), NOT in the id
126
+ knowledge/http-caching # default-bundle implied (bundle omitted)
127
+ ```
128
+
129
+ **Component is not a ref segment.** Each bundle has one configured component root, and its adapter derives concept IDs relative to that root. Component is recorded as a **provenance column**, used for filtering/write-policy/adapter-selection, never for identity.
130
+
131
+ **Invariants (normative §11.2):** provider details never appear in refs; `type` never appears in the ref; changing a Git remote/cache/materializer never changes a ref; reclassifying `type` without moving the file never changes the ref; moving/renaming is an explicit state-rekey. The core MUST NOT parse a file path *out of* a concept ID — it stores the ref and looks the path up in the index. `asset-ref.ts` survives as a **pure parser** (bundle-prefix split on `//`, `validateName` traversal/null-byte/drive-letter guards `:121-136`); the closed union `isAssetType` `:109`, `TYPE_ALIASES` `:25`, `type:name` parsing are deleted.
132
+
133
+ ### 1.4 Config shape (normative §10.1) — replaces `stashDir`/`sources[]`/`installed[]`/`wikiName`
134
+
135
+ ```jsonc
136
+ { "defaultBundle": "personal",
137
+ "bundles": {
138
+ "personal": { "path": "~/akm", "components": { "main": { "root": ".", "adapter": "akm", "writable": true } } },
139
+ "team-catalog": { "git": "https://github.com/acme/team-catalog.git", "components": { "main": { "root": ".", "adapter": "okf" } } }
140
+ },
141
+ // "bindings": { ... } — Tier-B target shape; NOT emitted or read in 0.9.0 (normative §18 staging note)
142
+ }
143
+ ```
144
+
145
+ `bindings` are workspace state (normative §18), never written into portable files.
146
+
147
+ ---
148
+
149
+ ## 2. The adapter contract (one interface; optional methods, not a facet hierarchy)
150
+
151
+ Per History §8.3 / the reconciliation, the adapter is **one interface with optional capability methods** — not separate `extends` facets, and not a semantic-view registry. Renderer/action is a **data table** keyed on `type`.
152
+
153
+ ```ts
154
+ export interface BundleAdapter {
155
+ readonly id: string;
156
+ readonly version: string; // feeds incrementality (§4) + fingerprints
157
+ readonly extensions: readonly string[]; // recognized extensions; longest-match stripping + collision priority
158
+
159
+ // REQUIRED — the single-file recognition primitive; replaces the matcher stack
160
+ // (matchers.ts:151-305; file-context.ts:242-265)
161
+ recognize(c: BundleComponent, file: FileContext): IndexDocument | null;
162
+
163
+ // OPTIONAL — full-component scan for non-per-file layouts (website snapshots,
164
+ // llm-wiki multi-file semantics). When absent, the CORE scans:
165
+ // scanComponent(c, adapter) = core walk (git-aware, symlink-safe,
166
+ // adapter-specific directory policy) × adapter.recognize per file.
167
+ // The core walk is ONE implementation carrying the security policy; adapters never
168
+ // reimplement it. An adapter overriding index() MUST keep recognize() coherent
169
+ // (conformance: index() == fold of recognize() over the walk) or declare
170
+ // component-level incrementality (§4).
171
+ index?(inst: BundleInstallation, c: BundleComponent): AsyncIterable<IndexDocument>;
172
+
173
+ // OPTIONAL — item-scoped incrementality (§4). Default: identity (one file = one item).
174
+ affectedItems?(c: BundleComponent, changedPaths: string[]): string[];
175
+
176
+ // REQUIRED — native validation (change-transaction pre-commit + lint --fix); adapter
177
+ // MUST NOT write and MUST NOT read the live filesystem: ctx serves the run snapshot
178
+ // WITH the pending changes overlaid (one core overlay implementation), plus a
179
+ // read-only resolveRef for link/xref existence (normative §12.1). Cross-component
180
+ // ref existence is a CORE base check, not an adapter concern.
181
+ validate(c: BundleComponent, changes: FileChange[], ctx: ValidateContext): Promise<Diagnostic[]>;
182
+
183
+ // OPTIONAL — placement / discovery
184
+ placeNew?(c: BundleComponent, conceptId: string): string; // replaces TYPE_DIRS + resolveAssetPathFromName
185
+ directoryList?(c: BundleComponent): string[]; // owned dirs; feeds git exact-path staging (git-stash.ts:241)
186
+ looksLikeRoot?(root: string): boolean; // install-time probe; ordered per §1.2
187
+
188
+ // OPTIONAL — authoring facet (normative §12.2)
189
+ getAuthoringContext?(c: BundleComponent, target: AuthoringTarget, op: "create"|"update"|"move"|"consolidate"): Promise<AuthoringContext>;
190
+ create?(c: BundleComponent, req: CreateRequest): Promise<FileChange[]>;
191
+
192
+ // OPTIONAL — export facet (normative §12.3): portable runtime exports (workflow/task/env/agent/command/skill/script)
193
+ listExports?(inst: BundleInstallation, c: BundleComponent): AsyncIterable<BundleExport>;
194
+ planBinding?(c: BundleComponent, exp: BundleExport, req: BindingRequest): Promise<BindingPlan>;
195
+
196
+ // OPTIONAL — memory lifecycle facet (normative §12.4, §25)
197
+ listMemories?(inst: BundleInstallation, c: BundleComponent): AsyncIterable<MemoryRecord>;
198
+ renderMemoryPlan?(c: BundleComponent, plan: MemorySemanticPlan): Promise<FileChange[]>;
199
+ validateMemoryPlan?(c: BundleComponent, plan: MemorySemanticPlan, changes: FileChange[]): Promise<Diagnostic[]>;
200
+ }
201
+ ```
202
+
203
+ **Status (verified against `src/core/adapter/bundle-adapter.ts`): the 7
204
+ OPTIONAL authoring/export/memory facet methods above (`getAuthoringContext`,
205
+ `create`, `listExports`, `planBinding`, `listMemories`, `renderMemoryPlan`,
206
+ `validateMemoryPlan`) are not declared on the shipped `BundleAdapter`
207
+ interface.** They are deliberately deferred Tier-B — the referenced types
208
+ (`AuthoringContext`, `CreateRequest`, `BundleExport`, `BindingRequest`,
209
+ `BindingPlan`, `MemoryRecord`, `MemorySemanticPlan`) are shapeless in every
210
+ spec doc, and the code leaves an explicit "FLAGGED for maintainer" note
211
+ rather than committing placeholder `Record<string, unknown>` types. The
212
+ `recognize`/`index?`/`affectedItems?`/`validate`/`placeNew?`/`directoryList?`/
213
+ `looksLikeRoot?` methods above are shipped as declared.
214
+
215
+ **Renderer/action = data table keyed on the open `type`, pointing at a named-function core module** (plan §2.3; normative §15.4). The *mapping* is data; the renderer *implementations* (env-keys-only, secret-name-only, script-exec-hints, markdown view modes, generic) remain a small static core module — env/secret redaction is existing behavior ported as code, keyed on the **adapter**, never on `type`. The table is **typed over the `KNOWN_TYPES` const tuple** so the compiler enforces an entry for every type AKM itself knows (restoring the closed union's exhaustiveness for our own tables), while lookup stays open-string with a generic fallback:
216
+
217
+ ```ts
218
+ export const KNOWN_TYPES = ["knowledge", "workflow", /* … */] as const;
219
+ export type KnownType = (typeof KNOWN_TYPES)[number];
220
+
221
+ export const TYPE_PRESENTATION: Record<KnownType, { renderer: string; action: (r: ItemRef) => string }> = {
222
+ "knowledge": { renderer: "knowledge-md", action: (r) => `akm show ${r} -> read reference material` },
223
+ "workflow": { renderer: "workflow-md", action: buildWorkflowAction },
224
+ // compiler enforces exhaustiveness over KNOWN_TYPES
225
+ };
226
+ export function presentationFor(type: string | undefined) { /* open lookup; unknown type ⇒ generic renderer + `akm show <ref>` — third-party OKF types never dropped */ }
227
+ ```
228
+
229
+ The nine index-time metadata contributors currently registered by `output/renderers.ts` move into the owning adapters' `recognize` — they are index-time concerns and this part of the port is clean.
230
+
231
+ **Forbidden (normative §12.5):** adapters MUST NOT implement search, own proposal/outcome stores, apply writes or Git, **authorize execution**, register arbitrary improve stages, or replace core refs/diagnostics/change envelopes. The authoring/export/memory methods are **targeted ports, not semantic views** (History §8.3).
232
+
233
+ ---
234
+
235
+ ## 3. IndexDocument normalized projection
236
+
237
+ ```ts
238
+ export interface IndexDocument {
239
+ ref: ItemRef; // fully-qualified "<bundle>//<concept-id>" (canonical stored spelling, §1.3)
240
+ bundle: BundleId;
241
+ component: ComponentId; // PROVENANCE from the bundle's single configured component, not a ref segment
242
+ conceptId: string; // adapter-owned path identity; opaque to the core
243
+ path: string; // absolute local path (the read path)
244
+ hash: string;
245
+ adapterId: string;
246
+ type?: string; // open adapter-supplied label; presents/ranks/filters; NEVER executes or identifies
247
+
248
+ name: string; // FTS 10; OKF adapter maps `title`
249
+ description?: string; // FTS 5
250
+ tags?: string[]; // FTS 3
251
+ hints?: string[]; // FTS 2
252
+ content?: string; // FTS 1 (bounded)
253
+
254
+ // FIRST-CLASS query-time signals — read by ranking contributors and result
255
+ // filters at query time, therefore NOT foldable into documentJson (the parity
256
+ // gate fails or the filters silently vanish otherwise). Pinned by a lint.
257
+ aliases?: string[]; // exact-alias 1.5 boost is distinct from the tags signal — NOT folded into tags
258
+ searchHints?: string[];
259
+ quality?: string; // curated boost + proposed-by-default exclusion filter
260
+ confidence?: number;
261
+ beliefState?: string; // + currentBeliefRefs/supersededBy: boosts, ceilings, --belief filter
262
+ currentBeliefRefs?: string[];
263
+ supersededBy?: string;
264
+ scope?: Record<string, string>;
265
+ captureMode?: string;
266
+ lessonStrength?: number;
267
+ pinned?: boolean;
268
+ fileSize?: number; // hit size + estimatedTokens
269
+ derivedFrom?: string; // derived-twin belief inheritance
270
+ updated?: string; // OKF adapter maps `timestamp`
271
+ links?: string[]; // resolved native links = relationships (§9); navigation/lint, NOT graph boost
272
+ documentJson?: unknown; // opaque adapter extras ONLY; not FTS, never parsed by core
273
+ }
274
+ ```
275
+
276
+ Persisted index columns migrate `entry_key/stash_dir/entry_type/entry_json` → `item_ref/bundle_id/component_id/concept_id/adapter_id/type/file_path/content_hash/document_json` plus the pinned signal columns (normative §14.4), keeping the integer row id for FTS/vector joins — and durable behavioral state (utility, usage, feedback) re-keys onto `item_ref` so row-id churn can never destroy it (§4).
277
+
278
+ **FTS5 schema + bm25 weights UNCHANGED and load-bearing** (schema.ts:159; db.ts:1024 `bm25(entries_fts,0,10,5,3,2,1)`). The fold of richer native metadata (examples/usage/intent/xrefs/whenToUse/toc/parameters/content) into `hints`/`content` is a **core-shared helper adapters call** — one fold, not ten — because embedding-input hashes and the frozen retrieval canaries are pinned to that exact surface (search-fields.ts:28-33). The deterministic nDCG/MRR/recall/banned-hit parity gate governs the cutover **and additionally checks filter-behavior parity (proposed/belief/scope result sets) and whyMatched parity**; weights/columns do not move (normative §14.4, D12). The canary re-mint (`akm improve canary --refresh`) is a named migration step.
279
+
280
+ ### 3.4 Known-`type` presentation set (not a closed union)
281
+ No closed set replaces `AkmAssetType`. AKM keeps `TYPE_PRESENTATION` + ranking rules for the `type`s it renders/ranks; any other `type` renders generically and stays searchable (normative §15.1). A lint keeps the *spelling* of the known set consistent across the presentation/ranking tables, the search `--type` filter tokens, and the shipped assets/hints (plan §7.3); it never constrains what `type`s may exist. Body-ref recognition no longer keys on types at all: lint's missing-ref scan, `akm mv` xref rewriting, and search ref-prefix queries anchor on the fully-qualified `bundle//conceptId` grammar (normative §11.1), whose bundle-slug charset (no `:`/`.`/`#`) keeps it lexically distinguishable from URLs in prose.
282
+
283
+ ---
284
+
285
+ ## 4. Indexing loop, incrementality, registry
286
+
287
+ Scan loop (replaces `akmIndex` walk + wiki branch): for each installation → each component → `scanComponent` (core walk × `recognize`, or the adapter's `index()` override) → **drain the full document stream** (any scan error aborts before the first write — this makes last-known-good true by construction, and respects the async-scan/sync-transaction split the current indexer already enforces, indexer.ts:718-723) → one write transaction that **diff-persists**:
288
+
289
+ - upsert by `item_ref` (ON CONFLICT DO UPDATE), preserving `entries.id` so embeddings/FTS/vector joins survive and re-embedding is skipped when `content_hash` is unchanged;
290
+ - delete only rows whose ref disappeared, via the full `deleteRelatedRows` cascade including the usage-event detach-and-relink behavior (never the #624-P1 cascade-wipe);
291
+ - the wipe-set includes `utility_scores_scoped` (fixing the B4 gap) — but utility/usage state re-keys onto `item_ref` in the schema migration so even id churn cannot destroy it;
292
+ - a zero-document scan is a legitimate mass-delete only when a core preflight confirms the component root exists and is readable; otherwise last-known-good rows are preserved with a warning.
293
+
294
+ **NOT truncate-and-rewrite** — truncation would mint new row ids and cascade-destroy embeddings/utility/usage, contradicting the row-id-preservation promise above.
295
+
296
+ Adapters/materializers/registry/network **never run at query time** (normative §14.3, D11). A failed component scan preserves last-known-good rows and keeps other bundles searchable.
297
+
298
+ **Incrementality is ITEM-scoped, not file-scoped**: the mount manifest is `{ scanGeneration, adapterVersion, items: {conceptId → {files: {path → hash,mtimeMs}}} }`. A changed path maps to affected item(s) via `affectedItems` (default: identity); every file of an affected item re-recognizes together, so directory-scoped items (skill = the dir; llm-wiki pages under `schema.md`) stay coherent — a sibling edit updates the item, deleting the primary file deletes the item, deleting a sibling does not. Adapters MAY declare coupling files (wiki `schema.md`) whose change escalates to a component rescan. The FTS dirty-queue (schema.ts:352) and zero-row dir-state classification (dir-staleness.ts) carry forward into this manifest.
299
+
300
+ Registry is a **static frozen `BUILTIN_ADAPTERS`** map (normative §12.6): `website-snapshot`, `agent-skills`, `claude`, `opencode`, `dotenv`, `akm-workflow`, `akm-task`, `llm-wiki`, **`akm`**, `okf`, `generic-files`. One adapter per component root is selected once via the **ordered probe list of §1.2** (deterministic winner, persisted; explicit config wins; `generic-files` is config-only). Probe overlap is intentional for supersets: OKF can recognize conformant AKM Markdown, while the earlier strong AKM probe selects the native adapter. Unknown `type` remains searchable and receives generic behavior; an unknown adapter id skips the component with a warning.
301
+
302
+ ---
303
+
304
+ ## 5. The first-class `okf` adapter
305
+
306
+ Pure OKF: **`type` from frontmatter, identity from path, no directory routing.**
307
+ - **recognize:** any `.md` not named `index.md`/`log.md` → one concept; `type` = frontmatter `type` (default `knowledge` + a `missing-type` info hint if absent). No directory gate (OKF §1).
308
+ - **links:** BOTH legal OKF link forms resolve — `/`-rooted bundle-relative (recommended by OKF §5.1) *and* standard relative paths (OKF §5.2). Links resolve against the component root to form the stored bundle-relative conceptId in `links`.
309
+ - **conceptId:** path within the bundle − `.md` (markdownSpec.toCanonicalName, asset-spec.ts:91-95).
310
+ - **authoring:** consumer-only in 0.9.0. AKM-specific write commands fail before touching an OKF target.
311
+ - **directoryList:** the component root (OKF concepts live anywhere).
312
+ - **renderer/action:** generic Markdown content plus heading-fragment selection for every type.
313
+ - **validate (LENIENT):** unknown frontmatter and absent optional timestamp never fail; `missing-ref` on OKF links is a **warning** (consumers MUST tolerate broken links); `missing-type` is info.
314
+ - **Reserved:** `index.md`/`log.md` recognized, not indexed as concepts; root `index.md` may carry `okf_version`; `akm index` never regenerates `index.md` (normative §14.6, D14).
315
+
316
+ ---
317
+
318
+ ## 5.1 The two markdown-family adapters — `akm` (current behavior) vs `okf` (frontmatter `type`) — BINDING, NOT OPEN TO RE-INTERPRETATION
319
+
320
+ `akm` and `okf` both index markdown-with-YAML-frontmatter, but they classify
321
+ `type` by **different, deliberately fixed** mechanisms. This is a binding 0.9.0
322
+ decision. An implementation MUST NOT collapse one into the other, swap their
323
+ recognition strategies, "modernize" `akm` onto frontmatter, or split `akm` into
324
+ per-`type` adapters. Any future proposal to do so is a **spec change**, not an
325
+ implementation detail, and requires amending this section first.
326
+
327
+ - **`okf` — `type` from frontmatter (OKF §1.2), NO directory gate.** The
328
+ first-class OKF adapter (§5). `recognize` reads the OKF `type` field from
329
+ each concept's YAML frontmatter; the directory a file lives in **never**
330
+ determines its `type`. `type` absent ⇒ `knowledge` (+ `missing-type` info).
331
+ Used for configured or detected OKF bundles and third-party OKF trees.
332
+
333
+ - **`akm` — CURRENT FUNCTIONALITY PRESERVED (the existing matcher stack); a
334
+ behavior-preserving port.** The AKM workspace's own adapter. Its
335
+ `recognize` / `placeNew` / `directoryList` / `validate` / presentation
336
+ reproduce **today's** classification VERBATIM — the `runMatchers` →
337
+ `classifyByExtension` / `classifyByDirectory` / `classifyByParentDirHint` /
338
+ `classifyBySmartMd` / `classifyByWiki` / `classifyByWorkflowProgram` stack and
339
+ the per-`type` placement / lint / render logic (`file-context.ts:242-265`,
340
+ `matchers.ts:151-305`, `asset-spec.ts`, the per-type linters/renderers). The
341
+ byte-for-byte recognition / placement / renderer / lint goldens (Chunk 0b) are
342
+ its conformance gate. The `akm` adapter:
343
+ - is **NOT** re-derived to a frontmatter-`type` model;
344
+ - emits matching `type` frontmatter on newly authored Markdown so the same
345
+ files remain conformant when consumed through the OKF baseline; the native
346
+ matcher remains authoritative and legacy files without `type` stay readable;
347
+ - is **NOT** split into one-adapter-per-`type` — per §6 / §0.2 the 14 AKM
348
+ formats are `type` **values** the single `akm` adapter emits, never adapters
349
+ (per-`type` renderer/validator/placement differences are data/functions keyed
350
+ on the open `type`, exactly as §2/§6 specify);
351
+ - introduces **NO** new positional / directory-name heuristics of its own — it
352
+ relocates the *existing* classification behind the `BundleAdapter` interface,
353
+ unchanged in behavior;
354
+ - emits the **qualified conceptId spelling** (ref-grammar decision D-R2,
355
+ `akm-0.9.0-ref-grammar-decision.md`): conceptId = the placement bundle-subdir
356
+ followed by the per-type canonical name — `knowledge/http-caching`,
357
+ `skills/code-review`, `scripts/db/migrate/run.sh` — the same spelling
358
+ `placeNew` consumes and this spec's §1.3 examples show. Markdown files strip
359
+ `.md`; directory-items (skill) and non-markdown extensions follow the
360
+ adapter's own path definition (normative §11.2 note). `entry.name`/FTS keep
361
+ the bare canonical name — identity ≠ search text.
362
+
363
+ **Reserved filenames (BINDING — decision D-R6).** Upstream OKF v0.1 §3.1
364
+ reserves `index.md` (directory listing, §6) and `log.md` (update history, §7) at
365
+ every level of an OKF bundle. The `okf` adapter must not emit concepts or accept
366
+ concept writes at those paths. The `akm` and `llm-wiki` adapters independently
367
+ reserve the same names as part of their own format contracts. Other adapters
368
+ own their reserved-name policy; OKF does not impose it on foreign formats.
369
+
370
+ **Why the two differ.** AKM classification is derived from directory, filename,
371
+ extension, or content probes, not trusted from frontmatter. AKM-authored
372
+ Markdown nevertheless carries the matching `type` field for OKF portability.
373
+ The field makes the Markdown concept interoperable; it does not change the
374
+ bundle's selected adapter or bypass AKM's stronger native behavior.
375
+
376
+ ---
377
+
378
+ ## 6. The `type` values AKM recognizes
379
+
380
+ These are **`type` values, not adapters**. The `okf` adapter reads them from
381
+ OKF frontmatter; the `akm` and other native adapters derive them according to
382
+ their own format rules. Presentation is keyed on `type` via
383
+ `TYPE_PRESENTATION`.
384
+
385
+ | `type` | OKF representation | native-derivation convention | type-specific validation |
386
+ |---|---|---|---|
387
+ | knowledge | yes | default when `type` absent | base only |
388
+ | command | yes | `.md` under `commands/` + `$ARGUMENTS`/`agent`-fm probe | `missing-name-or-type`; type∈{command} |
389
+ | agent | yes | `.md` under `agents/` + `tools`/`model` probe | `missing-name-or-type`; type∈{agent} |
390
+ | skill | yes | `SKILL.md`; item = the dir (item-scoped incrementality, §4) | `missing-skill-md` **+ NEW** Agent Skills contract — hard: name 1–64 (`^[a-z0-9]+(-[a-z0-9]+)*$`, NFKC, == parent dir name), description 1–1024, `compatibility` ≤500, `metadata` string→string map, YAML-mapping frontmatter; soft (warnings): body <500 lines / instructions <5k tokens, lowercase `skill.md` filename, `allowed-tools` portability. Strictness is per-adapter: `agent-skills` errors on unknown frontmatter (skills-ref behavior); `claude` allows Claude Code's documented extension fields |
391
+ | memory | yes | `.md` under `memories/` | `orphaned-stub` (delete fix); memory-lifecycle (§ normative 25) |
392
+ | lesson/fact/session/instruction | yes | `lessons/`/`facts/`/`sessions/`/`CLAUDE.md`·`AGENTS.md` | base (+`missing-category` for fact) |
393
+ | workflow | ext | unified `.md` workflow; orchestration in frontmatter, prose in the body | `placeholder-stub`, `invalid-workflow-structure` |
394
+ | task | AKM ext | `.yml` under `tasks/` (not OKF markdown) | `invalid-task-yaml`: `version: 2`+schedule+one target (`enabled` optional, defaults true, boolean when present) |
395
+ | env | AKM ext | `.env`/`*.env` under `env/` — **key NAMES only, values never indexed** | dangerous-key warn scan |
396
+ | secret | AKM ext | any file under `secrets/` minus `.lock`/`.sensitive` — **filename only** | dangerous-key scan; `classifyBySmartMd` bails on `secrets/` |
397
+ | script | AKM ext | 16 `SCRIPT_EXTENSIONS`; conceptId keeps extension | none |
398
+ | website | derived | website crawl snapshot (§7) | base (read-only) |
399
+ | wiki page | **LLM Wiki adapter** | `.md` under an LLM Wiki root (§7) — its own `type` values | native wiki validation (§7) |
400
+
401
+ **6 renderer mappings** (script/skill/command/agent/knowledge/memory) live only in `TYPE_PRESENTATION` now (they carried no `rendererName` on their old spec, plan §2.3).
402
+
403
+ ---
404
+
405
+ ## 7. The adapter set (format families)
406
+
407
+ An **adapter is a format family**, one per component root, emitting one or more
408
+ open `type`s. Markdown belongs to OKF only when the selected adapter is `okf`;
409
+ other Markdown formats retain their native semantics. A **"tool directory"**
410
+ (`.claude`/`.opencode`) is interpreted by its own adapter; no adapter competes
411
+ per-file.
412
+
413
+ | adapter | format / root | types | writable | notes |
414
+ |---|---|---|---|---|
415
+ | **okf** (§5) | OKF markdown; `type` from frontmatter | any OKF type | yes | first-class support for third-party OKF bundles |
416
+ | **akm** (**§5.1**, BINDING) | AKM workspace — **maintains current recognition/placement/lint/render functionality via the existing matcher stack** (behavior-preserving port; **NOT** frontmatter-`type`, **NOT** per-`type` adapters). AKM Markdown + AKM extensions (workflow/task/env/secret/script) under AKM subdirs | full §6 profile | yes (markdown/workflow/task); env/secret metadata-only | AKM's own workspace bundle; recognition contract fixed in **§5.1** |
417
+ | **llm-wiki** (**restored, DEV-7**) | LLM Wiki: `schema.md`, `index.md`, `log.md`, `raw/`, `pages/`, xrefs, citations, native ingest | wiki page kinds (adapter-owned) | yes | owns its native multi-file semantics + authoring/validation; `wiki` asset-*type* is gone but the **adapter** is first-class (normative §13.3) |
418
+ | **claude** | `.claude` tool dir — translator; derives `type` from dir | command, agent, skill, instruction | yes | AKM workspace layout **is** `.claude` minus the prefix |
419
+ | **opencode** | `.opencode` tool dir — translator (NEW) | command, agent, **skill**, instruction | yes | `AGENTS.md`=instruction; `config.json` not indexed; OpenCode has first-class skills (`.opencode/skills/<name>/SKILL.md`) and reads `.claude/skills/` — plural `commands/`/`agents/` dirs |
420
+ | **agent-skills** | standalone `SKILL.md` packages — translator | skill | yes | SKILL.md codec shared with claude as functions |
421
+ | **akm-workflow / akm-task / dotenv** | native workflow / task-YAML / dotenv formats | workflow / task / env | yes / yes / metadata-only | own executable/sensitive schemas; export facet (§ normative 18) |
422
+ | **website-snapshot** | crawl snapshot (website-ingest.ts:180) — read-only | website | **no** (Mode A) | export (Mode B) routes `content` through the destination adapter + FileChange txn; all SSRF/redirect/byte/depth/wall-clock/stale protections preserved |
423
+ | **generic-files** | any leftover file | document/script/file | yes | explicit-config ONLY (never auto-selected, §1.2) — a user who mounts a root with it indexes what they pointed it at, deliberately (the v0.2 sensitive-content refusal was withdrawn, deviation §4.3c) |
424
+
425
+ Instruction files (`CLAUDE.md`/`AGENTS.md`) are NEW; tool config files are runtime-config, never indexed. `sources/wiki-fetchers/`→`snapshot-fetchers/`; the one-element youtube registry inlines.
426
+
427
+ ---
428
+
429
+ ## 8. Single-component ownership
430
+
431
+ *(Retired by the v0.4 owner ruling.)* A bundle has one component root and one adapter. That adapter may emit every native `type` its format contains: for example, the `claude` adapter emits command/agent/skill/instruction from one `.claude` root rather than creating sub-components. If a package needs separately governed OKF, workflow, wiki, or tool roots, each root is registered as its own bundle.
432
+
433
+ ```
434
+ bundle "team-catalog" { root: ".", adapter: "okf" }
435
+ bundle "release-automation" { root: "workflows", adapter: "akm-workflow" }
436
+ bundle "team-wiki" { root: "wiki", adapter: "llm-wiki" }
437
+ bundle "project-claude" { root: ".claude", adapter: "claude" }
438
+ ```
439
+
440
+ There is no nested-root subtraction or cross-component collision machinery. The selected adapter owns traversal policy and claims or abstains on files throughout its one component root. Shared native contracts such as `SKILL.md` are implemented by shared functions used by the relevant adapters, not nested adapter dispatch.
441
+
442
+ ---
443
+
444
+ ## 9. Relationships: OKF links (deterministic; replaces LLM graph extraction for OKF content)
445
+
446
+ OKF bundle-relative links (`[x](/tables/customers.md)`, `[y](./other.md)` — both legal forms, §5) **are relationships** (OKF §5.3). The `okf`/`llm-wiki` adapters resolve them at `index` time into `IndexDocument.links` (target concept IDs, component-root-resolved then bundle-prefixed, §5). They persist to a dedicated `item_links(src_ref, dst_concept_id)` table with three consumers: the L1 overview (progressive disclosure), `related`-item output, and the base-linter broken-link check. Broken links are tolerated (warning), so relationship extraction never blocks indexing.
447
+
448
+ **Links do NOT feed `computeGraphBoost`.** The existing graph signal is entity-lexical (query tokens matched against extracted entity strings expanded over a confidence-weighted entity adjacency, graph-boost.ts:212-301); doc-level link edges carry no entity strings and cannot substitute for it. LLM graph extraction and its ranking boost remain a separate, measured concern resolved by the 0.9.1 ablation pass (plan §13.2, normative §26.3) — native links are navigation/lint/overview data, not a ranking contributor. If a native link-boost is ever wanted, it is a new contributor with its own nDCG gate.
449
+
450
+ ---
451
+
452
+ ## 10. Installation and activation (Tier A in 0.9.0 — DEV-3 revised; record/digests/CLI are Tier B)
453
+
454
+ **Tier A in 0.9.0 (DEV-3 as revised 2026-07-14; normative §18 staging note).** **Installation is not activation** — already true in code; 0.9.0 consolidates the existing scattered enforcement (the `registryId` block/warn, the add-time dangerous-key scan, task `enabled:` state, `writable`) into one workspace activation-policy point, verified by port-preservation tests. **No new trust/approval machinery ships** (deviation §4.3c). env/secret handling is unchanged (whole-file assets in bundles, resolved from the bundle). Everything else in this section is the **Tier-B target shape, deferred indefinitely**: the durable `Binding` record in `state.db` (export ref + digest, engine/harness, parameters, env/secret *references* — never resolved values, normative §28.4 — tool/fs policy, enabled state, scheduler identity), the `discover → install → index → bind → enable` lifecycle's explicit bind step, digest-pinned updates, and the bind CLI. Export kinds (`workflow`/`task`/`environment`/`agent`/`command`/`skill`/`script`) remain activation contracts, not storage types or identity; runtime handlers never infer authority from a `type` or frontmatter field (normative §8.4). Accepted Tier-A residual: refs into installed sources re-read current disk content per invocation (crontab semantics; plan Chunk 6.5). Target-state rules: normative §18–§22.
455
+
456
+ ---
457
+
458
+ ## 11. Improve — three semantic operations (IN SCOPE — DEV-5)
459
+
460
+ Per **History D20** and normative **§24**, restored for 0.9.0 (reversing the two-verb reduction):
461
+
462
+ ```
463
+ revise improve an existing durable item
464
+ learn create a new durable item from evidence
465
+ consolidate bound a memory tier while preserving knowledge (the only op that may retire source content)
466
+ ```
467
+
468
+ Evidence-driven (corrective evidence required for unattended semantic change; importance only orders), one stable snapshot per run, input fingerprints, and the three-level verification ladder (native safety / objective comparison / field outcome). Model confidence is diagnostic, never authority. Full stages, corrective-evidence list, verification ladder, change classes, process mapping, and the "must earn their way back" list: normative §24 + History §9. The plan's improve *decomposition* (the god-function → passes refactor, deletions of unproven lanes) stands; the *verb count* is three, not two.
469
+
470
+ ---
471
+
472
+ ## 12. Memory (DEFERRED — DEV-4 revised 2026-07-14; 0.9.0 = consolidate decomposition only)
473
+
474
+ **0.9.0 ships only the consolidate.ts decomposition with existing behavior preserved exactly** (plan §6, deviation §4.3b): the current merge/delete/promote/contradict ops through `archiveMemory`, journals, LOOK/CHANGE separation, hot-capture guard, contradiction preserve-and-qualify, proposal-gating — all as today, verified by goldens. The optional memory methods on `BundleAdapter` (§2) are the **Tier-B target shape** and are not implemented by any 0.9.0 adapter.
475
+
476
+ The lifecycle state model — operational states, water-marks/backpressure, claim coverage, sandbox evaluation, the content-addressed archive, purge, overlay, two-phase — is **target-state feature work staged behind the claim extractor + benchmark** (normative §25 release-staging note; History D21–D24 record the target design). It gets its own design pass when its prerequisite exists.
477
+
478
+ ---
479
+
480
+ ## 13. Grounding index (what each element replaces)
481
+
482
+ | New | Replaces | file:line |
483
+ |---|---|---|
484
+ | native bundle adapters, including `okf` and `llm-wiki` | `AssetSpec` + `stashDir` + wiki-as-type | asset-spec.ts; config-types.ts:99 |
485
+ | ref `[<bundle>//]<concept-id>` (path identity) | `AssetRef{type,name,origin}` | asset-ref.ts:11-116 |
486
+ | open adapter-supplied `type` | closed `AkmAssetType` + `entry_type` | common.ts:29-88; asset-ref.ts:109 |
487
+ | normalized `IndexDocument` projection | `StashEntry` | metadata.ts:60-189 |
488
+ | adapter `recognize`/`index` + optional methods | `runMatchers`/`classifyBy*`/walker | file-context.ts:242-265; matchers.ts:151-305; walker.ts:73 |
489
+ | `placeNew`/`directoryList` | `TYPE_DIRS`/`resolveAssetPathFromName` | asset-spec.ts:140-226; path-resolver.ts:27-38 |
490
+ | `TYPE_PRESENTATION` (open `type`) | `TYPE_TO_RENDERER`/`ACTION_BUILDERS` + spec split-brain | asset-registry.ts:21-58 |
491
+ | Tier-A activation-policy point (install≠activate consolidation; `Binding` record is Tier B) | scattered existing enforcement: `registryId` block/warn, dangerous-key scan, task `enabled:`, `writable` | env-binding.ts:110-121; add-cli.ts:74-215; tasks.ts; search-source.ts:35 |
492
+ | three-verb improve + memory lifecycle | improve god-modules + consolidate.ts | commands/improve/* |
493
+ | OKF links → `links` | LLM graph extraction | indexer/graph/* |
494
+
495
+ ---
496
+
497
+ ## References / Citations
498
+
499
+ - **OKF v0.1 → v0.2** — [`GoogleCloudPlatform/knowledge-catalog` `okf/SPEC.md`](https://github.com/GoogleCloudPlatform/knowledge-catalog/blob/main/okf/SPEC.md); [Google Cloud announcement (2026-06-12)](https://cloud.google.com/blog/products/data-analytics/how-the-open-knowledge-format-can-improve-data-sharing/). Concept identity = path − `.md`; required open `type`; recommended `title`/`description`/`resource`/`tags`; reserved `index.md`/`log.md` at every level (both optional); TWO link forms (`/`-rooted and relative, §5); `okf_version` optional, root-index only (even Google's reference bundles omit it — probes must not require it); consumers MUST NOT reject on unknown types/fields/broken links (the `okf` adapter's leniency is a conformance requirement, not a courtesy). **v0.2 (#730)** adds the trust/provenance family (`generated`/`verified`/`sources`), the lifecycle family (`status`/`stale_after`), and the actor convention (`<producer>/<version>` / `human:<id>` / `process:<id>`); `timestamp` is superseded by `generated.at` but remains a valid fallback reading — see §0.1 above for the full mapping and the [conformance runbook](../testing/okf-v0.2-conformance-runbook.md) for the pinned upstream commit (`KC_REF`). Caveats absorbed into this spec: OKF is a young single-vendor **Draft** with no governance body — AKM **vendors a frozen copy of the spec rules it implements** and treats `okf_version` handling as best-effort; manifests, versioning, dependencies, integrity, and components are AKM extensions layered around OKF, not OKF features.
500
+ - **Agent Skills** — the `SKILL.md` contract: hard limits name 1–64 (charset `^[a-z0-9]+(-[a-z0-9]+)*$`, must equal the parent dir name) and description 1–1024; `compatibility` ≤500; body <500 lines is *guidance*, not a rule; progressive disclosure = metadata / instructions / resources (akm's L0/L1/L2 retrieval levels are akm-internal naming, not the upstream terms). Spec: [agentskills.io/specification](https://agentskills.io/specification) (Anthropic-originated open standard; **unversioned, no tags/changelog — pin behavior by vendoring the `skills-ref` validator rules**, currently 0.1.0); Anthropic docs now live at platform.claude.com (API) and code.claude.com (Claude Code). Claude Code *extends* the standard (~13 extra frontmatter fields, all-optional metadata), so `.claude/skills` compatibility is one-way: validation strictness is per-adapter (§6).
501
+ - **AKM normative** — `akm-format-neutral-bundle-workspace-spec.md` (bindings §18, improve §24, memory §25), `akm-architecture-decision-history.md` (D1–D26), and the `akm-0.9.0-*` companions in this directory; `file:line` refs are to the current tree.