akm-cli 0.9.29 → 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 (162) hide show
  1. package/CHANGELOG.md +41 -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/commands/sources/plugin-upgrade.js +46 -23
  6. package/dist/core/file-lock.js +10 -1
  7. package/dist/llm/client.js +33 -3
  8. package/dist/scripts/akm-migrate-node.js +5 -1
  9. package/dist/scripts/akm-migrate.js +5 -1
  10. package/docs/README.md +42 -41
  11. package/docs/agents/README.md +15 -0
  12. package/docs/agents/agent-install.md +14 -0
  13. package/docs/architecture/README.md +67 -0
  14. package/docs/architecture/adapters.md +272 -0
  15. package/docs/architecture/akm-architecture-decision-history.md +2055 -0
  16. package/docs/architecture/akm-core-principles.md +126 -0
  17. package/docs/architecture/architecture.md +579 -0
  18. package/docs/architecture/comparisons/claude-code-vs-akm-workflows-full.md +550 -0
  19. package/docs/architecture/decisions/0001-no-interpolation-attached-structured-context.md +72 -0
  20. package/docs/architecture/decisions/0002-unit-reuse-and-input-hash-scope.md +142 -0
  21. package/docs/architecture/decisions/0003-child-env-allowlist-and-provenance.md +189 -0
  22. package/docs/architecture/decisions/0004-task-input-contract-and-flag-coercion.md +97 -0
  23. package/docs/architecture/decisions/0005-task-result-vocabulary-and-legacy-read-mapping.md +108 -0
  24. package/docs/architecture/decisions/0006-task-source-version-routing.md +124 -0
  25. package/docs/architecture/decisions/0007-workflow-composition-bounds.md +83 -0
  26. package/docs/architecture/decisions/0008-task-binding-normalization.md +88 -0
  27. package/docs/architecture/decisions/0009-child-run-publication-column-parity.md +80 -0
  28. package/docs/architecture/decisions/0010-driver-protocol-cut.md +36 -0
  29. package/docs/architecture/decisions/0011-engine-run-loop-invariants.md +125 -0
  30. package/docs/architecture/decisions/README.md +62 -0
  31. package/docs/architecture/improvement.md +440 -0
  32. package/docs/architecture/internals/classification.md +154 -0
  33. package/docs/architecture/internals/fresh-host-rebuild-runbook.md +40 -0
  34. package/docs/architecture/internals/functional-contract-patterns.md +340 -0
  35. package/docs/architecture/internals/health-advisories.md +110 -0
  36. package/docs/architecture/internals/improve-workflow.md +713 -0
  37. package/docs/architecture/internals/indexing.md +498 -0
  38. package/docs/architecture/internals/registry-network-boundary.md +57 -0
  39. package/docs/architecture/internals/search.md +249 -0
  40. package/docs/architecture/internals/storage-locations.md +943 -0
  41. package/docs/architecture/persisted-data-compat.md +59 -0
  42. package/docs/architecture/reviews/env-secret-access.md +319 -0
  43. package/docs/architecture/runtime-boundary-design.md +153 -0
  44. package/docs/architecture/specs/0.9.0-close-out-plan.md +361 -0
  45. package/docs/architecture/specs/0.9.0-decisions.md +528 -0
  46. package/docs/architecture/specs/0.9.0-docs-code-drift-register.md +745 -0
  47. package/docs/architecture/specs/0.9.0-open-items-register.md +135 -0
  48. package/docs/architecture/specs/0.9.0-public-api-issue-backlog.md +740 -0
  49. package/docs/architecture/specs/0.9.0-release-surface-review.md +636 -0
  50. package/docs/architecture/specs/agent-command-engine-model-design.md +513 -0
  51. package/docs/architecture/specs/akm-0.9.0-bundle-adapter-spec.md +501 -0
  52. package/docs/architecture/specs/akm-0.9.0-ref-grammar-decision.md +291 -0
  53. package/docs/architecture/specs/akm-format-neutral-bundle-workspace-spec.md +2059 -0
  54. package/docs/architecture/specs/di-seams-plan.md +539 -0
  55. package/docs/architecture/specs/driver-protocol-keep-or-cut.md +275 -0
  56. package/docs/architecture/specs/fact-asset-type.md +142 -0
  57. package/docs/architecture/specs/improve-collapse-churn-detector-design.md +634 -0
  58. package/docs/architecture/specs/okf-support.md +148 -0
  59. package/docs/architecture/specs/ref.md +329 -0
  60. package/docs/architecture/specs/reviews/task-workflow-unification/README.md +72 -0
  61. package/docs/architecture/specs/reviews/task-workflow-unification/findings-consolidated.md +152 -0
  62. package/docs/architecture/specs/reviews/task-workflow-unification/library-eval-alternatives.md +352 -0
  63. package/docs/architecture/specs/reviews/task-workflow-unification/library-eval-bunqueue.md +300 -0
  64. package/docs/architecture/specs/reviews/task-workflow-unification/library-eval-openworkflow.md +402 -0
  65. package/docs/architecture/specs/reviews/task-workflow-unification/opus-review-1.md +758 -0
  66. package/docs/architecture/specs/reviews/task-workflow-unification/opus-review-2.md +645 -0
  67. package/docs/architecture/specs/reviews/task-workflow-unification/opus-review-3.md +602 -0
  68. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-adversarial.md +27 -0
  69. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-architecture.md +27 -0
  70. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-coverage.md +74 -0
  71. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-security.md +15 -0
  72. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r2-adversarial.md +132 -0
  73. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r2-verification.md +147 -0
  74. package/docs/architecture/specs/stash-conventions-code-spec.md +275 -0
  75. package/docs/architecture/specs/stash-organization-conventions.md +377 -0
  76. package/docs/architecture/specs/task-workflow-format-unification.md +721 -0
  77. package/docs/architecture/specs/workflow-engine-buy-vs-build.md +231 -0
  78. package/docs/architecture/specs/workflow-format-unification.md +437 -0
  79. package/docs/architecture/testing/manual-testing-checklist.md +3420 -0
  80. package/docs/architecture/testing/okf-v0.2-conformance-runbook.md +924 -0
  81. package/docs/architecture/testing/task-workflow-manual-tests.md +1817 -0
  82. package/docs/architecture/testing/testing-workflow.md +446 -0
  83. package/docs/architecture/workflow-engine.md +274 -0
  84. package/docs/guides/README.md +33 -0
  85. package/docs/guides/author-bundles.md +310 -0
  86. package/docs/guides/author-workflows.md +520 -0
  87. package/docs/guides/bundles.md +321 -0
  88. package/docs/guides/capture-knowledge.md +136 -0
  89. package/docs/guides/claude-code-vs-akm-workflows.md +30 -0
  90. package/docs/guides/concepts.md +93 -0
  91. package/docs/guides/discover-and-load.md +158 -0
  92. package/docs/guides/getting-started.md +240 -0
  93. package/docs/guides/improve-the-library.md +246 -0
  94. package/docs/guides/knowledge-management.md +18 -0
  95. package/docs/guides/recipes/headless-install.md +97 -0
  96. package/docs/guides/recipes/website-source.md +28 -0
  97. package/docs/guides/run-workflows.md +279 -0
  98. package/docs/guides/scheduling.md +123 -0
  99. package/docs/guides/use-with-any-agent.md +129 -0
  100. package/docs/guides/wikis.md +81 -0
  101. package/docs/maintainers/README.md +19 -0
  102. package/docs/maintainers/curate-workmap.md +336 -0
  103. package/docs/maintainers/eval.md +3 -0
  104. package/docs/maintainers/local-development.md +108 -0
  105. package/docs/maintainers/release-checklist.md +103 -0
  106. package/docs/migration/README.md +2 -2
  107. package/docs/migration/release-notes/0.0.13.md +1 -1
  108. package/docs/migration/release-notes/0.1.0.md +1 -1
  109. package/docs/migration/release-notes/0.2.0.md +1 -1
  110. package/docs/migration/release-notes/0.3.0.md +1 -1
  111. package/docs/migration/release-notes/0.5.0.md +1 -1
  112. package/docs/migration/release-notes/0.6.0.md +1 -1
  113. package/docs/migration/release-notes/0.7.0.md +1 -1
  114. package/docs/migration/release-notes/0.7.3.md +2 -2
  115. package/docs/migration/release-notes/0.7.4.md +1 -1
  116. package/docs/migration/release-notes/0.7.5.md +1 -1
  117. package/docs/migration/release-notes/0.8.0.md +1 -1
  118. package/docs/migration/release-notes/0.9.0.md +1 -1
  119. package/docs/migration/release-notes/0.9.14.md +1 -1
  120. package/docs/migration/release-notes/0.9.15.md +1 -1
  121. package/docs/migration/release-notes/0.9.16.md +1 -1
  122. package/docs/migration/release-notes/0.9.17.md +1 -1
  123. package/docs/migration/release-notes/0.9.19.md +1 -1
  124. package/docs/migration/release-notes/0.9.2.md +1 -1
  125. package/docs/migration/release-notes/README.md +27 -31
  126. package/docs/migration/v0.5-to-v0.6.md +759 -0
  127. package/docs/migration/v0.8-to-v0.9.md +1 -1
  128. package/docs/plans/0.9.2-agent-command-workflow-plan.md +423 -0
  129. package/docs/posts/README.md +30 -0
  130. package/docs/posts/akm-command-tour.md +495 -0
  131. package/docs/posts/akm-logo-sized.webp +0 -0
  132. package/docs/posts/belief-aware-memory-12.md +139 -0
  133. package/docs/posts/config-v2-lessons-16.md +191 -0
  134. package/docs/posts/improve-loop-autonomous-10.md +225 -0
  135. package/docs/posts/improve-pipeline-debugging-0803.md +179 -0
  136. package/docs/posts/intro-part-01.md +76 -0
  137. package/docs/posts/intro-part-02.md +221 -0
  138. package/docs/posts/intro-part-03.md +190 -0
  139. package/docs/posts/intro-part-04.md +221 -0
  140. package/docs/posts/llm-mode-reflect-13.md +166 -0
  141. package/docs/posts/openpalm-built-on-akm.md +86 -0
  142. package/docs/posts/progressive-disclosure-06.md +129 -0
  143. package/docs/posts/proposal-safety-net-15.md +112 -0
  144. package/docs/posts/release-0.5.0.md +247 -0
  145. package/docs/posts/release-0.6.0.md +117 -0
  146. package/docs/posts/release-0.7.0.md +159 -0
  147. package/docs/posts/release-0.8.0.md +332 -0
  148. package/docs/posts/scattered-skills-05.md +100 -0
  149. package/docs/posts/task-assets-persistent-workflows-11.md +222 -0
  150. package/docs/posts/team-skills-07.md +198 -0
  151. package/docs/posts/wiki-agent-knowledge-08.md +223 -0
  152. package/docs/posts/workflows-vaults-09.md +321 -0
  153. package/docs/product-surface.md +54 -0
  154. package/docs/reference/README.md +1 -2
  155. package/docs/reference/asset-types.md +168 -0
  156. package/docs/reference/cli.md +5 -6
  157. package/docs/reference/env-and-secrets.md +126 -0
  158. package/docs/reference/memory.md +124 -0
  159. package/docs/reference/refs.md +156 -0
  160. package/docs/reference/registry.md +489 -0
  161. package/docs/reference/website-sources.md +141 -0
  162. package/package.json +12 -15
