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.
- package/CHANGELOG.md +41 -0
- package/README.md +10 -10
- package/ROADMAP.md +112 -0
- package/dist/commands/improve/improve-cli.js +33 -12
- package/dist/commands/sources/plugin-upgrade.js +46 -23
- package/dist/core/file-lock.js +10 -1
- package/dist/llm/client.js +33 -3
- package/dist/scripts/akm-migrate-node.js +5 -1
- package/dist/scripts/akm-migrate.js +5 -1
- package/docs/README.md +42 -41
- package/docs/agents/README.md +15 -0
- package/docs/agents/agent-install.md +14 -0
- package/docs/architecture/README.md +67 -0
- package/docs/architecture/adapters.md +272 -0
- package/docs/architecture/akm-architecture-decision-history.md +2055 -0
- package/docs/architecture/akm-core-principles.md +126 -0
- package/docs/architecture/architecture.md +579 -0
- package/docs/architecture/comparisons/claude-code-vs-akm-workflows-full.md +550 -0
- package/docs/architecture/decisions/0001-no-interpolation-attached-structured-context.md +72 -0
- package/docs/architecture/decisions/0002-unit-reuse-and-input-hash-scope.md +142 -0
- package/docs/architecture/decisions/0003-child-env-allowlist-and-provenance.md +189 -0
- package/docs/architecture/decisions/0004-task-input-contract-and-flag-coercion.md +97 -0
- package/docs/architecture/decisions/0005-task-result-vocabulary-and-legacy-read-mapping.md +108 -0
- package/docs/architecture/decisions/0006-task-source-version-routing.md +124 -0
- package/docs/architecture/decisions/0007-workflow-composition-bounds.md +83 -0
- package/docs/architecture/decisions/0008-task-binding-normalization.md +88 -0
- package/docs/architecture/decisions/0009-child-run-publication-column-parity.md +80 -0
- package/docs/architecture/decisions/0010-driver-protocol-cut.md +36 -0
- package/docs/architecture/decisions/0011-engine-run-loop-invariants.md +125 -0
- package/docs/architecture/decisions/README.md +62 -0
- package/docs/architecture/improvement.md +440 -0
- package/docs/architecture/internals/classification.md +154 -0
- package/docs/architecture/internals/fresh-host-rebuild-runbook.md +40 -0
- package/docs/architecture/internals/functional-contract-patterns.md +340 -0
- package/docs/architecture/internals/health-advisories.md +110 -0
- package/docs/architecture/internals/improve-workflow.md +713 -0
- package/docs/architecture/internals/indexing.md +498 -0
- package/docs/architecture/internals/registry-network-boundary.md +57 -0
- package/docs/architecture/internals/search.md +249 -0
- package/docs/architecture/internals/storage-locations.md +943 -0
- package/docs/architecture/persisted-data-compat.md +59 -0
- package/docs/architecture/reviews/env-secret-access.md +319 -0
- package/docs/architecture/runtime-boundary-design.md +153 -0
- package/docs/architecture/specs/0.9.0-close-out-plan.md +361 -0
- package/docs/architecture/specs/0.9.0-decisions.md +528 -0
- package/docs/architecture/specs/0.9.0-docs-code-drift-register.md +745 -0
- package/docs/architecture/specs/0.9.0-open-items-register.md +135 -0
- package/docs/architecture/specs/0.9.0-public-api-issue-backlog.md +740 -0
- package/docs/architecture/specs/0.9.0-release-surface-review.md +636 -0
- package/docs/architecture/specs/agent-command-engine-model-design.md +513 -0
- package/docs/architecture/specs/akm-0.9.0-bundle-adapter-spec.md +501 -0
- package/docs/architecture/specs/akm-0.9.0-ref-grammar-decision.md +291 -0
- package/docs/architecture/specs/akm-format-neutral-bundle-workspace-spec.md +2059 -0
- package/docs/architecture/specs/di-seams-plan.md +539 -0
- package/docs/architecture/specs/driver-protocol-keep-or-cut.md +275 -0
- package/docs/architecture/specs/fact-asset-type.md +142 -0
- package/docs/architecture/specs/improve-collapse-churn-detector-design.md +634 -0
- package/docs/architecture/specs/okf-support.md +148 -0
- package/docs/architecture/specs/ref.md +329 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/README.md +72 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/findings-consolidated.md +152 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/library-eval-alternatives.md +352 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/library-eval-bunqueue.md +300 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/library-eval-openworkflow.md +402 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/opus-review-1.md +758 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/opus-review-2.md +645 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/opus-review-3.md +602 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-adversarial.md +27 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-architecture.md +27 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-coverage.md +74 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-security.md +15 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/panel-r2-adversarial.md +132 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/panel-r2-verification.md +147 -0
- package/docs/architecture/specs/stash-conventions-code-spec.md +275 -0
- package/docs/architecture/specs/stash-organization-conventions.md +377 -0
- package/docs/architecture/specs/task-workflow-format-unification.md +721 -0
- package/docs/architecture/specs/workflow-engine-buy-vs-build.md +231 -0
- package/docs/architecture/specs/workflow-format-unification.md +437 -0
- package/docs/architecture/testing/manual-testing-checklist.md +3420 -0
- package/docs/architecture/testing/okf-v0.2-conformance-runbook.md +924 -0
- package/docs/architecture/testing/task-workflow-manual-tests.md +1817 -0
- package/docs/architecture/testing/testing-workflow.md +446 -0
- package/docs/architecture/workflow-engine.md +274 -0
- package/docs/guides/README.md +33 -0
- package/docs/guides/author-bundles.md +310 -0
- package/docs/guides/author-workflows.md +520 -0
- package/docs/guides/bundles.md +321 -0
- package/docs/guides/capture-knowledge.md +136 -0
- package/docs/guides/claude-code-vs-akm-workflows.md +30 -0
- package/docs/guides/concepts.md +93 -0
- package/docs/guides/discover-and-load.md +158 -0
- package/docs/guides/getting-started.md +240 -0
- package/docs/guides/improve-the-library.md +246 -0
- package/docs/guides/knowledge-management.md +18 -0
- package/docs/guides/recipes/headless-install.md +97 -0
- package/docs/guides/recipes/website-source.md +28 -0
- package/docs/guides/run-workflows.md +279 -0
- package/docs/guides/scheduling.md +123 -0
- package/docs/guides/use-with-any-agent.md +129 -0
- package/docs/guides/wikis.md +81 -0
- package/docs/maintainers/README.md +19 -0
- package/docs/maintainers/curate-workmap.md +336 -0
- package/docs/maintainers/eval.md +3 -0
- package/docs/maintainers/local-development.md +108 -0
- package/docs/maintainers/release-checklist.md +103 -0
- package/docs/migration/README.md +2 -2
- package/docs/migration/release-notes/0.0.13.md +1 -1
- package/docs/migration/release-notes/0.1.0.md +1 -1
- package/docs/migration/release-notes/0.2.0.md +1 -1
- package/docs/migration/release-notes/0.3.0.md +1 -1
- package/docs/migration/release-notes/0.5.0.md +1 -1
- package/docs/migration/release-notes/0.6.0.md +1 -1
- package/docs/migration/release-notes/0.7.0.md +1 -1
- package/docs/migration/release-notes/0.7.3.md +2 -2
- package/docs/migration/release-notes/0.7.4.md +1 -1
- package/docs/migration/release-notes/0.7.5.md +1 -1
- package/docs/migration/release-notes/0.8.0.md +1 -1
- package/docs/migration/release-notes/0.9.0.md +1 -1
- package/docs/migration/release-notes/0.9.14.md +1 -1
- package/docs/migration/release-notes/0.9.15.md +1 -1
- package/docs/migration/release-notes/0.9.16.md +1 -1
- package/docs/migration/release-notes/0.9.17.md +1 -1
- package/docs/migration/release-notes/0.9.19.md +1 -1
- package/docs/migration/release-notes/0.9.2.md +1 -1
- package/docs/migration/release-notes/README.md +27 -31
- package/docs/migration/v0.5-to-v0.6.md +759 -0
- package/docs/migration/v0.8-to-v0.9.md +1 -1
- package/docs/plans/0.9.2-agent-command-workflow-plan.md +423 -0
- package/docs/posts/README.md +30 -0
- package/docs/posts/akm-command-tour.md +495 -0
- package/docs/posts/akm-logo-sized.webp +0 -0
- package/docs/posts/belief-aware-memory-12.md +139 -0
- package/docs/posts/config-v2-lessons-16.md +191 -0
- package/docs/posts/improve-loop-autonomous-10.md +225 -0
- package/docs/posts/improve-pipeline-debugging-0803.md +179 -0
- package/docs/posts/intro-part-01.md +76 -0
- package/docs/posts/intro-part-02.md +221 -0
- package/docs/posts/intro-part-03.md +190 -0
- package/docs/posts/intro-part-04.md +221 -0
- package/docs/posts/llm-mode-reflect-13.md +166 -0
- package/docs/posts/openpalm-built-on-akm.md +86 -0
- package/docs/posts/progressive-disclosure-06.md +129 -0
- package/docs/posts/proposal-safety-net-15.md +112 -0
- package/docs/posts/release-0.5.0.md +247 -0
- package/docs/posts/release-0.6.0.md +117 -0
- package/docs/posts/release-0.7.0.md +159 -0
- package/docs/posts/release-0.8.0.md +332 -0
- package/docs/posts/scattered-skills-05.md +100 -0
- package/docs/posts/task-assets-persistent-workflows-11.md +222 -0
- package/docs/posts/team-skills-07.md +198 -0
- package/docs/posts/wiki-agent-knowledge-08.md +223 -0
- package/docs/posts/workflows-vaults-09.md +321 -0
- package/docs/product-surface.md +54 -0
- package/docs/reference/README.md +1 -2
- package/docs/reference/asset-types.md +168 -0
- package/docs/reference/cli.md +5 -6
- package/docs/reference/env-and-secrets.md +126 -0
- package/docs/reference/memory.md +124 -0
- package/docs/reference/refs.md +156 -0
- package/docs/reference/registry.md +489 -0
- package/docs/reference/website-sources.md +141 -0
- 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.
|