akm-cli 0.9.30 → 0.9.32
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 +40 -0
- package/README.md +10 -10
- package/ROADMAP.md +112 -0
- package/dist/commands/feedback-cli.js +21 -13
- package/dist/commands/improve/improve-cli.js +33 -12
- package/dist/core/errors.js +1 -0
- package/dist/core/file-lock.js +10 -1
- package/dist/indexer/usage/usage-events.js +6 -2
- package/dist/llm/client.js +33 -3
- package/dist/scripts/akm-migrate-node.js +6 -1
- package/dist/scripts/akm-migrate.js +6 -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/data-and-telemetry.md +6 -0
- 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,528 @@
|
|
|
1
|
+
# 0.9.0 surface decisions
|
|
2
|
+
|
|
3
|
+
The decision record behind the 0.9.0 surface changes. Each entry states what
|
|
4
|
+
was decided, why, what it breaks, and where the normative text now lives.
|
|
5
|
+
|
|
6
|
+
Companion documents:
|
|
7
|
+
- [`0.9.0-release-surface-review.md`](./0.9.0-release-surface-review.md) — the
|
|
8
|
+
full review and the prioritized action list.
|
|
9
|
+
- [`ref.md`](./ref.md) — the normative ref grammar.
|
|
10
|
+
- [`../../../STABILITY.md`](../../../STABILITY.md) — the stability contract.
|
|
11
|
+
|
|
12
|
+
**Governing principle.** 0.9.x is the last series that may break freely
|
|
13
|
+
(`STABILITY.md`). Every ambiguity we carry past it becomes a migration we owe
|
|
14
|
+
users later. So the bias throughout is: decide now, break now, and prefer
|
|
15
|
+
removing a half-built surface over shipping it behind a label.
|
|
16
|
+
|
|
17
|
+
> **"Decided" ≠ "shipped."** Every entry below records a decision and carries a
|
|
18
|
+
> **Status** line stating whether it is in the code today. As of the 0.9.0
|
|
19
|
+
> release every decision is either shipped, partial, or explicitly reversed —
|
|
20
|
+
> but the rule stands for future amendments: do not read a decision as a
|
|
21
|
+
> description of current behavior, and do not copy one into `STABILITY.md` (the
|
|
22
|
+
> user-facing contract) until its status says shipped.
|
|
23
|
+
|
|
24
|
+
| Decision | Status |
|
|
25
|
+
| --- | --- |
|
|
26
|
+
| D1 `#fragment` section selector | **Shipped** |
|
|
27
|
+
| D2 remove `show` view grammar | **Shipped** |
|
|
28
|
+
| D3 `akm mv` stays, Experimental | **Reversed** — mv ships; **removed outright 2026-07-30** (see amendment below) |
|
|
29
|
+
| D4 conceptId-prefix browse | **Shipped** |
|
|
30
|
+
| D5 remove `akm bundle` | **Shipped** |
|
|
31
|
+
| D6 free-form `type` | **Shipped** at runtime; CLI help text updated |
|
|
32
|
+
| D7 all six formats everywhere | **Shipped** |
|
|
33
|
+
| D8 gate improve autonomy | **Shipped** |
|
|
34
|
+
| D9 `--auto-accept` warn-and-ignore | **Shipped** (warns, and no longer poisons the scope positional) |
|
|
35
|
+
| D10 extract migration machinery | Partial (`akm-migrate` bin exists; code still in-repo) |
|
|
36
|
+
| D11 OKF foundational | Partial (the `okf` adapter has landed) |
|
|
37
|
+
| D12 `placeNew()` wiring | **Deferred to 0.10** |
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## D1 — `#fragment` becomes a section selector for markdown items
|
|
42
|
+
|
|
43
|
+
**Status: SHIPPED, `show`-only scope for 0.9.0 (ruled 2026-07-26, Q-06).**
|
|
44
|
+
`akm show knowledge/guide#auth` returns just that section. `parseRefInput`
|
|
45
|
+
(`src/core/asset/resolve-ref.ts`), the ref parser every other ref-consuming
|
|
46
|
+
command routes through (graph, tasks, improve, proposals, the utility repo,
|
|
47
|
+
the indexer walk), still rejects any `#fragment` outright with
|
|
48
|
+
`INVALID_FLAG_VALUE` — `show` works only because it bypasses that parser.
|
|
49
|
+
Wider rollout across those commands is post-0.9.0.
|
|
50
|
+
|
|
51
|
+
**Decided.** The fragment production is implemented rather than merely
|
|
52
|
+
declared. For markdown-document items the core resolves `#fragment` as a
|
|
53
|
+
section selector (heading slug, falling back to case-insensitive heading
|
|
54
|
+
text). For all other item kinds it stays an adapter-owned selector, opaque to
|
|
55
|
+
the core, per spec §11.3. Fragments are input-only and never stored.
|
|
56
|
+
|
|
57
|
+
**Why.** `STABILITY.md` declared `[bundle//]conceptId[#fragment]` **Stable**
|
|
58
|
+
while every input boundary rejected fragments outright and nothing consumed
|
|
59
|
+
them — a production that was stable on paper and unusable in practice. Two
|
|
60
|
+
ways out: delete it from the grammar, or give it a meaning. Deleting it
|
|
61
|
+
forecloses the exports/bindings design that spec §11.3 reserves it for;
|
|
62
|
+
implementing the markdown case costs almost nothing (the parser already
|
|
63
|
+
returns the fragment and the resolver already carries it) and retires a
|
|
64
|
+
competing grammar in the same move (D2).
|
|
65
|
+
|
|
66
|
+
**Breaks.** Nothing — fragments were previously rejected everywhere, so this
|
|
67
|
+
is purely additive at the input boundary. The spec text changes (§11.3 gains
|
|
68
|
+
the markdown carve-out).
|
|
69
|
+
|
|
70
|
+
**Normative text.** [`ref.md` § Fragments](./ref.md#fragments).
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## D2 — the `akm show` view-mode grammar is removed
|
|
75
|
+
|
|
76
|
+
**Status: SHIPPED.** `normalizeShowArgv` and the `KnowledgeView` type are gone; a positional after the ref is a usage error naming `#fragment`.
|
|
77
|
+
|
|
78
|
+
**Decided.** `akm show <ref> toc|section "H"|lines A B|frontmatter|full` is
|
|
79
|
+
deleted. `#fragment` (D1) replaces `section`; no fragment means the whole
|
|
80
|
+
item, replacing `full`; an unmatched fragment lists the available slugs,
|
|
81
|
+
replacing `toc`. `lines` and `frontmatter` are dropped outright.
|
|
82
|
+
|
|
83
|
+
**Why.** It was a second argv parser: `normalizeShowArgv` rewrote
|
|
84
|
+
`process.argv` before citty saw it and injected hidden `--akmView` /
|
|
85
|
+
`--akmHeading` / `--akmStart` / `--akmEnd` flags (which were never rejected
|
|
86
|
+
when passed directly). Its keywords were reserved words in ref position. With
|
|
87
|
+
D1 in place it is redundant for the one mode that carried real weight.
|
|
88
|
+
|
|
89
|
+
**Breaks.** A documented Stable read-command spelling. Requires a CHANGELOG
|
|
90
|
+
migration note. `lines` has no replacement — every response carries `path`, so
|
|
91
|
+
callers slice the file themselves. `frontmatter` has no replacement; if a
|
|
92
|
+
raw-YAML projection proves necessary it returns as a `--shape` value, which
|
|
93
|
+
`STABILITY.md` already designates as the projection axis.
|
|
94
|
+
|
|
95
|
+
**Normative text.** [`ref.md` § Superseded: the `akm show` view-mode grammar](./ref.md#superseded-the-akm-show-view-mode-grammar).
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## D3 — renames are delete + create; `akm mv` ships Experimental
|
|
100
|
+
|
|
101
|
+
**Status: REVERSED.** `akm mv` ships in 0.9.0. `src/cli.ts` registers
|
|
102
|
+
`mvCommand` and `src/commands/mv-cli.ts` ships in full. What 0.9.0 changes is
|
|
103
|
+
the command's classification — **Experimental**, outside the stability
|
|
104
|
+
contract — and the recommended rename procedure.
|
|
105
|
+
|
|
106
|
+
**Amended 2026-07-30.** `akm mv` was removed outright before the 0.9.0
|
|
107
|
+
release — `src/cli.ts` no longer registers `mvCommand` and
|
|
108
|
+
`src/commands/mv-cli.ts` no longer exists; there is no alias or stub. The
|
|
109
|
+
Experimental classification recorded above never got the chance to matter in
|
|
110
|
+
practice. The recommended rename procedure below (plain filesystem move plus
|
|
111
|
+
`akm index` and `akm lint`) is now the *only* procedure. Carrying learned
|
|
112
|
+
state across a rename is opt-in and out-of-band: `bun
|
|
113
|
+
scripts/rekey-asset-ref.ts <old-ref> <new-ref>`, run from a source checkout
|
|
114
|
+
before `akm index`, re-keys the `entries` row plus `asset_salience`/
|
|
115
|
+
`asset_outcome`/`usage_events` in place. Automated garbage collection of
|
|
116
|
+
orphaned rows left by renames that skip that script is tracked as issue #733;
|
|
117
|
+
until it lands, the script is the only path. See
|
|
118
|
+
[`v0.9.0-troubleshooting.md`](../../migration/v0.9.0-troubleshooting.md).
|
|
119
|
+
|
|
120
|
+
**Decided.** A rename or move produces a **new identity**. Learned state
|
|
121
|
+
(utility, salience, outcomes, usage history) does not follow it. Cross-bundle
|
|
122
|
+
movement is copy/import plus delete. Spec §11.2's "MUST use an explicit
|
|
123
|
+
state-rekey transaction" is amended accordingly. The recommended rename
|
|
124
|
+
procedure is a plain filesystem move plus `akm index` and `akm lint`;
|
|
125
|
+
`akm mv` remains available for callers who want the tooled path and accept
|
|
126
|
+
Experimental risk, and the identity preservation it advertises is not a
|
|
127
|
+
contract.
|
|
128
|
+
|
|
129
|
+
**Why Experimental.** The command's primary integrity promise is implemented
|
|
130
|
+
inverted. Spec §11.1 names it directly — inbound-ref rewriting "operate[s] only
|
|
131
|
+
on these anchored [`bundle//conceptId`] forms; bare short refs in prose are not
|
|
132
|
+
recognized as refs" — but `buildRewritePatterns` emits five patterns, three
|
|
133
|
+
dead `type:name` spellings and two bare-conceptId spellings, and **no
|
|
134
|
+
`bundle//` arm at all**. It rewrites precisely what the spec says is not a ref
|
|
135
|
+
and leaves every real prose ref dangling. Separately, the reserved-filename
|
|
136
|
+
guard `ref.md` requires of `akm mv` does not exist in the file; it hardcodes
|
|
137
|
+
seven types (`MV_SUPPORTED_TYPES`) and the primary writable bundle only; it can
|
|
138
|
+
change bundle provenance by omitting `bundleId` on its finalizing index call;
|
|
139
|
+
and its documented failure semantics ("the move still succeeds" with warnings)
|
|
140
|
+
contradict an implementation that throws after the irreversible filesystem
|
|
141
|
+
commit.
|
|
142
|
+
|
|
143
|
+
Cost on the other side of the ledger: 1,452 LOC plus ~2,190 LOC of tests and
|
|
144
|
+
two permanent function-size-ratchet exemptions — for what the originating spec
|
|
145
|
+
itself called "the highest-effort, lowest-frequency operation".
|
|
146
|
+
|
|
147
|
+
Those defects are why delete + create is what the docs prescribe and why the
|
|
148
|
+
command carries no contract. They are not why it would be deleted: the code is
|
|
149
|
+
already written and tested, the label bounds what users may rely on, and the
|
|
150
|
+
redesign below is the real fix.
|
|
151
|
+
|
|
152
|
+
**Breaks.** Nothing. `akm mv` is unchanged code, still registered, still
|
|
153
|
+
executable. The changes are the Experimental classification and the documented
|
|
154
|
+
recommendation. The bundle refactor already solved the problems that motivated
|
|
155
|
+
the command *except* item rename, and rename is the case where delete+create is
|
|
156
|
+
defensible: `index.db` is a regenerable cache, and the row-ID preservation `mv`
|
|
157
|
+
performs leaves the embedding stale anyway (the `search_text` changes without
|
|
158
|
+
invalidating it).
|
|
159
|
+
|
|
160
|
+
**Future.** A narrow same-bundle `akm rename` is the eventual fix for the
|
|
161
|
+
defects above and is deferred past 0.9.0. It would resolve through the index,
|
|
162
|
+
use adapter-owned placement, accept only qualified refs, rewrite only anchored
|
|
163
|
+
prose refs, apply one qualified old→new state mapping, and rebuild derived
|
|
164
|
+
index data rather than preserve row IDs.
|
|
165
|
+
|
|
166
|
+
**Normative text.** [`ref.md` § Renames and moves](./ref.md#renames-and-moves);
|
|
167
|
+
spec §11.2.
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## D4 — browse uses conceptId prefixes, not `<type>:`
|
|
172
|
+
|
|
173
|
+
**Status: SHIPPED.** `parseRefPrefixQuery` parses conceptId and `bundle//`
|
|
174
|
+
prefixes and consults no type list; `enumerateEntries` matches on conceptId and
|
|
175
|
+
bundleId. The `scripts/lint-shipped-assets.ts` carve-out is removed, so the
|
|
176
|
+
retired spelling is now an offense in agent-facing assets.
|
|
177
|
+
|
|
178
|
+
**Decided.** Subtree enumeration is `akm search "memories/"`,
|
|
179
|
+
`"memories/projecta/"`, `"bundle//"`, `"bundle//skills/"`. The
|
|
180
|
+
`akm search "<type>:"` / `"<type>:<prefix>/"` grammar is removed.
|
|
181
|
+
|
|
182
|
+
**Why.** Three defects, each independently disqualifying. It resurrected the
|
|
183
|
+
singular `type:` spelling the release had just removed, as query syntax, in
|
|
184
|
+
the same release. It validated tokens against the `akm` adapter's placement
|
|
185
|
+
types, so items from every other adapter (`website`, `wiki-source`, wiki
|
|
186
|
+
`pageKind`s, `instruction`) could not be enumerated at all. And it matched
|
|
187
|
+
`namePrefix` against item *names* while every emitted ref is a conceptId — so
|
|
188
|
+
copying a ref prefix out of search output and pasting it back in silently
|
|
189
|
+
degraded to a keyword search.
|
|
190
|
+
|
|
191
|
+
**Breaks.** The `<type>:` browse spelling. Requires a CHANGELOG migration
|
|
192
|
+
note.
|
|
193
|
+
|
|
194
|
+
**Bonus.** `bundle//` enumeration is the replacement for the removed
|
|
195
|
+
`akm bundle items` (D5).
|
|
196
|
+
|
|
197
|
+
**Implementation note.** `scripts/lint-shipped-assets.ts` is a zero-tolerance
|
|
198
|
+
gate that fails on any dead `type:name` token in agent-facing shipped assets —
|
|
199
|
+
but it carries an explicit carve-out permitting the `<type>:` /
|
|
200
|
+
`<type>:<prefix>/` search grammar because it was "still current". That
|
|
201
|
+
carve-out must be **removed** when this lands, so the gate also catches
|
|
202
|
+
`memory:projectA/`. Otherwise the retired grammar keeps a sanctioned path back
|
|
203
|
+
into the material agents read.
|
|
204
|
+
|
|
205
|
+
**Normative text.** [`ref.md` § Ref-prefix enumeration](./ref.md#ref-prefix-enumeration-browse).
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
## D5 — `akm bundle` is removed
|
|
210
|
+
|
|
211
|
+
**Status: SHIPPED.** `akm bundle` is no longer registered.
|
|
212
|
+
|
|
213
|
+
**Decided.** The `akm bundle {list,show,items}` noun group is deleted.
|
|
214
|
+
Bundles are inspected through `akm list` (extended additively with the
|
|
215
|
+
default marker, the desired source descriptor, `registryId`, the full lock
|
|
216
|
+
block, `components`, and per-bundle item counts) and enumerated through
|
|
217
|
+
`akm search "bundle//"` (D4).
|
|
218
|
+
|
|
219
|
+
**Why.** It was a half-built noun group by its own admission — the source
|
|
220
|
+
comment records that the lifecycle verbs
|
|
221
|
+
(`create`/`install`/`update`/`remove`/`sync`/`export`) "stay on their existing
|
|
222
|
+
top-level commands for 0.9.0" — so `akm bundle list` coexisted with
|
|
223
|
+
`akm list` over the same objects. Leaving that split unresolved means either
|
|
224
|
+
moving five lifecycle verbs under a noun group after release (expensive) or
|
|
225
|
+
carrying two competing inventories forever. It is undocumented in
|
|
226
|
+
`docs/reference/cli.md`, absent from `STABILITY.md`, and has no consumers
|
|
227
|
+
beyond its own CLI file and one test — so removal is nearly free.
|
|
228
|
+
|
|
229
|
+
**Breaks.** Three undocumented commands. The unique data they exposed
|
|
230
|
+
(resolved lock detail, components, per-bundle counts) must land on `akm list`
|
|
231
|
+
in the same change or it is lost.
|
|
232
|
+
|
|
233
|
+
---
|
|
234
|
+
|
|
235
|
+
## D6 — asset `type` is free-form and stays unvalidated
|
|
236
|
+
|
|
237
|
+
**Status: SHIPPED.** Runtime filtering is unvalidated
|
|
238
|
+
(`src/commands/read/search.ts` passes `--type` straight through), and the
|
|
239
|
+
`search` / `curate` `--type` help text now describes the open set. Shell
|
|
240
|
+
completions still offer only the built-ins, which is inherent — a completion
|
|
241
|
+
list cannot enumerate an open set.
|
|
242
|
+
|
|
243
|
+
**Decided.** `--type` is an exact match against an open set, deliberately not
|
|
244
|
+
validated. An unrecognized type returns zero hits rather than an error. The
|
|
245
|
+
help text says so. The closed set survives only where a type selects a *write
|
|
246
|
+
placement* (`akm propose`, `placeNew`).
|
|
247
|
+
|
|
248
|
+
**Why.** This reverses an earlier recommendation in the review. Under the
|
|
249
|
+
bundle/adapter model `IndexDocument.type` is an open string by contract, the
|
|
250
|
+
closed union was deliberately deleted, and adapters legitimately emit types
|
|
251
|
+
outside the placement set. Validation would reject valid queries against
|
|
252
|
+
adapter-defined content. The real defect is documentation: the help enum
|
|
253
|
+
listed 10 of 13 placement types and none of the adapter space.
|
|
254
|
+
|
|
255
|
+
**Breaks.** Nothing. Documentation-only.
|
|
256
|
+
|
|
257
|
+
**Normative text.** [`ref.md` § Asset types are free-form](./ref.md#asset-types-are-free-form).
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
## D7 — one output contract, no bespoke renderers
|
|
262
|
+
|
|
263
|
+
**Status: SHIPPED.** `md` and `html` are registry-driven with generic fallbacks
|
|
264
|
+
(`src/output/render-registry.ts`, `src/output/generic-render.ts`); `akm health`
|
|
265
|
+
registers its renderers instead of intercepting, so nothing branches on format
|
|
266
|
+
before `output()`; the startup `--format html` rejection is gone because html is
|
|
267
|
+
now valid everywhere; `graph export`'s local `--format` is deleted; and the
|
|
268
|
+
exempt set is declared in `src/output/format-exempt.ts`.
|
|
269
|
+
|
|
270
|
+
**Amendments after the first landing.** The initial D7 implementation carried
|
|
271
|
+
two compromises that were subsequently removed rather than kept:
|
|
272
|
+
|
|
273
|
+
1. *`akm health` no longer branches on `--format` at all.* The first landing
|
|
274
|
+
kept a format-driven READ (`--format html` performed a richer query for
|
|
275
|
+
trend deltas) plus module-level context bound for the renderer. Both are
|
|
276
|
+
gone: the full report is a **data** flag — `akm health --report` fetches
|
|
277
|
+
per-run rows, window-compare deltas, and the pending proposal queue, and
|
|
278
|
+
carries them in the result (`runs`/`deltas`/`report`). The registered
|
|
279
|
+
md/html renderers are pure functions of that result and fire on its shape,
|
|
280
|
+
never on the format. This also closed a hole in D7 itself: the report
|
|
281
|
+
dataset was previously reachable ONLY as html; it is now ordinary data in
|
|
282
|
+
every format. Breaking: `akm health --format html` alone now renders
|
|
283
|
+
generically — use `--report`; the html-only `--compare` flag is replaced by
|
|
284
|
+
`--window-compare`.
|
|
285
|
+
|
|
286
|
+
2. *The citty flag mis-capture is fixed at the root, so the `sync` and
|
|
287
|
+
`env unset` workarounds ARE deleted after all.* The release review (B2)
|
|
288
|
+
was right that they should go but wrong about why they existed: they
|
|
289
|
+
guarded against citty parsing each command level with only its own args, so
|
|
290
|
+
a root-declared global flag was unknown at the leaf and its space-separated
|
|
291
|
+
value fell through as a positional. `GLOBAL_OUTPUT_ARGS`
|
|
292
|
+
(`src/cli/shared.ts`) now redeclares `--format`/`--detail`/`--shape`/
|
|
293
|
+
`--output` on every `defineJsonCommand` leaf (declared args win on
|
|
294
|
+
collision, e.g. `hints --detail`), so the parser consumes the values and
|
|
295
|
+
the workarounds are unnecessary rather than merely inconvenient. The
|
|
296
|
+
declarations are parse-only; the output mode is still read once from the
|
|
297
|
+
invocation singleton.
|
|
298
|
+
|
|
299
|
+
3. *`akm graph export`'s artifact payload follows the `--out` extension*
|
|
300
|
+
(`.jsonl` → JSONL, else JSON), not the global `--format`. The first landing
|
|
301
|
+
mapped the global flag onto the payload where the 1:1 mapping existed,
|
|
302
|
+
which still overloaded one flag with two meanings — payload and envelope
|
|
303
|
+
are separate concerns, and the destination names the payload.
|
|
304
|
+
|
|
305
|
+
**Decided.** All six `--format` values work on every command. Rendering
|
|
306
|
+
becomes registry-driven (md and html registries mirroring the existing
|
|
307
|
+
shapes/text registries) with generic fallbacks derived from the shaped
|
|
308
|
+
envelope. `akm health` keeps its rich output by *registering* renderers rather
|
|
309
|
+
than intercepting before `output()`. `akm graph export --format` is deleted in
|
|
310
|
+
favour of the global flag. Format-exempt commands are declared rather than
|
|
311
|
+
implicit.
|
|
312
|
+
|
|
313
|
+
**Why.** The status quo had three inconsistent failure modes: `md` silently
|
|
314
|
+
emitted JSON everywhere except `health`, `html` threw everywhere except
|
|
315
|
+
`health`, and 37 commands silently emitted JSON under `--format text`. Silent
|
|
316
|
+
wrong-format output from a documented Stable contract is the worst of the
|
|
317
|
+
available behaviors. `graph export --format` additionally collided with the
|
|
318
|
+
global flag — one token, two parsers — which is what forced the citty
|
|
319
|
+
workarounds in `sync` and `env unset`.
|
|
320
|
+
|
|
321
|
+
**Breaks.** `akm graph export --format` (use the global `--format`). The
|
|
322
|
+
`html` generic fallback reverses a prior decision (chunk-9 WI-9.4c) that
|
|
323
|
+
removed the JSON-in-`<pre>` fallback; that decision is explicitly re-opened
|
|
324
|
+
here.
|
|
325
|
+
|
|
326
|
+
---
|
|
327
|
+
|
|
328
|
+
## D8 — gate improve *autonomy*, not improve
|
|
329
|
+
|
|
330
|
+
**Status: SHIPPED.** `experimental.improveAutonomy` exists in the schema
|
|
331
|
+
(`src/core/config/schema/experimental.ts`), is read through one predicate
|
|
332
|
+
(`src/core/config/experimental.ts`), and gates five lanes via
|
|
333
|
+
`src/commands/improve/autonomy-gate.ts`. Three are downgraded in the strategy
|
|
334
|
+
config at `resolveImprovePlan`; the memory-cleanup and contradiction passes ask
|
|
335
|
+
the gate directly, because their only prior guard —
|
|
336
|
+
`shouldAnalyzeMemoryCleanup` — reads scope and eligible-memory count and no
|
|
337
|
+
strategy flag at all.
|
|
338
|
+
|
|
339
|
+
Because the gate runs BEFORE `buildImprovePlan`'s LLM preflight, a gated lane
|
|
340
|
+
also stops demanding an engine: a strategy whose only model-backed process is
|
|
341
|
+
gated now resolves with no engine configured. That asymmetry is what
|
|
342
|
+
`tests/improve-plan-autonomy-wiring.test.ts` uses to prove the ordering.
|
|
343
|
+
|
|
344
|
+
Reporting: each downgrade warns naming the lane and the key, appends an
|
|
345
|
+
`improve_skipped` event with `reason: "autonomy_gated"` (which `akm health`
|
|
346
|
+
already aggregates by reason, so it needed no new machinery), and is listed by
|
|
347
|
+
`akm tasks doctor` under `improveAutonomy.gatedLanes`. Wiring doctor also fixed a
|
|
348
|
+
defect the gate would otherwise have introduced: doctor resolved the RAW strategy
|
|
349
|
+
for `improveTriage.applyMode`, so a `promote` strategy under a review-first
|
|
350
|
+
config would have reported "promote" while the run used "queue" — the diagnostic
|
|
351
|
+
command misreporting the thing it exists to diagnose. It now resolves the gated
|
|
352
|
+
strategy.
|
|
353
|
+
|
|
354
|
+
**One extra fix this surfaced.** `akm improve` rejected the global `--format`
|
|
355
|
+
outright (`akm improve does not accept --format`), which made it a fourth
|
|
356
|
+
inconsistent format behaviour after D7 — neither compliant nor declared exempt,
|
|
357
|
+
while `STABILITY.md` claimed all six formats work on every non-exempt command.
|
|
358
|
+
It does emit an envelope through `output()` (always under `--dry-run`, otherwise
|
|
359
|
+
under `--json-to-stdout`), so the rejection is removed and `--format` now applies
|
|
360
|
+
to that envelope. Progress output stays on stderr either way.
|
|
361
|
+
|
|
362
|
+
**Decided.** `akm improve` stays on by default, review-first, with its
|
|
363
|
+
schedules intact. A single opt-in — `experimental.improveAutonomy` — gates the
|
|
364
|
+
lanes that mutate assets without review: consolidate's merge/delete/contradict,
|
|
365
|
+
the memory-cleanup and contradiction passes, memory-inference writes, and triage
|
|
366
|
+
`applyMode: "promote"`. A gated lane never becomes a silent no-op: it emits an
|
|
367
|
+
event naming the config key, surfaces in `akm tasks doctor`, and raises a health
|
|
368
|
+
advisory.
|
|
369
|
+
|
|
370
|
+
**Amendment — `sync.push` is NOT gated.** An earlier draft of this decision put
|
|
371
|
+
unattended push behind the gate and flipped its default to `false`. That is
|
|
372
|
+
reversed: `sync.push` keeps its `true` default and stays outside
|
|
373
|
+
`experimental.improveAutonomy`. Push is materially different from the other five
|
|
374
|
+
lanes — it publishes already-committed content to a remote the user configured
|
|
375
|
+
for exactly that purpose, rather than mutating or deleting assets without
|
|
376
|
+
review — and it already has two direct, documented opt-outs
|
|
377
|
+
(`improve.strategies.<name>.sync.push: false` and `--no-push`). Gating it would
|
|
378
|
+
have added a third control over the same behavior while silently stopping a
|
|
379
|
+
publish step that working setups depend on.
|
|
380
|
+
|
|
381
|
+
**Why.** A blanket experimental gate on `akm improve` would have silently
|
|
382
|
+
turned installed schedules into no-ops and removed the only normal producer of
|
|
383
|
+
memory inference and graph extraction — contradicting 0.8's positioning of
|
|
384
|
+
improve as the unified maintenance entry point, `STABILITY.md`'s Evolving
|
|
385
|
+
promise, and the roadmap's "harden the 0.8 baseline" framing. But the default
|
|
386
|
+
strategy is not actually review-only: an audit confirmed six direct-mutation
|
|
387
|
+
lanes, one of which (memory cleanup / belief-state archiving) is gated by no
|
|
388
|
+
strategy flag at all and runs on any improve run covering memories. Gating the
|
|
389
|
+
autonomy resolves the contradiction without removing the feature.
|
|
390
|
+
|
|
391
|
+
**Breaks.** Users relying on unattended promotion, direct consolidate
|
|
392
|
+
merge/delete, memory-inference writes, or the memory-cleanup and contradiction
|
|
393
|
+
passes must set the key. Nothing changes for `sync.push`: git-backed bundles
|
|
394
|
+
with a remote keep pushing after an improve run exactly as they do today.
|
|
395
|
+
|
|
396
|
+
**Scope notes.** Three direct writes stay ungated by design and are documented
|
|
397
|
+
in `STABILITY.md`: `extract`'s session indexing (additive `sessions/**`
|
|
398
|
+
writes), distill's encoding-salience frontmatter stamp (metadata only), and
|
|
399
|
+
`sync.push` (publishes already-committed content to a remote the user
|
|
400
|
+
configured, and already has `sync.push: false` / `--no-push`).
|
|
401
|
+
|
|
402
|
+
---
|
|
403
|
+
|
|
404
|
+
## D9 — `--auto-accept` is removed
|
|
405
|
+
|
|
406
|
+
**Status: SHIPPED.** `akm improve --auto-accept …` now warns and names the replacement, and the space-separated form no longer leaves its value in the scope positional (which had reduced the run to a zero-match no-op that exited 0).
|
|
407
|
+
|
|
408
|
+
**Decided.** The strict 0.9 runtime does not parse the retired confidence-gate
|
|
409
|
+
flag. Scheduled commands must remove it rather than silently continuing with a
|
|
410
|
+
different policy.
|
|
411
|
+
|
|
412
|
+
**Replacement.** `akm improve && akm proposal drain --promote --yes`
|
|
413
|
+
(defaults: `personal-stash` policy, 25-accept ceiling), or a `triage` block
|
|
414
|
+
with `applyMode: "promote"`. Note the config-only path drains the *standing*
|
|
415
|
+
backlog as a pre-pass, so run N's proposals promote at the start of run N+1;
|
|
416
|
+
closing that one-cycle gap needs an opt-in post-generation drain.
|
|
417
|
+
|
|
418
|
+
---
|
|
419
|
+
|
|
420
|
+
## D10 — migration machinery leaves the core
|
|
421
|
+
|
|
422
|
+
**Status: PARTIAL.** An `akm-migrate` binary exists, but the migration code
|
|
423
|
+
still lives in this repo. **Amended 2026-07-27 (R-029 ruling):** `akm backup`
|
|
424
|
+
is REMOVED from the CLI outright rather than kept as a forwarder — the
|
|
425
|
+
capability lives at `akm-migrate backup` / `akm-migrate restore`, which
|
|
426
|
+
already existed; a cleaner backup story is deferred past 0.9.0. The migration
|
|
427
|
+
guide and 0.9.0 release notes now teach the `akm-migrate` spelling.
|
|
428
|
+
|
|
429
|
+
**Decided.** Apply/backup/restore move to a separately published
|
|
430
|
+
`akm-migrate` package; `akm migrate` stays a thin forwarder (`akm backup` is
|
|
431
|
+
gone per the amendment above); `akm config migrate` and the
|
|
432
|
+
`akm-migrate-storage` bin entry are removed from the CLI. If the extraction
|
|
433
|
+
does not make 0.9.0, the *declaration* still ships: these surfaces are
|
|
434
|
+
Internal and scheduled for removal at 0.10.
|
|
435
|
+
|
|
436
|
+
**Why.** ~8,820 LOC of production code plus ~7,130 LOC of tests, pinned to a
|
|
437
|
+
one-time 0.8→0.9 cutover (`akm backup` hard-rejects any `--for` value except
|
|
438
|
+
the literal `0.9.0`), currently occupying three top-level commands and a
|
|
439
|
+
second published binary permanently.
|
|
440
|
+
|
|
441
|
+
**Risks to manage.** The extracted package shares the runtime boundary
|
|
442
|
+
(lint-frozen to two files), the cross-process lock protocol, and
|
|
443
|
+
ordered migration IDs, so it needs an exact-pin peer dependency. The core must
|
|
444
|
+
keep the pending-operation gate, ledger prefix refusal, and pointer messages.
|
|
445
|
+
|
|
446
|
+
**Breaks.** `akm config migrate` (use `akm migrate`); the
|
|
447
|
+
`akm-migrate-storage` bin (npm-only precedent already exists — `install.sh`
|
|
448
|
+
never shipped it).
|
|
449
|
+
|
|
450
|
+
---
|
|
451
|
+
|
|
452
|
+
## D11 — OKF is the first-class Markdown baseline; adapters progressively enhance it
|
|
453
|
+
|
|
454
|
+
**Status: PARTIAL.** The `okf` adapter has landed.
|
|
455
|
+
|
|
456
|
+
**Decided.** AKM supports OKF through a first-class built-in `okf` adapter.
|
|
457
|
+
Every applicable OKF conformance case must pass. OKF supplies the
|
|
458
|
+
least-common-denominator path identity, open type, content, links, and heading
|
|
459
|
+
fragment behavior for Markdown concepts. It is not the database schema and does
|
|
460
|
+
not serialize non-Markdown native formats.
|
|
461
|
+
|
|
462
|
+
**Why.** A conformant OKF bundle must work end to end: if search emits
|
|
463
|
+
`okfbundle//tables/customers`, show must accept that ref, preserve the OKF
|
|
464
|
+
concept ID and metadata, and retain OKF links. The current parser's requirement
|
|
465
|
+
that every concept ID begin with an AKM placement directory is therefore an
|
|
466
|
+
OKF support bug.
|
|
467
|
+
|
|
468
|
+
AKM Markdown is an OKF-compatible superset: AKM producers emit the required
|
|
469
|
+
open `type` field and retain additional AKM metadata. The selected adapter owns
|
|
470
|
+
capabilities. The `okf` adapter applies only generic content/fragment behavior;
|
|
471
|
+
the `akm` adapter progressively adds command, script, workflow, task,
|
|
472
|
+
environment, secret, memory, lesson, and other native handling. Unknown types
|
|
473
|
+
remain valid data and fall back to generic behavior.
|
|
474
|
+
|
|
475
|
+
**Required changes.** Ref resolution accepts opaque adapter concept IDs;
|
|
476
|
+
identity persists by concept ID rather than type/title; OKF content, metadata,
|
|
477
|
+
and links survive indexing; heading fragments work through generic show; and
|
|
478
|
+
AKM-specific write commands reject consumer-only OKF targets before mutation.
|
|
479
|
+
Adapter ownership is persisted at registration and explicit configuration wins.
|
|
480
|
+
The `akm` adapter keeps matcher-based classification while its Markdown writers
|
|
481
|
+
emit OKF-compatible frontmatter.
|
|
482
|
+
|
|
483
|
+
**Breaks.** None intended. This widens valid refs for installed OKF bundles
|
|
484
|
+
without changing AKM-native refs or classification.
|
|
485
|
+
|
|
486
|
+
**Normative text.** [`okf-support.md`](./okf-support.md);
|
|
487
|
+
[`akm-0.9.0-bundle-adapter-spec.md`](./akm-0.9.0-bundle-adapter-spec.md);
|
|
488
|
+
[`ref.md`](./ref.md).
|
|
489
|
+
|
|
490
|
+
---
|
|
491
|
+
|
|
492
|
+
## D12 — `BundleAdapter.placeNew()` stays unwired until 0.10
|
|
493
|
+
|
|
494
|
+
**Status: DEFERRED to 0.10.** The interface declares `placeNew(c, conceptId)`
|
|
495
|
+
OPTIONAL (`src/core/adapter/bundle-adapter.ts`), and 8 of the built-in adapter
|
|
496
|
+
modules already implement it — `generic-files`, `akm`, `llm-wiki`,
|
|
497
|
+
`agent-skills`, `dotenv`, `akm-workflow`, `akm-task`, and the shared
|
|
498
|
+
`tool-dir-shared` factory (consumed by the `claude` and `opencode` adapters).
|
|
499
|
+
`website-snapshot` deliberately has none — it is read-only (Mode A); export
|
|
500
|
+
(Mode B) is a separate, also-deferred facet. Nothing in `src/` calls
|
|
501
|
+
`.placeNew(` anywhere.
|
|
502
|
+
|
|
503
|
+
**Decided.** 0.9.0 leaves placement on AKM's existing flat
|
|
504
|
+
type→directory table: `resolveAssetFilePath` resolves
|
|
505
|
+
`stashDirFor(ref.type)` (`src/core/write-source.ts`) against the
|
|
506
|
+
`PLACEMENT_SPECS` table (`src/core/asset/asset-placement.ts`). Routing writes
|
|
507
|
+
through per-adapter `placeNew()` instead is deferred to 0.10 as its own
|
|
508
|
+
change.
|
|
509
|
+
|
|
510
|
+
**Why.** `stashDirFor(` has 36 call sites across 19 files — the indexer,
|
|
511
|
+
storage repositories, sources, core, and 7 command modules. That is the write
|
|
512
|
+
path this release rests on. Cutting it over to per-adapter placement is a
|
|
513
|
+
large, separable refactor; sequencing it after the rest of the 0.9.0 adapter
|
|
514
|
+
cutover keeps this release's blast radius bounded. Placement for every existing bundle is already correct
|
|
515
|
+
today — this is a routing change, not a bug fix, and not unfinished work
|
|
516
|
+
so much as a deliberately later chunk of the same refactor. (Compare the
|
|
517
|
+
interface's own closing comment on the Tier-B authoring/export/memory
|
|
518
|
+
facets, similarly flagged rather than stubbed.)
|
|
519
|
+
|
|
520
|
+
**Breaks.** None. No user-visible change: nothing calls `placeNew()` before
|
|
521
|
+
0.10, so write behavior for every existing bundle is unchanged. The 8
|
|
522
|
+
adapters that already implement it get no exercise from that code path yet —
|
|
523
|
+
treat those method bodies as unwired, not battle-tested, until 0.10 routes
|
|
524
|
+
writes through them.
|
|
525
|
+
|
|
526
|
+
**Normative text.** [`akm-0.9.0-bundle-adapter-spec.md`](./akm-0.9.0-bundle-adapter-spec.md)
|
|
527
|
+
§2; `src/core/adapter/bundle-adapter.ts` (interface + its closing comment on
|
|
528
|
+
deferred facets, same framing).
|