@@ -0,0 +1,291 @@
1
+ # AKM 0.9.0 — Ref-grammar decision + revised Chunk-5 flip plan
2
+
3
+ **Status:** DECIDED — binding for the Chunk-5 flip and Chunk 8. Amends the adapter spec
4
+ (`akm-0.9.0-bundle-adapter-spec.md` §1.3/§5.1) and the normative spec
5
+ (`akm-format-neutral-bundle-workspace-spec.md` §11.1) only where §"Spec amendments" below says so;
6
+ everything else in both documents stands.
7
+ **Date:** 2026-07-18. **Context:** PR #719, branch `claude/akm-architecture-refactor-fubvd7`
8
+ (Chunk 5 ~70% banked; the flip stalled six times on the test-codemod problem).
9
+ **Question:** one canonical ref grammar (`[bundle//]conceptId`) vs. multiple ref formats — and,
10
+ downstream of that, how the deferred Chunk-5 flip + script-only test codemod actually executes.
11
+
12
+ ---
13
+
14
+ ## 1. The decision in one paragraph
15
+
16
+ **Keep a single canonical grammar and a single stored spelling (Option A's end-state), and take
17
+ the workable half of Option B as the abstraction: refs are `parse → resolve → serialize`, and the
18
+ short (bundle-omitted) form is a first-class *accepted input* at every boundary — CLI, repository
19
+ lookups, and tests — resolved by a deterministic, behavior-preserving rule.** There is no second
20
+ grammar: the short form is the same production with the optional prefix omitted, not a different
21
+ format. `type:name` is not an accepted form anywhere after the flip (it survives only inside the
22
+ frozen `scripts/akm-migrate/migrate/legacy/` copy). This dissolves the codemod problem — the measured blocker was
23
+ never the grammar, it was the assumption that tests must *spell the bundle*; they don't, because
24
+ resolution supplies it, exactly the way origin-less `type:name` refs already work today.
25
+
26
+ Full Option B (a plural-format ref abstraction with a `type:name` compatibility spelling) is
27
+ **rejected**: normative §11.4 prohibits a permanent dual-parser, §11.2 prohibits `type` in refs,
28
+ and the measured test suite shows the compatibility form buys nothing — only ~225 of the ~4,700
29
+ ref literals are origin-qualified; the rest are already short refs relying on resolution.
30
+
31
+ ---
32
+
33
+ ## 2. Sub-decisions (each binding)
34
+
35
+ ### D-R1 — Grammar model: one grammar, resolver-first abstraction
36
+
37
+ ```
38
+ ref := [ <bundle> "//" ] <concept-id> [ "#" <fragment> ] (unchanged, §11.1)
39
+ ```
40
+
41
+ The ref abstraction is three functions with a type-level distinction between *maybe-short* and
42
+ *resolved*:
43
+
44
+ - **parse** — pure syntax, no I/O, no workspace knowledge. Already built:
45
+ `parseBundleRef` / `BUNDLE_REF_RE` (`src/core/asset/asset-ref.ts:258,205`). Returns
46
+ `BundleRef { bundle?: string; conceptId; fragment? }`.
47
+ - **resolve** — `resolveRef(input: string | BundleRef, ctx: RefContext): ResolvedRef` where
48
+ `ResolvedRef` is `BundleRef & { bundle: string }` (branded or structurally narrowed). `ctx`
49
+ carries the resolution surface (see D-R4). This is the one new module the flip adds (small,
50
+ pure over an injected bundle list + an index lookup callback).
51
+ - **serialize** — `bundleRefToString` (`asset-ref.ts:248`), unchanged. Serializing a
52
+ `ResolvedRef` always emits the fully-qualified form.
53
+
54
+ **The core rule:** *only `ResolvedRef` crosses a storage boundary; only unresolved input crosses
55
+ an input boundary.* Repositories, state writers, and durable keys take/emit fully-qualified refs
56
+ exclusively; parsers and CLI/API entrypoints are the only place short forms exist. This is
57
+ §11.1's "short form is input sugar" made structural instead of conventional.
58
+
59
+ ### D-R2 — conceptId spelling: the qualified `<stash-subdir>/<canonical-name>` form
60
+
61
+ This resolves the open recognize/placeNew spelling split documented at
62
+ `src/core/adapter/adapters/akm-adapter.ts:397-403` ("owned downstream (Chunk 3/5)" — i.e., here).
63
+
64
+ The `akm` adapter's conceptId is the **qualified form**: the placement bundle-subdir followed by
65
+ the per-type canonical name — `knowledge/http-caching`, `skills/code-review`,
66
+ `scripts/db/migrate/run.sh`, `workflows/release`. Not the bare canonical name that `recognize()`
67
+ currently emits (`akm-adapter.ts:198,224`), and not the raw file path (a skill's id is
68
+ `skills/<dir>`, not `skills/<dir>/SKILL`; per normative §11.2 the adapter owns both stripping
69
+ directions, so "path within the bundle" means *the item's path as the adapter defines it* — a
70
+ directory-item's path is its directory).
71
+
72
+ Why qualified beats the banked bare-name spelling:
73
+
74
+ 1. **It makes the codemod purely textual.** `type:name → stashDirFor(type)/name` is a static
75
+ 13-row table (`asset-placement.ts:89-165`: skill→skills, command→commands, agent→agents,
76
+ knowledge→knowledge, workflow→workflows, script→scripts, memory→memories, env→env,
77
+ secret→secrets, lesson→lessons, task→tasks, session→sessions, fact→facts). No runtime helper,
78
+ no semantic transform — the script-only gate holds.
79
+ 2. **No cross-type identity collisions.** Bare names make `skill:deploy` and `workflow:deploy`
80
+ both `bundle//deploy` — a behavior change (today's `entry_key = stashDir:type:name` keeps them
81
+ distinct) and an unfixable ambiguity for the ~4,700 test literals. Qualified ids keep them
82
+ distinct (`skills/deploy` vs `workflows/deploy`) with zero new machinery.
83
+ 3. **It is the spelling `placeNew` already consumes** (`akm-adapter.ts:405`) and the spelling the
84
+ adapter spec's §1.3 examples already show (`personal//knowledge/http-caching`,
85
+ `team-catalog//workflows/release`). Only `recognize()` and the additive `item_ref` writer
86
+ disagree, and both are one-line derivations.
87
+ 4. **It preserves §11.2's reclassification invariant** far better than bare names: the qualified
88
+ id is anchored on where the file *is*; a bare canonical name depends on per-type ext-keep/strip
89
+ rules and can change when only the `type` changes.
90
+
91
+ **Search surfaces do not move.** `entry.name` / the FTS `name` column keep the *bare* canonical
92
+ name exactly as today (identity ≠ search text); `bm25(entries_fts,0,10,5,3,2,1)` and the §12.3
93
+ goldens are untouched by construction. Only `IndexDocument.conceptId` / `ref` / `item_ref` change
94
+ spelling.
95
+
96
+ Cost: the two banked derivation sites change (`akm-adapter.ts` recognize; `indexer.ts:1032`
97
+ `itemRef = ${bundle}//${entry.name}` → the qualified spelling) and the shadow-parity harness +
98
+ byte-identity proof re-run. The harness exists and is exactly the tool for this — that proof is
99
+ an afternoon, not a redesign. This is the *only* piece of banked Chunk-5 work this decision
100
+ revises.
101
+
102
+ ### D-R3 — Canonical storage-key rule and accepted input forms
103
+
104
+ | Surface | Accepted form(s) | Stored/emitted form |
105
+ |---|---|---|
106
+ | Index identity (`entries.item_ref`, UNIQUE post-flip) | — (writer-derived) | fully-qualified `bundle//conceptId` |
107
+ | Durable state keys (`usage_events.entry_ref`, utility, feedback, proposal targets, `.derived-twin` bases) | — (derived from a resolved entry, never from raw input) | fully-qualified |
108
+ | Refs inside bundle content (frontmatter fields, workflow/task target refs) | short or fully-qualified | resolved against the **containing** bundle at index/parse time; stored fully-qualified |
109
+ | Prose body-refs (lint missing-ref scan, `akm mv` xref rewrite, search ref-prefix) | fully-qualified anchored form ONLY (`BUNDLE_REF_RE`); bare short tokens in prose are not refs | n/a (recognition, not storage) |
110
+ | CLI args / programmatic API / **tests** | short or fully-qualified (+ `#fragment`) | resolved per D-R4 before any lookup or write |
111
+ | `type:name` (old grammar) | **nowhere** after the flip; frozen migrator only | migrated once per §11.4 |
112
+
113
+ Unchanged from normative §11.1 except one amendment (D-R4's fallback order). The
114
+ "three legacy spellings per ref" probing that §11.1 calls out as the cost of leaving this open
115
+ (`rekeyStateDbForMove`) is exactly what this table retires.
116
+
117
+ ### D-R4 — Resolution rule for short input refs (the §11.1 amendment)
118
+
119
+ §11.1 currently says CLI sugar resolves "against the workspace `defaultBundle`" — full stop. That
120
+ is a silent behavior regression: today an origin-less ref searches **all** sources in priority
121
+ order (`asset-ref.ts:22` — "primary → search paths → installed"), and 182 test files plus real
122
+ CLI muscle memory depend on it. Amended rule:
123
+
124
+ > A short ref from CLI/API input resolves to the **defaultBundle** if the conceptId exists there,
125
+ > otherwise to the first bundle containing the conceptId in **installation priority order**
126
+ > (the `deriveInstallations` / config order — the same order origin-less lookups walk today).
127
+ > First match wins, deterministically. No match → not-found error naming the forms tried.
128
+
129
+ Content-internal short refs resolve to the **containing** bundle, never defaultBundle (unchanged,
130
+ §11.1). The old `local//` scoping (primary-only) is replaced by an explicit
131
+ `resolveRef(input, { only: bundleId })` API option, not a ref spelling. A later lint MAY warn
132
+ when a short ref shadows the same conceptId in a lower-priority bundle; it is not a 0.9.0 gate.
133
+
134
+ ### D-R5 — Bundle identity (the Chunk-8 coupling, pinned now)
135
+
136
+ A bundle id is a **workspace-assigned slug** (charset per §11.1: no `/ : . #` or whitespace),
137
+ chosen by this precedence:
138
+
139
+ 1. **Config key** — the key in the Chunk-8 `bundles` map. Authoritative once Chunk 8 lands.
140
+ 2. **`registryId`** — for registry-installed sources (today's behavior, `installations.ts:115`).
141
+ 3. **`slugForPath(sourcePath)`** — basename slug, batch-unique via path-hash suffix
142
+ (`installations.ts:73,147`) — the fallback for unconfigured ad-hoc sources only.
143
+
144
+ Stability semantics:
145
+
146
+ - The id is **workspace-scoped and stable under path moves once configured**: Chunk 8's config
147
+ migration writes the `bundles` map keyed by exactly what rule 2/3 derives today
148
+ (`registryId ?? slugForPath(path)`), so **no second identity migration happens at Chunk 8** —
149
+ the §11.4 `type:name → conceptId` re-key is the only one. After migration, editing a bundle's
150
+ `path` doesn't change its key; changing the key is `akm bundle rename` (§11.5 rekey
151
+ transaction, with the §11.5 startup guard against silently re-minted state).
152
+ - `defaultBundle` = the primary bundle's derived id, emitted by the migrator.
153
+ - **mkdtemp instability is confined and irrelevant**: an unconfigured tmp-dir fixture gets a
154
+ random slug, but under D-R1/D-R4 tests never need to spell it — they speak short refs. The few
155
+ tests that assert fully-qualified *stored* keys pin identity explicitly (set `registryId`, or
156
+ mount the source at a fixed-basename child of the tmp dir); that is the hand-edit bucket, not
157
+ the codemod.
158
+
159
+ ---
160
+
161
+ ## 3. Why this dissolves the forcing problem
162
+
163
+ The stall analysis framed the choice as (a) inject runtime `bundleFor(dir)` helpers into 182 test
164
+ files (semantic transform — violates the script-only gate) or (b) use the short form for
165
+ content-internal refs only. Both assume API boundaries demand fully-qualified refs. They don't —
166
+ and never did in the old grammar either: `AssetRef.origin` is optional, `findEntryIdByRef` takes
167
+ an optional `stashDir`, and the suite's literals are overwhelmingly origin-less
168
+ (~4,700 total, ~225 origin-qualified, 8 files setting `registryId`). **Today's tests already
169
+ exercise a resolve-at-lookup model.** Making short-form resolution first-class in the new grammar
170
+ (D-R1/D-R4) means the codemod maps short ref → short ref:
171
+
172
+ ```
173
+ "skill:code-review" → "skills/code-review" (static table, D-R2)
174
+ "script:db/migrate/run.sh" → "scripts/db/migrate/run.sh"
175
+ "knowledge:guide.md" → "knowledge/guide" (markdown ext-strip, same table)
176
+ "npm:@scope/pkg//skill:x" → hand bucket if asserted as a stored key; else registryId is the
177
+ bundle id and the mapping is textual (D-R5 rule 2)
178
+ "local//skill:x" → hand bucket (scoped-resolve API or fixture registryId), ~subset of 225
179
+ ```
180
+
181
+ No literal ever needs the random `akm-<hash>` slug. The codemod is a table-driven regex over
182
+ `.ts` + JSON fixtures — squarely inside the plan §15 rule-2 "script-only, zero hand-edited
183
+ hunks, ≥20-literal mutation spot-check" gate.
184
+
185
+ **Why not full Option B anyway?** A retained `type:name` parser is (1) prohibited as a permanent
186
+ dual-parser (§11.4), (2) reintroduces `type` into identity against §11.2 and D28, (3) keeps ~216
187
+ src parse sites alive that the flip exists to delete, and (4) solves only the same problem the
188
+ resolver already solves. Multiple *stored* spellings are strictly worse: every reader grows
189
+ N-way probing (the `rekeyStateDbForMove` disease §11.1 already diagnoses), and durable-state
190
+ survival across rebuilds (usage_events relink, derived-twin base lookup) would need spelling
191
+ normalization at every join forever.
192
+
193
+ ---
194
+
195
+ ## 4. Revised Chunk-5 flip execution plan
196
+
197
+ Every step lands green on the integration branch; the dual-input window opens at F1 and closes at
198
+ F5 **inside the same chunk**, satisfying §11.4's no-permanent-dual-parser rule. Chunk-8 scope
199
+ (three-DB merge, config migration, journaled cutover) is untouched.
200
+
201
+ - **F0 — Pin the conceptId spelling (additive, ~2 sites).** Change `recognize()`'s conceptId and
202
+ the `item_ref` writer (`indexer.ts:1032`) to the D-R2 qualified form; `entry.name`/FTS
203
+ untouched. Re-run the shadow-parity harness (`tests/integration/shadow-scan-parity.test.ts`)
204
+ and the byte-identity proof for the `item_ref` derivation; delete the spelling-tension NOTE at
205
+ `akm-adapter.ts:397`. Gate: parity green, §12.3 suites green (they must be unaffected — FTS
206
+ inputs unchanged).
207
+ - **F1 — Resolution layer + dual-input readers repointed onto `item_ref`.** Add
208
+ `resolveRef`/`RefContext`/`ResolvedRef` (D-R1, D-R4). Repoint the seven readers
209
+ (`index-entries-repository.ts:41,178,245,386,534,727,755`) to key on `item_ref`, accepting
210
+ BOTH grammars at the input edge (old `type:name` translated via the static D-R2 table +
211
+ source→bundle map; new refs resolved via D-R4). `getEntryByRef(db, type, name)` gains a
212
+ ref-shaped overload; `.derived-twin` suffix logic moves to conceptId-suffix on `item_ref`.
213
+ Additive; the whole existing suite stays green on the old literals. Gate: full suite green
214
+ pre-codemod; readers' old-grammar path is a thin shim marked for F5 deletion.
215
+ - **F2 — The script-only codemod (the ~4,700 literals, ~150+ files).** One script in `scripts/`:
216
+ the D-R2 static table over quoted/template `[origin//]type:name` literals in `tests/**` (.ts +
217
+ fixture JSON), per-type name normalization (markdown `±.md`), `registryId` origins carried as
218
+ bundle ids, `DESIGNATIONS.json` path/hash regeneration. Lands atomically with nothing else in
219
+ the commit. Gate: suite green behind the F1 dual readers; mutation spot-check — revert ≥20
220
+ random re-keyed literals, suite must go red, recorded in the chunk ledger; grep ratchet arms
221
+ `type-prefix literal in tests/` → shrink-only.
222
+ - **F3 — The hand bucket (separate, individually reviewable commits; ~40–60 files as already
223
+ ledgered in plan §12.1).** parseAssetRef unit tests ported to parseBundleRef/resolveRef;
224
+ `local//` scoping tests → `{only}` resolution option; tests asserting stored-key spellings pin
225
+ bundle identity via `registryId` or fixed-basename fixture roots; goldens re-baselined where
226
+ the *asserted key* (not ranking) changed.
227
+ - **F4 — The flip proper.** Swap the live scan loop: `generateMetadataFlat` (`indexer.ts:873`) →
228
+ `scanComponent` (`scan-component.ts:136`) over `deriveInstallations`; `StashEntry` →
229
+ `IndexDocument` rename; `entry_key/stash_dir/entry_type` demoted, `item_ref` becomes THE key
230
+ with the UNIQUE constraint (`index-schema.ts:242` note); diff persistence per plan; the
231
+ shadow-parity harness flips to assert the **persisted index** against the legacy stream one
232
+ last time, then the legacy stream is deleted. Index-db-resident state (`usage_events`,
233
+ utility/feedback) re-keys onto `item_ref` via the §11.4 join-against-last-good-index mapping
234
+ with orphan quarantine. `REF_RE` at `base-linter.ts:182` retargets to `BUNDLE_REF_RE`. Gate:
235
+ §12.3 full parity (nDCG/MRR/recall + filter + whyMatched), durable-state survival suite
236
+ (relink across full rebuild, derived-twin base lookup, content-hash skip), fn-size + cycle
237
+ ratchets (db trio leaves the baseline per DoD 11).
238
+ - **F5 — Delete the old grammar.** `parseAssetRef`/`makeAssetRef`/`refToString`/`AssetRef`/
239
+ `TYPE_ALIASES` deleted (~216 sites already repointed by F1/F4); the F1 old-grammar reader shim
240
+ deleted; frozen `scripts/akm-migrate/migrate/legacy/legacy-layout.ts` untouched. Gate: grep `parseAssetRef` →
241
+ 0, `StashEntry` → 0 (declared scopes); tests type-prefix ratchet → 0 and flipped absolute.
242
+
243
+ **Chunk 8 then consumes D-R5 as settled:** the config migrator emits `bundles` keys equal to the
244
+ already-derived ids (no re-key), `defaultBundle`, the §11.5 startup guard, and the three-DB
245
+ merge re-key runs over refs that are already in final spelling.
246
+
247
+ ### D-R6 — Adapter-owned reserved filenames (BINDING)
248
+
249
+ Verified against upstream OKF v0.1 §3.1/§6/§7 (2026-07-19 audit): `index.md`
250
+ (directory listing, progressive disclosure) and `log.md` (update history) are
251
+ reserved structural files at every level of an **OKF bundle** and "MUST NOT be
252
+ used for concept documents." This is an OKF adapter rule, not a cross-format
253
+ rule derived from OKF.
254
+
255
+ 1. **OKF.** The `okf` adapter never indexes those paths as concepts and refuses
256
+ concept writes to them. Structural generation remains an OKF-specific
257
+ bundle-maintenance operation.
258
+ 2. **AKM and LLM Wiki.** These adapters independently reserve the same names
259
+ under their own format contracts. Their recognition and write paths enforce
260
+ those rules without treating the files as OKF.
261
+ 3. **Other adapters.** Each adapter declares its own structural and reserved
262
+ names. The ref grammar does not prohibit a concept ID solely because its
263
+ final segment is `index` or `log`.
264
+
265
+ ## 5. Spec amendments (exhaustive)
266
+
267
+ 1. Normative §11.1: CLI/API short-ref resolution — replace "resolved … against the workspace
268
+ `defaultBundle`" with the D-R4 defaultBundle-then-priority-order rule.
269
+ 2. Normative §7.8/§11.2 (clarifying note, no rule change): "path within the bundle" is the item's
270
+ path *as the adapter defines it*; a directory-item's path is its directory (skills).
271
+ 3. Adapter spec §5.1: pin the akm adapter's conceptId to the D-R2 qualified spelling; drop the
272
+ recognize/place spelling-tension note.
273
+ 4. Plan §11 Chunk 5: insert F0/F1 (spelling pin + resolver/dual-reader step) ahead of the codemod;
274
+ codemod and grep gates otherwise unchanged.
275
+ 5. Adapter spec §5.1/§6 (+ Chunk-8 checklist): the D-R6 reserved-filename rule — `index.md`/
276
+ `log.md` are never recognized as items and never valid write targets; the akm adapter's
277
+ exclusion + existing-file handling land with F4/Chunk 8.
278
+
279
+ ## 6. Invariants check
280
+
281
+ - **FTS5 schema + bm25 weights unchanged** — D-R2 keeps `name`/search fields on the bare
282
+ canonical name; identity-only change (spec line 245 holds).
283
+ - **§12.3 parity** — gated at F0 (must be no-op) and F4 (full run).
284
+ - **Durable-state survival** — single stored spelling + F4 re-key with §11.4 orphan quarantine;
285
+ relink/derived-twin/content-hash suites gate F4.
286
+ - **Cycle ratchet ≤10 / fn-size shrink-only** — resolver is a new pure leaf; db trio exits the
287
+ baseline at F4 per DoD 11.
288
+ - **No new trust machinery** — resolution is name lookup only; `trusted` untouched.
289
+ - **Frozen migrator** — never edited; it is where `type:name` parsing lives forever.
290
+ - **Script-only codemod gate** — preserved by construction (D-R2 static table); hand edits are
291
+ segregated in F3 exactly as plan §15 rule 2 requires.