akm-cli 0.9.1 → 0.9.2-alpha.2

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 (350) hide show
  1. package/CHANGELOG.md +103 -28
  2. package/README.md +3 -1
  3. package/SECURITY.md +1 -1
  4. package/STABILITY.md +1 -1
  5. package/dist/akm +2 -2
  6. package/dist/akm-migrate +2 -2
  7. package/dist/assets/hints/cli-hints-full.md +14 -9
  8. package/dist/assets/improve-strategies/proactive-maintenance.json +1 -1
  9. package/dist/assets/improve-strategies/reflect-distill.json +1 -1
  10. package/dist/assets/models.json +35 -0
  11. package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +3 -4
  12. package/dist/assets/stash-skeleton/facts/conventions/organization.md +1 -3
  13. package/dist/assets/tasks/core/extract.yml +6 -5
  14. package/dist/assets/tasks/core/improve.yml +6 -5
  15. package/dist/assets/tasks/core/index-refresh.yml +6 -5
  16. package/dist/assets/tasks/core/sync.yml +6 -5
  17. package/dist/assets/tasks/core/version-check.yml +6 -5
  18. package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +6 -5
  19. package/dist/assets/tasks/improve/akm-improve-catchup.yml +6 -5
  20. package/dist/assets/tasks/improve/akm-improve-consolidate.yml +6 -5
  21. package/dist/assets/tasks/improve/akm-improve-frequent.yml +6 -5
  22. package/dist/assets/tasks/improve/akm-improve-nightly.yml +6 -5
  23. package/dist/cli/confirm.js +2 -2
  24. package/dist/cli/parse-args.js +3 -24
  25. package/dist/cli/retired-commands.js +1 -1
  26. package/dist/cli/shared.js +2 -2
  27. package/dist/cli.js +11 -9
  28. package/dist/commands/agent/agent-dispatch.js +55 -89
  29. package/dist/commands/agent/contribute-cli.js +12 -45
  30. package/dist/commands/command/builtin-action.js +32 -0
  31. package/dist/commands/command/command-cli.js +99 -0
  32. package/dist/commands/command/command-execution.js +308 -0
  33. package/dist/commands/command/execution-source-loader.js +176 -0
  34. package/dist/commands/command/portable-template.js +60 -0
  35. package/dist/commands/config-cli.js +10 -4
  36. package/dist/commands/env/env.js +4 -2
  37. package/dist/commands/feedback-cli.js +1 -1
  38. package/dist/commands/health/checks.js +241 -29
  39. package/dist/commands/health/html-report.js +0 -14
  40. package/dist/commands/health/report-view-model.js +0 -1
  41. package/dist/commands/health/surfaces.js +6 -7
  42. package/dist/commands/health/types.js +0 -2
  43. package/dist/commands/health.js +63 -18
  44. package/dist/commands/improve/collapse-detector.js +5 -6
  45. package/dist/commands/improve/consolidate.js +251 -214
  46. package/dist/commands/improve/distill/promote-memory.js +71 -34
  47. package/dist/commands/improve/distill/quality-gate.js +17 -5
  48. package/dist/commands/improve/distill.js +232 -155
  49. package/dist/commands/improve/eligibility.js +112 -79
  50. package/dist/commands/improve/execution.js +57 -0
  51. package/dist/commands/improve/extract-cli.js +5 -5
  52. package/dist/commands/improve/extract-prompt.js +64 -22
  53. package/dist/commands/improve/extract.js +608 -360
  54. package/dist/commands/improve/improve-strategies.js +43 -14
  55. package/dist/commands/improve/improve.js +249 -29
  56. package/dist/commands/improve/loop-stages.js +11 -17
  57. package/dist/commands/improve/memory/memory-contradiction-detect.js +90 -66
  58. package/dist/commands/improve/outcome-loop.js +22 -38
  59. package/dist/commands/improve/planner.js +134 -0
  60. package/dist/commands/improve/preparation.js +730 -409
  61. package/dist/commands/improve/reflect.js +386 -223
  62. package/dist/commands/improve/run-context.js +3 -4
  63. package/dist/commands/improve/salience.js +6 -58
  64. package/dist/commands/improve/session-asset.js +12 -12
  65. package/dist/commands/lint/index.js +101 -29
  66. package/dist/commands/migrate-cli.js +11 -69
  67. package/dist/commands/migration-tool.js +6 -9
  68. package/dist/commands/models-cli.js +27 -0
  69. package/dist/commands/proposal/drain.js +258 -186
  70. package/dist/commands/proposal/proposal-cli.js +32 -10
  71. package/dist/commands/proposal/proposal.js +2 -5
  72. package/dist/commands/proposal/propose.js +192 -172
  73. package/dist/commands/proposal/repository.js +54 -91
  74. package/dist/commands/proposal/validators/proposal-validators.js +9 -7
  75. package/dist/commands/read/curate.js +53 -22
  76. package/dist/commands/read/registry-search.js +25 -9
  77. package/dist/commands/read/remember-cli.js +14 -2
  78. package/dist/commands/read/search.js +10 -4
  79. package/dist/commands/read/show.js +139 -153
  80. package/dist/commands/registry-cli.js +16 -7
  81. package/dist/commands/remember.js +33 -18
  82. package/dist/commands/sources/add-cli.js +19 -178
  83. package/dist/commands/sources/bundle-cli.js +15 -3
  84. package/dist/commands/sources/dangerous-env-audit.js +135 -0
  85. package/dist/commands/sources/info.js +2 -1
  86. package/dist/commands/sources/installed-stashes.js +901 -177
  87. package/dist/commands/sources/schema-repair.js +174 -95
  88. package/dist/commands/sources/self-update.js +30 -74
  89. package/dist/commands/sources/source-add.js +3 -5
  90. package/dist/commands/sources/sources-cli.js +2 -15
  91. package/dist/commands/sources/update-transaction.js +220 -0
  92. package/dist/commands/tasks/tasks-cli.js +3 -3
  93. package/dist/commands/tasks/tasks.js +736 -317
  94. package/dist/commands/workflow-cli.js +2 -2
  95. package/dist/core/adapter/adapters/agent-skills-adapter.js +3 -0
  96. package/dist/core/adapter/adapters/akm-adapter.js +85 -35
  97. package/dist/core/adapter/adapters/akm-lint.js +54 -39
  98. package/dist/core/adapter/adapters/akm-metadata.js +45 -45
  99. package/dist/core/adapter/adapters/akm-task-adapter.js +32 -49
  100. package/dist/core/adapter/adapters/akm-workflow-adapter.js +38 -23
  101. package/dist/core/adapter/adapters/dotenv-adapter.js +30 -1
  102. package/dist/core/adapter/adapters/generic-files-adapter.js +11 -0
  103. package/dist/core/adapter/adapters/index.js +0 -9
  104. package/dist/core/adapter/adapters/llm-wiki-adapter.js +4 -0
  105. package/dist/core/adapter/adapters/okf-adapter.js +4 -0
  106. package/dist/core/adapter/adapters/opencode-adapter.js +5 -8
  107. package/dist/core/adapter/adapters/tool-dir-shared.js +63 -6
  108. package/dist/core/adapter/adapters/website-snapshot-adapter.js +4 -0
  109. package/dist/core/adapter/execution-source.js +308 -0
  110. package/dist/core/adapter/recognize-match.js +36 -13
  111. package/dist/core/adapter/registry.js +0 -9
  112. package/dist/core/asset/stash-meta.js +94 -4
  113. package/dist/core/common.js +6 -11
  114. package/dist/core/config/config-io.js +3 -3
  115. package/dist/core/config/config-schema.js +18 -40
  116. package/dist/core/config/config-sources.js +11 -21
  117. package/dist/core/config/config-walker.js +31 -13
  118. package/dist/core/config/config.js +23 -26
  119. package/dist/core/config/schema/engines.js +8 -7
  120. package/dist/core/config/schema/improve-processes.js +29 -5
  121. package/dist/core/config/schema/index-config.js +0 -27
  122. package/dist/core/config/schema/primitives.js +1 -23
  123. package/dist/core/config/schema/sources-bundles.js +13 -16
  124. package/dist/core/errors.js +2 -0
  125. package/dist/core/events.js +68 -32
  126. package/dist/core/extra-params.js +1 -0
  127. package/dist/core/improve-result.js +315 -0
  128. package/dist/core/lesson-lint.js +0 -6
  129. package/dist/core/maintenance-barrier.js +4 -4
  130. package/dist/core/network-policy.js +152 -0
  131. package/dist/core/paths.js +1 -1
  132. package/dist/core/recognition-util.js +4 -4
  133. package/dist/core/registry-url.js +456 -0
  134. package/dist/core/state/migrations.js +161 -47
  135. package/dist/core/state-db.js +453 -80
  136. package/dist/core/system-error.js +32 -0
  137. package/dist/core/time.js +2 -12
  138. package/dist/core/write-source.js +0 -18
  139. package/dist/execution/directory-identity.js +52 -0
  140. package/dist/execution/executable-identity.js +107 -0
  141. package/dist/execution/guarded-source.js +398 -0
  142. package/dist/execution/json.js +95 -0
  143. package/dist/{commands/health/types-session-log.js → execution/limits.js} +2 -1
  144. package/dist/execution/record.js +55 -0
  145. package/dist/execution/resolved-request.js +730 -0
  146. package/dist/execution/source.js +320 -0
  147. package/dist/indexer/bundle-identity-guard.js +5 -4
  148. package/dist/indexer/db/graph-db.js +33 -0
  149. package/dist/indexer/graph/graph-boost.js +3 -4
  150. package/dist/indexer/graph/graph-extraction.js +562 -373
  151. package/dist/indexer/index-written-assets.js +78 -39
  152. package/dist/indexer/indexer.js +471 -432
  153. package/dist/indexer/installations.js +6 -0
  154. package/dist/indexer/lookup/adapter-concept-owner.js +283 -0
  155. package/dist/indexer/materialize-embeddings.js +155 -0
  156. package/dist/indexer/passes/memory-inference.js +227 -174
  157. package/dist/indexer/passes/metadata.js +263 -118
  158. package/dist/indexer/scan/doc-to-entry.js +7 -10
  159. package/dist/indexer/scan/drain-dir.js +51 -23
  160. package/dist/indexer/search/db-search.js +156 -50
  161. package/dist/indexer/search/fts-query.js +40 -40
  162. package/dist/indexer/search/ranking.js +36 -1
  163. package/dist/indexer/search/search-attribution.js +3 -1
  164. package/dist/indexer/search/search-fields.js +23 -14
  165. package/dist/indexer/search/search-hit-enrichers.js +1 -1
  166. package/dist/indexer/search/search-source.js +7 -16
  167. package/dist/indexer/search/semantic-status.js +10 -1
  168. package/dist/indexer/usage/show-usage.js +105 -0
  169. package/dist/indexer/usage/usage-events.js +7 -2
  170. package/dist/indexer/walk/matchers.js +40 -10
  171. package/dist/indexer/walk/path-resolver.js +5 -2
  172. package/dist/indexer/walk/walker.js +20 -2
  173. package/dist/integrations/agent/builder-shared.js +3 -6
  174. package/dist/integrations/agent/conversation-fallback.js +16 -0
  175. package/dist/integrations/agent/engine-resolution.js +87 -87
  176. package/dist/integrations/agent/execution-cascade.js +566 -0
  177. package/dist/integrations/agent/execution-definitions.js +211 -0
  178. package/dist/integrations/agent/execution-lowering.js +811 -0
  179. package/dist/integrations/agent/execution-preparation.js +67 -0
  180. package/dist/integrations/agent/index.js +0 -2
  181. package/dist/integrations/agent/inline-execution.js +74 -0
  182. package/dist/integrations/agent/model-map.js +515 -0
  183. package/dist/integrations/agent/persona-fallback.js +30 -0
  184. package/dist/integrations/agent/request-lowering.js +186 -0
  185. package/dist/integrations/agent/runner-dispatch.js +230 -37
  186. package/dist/integrations/agent/runner.js +12 -83
  187. package/dist/integrations/harnesses/aider/agent-builder.js +8 -0
  188. package/dist/integrations/harnesses/aider/index.js +0 -1
  189. package/dist/integrations/harnesses/amazonq/agent-builder.js +8 -0
  190. package/dist/integrations/harnesses/amazonq/index.js +0 -1
  191. package/dist/integrations/harnesses/claude/agent-builder.js +14 -1
  192. package/dist/integrations/harnesses/claude/index.js +1 -5
  193. package/dist/integrations/harnesses/claude/session-log.js +3 -33
  194. package/dist/integrations/harnesses/codex/agent-builder.js +8 -0
  195. package/dist/integrations/harnesses/codex/index.js +0 -1
  196. package/dist/integrations/harnesses/copilot/agent-builder.js +8 -0
  197. package/dist/integrations/harnesses/copilot/index.js +0 -1
  198. package/dist/integrations/harnesses/gemini/agent-builder.js +8 -0
  199. package/dist/integrations/harnesses/gemini/index.js +0 -1
  200. package/dist/integrations/harnesses/index.js +4 -44
  201. package/dist/integrations/harnesses/opencode/agent-builder.js +16 -9
  202. package/dist/integrations/harnesses/opencode/index.js +0 -2
  203. package/dist/integrations/harnesses/opencode/session-log.js +14 -204
  204. package/dist/integrations/harnesses/opencode-sdk/harness.js +12 -1
  205. package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +40 -42
  206. package/dist/integrations/harnesses/openhands/agent-builder.js +8 -0
  207. package/dist/integrations/harnesses/openhands/index.js +0 -1
  208. package/dist/integrations/harnesses/pi/agent-builder.js +8 -0
  209. package/dist/integrations/harnesses/pi/index.js +0 -1
  210. package/dist/integrations/harnesses/shared.js +0 -1
  211. package/dist/integrations/harnesses/types.js +1 -3
  212. package/dist/integrations/lockfile.js +82 -79
  213. package/dist/integrations/session-logs/index.js +6 -17
  214. package/dist/integrations/session-logs/provider-base.js +1 -29
  215. package/dist/llm/client.js +10 -5
  216. package/dist/llm/embedder.js +6 -7
  217. package/dist/llm/embedders/local.js +37 -88
  218. package/dist/llm/embedders/types.js +1 -1
  219. package/dist/llm/graph-extract.js +75 -50
  220. package/dist/llm/index-passes.js +43 -5
  221. package/dist/llm/memory-infer.js +8 -6
  222. package/dist/llm/metadata-enhance.js +5 -3
  223. package/dist/llm/structured-call.js +122 -25
  224. package/dist/output/format-exempt.js +1 -1
  225. package/dist/output/render-registry.js +0 -16
  226. package/dist/output/renderers.js +12 -7
  227. package/dist/output/shapes/curate.js +1 -0
  228. package/dist/output/shapes/helpers.js +10 -2
  229. package/dist/output/shapes/passthrough.js +2 -0
  230. package/dist/output/text/command-format.js +31 -33
  231. package/dist/output/text/health-format.js +1 -29
  232. package/dist/output/text/migrate.js +6 -56
  233. package/dist/output/text/proposal-format.js +16 -1
  234. package/dist/output/text/workflow-format.js +16 -0
  235. package/dist/registry/network.js +279 -0
  236. package/dist/registry/pinned-request-helper.js +247 -0
  237. package/dist/registry/pinned-transport.js +717 -0
  238. package/dist/registry/providers/skills-sh.js +18 -6
  239. package/dist/registry/providers/static-index.js +20 -7
  240. package/dist/registry/resolve.js +53 -28
  241. package/dist/scripts/akm-migrate-node.js +19334 -52269
  242. package/dist/scripts/akm-migrate.js +19270 -51612
  243. package/dist/setup/registry-stash-loader.js +64 -20
  244. package/dist/setup/semantic-assets.js +9 -34
  245. package/dist/setup/setup.js +12 -30
  246. package/dist/setup/source-identity.js +17 -0
  247. package/dist/setup/steps/sources.js +36 -15
  248. package/dist/setup/steps/tasks.js +39 -11
  249. package/dist/sources/providers/git-provider.js +3 -3
  250. package/dist/sources/providers/npm.js +2 -2
  251. package/dist/sources/providers/provider-utils.js +4 -3
  252. package/dist/sources/providers/website.js +11 -7
  253. package/dist/sources/snapshot-fetchers/host-guard.js +9 -136
  254. package/dist/sources/snapshot-fetchers/website-ingest.js +25 -109
  255. package/dist/sources/website-url.js +73 -0
  256. package/dist/storage/engines/sqlite-migrations.js +81 -26
  257. package/dist/storage/managed-db.js +27 -24
  258. package/dist/storage/repositories/events-repository.js +3 -0
  259. package/dist/storage/repositories/index-connection.js +42 -10
  260. package/dist/storage/repositories/index-entries-repository.js +203 -229
  261. package/dist/storage/repositories/index-entry-mapper.js +8 -12
  262. package/dist/storage/repositories/index-entry-schema.js +255 -0
  263. package/dist/storage/repositories/index-fts-repository.js +64 -71
  264. package/dist/storage/repositories/index-llm-cache-repository.js +8 -13
  265. package/dist/storage/repositories/index-meta-repository.js +0 -11
  266. package/dist/storage/repositories/index-schema.js +74 -350
  267. package/dist/storage/repositories/index-utility-repository.js +12 -17
  268. package/dist/storage/repositories/index-vec-repository.js +56 -7
  269. package/dist/storage/repositories/proposals-repository.js +4 -127
  270. package/dist/storage/repositories/registry-cache.js +2 -1
  271. package/dist/storage/repositories/task-history-repository.js +20 -40
  272. package/dist/storage/repositories/workflow-runs-repository.js +228 -129
  273. package/dist/storage/sqlite-read-snapshot.js +148 -0
  274. package/dist/tasks/backends/cron.js +170 -42
  275. package/dist/tasks/backends/index.js +1 -1
  276. package/dist/tasks/backends/launchd.js +787 -202
  277. package/dist/tasks/backends/schtasks.js +282 -83
  278. package/dist/tasks/embedded.js +7 -7
  279. package/dist/tasks/frozen-script.js +50 -0
  280. package/dist/tasks/resolve-akm-bin.js +5 -1
  281. package/dist/tasks/runner.js +239 -251
  282. package/dist/tasks/runtime-v3.js +281 -0
  283. package/dist/tasks/scheduler-binding.js +272 -0
  284. package/dist/tasks/scheduler-invocation.js +57 -43
  285. package/dist/tasks/scheduler-sync.js +654 -0
  286. package/dist/tasks/source-v3.js +752 -0
  287. package/dist/tasks/standalone-script-entry.js +5 -0
  288. package/dist/tasks/task-id.js +29 -0
  289. package/dist/workflows/authoring/authoring.js +15 -32
  290. package/dist/workflows/exec/dispatch-redaction.js +14 -8
  291. package/dist/workflows/exec/exec-unit.js +7 -28
  292. package/dist/workflows/exec/frozen-judge.js +57 -89
  293. package/dist/workflows/exec/lowering-notices.js +23 -0
  294. package/dist/workflows/exec/native-executor.js +301 -458
  295. package/dist/workflows/exec/param-secrets.js +4 -3
  296. package/dist/workflows/exec/run-workflow.js +26 -32
  297. package/dist/workflows/exec/step-work.js +105 -109
  298. package/dist/workflows/exec/unit-dispatch.js +103 -27
  299. package/dist/workflows/exec/unit-writer.js +3 -3
  300. package/dist/workflows/exec/worktree.js +2 -2
  301. package/dist/workflows/ir/compile.js +86 -72
  302. package/dist/workflows/ir/environment-v4.js +328 -0
  303. package/dist/workflows/ir/freeze-v4.js +122 -0
  304. package/dist/workflows/ir/plan-hash.js +13 -7
  305. package/dist/workflows/ir/schema-v4.js +525 -0
  306. package/dist/workflows/ir/schema.js +25 -284
  307. package/dist/workflows/ir/source-freeze-v4.js +506 -0
  308. package/dist/workflows/parser.js +27 -24
  309. package/dist/workflows/program/schema.js +1 -2
  310. package/dist/workflows/renderer.js +42 -29
  311. package/dist/workflows/resource-limits.js +4 -5
  312. package/dist/workflows/runtime/agent-identity.js +11 -13
  313. package/dist/workflows/runtime/plan-classifier.js +8 -8
  314. package/dist/workflows/runtime/runs.js +27 -43
  315. package/dist/workflows/runtime/workflow-asset-loader.js +45 -205
  316. package/dist/workflows/source-files.js +373 -0
  317. package/dist/workflows/source-ir/compile.js +196 -0
  318. package/dist/workflows/source-ir/github-yaml.js +577 -0
  319. package/dist/workflows/source-ir/ordering.js +38 -0
  320. package/dist/workflows/source-ir/program.js +50 -0
  321. package/dist/workflows/source-ir/result.js +26 -0
  322. package/dist/workflows/source-ir/schema.js +772 -0
  323. package/dist/workflows/source-ir/semantics.js +242 -0
  324. package/dist/workflows/source-ir/uses.js +14 -0
  325. package/docs/README.md +2 -0
  326. package/docs/migration/README.md +3 -1
  327. package/docs/migration/release-notes/0.9.2.md +55 -0
  328. package/docs/migration/release-notes/README.md +5 -0
  329. package/docs/migration/v0.8-to-v0.9.md +76 -1077
  330. package/docs/migration/v0.9.0-troubleshooting.md +104 -516
  331. package/docs/migration/v0.9.1-to-v0.9.2.md +150 -0
  332. package/docs/reference/README.md +1 -0
  333. package/docs/reference/cli.md +230 -98
  334. package/docs/reference/configuration.md +159 -36
  335. package/docs/reference/data-and-telemetry.md +19 -1
  336. package/docs/reference/supported-formats.md +23 -3
  337. package/docs/reference/tasks.md +182 -0
  338. package/docs/reference/workflow-schema.md +91 -40
  339. package/docs/reference/workflows.md +33 -6
  340. package/package.json +10 -6
  341. package/schemas/akm-config.json +372 -224
  342. package/schemas/akm-task.json +324 -80
  343. package/schemas/akm-workflow.json +6 -9
  344. package/dist/core/migration-operation.js +0 -75
  345. package/dist/integrations/agent/model-aliases.js +0 -74
  346. package/dist/tasks/parser.js +0 -380
  347. package/dist/tasks/schema.js +0 -123
  348. package/dist/tasks/validator.js +0 -80
  349. package/dist/workflows/ir/freeze.js +0 -320
  350. package/dist/workflows/runtime/document-cache.js +0 -13
