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,361 @@
1
+ # akm 0.9.0 — milestone close-out plan
2
+
3
+ **Status:** PLANNED (2026-07-30). Owner ruling applied: all four open issues
4
+ ship in 0.9.0.
5
+
6
+ The release sits at `0.9.0-rc.11` with the CLI overhaul (#734) merged and the
7
+ [open-items register](0.9.0-open-items-register.md) recording its close-out
8
+ state. This document is the implementation plan for the four issues remaining
9
+ in the 0.9.0 milestone, in landing order.
10
+
11
+ ## Milestone triage
12
+
13
+ All five open issues across 0.9.0 and 0.9.1 were reviewed. An initial
14
+ recommendation deferred #733 and #730 to 0.9.1; the owner ruled both stay in
15
+ 0.9.0. Final state:
16
+
17
+ | Issue | Milestone | Scope in one line |
18
+ | --- | --- | --- |
19
+ | #692 salience boost | 0.9.0 | Remove the R2 contributor from default ranking; the removal also deletes a confirmed 5 s hot-path stall. |
20
+ | #672 repositories + guard | 0.9.0 | Move salience/outcome SQL behind `src/storage/repositories/`; add a raw-SQL lint rule. |
21
+ | #733 orphan-GC | 0.9.0 | One maintenance pass, one additive migration, one event type, one config gate. Lean by design — see Workstream C. |
22
+ | #730 OKF v0.2 | 0.9.0 | Read v0.2 frontmatter; stamp `generated`/`verified` on AKM-native writes via proposals; conformance updated. The `okf` adapter stays consumer-only. |
23
+ | #652 write provenance | 0.9.1 | Unchanged — already re-scoped by the rc-5 audit to attribution/concurrency polish. |
24
+
25
+ Sequencing note: A and B are small and touch the same salience surface — land
26
+ them first (A deletes a raw-SQL site B would otherwise relocate). C and D are
27
+ independent of each other and of A/B, and can proceed in parallel after.
28
+
29
+ ## Workstream A — #692: remove the salience boost from default ranking
30
+
31
+ **Decision: fix option 1 (removal), the issue's stated preference.** The R2
32
+ contributor multiplies search/curate scores by up to 1.2× from a signal that is
33
+ retrieval-dominated (`w_r = 0.60`, `src/commands/improve/salience.ts:356-360`),
34
+ warm-starts non-zero with no outcome evidence (`salience.ts:293-297`), has zero
35
+ pack coverage, and measures as noise on live data (max ×1.071). No measured
36
+ curate-bench delta justifies it, and `STABILITY.md:308` classifies ranking as a
37
+ tuning target — removal in 0.9.0 is contractually clean.
38
+
39
+ **No config gate is added.** A config key for a term being removed would be
40
+ dead surface that the 1.0 freeze would then have to carry. If a future
41
+ curate-golden-bench delta proves the signal out, reintroduction behind a
42
+ default-off gate happens then (the contributor stays exported for exactly that
43
+ experiment). `rank_score` itself is untouched — it remains the improve-internal
44
+ selection signal (proactive/high-salience lanes, forgetting safety).
45
+
46
+ The removal also deletes the hot-path defect confirmed in the rc-5 audit
47
+ as a side effect rather than tuning around it: today every default search
48
+ acquires the maintenance activity synchronously — up to a 5 s spin
49
+ (`src/core/maintenance-barrier.ts:91-107`) plus a lock-file create — before the
50
+ 250 ms SQLite busy-timeout even applies (`src/indexer/search/ranking.ts:102`).
51
+
52
+ ### Changes
53
+
54
+ 1. `src/indexer/search/ranking-contributors.ts:551-554` — drop
55
+ `salienceRankingContributor` from `defaultUtilityRankingContributors`
56
+ (the list becomes `[utilityRankingContributor]`). The contributor and its
57
+ constants stay exported.
58
+ 2. `src/indexer/search/ranking.ts` — delete `loadSalienceRankScores`
59
+ (`:96-139`) and the `:263` default fallback. Its only production caller is
60
+ that fallback; tests are the only other importers. New semantics for
61
+ `RankEntriesOptions.salienceRankScores`: a `Map` applies the contributor
62
+ explicitly (tests/evals); `null`/`undefined` mean off. Update the option's
63
+ doc comment (`:58-64`) accordingly.
64
+ 3. With the loader gone, the search path holds no maintenance-barrier
65
+ acquisition and opens no state.db handle. `db-search.ts:502-511` needs no
66
+ edit beyond whatever the option-type change forces.
67
+ 4. Remove the now-dead barrier import from `ranking.ts:6` and confirm the
68
+ search layer has no remaining `maintenance-barrier` dependency.
69
+
70
+ ### Tests
71
+
72
+ - `tests/integration/ranking-salience-boost.test.ts` — keep the contributor
73
+ math block (boost exactness at rank 1.0 / 0.5, no-op cases) exercised via
74
+ explicit injection. Replace the state.db read-path block: the held-barrier
75
+ test (`:111-131`, currently budgeted 10 s) inverts into the release's
76
+ regression guard — *search with the maintenance barrier held completes
77
+ without waiting*. Keep the "search never creates the state.db file"
78
+ assertion (`:101-109`) in its new form: default search never touches
79
+ state.db at all.
80
+ - `tests/integration/ranking-contributor-ablation.test.ts:52-53` — update for
81
+ the one-entry default list; ablation of `"salience-ranking"` against an
82
+ explicitly-supplied list still proves the mechanism.
83
+ - `tests/integration/curate-golden-eval.test.ts` and
84
+ `tests/integration/ranking-regression.test.ts` — expected neutral (live
85
+ effect measured as noise); run and record the deltas in the PR description.
86
+
87
+ ### Acceptance
88
+
89
+ - Bare `akm search` under a held maintenance barrier returns promptly (no 5 s
90
+ stall) — covered by the inverted regression test.
91
+ - Default search/curate perform zero state.db reads and create no lock files.
92
+ - Golden evals within tolerance; CHANGELOG entry under Changed noting removal,
93
+ the retained improve-internal role of `rank_score`, and the latency fix.
94
+ - Close #692 citing option 1 and the reintroduction path.
95
+
96
+ ## Workstream B — #672: salience/outcome repositories + widened SQL guard
97
+
98
+ Part 1 of the issue (prep-stage accumulator decomposition) shipped at
99
+ `028cc3de`. This lands the remaining part 2, with two corrections to the issue
100
+ text discovered against the tree:
101
+
102
+ - **Location correction.** The issue proposes `src/core/state/salience-repo.ts`
103
+ / `outcome-repo.ts`; the tree's actual convention is
104
+ `src/storage/repositories/*-repository.ts` (22 files, including the state.db
105
+ precedents `proposals-repository.ts`, `improve-runs-repository.ts`,
106
+ `events-repository.ts`, whose shared pattern is "extracted verbatim …
107
+ re-exported so existing importers resolve"). Follow the tree.
108
+ - **Guard correction.** The issue calls the widening "a one-line allowlist
109
+ change", but `scripts/lint-repository-sql.ts` enforces *DB-owner imports and
110
+ direct opens* (`RULES` `:55-71`), not raw SQL. `salience.ts` and
111
+ `outcome-loop.ts` take `db` parameters and import no owners — they would
112
+ pass a widened prefix list today with their SQL intact, and commands
113
+ legitimately import owners like `withStateDb`, so prefix-widening alone
114
+ cannot express the intended boundary. The faithful implementation is a new
115
+ rule.
116
+
117
+ ### Changes
118
+
119
+ 1. `src/storage/repositories/salience-repository.ts` — verbatim moves from
120
+ `src/commands/improve/salience.ts`: `AssetSalienceRow` (`:380-393`),
121
+ `upsertAssetSalience` (`:425-458`), `getAssetSalience` (`:463-473`),
122
+ `getAllRankScores` (`:484-494`), `recordNoOp` (`:509-514`),
123
+ `resetConsecutiveNoOps` (`:520-525`), `getConsecutiveNoOps` (`:531-535`).
124
+ Add `getTopRetrievalSalience(db, limit)` absorbing the health read
125
+ (`src/commands/health/metrics.ts:246-251`).
126
+ 2. `src/storage/repositories/outcome-repository.ts` — verbatim moves from
127
+ `src/commands/improve/outcome-loop.ts`: the upsert SQL inside
128
+ `updateAssetOutcome` (`:245-268`; the domain function stays put and calls
129
+ the repository), `getAssetOutcome` (`:278-288`), `getAllAssetOutcomes`
130
+ (`:293-302`), `getOutcomeScoresByRef` (`:308-323`).
131
+ 3. Re-export the moved functions from `improve/salience.ts` and
132
+ `improve/outcome-loop.ts` per the established precedent, so the six improve
133
+ importers and eleven test files do not churn in this PR.
134
+ 4. `src/commands/health/metrics.ts` — replace the inline
135
+ `SELECT retrieval_salience …` with the repository call; the `withStateDb`
136
+ handle it already holds is passed through.
137
+ 5. The fifth raw-SQL site (`ranking.ts:122`) is deleted by Workstream A; if A
138
+ has not merged first, its chunked select moves behind
139
+ `salience-repository.ts` instead.
140
+ 6. `scripts/lint-repository-sql.ts` — add a third rule, `state-table-sql`:
141
+ flag raw SQL naming `asset_salience` or `asset_outcome` anywhere under
142
+ `src/` except `src/storage/repositories/` and
143
+ `src/core/state/migrations.ts`. Per-rule scoping (the existing two rules
144
+ keep their current `GUARDED_PREFIXES`; the new rule carries its own
145
+ scope/exclusions). Workstream C's pass consumes the repositories, so the
146
+ rule holds at zero from day one.
147
+
148
+ ### Tests
149
+
150
+ - `tests/integration/lint-repository-sql.test.ts` — the live-tree-is-zero test
151
+ now also proves no raw salience/outcome SQL survives outside repositories.
152
+ Add fixtures: raw `asset_salience` SQL under `src/commands/improve/` fires;
153
+ the identical string inside `src/storage/repositories/` does not; prose
154
+ mentions still do not (comment-stripping already covered). The `:48-53`
155
+ assertion that `src/commands/improve/preparation.ts` is unguarded is updated
156
+ to reflect the new rule's coverage.
157
+ - The improve-side suites
158
+ (`tests/integration/commands/improve/{salience,salience-wiring,outcome-loop,outcome-loop-wiring,outcome-invariance}.test.ts`,
159
+ `tests/integration/health-ws5-observability.test.ts`) must pass unchanged —
160
+ verbatim moves, pure refactor, no behavior delta.
161
+
162
+ ### Acceptance
163
+
164
+ - `bun run lint` green with the new rule at zero violations.
165
+ - No test-behavior changes outside the lint meta-test.
166
+ - Close #672 with a comment recording the two corrections above.
167
+
168
+ ## Workstream C — #733: orphan-GC pass (lean)
169
+
170
+ Deliberately minimal: **one maintenance pass, one additive migration, one
171
+ event type, one config gate.** No quarantine archive, no circuit breaker, no
172
+ health-advisory plumbing, no new tables. The issue's design constraints are
173
+ each satisfied by something that already exists or by the smallest possible
174
+ addition:
175
+
176
+ - **Absent ≠ deleted** is inherited from the indexer, not re-implemented: an
177
+ incomplete or failed scan preserves a source's last-known-good `entries`
178
+ rows (`src/indexer/indexer.ts:1195-1199`), and mass-wipe is already blocked
179
+ upstream (`preserveExistingIndex` + the `fullDelete && scanComplete` gate).
180
+ So "ref not present in `entries.item_ref`" *is* the authoritative-deletion
181
+ predicate — a temporarily unreachable source never surfaces candidates.
182
+ - **Grace window** needs a clock rows don't have (`updated_at` is bumped by
183
+ improve itself and `mtime` doesn't exist for rows), so: one additive
184
+ migration (`021`, mirroring the 6-line migration-011 precedent) adds
185
+ `missing_since INTEGER DEFAULT NULL` to `asset_salience` and
186
+ `asset_outcome`. Grace duration is a named constant
187
+ (`STATE_GC_GRACE_MS`, 7 days), mirroring `TXN_SWEEP_GRACE_MS`
188
+ (`src/core/fs-txn.ts:298`) — not a config knob.
189
+ - **Prove before deleting**: the pass always runs and always reports; actual
190
+ row deletion is behind a single boolean, `improve.stateGc.collect`
191
+ (default **false** for 0.9.0). Every run emits the counts either way, so
192
+ live data accumulates proof; flipping the default later is a one-line
193
+ change plus a CHANGELOG note.
194
+ - **Events**: one new documented `EventType` literal, `asset_state_gc`, with
195
+ the sentinel ref `asset_state/_gc` (same convention as
196
+ `proposals/_orphan-purge`), emitted only when there is something to say
197
+ (the rekey script's no-op-stays-silent precedent).
198
+
199
+ **Scope cut: `usage_events` is excluded.** Attached rows (`entry_id` set)
200
+ already cascade on entry deletion (`deleteUsageEventsByEntryIds`,
201
+ `src/storage/repositories/index-entries-repository.ts:607-618`), and the
202
+ 90-day retention purge (`purgeOldUsageEvents`,
203
+ `src/indexer/usage/usage-events.ts:141`) bounds detached remnants. If live
204
+ data shows that purge isn't reaching them, extending the pass is a follow-up.
205
+
206
+ ### Changes
207
+
208
+ 1. Migration `021-asset-state-missing-since` in
209
+ `src/core/state/migrations.ts` — the two `ALTER TABLE … ADD COLUMN`
210
+ statements, nothing else.
211
+ 2. `runOrphanStateGcPass(ctx)` in `src/commands/improve/loop-stages.ts`,
212
+ registered in the maintenance sequence at `:1005-1036` next to
213
+ `runOrphanProposalPurgePass` (`:1303`), which it copies structurally
214
+ (same `{count, warnings}` return, same borrowed-connection handling via
215
+ `withStateDb(…, { borrowed })` — the #585 pattern at `:1400`). Per run:
216
+ a. Collect distinct refs from both tables (repository calls — Workstream
217
+ B's modules), resolve them against `entries.item_ref` with the same
218
+ chunked-probe shape the rekey script uses
219
+ (`scripts/rekey-asset-ref.ts:278`), reusing the existing
220
+ legacy-spelling normalization from `preparation.ts:2153-2163` so a
221
+ live asset keyed under an old spelling is never a candidate.
222
+ b. Unresolved and `missing_since IS NULL` → stamp now. Resolved and
223
+ `missing_since` set → clear it (the asset came back).
224
+ c. If `improve.stateGc.collect` is true: delete rows whose
225
+ `missing_since` is older than the grace constant, per-table, in one
226
+ transaction each.
227
+ d. Emit `asset_state_gc` with `{pending, collected, byTable}` when either
228
+ is nonzero; surface the same counts in the pass summary line like the
229
+ neighboring purge passes do.
230
+ 3. Config: `stateGc: { collect: boolean }` added to
231
+ `ImproveConfigSchema` (`src/core/config/schema/improve.ts`), default
232
+ false; JSON schema regenerated via `scripts/gen-config-schema.ts`.
233
+
234
+ ### Tests
235
+
236
+ One integration suite, `tests/integration/commands/improve/state-gc.test.ts`:
237
+
238
+ - Orphaned ref is stamped, not deleted, on first sighting; deleted only after
239
+ the grace elapses *and* `collect` is on (fake clock via the stamped value).
240
+ - Default config: nothing is ever deleted; counts still reported.
241
+ - A live asset whose state row carries a legacy ref spelling is not a
242
+ candidate (the normalization case).
243
+ - A ref that resolves again after being stamped has `missing_since` cleared.
244
+ - The event appears in `akm log` with the expected metadata; a run with
245
+ nothing pending emits no event.
246
+ - Rekey-race guard: rows stamped but inside grace are untouched, and
247
+ `rekey-asset-ref.ts` still moves them intact.
248
+
249
+ ### Acceptance
250
+
251
+ - Field-failure class reproduced in a fixture (state rows under a retired
252
+ source root) is reported immediately and collected only with
253
+ `collect: true` after grace.
254
+ - No behavior change for any source that fails to scan (entries preserved →
255
+ zero candidates).
256
+ - CHANGELOG entry under Added; #733 closes with a note that the
257
+ `collect` default flips after live runs prove the report clean.
258
+
259
+ ## Workstream D — #730: OKF v0.2
260
+
261
+ Three parts: read-side adapter support, write-side provenance stamping through
262
+ the proposal path, and the conformance/spec updates. One scope decision up
263
+ front: **the `okf` adapter stays consumer-only.** AKM markdown is already an
264
+ OKF-compatible superset (`okf-support.md` progressive-enhancement contract),
265
+ so the new provenance fields are *written* only to AKM-native assets;
266
+ runbook §10's write-rejection contract and the tests at
267
+ `okf-conformance.test.ts:832-936` are unchanged.
268
+
269
+ ### D1 — read side (`src/core/adapter/adapters/okf-adapter.ts`)
270
+
271
+ Today `recognize` (`:125-171`) reads exactly five keys (`type`, `title`,
272
+ `description`, `tags`, `timestamp`); everything else folds into opaque
273
+ `documentJson`. Add, staying lenient (never reject):
274
+
275
+ 1. `updated` ← `generated.at`, falling back to legacy `timestamp` (the v0.2
276
+ breaking change, with the fallback v0.2 itself allows).
277
+ 2. Parse the v0.2 families into new optional `IndexDocument` fields
278
+ (`src/core/adapter/types.ts:141-296`): `generated` (`by`/`at`), `verified`
279
+ (list; tolerate the single-mapping form), v0.2 `sources` (object list),
280
+ `status`, `stale_after`, and `okf_version` (currently read nowhere in
281
+ `src/`).
282
+ 3. **Collision handling** — three AKM fields already occupy adjacent names:
283
+ `sources?: string[]` (wiki citations, silently drops non-strings at
284
+ `metadata.ts:486-489`), `generation?: number` (consolidation depth), and
285
+ `quality: "generated"`. The v0.2 families therefore land under *new,
286
+ distinct* field names (recommendation: a single namespaced
287
+ `provenance?: { sources, generatedBy, generatedAt, verified }` plus flat
288
+ `lifecycleStatus` / `staleAfter`), leaving the existing fields untouched.
289
+ Final naming is an owner call at PR review; the plan only fixes that no
290
+ existing field is overloaded.
291
+
292
+ ### D2 — write side (AKM-native assets via proposals)
293
+
294
+ The proposals system already tracks exactly what v0.2 wants on disk —
295
+ `source`/`sourceRun` (PROV-DM modeled, `proposal-types.ts:82-120`),
296
+ `gateDecision`, `review` — it just never leaves state.db. Project it at
297
+ promotion time:
298
+
299
+ 1. `promoteProposal` stamps `generated: { by, at }` into the written asset's
300
+ frontmatter, actor per the v0.2 convention (`<producer>/<version>` →
301
+ `akm/<pkg-version>` for automated lanes; `human:<id>` when a human
302
+ accepted the proposal).
303
+ 2. A proposal that passed its gate or review appends a
304
+ `verified: [{ by, at }]` entry alongside.
305
+ 3. Where a proposal carries `evidenceSources` (`types.ts:265-268`), project
306
+ them as v0.2 `sources` entries (`{ resource }` minimum).
307
+ 4. `DOCUMENT_JSON_CARRIED_FIELDS` (`akm-adapter.ts:192-213`) gains the new
308
+ keys so AKM's own adapter rereads what it wrote; `akm show` surfaces them.
309
+
310
+ Deeper consumers — `stale_after`-driven re-verification, trust-tier ranking —
311
+ are explicitly *not* 0.9.0 scope; they are the 0.9.x improve-tuning track.
312
+
313
+ ### D3 — conformance and spec docs
314
+
315
+ 1. Rewrite `docs/architecture/testing/okf-v0.1-conformance-runbook.md` for
316
+ v0.2 and bump the pinned `KC_REF` (`:57`), inspecting the upstream
317
+ `okf/SPEC.md` diff first as the runbook itself instructs (`:61-62`).
318
+ 2. Update the §0.1 OKF↔AKM field-mapping table in
319
+ `akm-0.9.0-bundle-adapter-spec.md` (`:22-35`) and the frozen-reference
320
+ paragraph (`:480`); add a v0.2 note to `okf-support.md`.
321
+ 3. Add the missing `tests/fixtures/format-family-goldens/okf/` golden — OKF
322
+ is the only registered adapter without one.
323
+
324
+ ### Tests
325
+
326
+ - `tests/core/adapter/okf-adapter.test.ts` — update the `timestamp`
327
+ assertions (`:142`, `:291`, `:300`) to cover `generated.at` precedence and
328
+ legacy fallback; add parsing cases for each new family, including the
329
+ `verified` single-mapping form and non-string v0.2 `sources` surviving
330
+ intact.
331
+ - `tests/integration/okf-conformance.test.ts` — v0.2 fixture bundle alongside
332
+ the v0.1 one; both must index; write-rejection block unchanged.
333
+ - Promotion-path test: an accepted automated proposal produces frontmatter
334
+ with `generated` (and `verified` when gated), round-tripping through
335
+ `asset-serialize.ts` and re-indexing losslessly.
336
+
337
+ ### Acceptance
338
+
339
+ - v0.1 and v0.2 bundles both index correctly (v0.1 fixtures byte-identical in
340
+ behavior to today).
341
+ - AKM-authored assets written through promotion carry `generated`, plus
342
+ `verified` when a gate/review confirmed them.
343
+ - Conformance runbook passes end to end at the new `KC_REF`; consumer-only
344
+ status intact.
345
+ - CHANGELOG entries under Added (v0.2 read support; provenance stamping);
346
+ #730 closes.
347
+
348
+ ## Sequencing and release
349
+
350
+ 1. **PR 1 — Workstream A** (behavior change; eval evidence + CHANGELOG).
351
+ 2. **PR 2 — Workstream B** (pure refactor + guard rule; rebases trivially).
352
+ 3. **PR 3 — Workstream C** and **PR 4 — Workstream D** in parallel (disjoint
353
+ surfaces: state.db/maintenance vs adapter/proposal serialization). D is the
354
+ largest; its one open naming decision (D1.3) should be settled in review,
355
+ not up front.
356
+ 4. Cut the next rc with all four merged, soak, ship **0.9.0**.
357
+ 5. On release: revisit milestone due dates (0.9.0's 2026-07-06 has passed;
358
+ 0.9.1 — now carrying only #652 — is dated 2026-08-08), and schedule the
359
+ two deliberate follow-ups: flipping `improve.stateGc.collect` on once live
360
+ reports prove clean, and the deeper v0.2 consumers on the improve-tuning
361
+ track.