@@ -1,7 +1,39 @@
1
1
  // This Source Code Form is subject to the terms of the Mozilla Public
2
2
  // License, v. 2.0. If a copy of the MPL was not distributed with this
3
3
  // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
- import { assertMigrationRegistry, runMigrations as runSqliteMigrations, } from "../../storage/engines/sqlite-migrations.js";
4
+ import { assertMigrationLedger, assertMigrationRegistry, runMigrations as runSqliteMigrations, } from "../../storage/engines/sqlite-migrations.js";
5
+ /**
6
+ * Explicit safety classification for every released state migration ID.
7
+ *
8
+ * This registry is deliberately separate from the immutable migration bodies:
9
+ * released IDs, order, and SQL stay byte-for-byte unchanged. A runtime
10
+ * assertion below requires this key order to match {@link STATE_MIGRATIONS}
11
+ * exactly, so appending a migration also requires an explicit safety decision.
12
+ */
13
+ export const STATE_MIGRATION_SAFETY_BY_ID = Object.freeze({
14
+ "001-initial-schema": "additive",
15
+ "002-task-history-per-run": "data-preserving-rebuild",
16
+ "003-improve-runs": "additive",
17
+ "004-extract-sessions-seen": "additive",
18
+ "005-proposal-fs-imports": "additive",
19
+ "006-proposals-pending-ref-source": "additive",
20
+ "007-consolidation-judged": "additive",
21
+ "008-body-embeddings": "additive",
22
+ "009-asset-salience": "additive",
23
+ "010-asset-outcome": "additive",
24
+ "011-asset-salience-homeostatic-demoted-at": "additive",
25
+ "012-improve-gate-thresholds": "additive",
26
+ "013-extract-sessions-content-hash": "additive",
27
+ "014-recombine-hypotheses": "additive",
28
+ "015-asset-salience-encoding-source": "additive",
29
+ "016-collapse-churn-detector": "additive",
30
+ "017-improve-run-strategy": "additive",
31
+ "018-drop-dead-lane-schema": "historical-destructive",
32
+ "019-proposal-fingerprints": "additive",
33
+ "020-three-db-cutover": "additive",
34
+ "021-asset-state-missing-since": "additive",
35
+ "022-workflow-unit-attempts": "additive",
36
+ });
5
37
  export const STATE_MIGRATIONS = [
6
38
  // ── Migration 001 — initial schema ──────────────────────────────────────────
7
39
  {
@@ -292,7 +324,7 @@ export const STATE_MIGRATIONS = [
292
324
  // captured — but persistent and queryable.
293
325
  //
294
326
  // Indexed (query) columns:
295
- // harness TEXT — harness name (claude-code, opencode, ...).
327
+ // harness TEXT — harness name (claude, opencode, ...).
296
328
  // session_id TEXT — platform-native session identifier.
297
329
  // processed_at TEXT — ISO-8601 UTC; when extract last ran on this session.
298
330
  // session_ended_at TEXT — session.endedAt at processing time. When a
@@ -346,29 +378,11 @@ export const STATE_MIGRATIONS = [
346
378
  },
347
379
  // ── Migration 005 — proposal_fs_imports ─────────────────────────────────────
348
380
  //
349
- // One-shot ledger for the legacy filesystem→SQLite proposal import (#578).
350
- //
351
- // VESTIGIAL as of the Chunk-8 fold: the legacy `proposal.json` import moved
352
- // OUT of the live per-operation path and INTO the one-time migrator
353
- // (`scripts/akm-migrate/migrate/legacy/proposal-fs-import.ts`, wired through
354
- // `akm-migrate apply`),
355
- // whose idempotency is INSERT OR IGNORE on the proposal UUID plus migrate-apply's
356
- // incomplete sentinel — it no longer reads or writes this ledger. The CREATE TABLE
357
- // stays because migration IDs are append-only: removing a released migration
358
- // would make the schema_migrations ledger of an
359
- // already-migrated rc database stop being an exact ordered prefix, and the
360
- // runner would refuse to open it. The empty table is harmless.
361
- //
362
- // Original purpose (pre-fold): the first proposal operation against a stash
363
- // imported any legacy `proposal.json` files (INSERT OR IGNORE) and recorded
364
- // the stash here so later invocations skipped the directory walk.
365
- //
366
- // Indexed (query) columns:
367
- // stash_dir TEXT PK — absolute stash root the import ran against.
368
- //
369
- // Non-indexed columns:
370
- // imported_at TEXT — ISO-8601 UTC; when the import completed.
371
- // imported_count INTEGER — rows actually inserted by the import.
381
+ // Released migration history is immutable. The filesystem proposal importer
382
+ // has been deleted from the current runtime, but existing databases can
383
+ // already contain this ledger id and table. Keeping the inert DDL here lets
384
+ // their migration prefix validate and lets fresh databases reproduce the
385
+ // same ordered schema history without restoring the importer.
372
386
  {
373
387
  id: "005-proposal-fs-imports",
374
388
  up: `
@@ -829,27 +843,10 @@ export const STATE_MIGRATIONS = [
829
843
  ON proposal_fingerprints(stash_dir, ref);
830
844
  `,
831
845
  },
832
- // ── Migration 020 three-DB cutover baseline DDL (Chunk 8, WI-8.2) ───────────
833
- //
834
- // The state.db half of the three-DB merge (plan §3.2/§8, normative §11.4,
835
- // chunk-8 cutover design §1). This migration is PURE,
836
- // IDEMPOTENT DDL ONLY — `CREATE TABLE IF NOT EXISTS` (+ indexes),
837
- // never a DROP or a data move. The actual data movement (the workflow.db merge,
838
- // the usage_events rescue from index.db, the full old-ref→item_ref re-key, and
839
- // the workflow.db delete / index.db quarantine) is idempotent migrate-apply
840
- // code driven by
841
- // `scripts/akm-migrate/migrate/legacy/three-db-cutover.ts`. See the no-DROP
842
- // contract carve-out note in `src/core/state-db.ts`.
843
- //
844
- // The three workflow tables are the 10 pre-cutover workflow migrations
845
- // (the frozen `scripts/akm-migrate/migrate/legacy/workflow-migrations-bodies.ts`
846
- // base schema + 001–010) folded into one baseline at their FINAL post-010 shape — column
847
- // lists, CHECK constraints, and indexes copied verbatim. `usage_events` mirrors
848
- // index.db's former `ensureUsageEventsSchema` (`src/indexer/usage/usage-events.ts`),
849
- // its new durable home. `legacy_state` mirrors `ensureLegacyStateTable`
850
- // (`src/storage/repositories/index-entries-repository.ts`), the orphan
851
- // quarantine archive re-homed from index.db (durable, auditable, purgeable).
852
- // Nothing else — NO bindings/lifecycle tables (Tier B / deferred, §3.2).
846
+ // Migration 020 installs the durable workflow, usage, and quarantine tables
847
+ // in state.db. It is additive/idempotent DDL only: current managed databases
848
+ // advance through the ledger automatically, while unknown/divergent ledgers
849
+ // fail closed. There is no external data-movement coordinator.
853
850
  {
854
851
  id: "020-three-db-cutover",
855
852
  up: `
@@ -983,8 +980,65 @@ export const STATE_MIGRATIONS = [
983
980
  ALTER TABLE asset_outcome ADD COLUMN missing_since INTEGER DEFAULT NULL;
984
981
  `,
985
982
  },
983
+ // ── Migration 022 — append-only durable workflow dispatch attempts ────────
984
+ //
985
+ // `workflow_run_units` is the current status/reuse projection. V4 writes
986
+ // every external dispatch reservation and terminal result here so
987
+ // retry/reclaim history, stable dispatch identity, and known usage cannot be
988
+ // erased by an upsert of that projection row.
989
+ {
990
+ id: "022-workflow-unit-attempts",
991
+ up: `
992
+ CREATE TABLE workflow_run_unit_attempts (
993
+ run_id TEXT NOT NULL,
994
+ unit_id TEXT NOT NULL,
995
+ attempt INTEGER NOT NULL CHECK (attempt >= 1),
996
+ dispatch_id TEXT NOT NULL,
997
+ step_id TEXT NOT NULL,
998
+ node_id TEXT NOT NULL,
999
+ phase TEXT NOT NULL CHECK (phase IN ('unit', 'gate')),
1000
+ runner TEXT,
1001
+ engine TEXT,
1002
+ model TEXT,
1003
+ input_hash TEXT NOT NULL,
1004
+ status TEXT NOT NULL CHECK (status IN ('running', 'completed', 'failed', 'skipped')),
1005
+ result_json TEXT,
1006
+ tokens INTEGER,
1007
+ failure_reason TEXT,
1008
+ session_id TEXT,
1009
+ worktree_path TEXT,
1010
+ started_at TEXT NOT NULL,
1011
+ finished_at TEXT,
1012
+ claim_holder TEXT NOT NULL,
1013
+ claim_expires_at TEXT NOT NULL,
1014
+ PRIMARY KEY (run_id, unit_id, attempt),
1015
+ FOREIGN KEY (run_id) REFERENCES workflow_runs(id) ON DELETE CASCADE
1016
+ );
1017
+ CREATE UNIQUE INDEX idx_workflow_run_unit_attempts_dispatch
1018
+ ON workflow_run_unit_attempts(dispatch_id);
1019
+ CREATE INDEX idx_workflow_run_unit_attempts_run_step
1020
+ ON workflow_run_unit_attempts(run_id, step_id, unit_id, attempt);
1021
+ CREATE INDEX idx_workflow_run_unit_attempts_running_claim
1022
+ ON workflow_run_unit_attempts(run_id, status, claim_expires_at);
1023
+ `,
1024
+ },
986
1025
  ];
987
1026
  assertMigrationRegistry(STATE_MIGRATIONS);
1027
+ function assertStateMigrationSafetyRegistry() {
1028
+ const migrationIds = STATE_MIGRATIONS.map((migration) => migration.id);
1029
+ const classifiedIds = Object.keys(STATE_MIGRATION_SAFETY_BY_ID);
1030
+ if (migrationIds.length !== classifiedIds.length ||
1031
+ migrationIds.some((migrationId, index) => classifiedIds[index] !== migrationId)) {
1032
+ throw new Error("State migration safety classifications must match the exact ordered migration registry.");
1033
+ }
1034
+ }
1035
+ assertStateMigrationSafetyRegistry();
1036
+ export function getStateMigrationSafety(migrationId) {
1037
+ const safety = STATE_MIGRATION_SAFETY_BY_ID[migrationId];
1038
+ if (!safety)
1039
+ throw new Error(`State migration ${migrationId} has no safety classification.`);
1040
+ return safety;
1041
+ }
988
1042
  /**
989
1043
  * Apply every pending migration in a single transaction per migration.
990
1044
  *
@@ -994,5 +1048,65 @@ assertMigrationRegistry(STATE_MIGRATIONS);
994
1048
  * Called automatically by `openStateDatabase()`.
995
1049
  */
996
1050
  export function runMigrations(db, options) {
997
- runSqliteMigrations(db, STATE_MIGRATIONS, { applyPending: options?.applyPending });
1051
+ const initialMigration = STATE_MIGRATIONS[0];
1052
+ if (!initialMigration)
1053
+ throw new Error("State migration registry has no initial migration.");
1054
+ let existingUnversionedSnapshotPrepared = false;
1055
+ const prepareExistingUnversionedState = (lockedDb) => {
1056
+ if (existingUnversionedSnapshotPrepared)
1057
+ return;
1058
+ if (!options?.existingUnversionedDatabase) {
1059
+ throw new Error("Refusing state.db initialization because its migration ledger disappeared after preflight.");
1060
+ }
1061
+ if (!options.allowHistoricalDestructiveStateUpgrade) {
1062
+ throw new Error("Refusing to migrate an existing unversioned state.db during an ordinary managed open. " +
1063
+ "Run `akm upgrade --force` to snapshot it before migration 001.");
1064
+ }
1065
+ const ledger = assertMigrationLedger(lockedDb, STATE_MIGRATIONS);
1066
+ if (ledger.migrationIds.length !== 0) {
1067
+ throw new Error("Refusing an existing unversioned state.db whose migration ledger changed after preflight.");
1068
+ }
1069
+ if (!options.beforeExistingUnversionedStateMigration) {
1070
+ throw new Error("An existing unversioned state.db requires a verified pre-migration safety-copy hook.");
1071
+ }
1072
+ options.beforeExistingUnversionedStateMigration(initialMigration);
1073
+ existingUnversionedSnapshotPrepared = true;
1074
+ };
1075
+ runSqliteMigrations(db, STATE_MIGRATIONS, {
1076
+ lockInitialMigrationPrefixThrough: options?.existingUnversionedDatabase ? "002-task-history-per-run" : undefined,
1077
+ beforeLedgerInitializationLocked(lockedDb) {
1078
+ if (options?.freshDatabase) {
1079
+ if (!options.verifyFreshDatabaseOwnership) {
1080
+ throw new Error("A fresh state.db migration requires verified file ownership.");
1081
+ }
1082
+ options.verifyFreshDatabaseOwnership();
1083
+ return;
1084
+ }
1085
+ prepareExistingUnversionedState(lockedDb);
1086
+ },
1087
+ beforeMigrationLocked(migration, lockedDb) {
1088
+ if (options?.freshDatabase) {
1089
+ if (!options.verifyFreshDatabaseOwnership) {
1090
+ throw new Error("A fresh state.db migration requires verified file ownership.");
1091
+ }
1092
+ options.verifyFreshDatabaseOwnership();
1093
+ }
1094
+ if (options?.existingUnversionedDatabase && !existingUnversionedSnapshotPrepared) {
1095
+ prepareExistingUnversionedState(lockedDb);
1096
+ }
1097
+ if (getStateMigrationSafety(migration.id) !== "historical-destructive" || options?.freshDatabase)
1098
+ return;
1099
+ // The writer lock closes the window between this exact-prefix decision,
1100
+ // the recovery snapshot, and the destructive migration transaction.
1101
+ assertMigrationLedger(lockedDb, STATE_MIGRATIONS);
1102
+ if (!options?.allowHistoricalDestructiveStateUpgrade) {
1103
+ throw new Error(`Refusing to apply historical destructive state migration ${migration.id} during an ordinary managed open. ` +
1104
+ "Run `akm upgrade --force` to create a sibling state.db safety copy and apply it deliberately.");
1105
+ }
1106
+ if (!options.beforeHistoricalDestructiveMigration) {
1107
+ throw new Error(`Historical destructive state migration ${migration.id} requires a verified safety-copy hook.`);
1108
+ }
1109
+ options.beforeHistoricalDestructiveMigration(migration);
1110
+ },
1111
+ });
998
1112
  }