akm-cli 0.9.17-alpha.1 → 0.9.17-alpha.10

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 (399) hide show
  1. package/CHANGELOG.md +1623 -0
  2. package/STABILITY.md +11 -10
  3. package/dist/akm +124 -193
  4. package/dist/akm-migrate +38 -19
  5. package/dist/assets/hints/cli-hints-full.md +6 -7
  6. package/dist/assets/improve-strategies/catchup.json +0 -3
  7. package/dist/assets/improve-strategies/consolidate.json +0 -1
  8. package/dist/assets/improve-strategies/default.json +1 -2
  9. package/dist/assets/improve-strategies/proactive-maintenance.json +1 -2
  10. package/dist/assets/improve-strategies/quick.json +1 -2
  11. package/dist/assets/improve-strategies/reflect-distill.json +1 -2
  12. package/dist/assets/improve-strategies/thorough.json +0 -3
  13. package/dist/assets/prompts/consolidate-pair.md +20 -0
  14. package/dist/assets/prompts/retrieval-relevance-judge.md +6 -0
  15. package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +20 -20
  16. package/dist/assets/stash-skeleton/facts/conventions/domains.md +2 -2
  17. package/dist/assets/templates/html/health.html +3 -5
  18. package/dist/cli/retired-commands.js +1 -1
  19. package/dist/cli/shared.js +6 -2
  20. package/dist/cli/unknown-flags.js +24 -1
  21. package/dist/cli.js +68 -10
  22. package/dist/commands/agent/agent-dispatch.js +1 -1
  23. package/dist/commands/command/command-execution.js +24 -62
  24. package/dist/commands/feedback-cli.js +0 -1
  25. package/dist/commands/health/accept-rate.js +2 -2
  26. package/dist/commands/health/archive-usage.js +92 -0
  27. package/dist/commands/health/checks.js +30 -75
  28. package/dist/commands/health/config-skew.js +38 -0
  29. package/dist/commands/health/data-dir-usage.js +25 -13
  30. package/dist/commands/health/egress.js +54 -0
  31. package/dist/commands/health/html-report.js +1 -42
  32. package/dist/commands/health/improve-metrics.js +136 -587
  33. package/dist/commands/health/md-report.js +1 -6
  34. package/dist/commands/health/plugin-staleness.js +53 -3
  35. package/dist/commands/health/renderers.js +12 -4
  36. package/dist/commands/health/report-view-model.js +14 -119
  37. package/dist/commands/health/types-improve.js +4 -19
  38. package/dist/commands/health/windows.js +64 -74
  39. package/dist/commands/health.js +135 -143
  40. package/dist/commands/improve/consolidate/chunking.js +25 -100
  41. package/dist/commands/improve/consolidate/continuity-check.js +137 -0
  42. package/dist/commands/improve/consolidate/pair-pass.js +791 -0
  43. package/dist/commands/improve/consolidate/sanitize.js +54 -149
  44. package/dist/commands/improve/consolidate.js +573 -1124
  45. package/dist/commands/improve/content-hash.js +16 -24
  46. package/dist/commands/improve/distill/content-repair.js +18 -100
  47. package/dist/commands/improve/distill-guards.js +20 -81
  48. package/dist/commands/improve/distill-promotion-policy.js +23 -243
  49. package/dist/commands/improve/distill.js +608 -1075
  50. package/dist/commands/improve/eligibility.js +126 -400
  51. package/dist/commands/improve/execution.js +8 -10
  52. package/dist/commands/improve/extract-prompt.js +1 -2
  53. package/dist/commands/improve/extract.js +487 -1046
  54. package/dist/commands/improve/feedback-valence.js +0 -25
  55. package/dist/commands/improve/improve-cli.js +54 -171
  56. package/dist/commands/improve/improve-result-file.js +10 -66
  57. package/dist/commands/improve/improve-strategies.js +35 -9
  58. package/dist/commands/improve/improve-usage-report.js +18 -64
  59. package/dist/commands/improve/improve.js +451 -1082
  60. package/dist/commands/improve/ledger.js +119 -0
  61. package/dist/commands/improve/locks.js +2 -8
  62. package/dist/commands/improve/loop-stages.js +401 -1192
  63. package/dist/commands/improve/memory/derived-ref.js +12 -77
  64. package/dist/commands/improve/memory/memory-belief.js +16 -118
  65. package/dist/commands/improve/memory/memory-improve.js +266 -14
  66. package/dist/commands/improve/outcome-loop.js +28 -156
  67. package/dist/commands/improve/planner.js +5 -15
  68. package/dist/commands/improve/preparation.js +776 -2349
  69. package/dist/commands/improve/proactive-maintenance.js +34 -101
  70. package/dist/commands/improve/reflect-noise.js +104 -280
  71. package/dist/commands/improve/reflect.js +642 -1364
  72. package/dist/commands/improve/retrieval-gate.js +127 -0
  73. package/dist/commands/improve/retrieval-scope.js +92 -0
  74. package/dist/commands/improve/salience.js +41 -240
  75. package/dist/commands/improve/session-asset.js +19 -100
  76. package/dist/commands/improve/stage.js +322 -0
  77. package/dist/commands/lint/base-linter.js +37 -15
  78. package/dist/commands/proposal/drain.js +258 -644
  79. package/dist/commands/proposal/proposal-cli.js +19 -20
  80. package/dist/commands/proposal/proposal-types.js +27 -41
  81. package/dist/commands/proposal/proposal.js +38 -8
  82. package/dist/commands/proposal/propose.js +134 -160
  83. package/dist/commands/proposal/repository.js +1099 -1475
  84. package/dist/commands/proposal/validators/proposal-quality-validators.js +71 -174
  85. package/dist/commands/proposal/validators/proposal-validators.js +1 -1
  86. package/dist/commands/proposal/validators/proposals.js +22 -89
  87. package/dist/commands/read/curate.js +105 -462
  88. package/dist/commands/read/knowledge.js +3 -2
  89. package/dist/commands/read/search-cli.js +16 -33
  90. package/dist/commands/read/search.js +17 -23
  91. package/dist/commands/read/show.js +57 -108
  92. package/dist/commands/sources/bundle-cli.js +25 -2
  93. package/dist/commands/sources/bundle-config-ops.js +4 -0
  94. package/dist/commands/sources/dangerous-env-audit.js +1 -2
  95. package/dist/commands/sources/info.js +127 -29
  96. package/dist/commands/sources/installed-stashes.js +197 -746
  97. package/dist/commands/sources/schema-repair.js +98 -129
  98. package/dist/commands/sources/source-add.js +62 -12
  99. package/dist/commands/sources/source-manage.js +9 -2
  100. package/dist/commands/sources/stash-cli.js +24 -4
  101. package/dist/commands/tasks/explain.js +10 -13
  102. package/dist/commands/tasks/tasks-cli.js +12 -13
  103. package/dist/commands/tasks/tasks.js +350 -936
  104. package/dist/commands/tasks/validate.js +26 -24
  105. package/dist/commands/workflow/plan.js +22 -29
  106. package/dist/commands/workflow-cli.js +4 -4
  107. package/dist/core/adapter/adapters/akm-adapter.js +2 -1
  108. package/dist/core/adapter/adapters/akm-lint.js +2 -3
  109. package/dist/core/adapter/adapters/akm-metadata.js +42 -12
  110. package/dist/core/adapter/adapters/akm-task-adapter.js +29 -8
  111. package/dist/core/adapter/adapters/akm-workflow-adapter.js +1 -1
  112. package/dist/core/adapter/execution-source.js +17 -29
  113. package/dist/core/asset/asset-placement.js +4 -13
  114. package/dist/core/asset/resolve-ref.js +1 -1
  115. package/dist/core/bundle-id.js +42 -5
  116. package/dist/core/bundle-rename.js +285 -0
  117. package/dist/core/config/config-io.js +1 -2
  118. package/dist/core/config/config-schema.js +9 -34
  119. package/dist/core/config/config-walker.js +1 -1
  120. package/dist/core/config/config.js +184 -111
  121. package/dist/core/config/engine-semantics.js +0 -2
  122. package/dist/core/config/legacy-source-shape-shim.js +38 -9
  123. package/dist/core/config/schema/embedding.js +20 -5
  124. package/dist/core/config/schema/engines.js +5 -0
  125. package/dist/core/config/schema/execution.js +1 -1
  126. package/dist/core/config/schema/experimental.js +1 -1
  127. package/dist/core/config/schema/improve-processes.js +37 -135
  128. package/dist/core/config/schema/improve.js +4 -42
  129. package/dist/core/config/schema/index-config.js +9 -48
  130. package/dist/core/config/schema/scheduler.js +12 -12
  131. package/dist/core/config/schema/search.js +6 -22
  132. package/dist/core/env-secret-ref.js +0 -1
  133. package/dist/core/errors.js +8 -9
  134. package/dist/core/file-change.js +13 -5
  135. package/dist/core/file-lock.js +76 -173
  136. package/dist/core/improve-result.js +26 -7
  137. package/dist/core/improve-types.js +0 -1
  138. package/dist/core/logs-db.js +2 -2
  139. package/dist/core/loopback.js +7 -12
  140. package/dist/core/non-task-input.js +20 -0
  141. package/dist/core/parse.js +13 -16
  142. package/dist/core/paths.js +0 -31
  143. package/dist/core/redaction.js +109 -2
  144. package/dist/core/run-lock.js +2 -5
  145. package/dist/core/spawn-env.js +1 -1
  146. package/dist/core/state/migrations.js +123 -61
  147. package/dist/core/state-db-scope.js +2 -4
  148. package/dist/core/state-db.js +126 -692
  149. package/dist/core/time.js +0 -20
  150. package/dist/core/type-presentation.js +1 -9
  151. package/dist/core/write-source.js +294 -1005
  152. package/dist/execution/input-contract.js +1 -1
  153. package/dist/execution/resolved-request.js +135 -689
  154. package/dist/execution/source.js +63 -257
  155. package/dist/execution/target-ref.js +1 -1
  156. package/dist/indexer/bundle-identity-guard.js +2 -2
  157. package/dist/indexer/db/llm-cache.js +2 -2
  158. package/dist/indexer/ensure-index.js +46 -87
  159. package/dist/indexer/index-rebuild-lock.js +3 -11
  160. package/dist/indexer/index-writer-lock.js +8 -17
  161. package/dist/indexer/index-written-assets.js +141 -154
  162. package/dist/indexer/indexer.js +400 -1124
  163. package/dist/indexer/links/declared-links.js +90 -0
  164. package/dist/indexer/materialize-embeddings.js +60 -397
  165. package/dist/indexer/passes/memory-inference.js +81 -90
  166. package/dist/indexer/passes/metadata.js +132 -219
  167. package/dist/indexer/read-preflight.js +0 -7
  168. package/dist/indexer/scan/doc-to-entry.js +2 -3
  169. package/dist/indexer/scan/drain-dir.js +1 -1
  170. package/dist/indexer/search/db-search.js +190 -590
  171. package/dist/indexer/search/fts-query.js +30 -41
  172. package/dist/indexer/search/ranking.js +28 -154
  173. package/dist/indexer/search/search-attribution.js +12 -32
  174. package/dist/indexer/search/search-fields.js +11 -15
  175. package/dist/indexer/search/search-hit-enrichers.js +54 -85
  176. package/dist/indexer/search/search-source.js +1 -4
  177. package/dist/indexer/usage/usage-events.js +36 -7
  178. package/dist/indexer/walk/walker.js +3 -4
  179. package/dist/integrations/agent/engine-fallback.js +23 -40
  180. package/dist/integrations/agent/engine-resolution.js +93 -183
  181. package/dist/integrations/agent/execution.js +507 -0
  182. package/dist/integrations/agent/model-map.js +28 -156
  183. package/dist/integrations/agent/request-lowering.js +66 -141
  184. package/dist/integrations/agent/runner-dispatch.js +143 -321
  185. package/dist/integrations/agent/runner.js +54 -14
  186. package/dist/integrations/lockfile.js +53 -101
  187. package/dist/llm/client.js +8 -10
  188. package/dist/llm/embedders/deterministic.js +2 -3
  189. package/dist/llm/embedders/profile.js +71 -0
  190. package/dist/llm/embedders/remote.js +11 -17
  191. package/dist/llm/feature-gate.js +0 -8
  192. package/dist/llm/index-passes.js +3 -5
  193. package/dist/llm/memory-infer.js +1 -2
  194. package/dist/llm/structured-call.js +5 -24
  195. package/dist/output/generic-render.js +23 -11
  196. package/dist/output/html-render.js +13 -10
  197. package/dist/output/render-registry.js +3 -32
  198. package/dist/output/shapes/helpers.js +25 -38
  199. package/dist/output/shapes/passthrough.js +1 -9
  200. package/dist/{indexer/graph/graph-types.js → output/text/bundle-rename.js} +4 -1
  201. package/dist/output/text/command-format.js +69 -31
  202. package/dist/output/text/helpers.js +1 -1
  203. package/dist/output/text/migrate.js +5 -14
  204. package/dist/output/text/proposal-format.js +48 -3
  205. package/dist/output/text/show-format.js +13 -17
  206. package/dist/output/text/workflow-format.js +0 -32
  207. package/dist/output/text.js +2 -0
  208. package/dist/registry/factory.js +4 -19
  209. package/dist/registry/network.js +66 -220
  210. package/dist/registry/providers/index.js +0 -2
  211. package/dist/registry/providers/skills-sh.js +3 -14
  212. package/dist/registry/providers/static-index.js +24 -26
  213. package/dist/registry/resolve.js +55 -131
  214. package/dist/scripts/akm-migrate-node.js +42938 -92375
  215. package/dist/scripts/akm-migrate.js +42930 -92365
  216. package/dist/setup/registry-stash-loader.js +4 -13
  217. package/dist/setup/semantic-assets.js +3 -44
  218. package/dist/setup/setup.js +1 -1
  219. package/dist/setup/steps/connection.js +5 -6
  220. package/dist/setup/steps/platforms.js +2 -2
  221. package/dist/setup/steps/tasks.js +25 -15
  222. package/dist/sources/provider-factory.js +17 -18
  223. package/dist/sources/providers/filesystem.js +2 -3
  224. package/dist/sources/providers/git-install.js +7 -1
  225. package/dist/sources/providers/git-provider.js +0 -3
  226. package/dist/sources/providers/git-stash.js +83 -21
  227. package/dist/sources/providers/npm.js +2 -4
  228. package/dist/sources/providers/provider-utils.js +5 -10
  229. package/dist/sources/providers/website.js +0 -2
  230. package/dist/sources/snapshot-fetchers/website-ingest.js +1 -1
  231. package/dist/sources/website-url.js +2 -2
  232. package/dist/storage/database.js +9 -35
  233. package/dist/storage/repositories/improve-ledger-repository.js +209 -0
  234. package/dist/storage/repositories/index-connection.js +39 -72
  235. package/dist/storage/repositories/index-entries-repository.js +88 -129
  236. package/dist/storage/repositories/index-entry-mapper.js +1 -2
  237. package/dist/storage/repositories/index-entry-schema.js +101 -268
  238. package/dist/storage/repositories/index-fts-repository.js +86 -256
  239. package/dist/storage/repositories/index-links-repository.js +143 -0
  240. package/dist/storage/repositories/index-llm-cache-repository.js +7 -9
  241. package/dist/storage/repositories/index-meta-repository.js +6 -4
  242. package/dist/storage/repositories/index-schema.js +257 -325
  243. package/dist/storage/repositories/index-utility-repository.js +8 -29
  244. package/dist/storage/repositories/index-vec-repository.js +133 -414
  245. package/dist/storage/repositories/outcome-repository.js +2 -1
  246. package/dist/storage/repositories/proposals-repository.js +100 -0
  247. package/dist/storage/repositories/registry-index-cache-repository.js +100 -0
  248. package/dist/storage/repositories/salience-repository.js +1 -19
  249. package/dist/storage/repositories/task-history-repository.js +26 -4
  250. package/dist/storage/repositories/workflow-runs-repository.js +53 -244
  251. package/dist/storage/sqlite-migrations.js +136 -0
  252. package/dist/storage/sqlite-pragmas.js +11 -9
  253. package/dist/storage/sqlite-transaction.js +170 -0
  254. package/dist/storage/state-db-integrity.js +34 -27
  255. package/dist/tasks/activation-config.js +134 -62
  256. package/dist/tasks/backends/cron.js +191 -302
  257. package/dist/tasks/backends/exec-utils.js +2 -5
  258. package/dist/tasks/backends/launchd.js +141 -748
  259. package/dist/tasks/backends/schtasks.js +119 -623
  260. package/dist/tasks/prepare/prepare-support.js +5 -15
  261. package/dist/tasks/prepare/prepare.js +0 -2
  262. package/dist/tasks/resolve-akm-bin.js +20 -79
  263. package/dist/tasks/run/attempt-lifecycle.js +0 -1
  264. package/dist/tasks/run/load-task.js +1 -1
  265. package/dist/tasks/scheduler-binding.js +20 -238
  266. package/dist/tasks/scheduler-invocation.js +136 -244
  267. package/dist/tasks/scheduler-lock.js +53 -0
  268. package/dist/tasks/scheduler-sync.js +368 -679
  269. package/dist/tasks/source/parse-task-source.js +55 -9
  270. package/dist/tasks/source/task-source-v3-frozen.js +3 -4
  271. package/dist/tasks/source/task-to-v4.js +464 -88
  272. package/dist/workflows/authoring/authoring.js +3 -12
  273. package/dist/workflows/compile.js +211 -0
  274. package/dist/workflows/concurrency-policy.js +13 -74
  275. package/dist/workflows/exec/child-invocation.js +3 -17
  276. package/dist/workflows/exec/child-workflow.js +32 -141
  277. package/dist/workflows/exec/dispatch-redaction.js +13 -53
  278. package/dist/workflows/exec/environment.js +98 -0
  279. package/dist/workflows/exec/exec-unit.js +33 -140
  280. package/dist/workflows/exec/frozen-judge.js +7 -59
  281. package/dist/workflows/exec/native-executor.js +82 -341
  282. package/dist/workflows/exec/param-secrets.js +29 -47
  283. package/dist/workflows/exec/run-workflow.js +154 -387
  284. package/dist/workflows/exec/scheduler.js +9 -36
  285. package/dist/workflows/exec/step-work.js +127 -430
  286. package/dist/workflows/exec/unit-dispatch.js +11 -63
  287. package/dist/workflows/exec/unit-writer.js +8 -52
  288. package/dist/workflows/exec/worktree.js +39 -273
  289. package/dist/workflows/freeze/child-output-references.js +4 -15
  290. package/dist/workflows/freeze/environment.js +99 -92
  291. package/dist/workflows/freeze/freeze.js +172 -0
  292. package/dist/workflows/freeze/step-values.js +19 -21
  293. package/dist/workflows/freeze/targets/child-workflow.js +23 -92
  294. package/dist/workflows/freeze/targets/command.js +10 -33
  295. package/dist/workflows/freeze/targets/script.js +5 -12
  296. package/dist/workflows/freeze/targets/shell.js +3 -6
  297. package/dist/workflows/freeze/targets/task.js +25 -80
  298. package/dist/workflows/freeze/task-bindings.js +20 -67
  299. package/dist/workflows/{source-ir/github-yaml.js → github-yaml.js} +88 -206
  300. package/dist/workflows/ir/params.js +6 -51
  301. package/dist/workflows/ir/plan-hash.js +2 -34
  302. package/dist/workflows/parser.js +140 -43
  303. package/dist/{commands/improve/consolidate/types.js → workflows/plan.js} +2 -1
  304. package/dist/workflows/renderer.js +36 -69
  305. package/dist/workflows/resource-limits.js +12 -120
  306. package/dist/workflows/runtime/agent-identity.js +8 -40
  307. package/dist/workflows/runtime/run-outputs.js +3 -6
  308. package/dist/workflows/runtime/run-plan.js +316 -0
  309. package/dist/workflows/runtime/runs.js +48 -200
  310. package/dist/workflows/runtime/workflow-asset-loader.js +24 -57
  311. package/dist/workflows/{source-ir/semantics.js → source-semantics.js} +16 -20
  312. package/dist/workflows/validate-summary.js +2 -7
  313. package/docs/integration/bundling-akm.md +49 -42
  314. package/docs/migration/README.md +1 -0
  315. package/docs/migration/release-notes/0.9.17.md +43 -0
  316. package/docs/migration/v0.9.1-to-v0.9.2.md +23 -7
  317. package/docs/reference/cli.md +229 -133
  318. package/docs/reference/configuration.md +71 -57
  319. package/docs/reference/data-and-telemetry.md +19 -21
  320. package/docs/reference/tasks.md +105 -39
  321. package/docs/reference/workflow-schema.md +14 -18
  322. package/docs/reference/workflows.md +6 -9
  323. package/package.json +1 -1
  324. package/schemas/akm-config.json +87 -754
  325. package/dist/assets/improve-strategies/graph-refresh.json +0 -15
  326. package/dist/assets/prompts/contradiction-judge.md +0 -33
  327. package/dist/assets/prompts/graph-extract-system.md +0 -1
  328. package/dist/assets/prompts/graph-extract-user-prompt.md +0 -35
  329. package/dist/assets/prompts/metadata-enhance-system.md +0 -1
  330. package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +0 -4
  331. package/dist/commands/health/advisories.js +0 -150
  332. package/dist/commands/health/metrics.js +0 -329
  333. package/dist/commands/health/surfaces.js +0 -102
  334. package/dist/commands/improve/anti-collapse.js +0 -83
  335. package/dist/commands/improve/collapse-detector.js +0 -432
  336. package/dist/commands/improve/consolidate/eligibility.js +0 -48
  337. package/dist/commands/improve/consolidate/merge.js +0 -146
  338. package/dist/commands/improve/distill/promote-memory.js +0 -329
  339. package/dist/commands/improve/distill/quality-gate.js +0 -500
  340. package/dist/commands/improve/memory/memory-contradiction-detect.js +0 -291
  341. package/dist/commands/improve/proposal-envelope.js +0 -31
  342. package/dist/commands/improve/run-context.js +0 -123
  343. package/dist/commands/improve/shared.js +0 -21
  344. package/dist/commands/improve/source-identity.js +0 -28
  345. package/dist/commands/improve/triage.js +0 -96
  346. package/dist/commands/proposal/drain-policies.js +0 -151
  347. package/dist/commands/sources/update-transaction.js +0 -220
  348. package/dist/core/action-contributors.js +0 -28
  349. package/dist/core/config/config-version-shim.js +0 -101
  350. package/dist/core/fs-txn.js +0 -405
  351. package/dist/core/lexical-score.js +0 -25
  352. package/dist/core/maintenance-barrier.js +0 -167
  353. package/dist/execution/executable-identity.js +0 -105
  354. package/dist/execution/guarded-source.js +0 -427
  355. package/dist/indexer/db/graph-db.js +0 -444
  356. package/dist/indexer/graph/graph-boost.js +0 -427
  357. package/dist/indexer/graph/graph-dedup.js +0 -95
  358. package/dist/indexer/graph/graph-extraction.js +0 -1182
  359. package/dist/indexer/search/name-match.js +0 -35
  360. package/dist/indexer/search/ranking-contributors.js +0 -515
  361. package/dist/indexer/search/ranking-types.js +0 -4
  362. package/dist/indexer/walk/project-context.js +0 -192
  363. package/dist/integrations/agent/execution-cascade.js +0 -566
  364. package/dist/integrations/agent/execution-definitions.js +0 -202
  365. package/dist/integrations/agent/execution-lowering.js +0 -841
  366. package/dist/integrations/agent/execution-preparation.js +0 -98
  367. package/dist/integrations/agent/inline-execution.js +0 -74
  368. package/dist/llm/graph-extract.js +0 -872
  369. package/dist/llm/metadata-enhance.js +0 -96
  370. package/dist/registry/create-provider-registry.js +0 -29
  371. package/dist/registry/pinned-request-helper.js +0 -247
  372. package/dist/registry/pinned-transport.js +0 -717
  373. package/dist/sources/providers/index.js +0 -14
  374. package/dist/storage/engines/sqlite-migrations.js +0 -271
  375. package/dist/storage/repositories/canaries-repository.js +0 -107
  376. package/dist/storage/repositories/embedding-salvage-repository.js +0 -184
  377. package/dist/storage/repositories/registry-cache.js +0 -113
  378. package/dist/tasks/scheduler-sync-preview.js +0 -52
  379. package/dist/tasks/source/task-to-v3.js +0 -507
  380. package/dist/workflows/freeze/resolve-steps.js +0 -86
  381. package/dist/workflows/freeze/source-freeze.js +0 -64
  382. package/dist/workflows/ir/compile.js +0 -321
  383. package/dist/workflows/ir/environment-v4.js +0 -330
  384. package/dist/workflows/ir/freeze-v4.js +0 -153
  385. package/dist/workflows/ir/schema-v4.js +0 -745
  386. package/dist/workflows/ir/schema.js +0 -354
  387. package/dist/workflows/program/schema.js +0 -78
  388. package/dist/workflows/runtime/checkin.js +0 -57
  389. package/dist/workflows/runtime/plan-classifier.js +0 -196
  390. package/dist/workflows/runtime/unit-checkin.js +0 -45
  391. package/dist/workflows/runtime/unit-phases.js +0 -20
  392. package/dist/workflows/schema.js +0 -4
  393. package/dist/workflows/source-ir/compile.js +0 -200
  394. package/dist/workflows/source-ir/program.js +0 -50
  395. package/dist/workflows/source-ir/result.js +0 -26
  396. package/dist/workflows/source-ir/schema.js +0 -786
  397. package/dist/workflows/source-ir/triggers.js +0 -79
  398. package/dist/workflows/source-ir/uses.js +0 -40
  399. package/dist/workflows/validator.js +0 -60
package/STABILITY.md CHANGED
@@ -281,8 +281,8 @@ CHANGELOG with a migration note.
281
281
  print unredacted. `akm task validate <path>` (new in 0.9.11) is the same
282
282
  kind of zero-write introspection as `explain`, but takes a bare filesystem
283
283
  path rather than a bundle-qualified ref — it reports whether that ONE file
284
- would parse cleanly (`valid`), auto-convert from task v2/v3 (`converts`),
285
- need a human decision the deterministic migrator can't make (`blocked`),
284
+ would parse cleanly (`valid`), need `akm migrate apply` first (`blocked`:
285
+ task v2/v3, or a retired `schedule[].enabled`),
286
286
  fail schema validation (`invalid`), or isn't a task source at all
287
287
  (`not-a-task`) — exactly the diagnostic `akm task sync` would produce for
288
288
  it, before the file is ever wired into a bundle or the scheduler.
@@ -366,8 +366,8 @@ for scripted use.
366
366
  ### `akm improve` autonomy — opt-in in 0.9.0
367
367
 
368
368
  **`akm improve` is review-first by default in 0.9.0.** The command itself is ON
369
- — its schedules, reflect/distill proposals, and graph extraction all run — but
370
- the lanes that mutate assets *without* review require an explicit opt-in:
369
+ — its schedules and reflect/distill proposals all run — but the lanes that
370
+ mutate assets *without* review require an explicit opt-in:
371
371
 
372
372
  ```sh
373
373
  akm config set experimental.improveAutonomy true
@@ -388,9 +388,10 @@ review-first config correctly shows `queue`.
388
388
  | memory cleanup | Belief-state frontmatter rewrites, archive moves | analyzed but not applied |
389
389
  | `triage` `applyMode: "promote"` | Auto-accepts queued proposals into the bundle | downgraded to `queue` — triage still runs, it just does not auto-accept |
390
390
 
391
- Consolidation remains enabled with autonomy off because merge, delete, and
392
- contradiction operations are advisory; promotion only emits a reviewable
393
- proposal.
391
+ Consolidation remains enabled with autonomy off: both its passes (promotion,
392
+ and the pair pass's duplicate/subsumed/supersedes judging) only ever emit a
393
+ reviewable proposal, and a pair-pass `retire` proposal is never auto-accepted
394
+ by `triage` `applyMode: "promote"` regardless of this gate.
394
395
 
395
396
  Because the gate is applied before the LLM preflight, a review-first workspace
396
397
  also needs fewer engines configured: a strategy whose only model-backed process
@@ -409,9 +410,9 @@ Autonomy is never inferred: an absent `experimental` section, an absent key, and
409
410
  an explicit `false` all read as off, so a partially-written or older config is
410
411
  review-first rather than accidentally permissive.
411
412
 
412
- Reflect, distill, extract candidates, validation, proactive-maintenance
413
- selection, and graph extraction are proposal-only and never write assets
414
- directly. Two further direct writes are ungated by design: `extract`'s session
413
+ Reflect, distill, extract candidates, validation, and proactive-maintenance
414
+ selection are proposal-only and never write assets directly. Two further
415
+ direct writes are ungated by design: `extract`'s session
415
416
  indexing (additive `sessions/**` writes,
416
417
  `processes.extract.indexSessions`, default on) and distill's
417
418
  encoding-salience frontmatter stamp (metadata only).
package/dist/akm CHANGED
@@ -4,212 +4,143 @@
4
4
  // file, You can obtain one at https://mozilla.org/MPL/2.0/.
5
5
 
6
6
  import { spawn, spawnSync } from "node:child_process";
7
- import { createHash } from "node:crypto";
8
- import fs from "node:fs";
9
- import path from "node:path";
10
7
  import { fileURLToPath } from "node:url";
11
8
 
12
- const CONTEXT_ARG = "--scheduler-context";
13
- const CONTEXT_KEYS = ["AKM_BUNDLE_DIR", "AKM_CONFIG_DIR", "AKM_DATA_DIR", "AKM_CACHE_DIR", "AKM_STATE_DIR"];
14
- const CONTROL_CHARACTER = /[\u0000-\u001f\u007f-\u009f]/;
15
-
16
- function invalidContext(file, reason) {
17
- throw new Error(`Invalid scheduler context descriptor "${file}": ${reason}.`);
18
- }
19
-
20
- function readSchedulerContext(file) {
21
- if (CONTROL_CHARACTER.test(file) || (!path.posix.isAbsolute(file) && !path.win32.isAbsolute(file))) {
22
- invalidContext(file, "path must be absolute");
23
- }
24
- let linkStat;
25
- try {
26
- linkStat = fs.lstatSync(file);
27
- } catch (error) {
28
- invalidContext(file, error instanceof Error ? error.message : String(error));
29
- }
30
- if (linkStat.isSymbolicLink()) invalidContext(file, "symbolic links are not allowed");
31
- if (!linkStat.isFile()) invalidContext(file, "path is not a regular file");
32
-
33
- let bytes;
34
- let fd;
35
- try {
36
- const noFollow = process.platform === "win32" ? 0 : fs.constants.O_NOFOLLOW;
37
- fd = fs.openSync(file, fs.constants.O_RDONLY | noFollow);
38
- const stat = fs.fstatSync(fd);
39
- if (!stat.isFile()) invalidContext(file, "path is not a regular file");
40
- if (process.platform !== "win32") {
41
- if (typeof process.getuid !== "function") {
42
- invalidContext(file, "current uid is unavailable for ownership verification");
43
- }
44
- const uid = process.getuid();
45
- if (stat.uid !== uid) invalidContext(file, `file owner ${stat.uid} does not match uid ${uid}`);
46
- if ((stat.mode & 0o077) !== 0) invalidContext(file, "group or other permissions must be disabled");
47
- }
48
- bytes = fs.readFileSync(fd);
49
- } finally {
50
- if (fd !== undefined) fs.closeSync(fd);
51
- }
52
-
53
- const match = /^([a-f0-9]{64})\.json$/.exec(path.basename(file));
54
- const digest = createHash("sha256").update(bytes).digest("hex");
55
- if (!match || match[1] !== digest) {
56
- invalidContext(file, "content SHA-256 does not match the descriptor filename");
9
+ // #956 round 3: install the signal-forwarding scaffolding before ANYTHING
10
+ // else in this process — env var setup, the bun-version probe, spawning the
11
+ // child — gets a chance to run. The three `process.once` listeners used to
12
+ // go up only after spawn() (below) returned; a scheduler preemption right
13
+ // after that syscall was enough for a signal to arrive with no listener yet,
14
+ // and the runtime's default (process-terminating) disposition killed the
15
+ // launcher outright, never reaching the child at all. `child` starts
16
+ // unset: a signal that arrives before it exists is queued and flushed the
17
+ // moment it does; if this process ends up never spawning one (the
18
+ // direct-import branch below), the queued signal is re-raised against
19
+ // ourselves once we hand default disposition back, so it behaves exactly
20
+ // like the runtime's own default rather than being silently swallowed.
21
+ let child;
22
+ let childExited = false;
23
+ const pendingSignals = [];
24
+ const forwardHandlers = new Map();
25
+ const forwardSignal = (signal) => {
26
+ if (childExited) return;
27
+ if (!child) {
28
+ pendingSignals.push(signal);
29
+ return;
57
30
  }
58
-
59
- let descriptor;
60
31
  try {
61
- descriptor = JSON.parse(bytes.toString("utf8"));
62
- } catch (error) {
63
- invalidContext(file, error instanceof Error ? error.message : String(error));
64
- }
65
- if (
66
- typeof descriptor !== "object" ||
67
- descriptor === null ||
68
- Array.isArray(descriptor) ||
69
- descriptor.version !== 1 ||
70
- Object.keys(descriptor).sort().join("\0") !== "environment\0version"
71
- ) {
72
- invalidContext(file, "expected the scheduler context v1 schema");
32
+ child.kill(signal);
33
+ } catch {
34
+ // Child exited in the race between the check above and here.
73
35
  }
74
- const environment = descriptor.environment;
75
- const expected = [...CONTEXT_KEYS, "PATH"].sort();
76
- const keys =
77
- environment && typeof environment === "object" && !Array.isArray(environment)
78
- ? Object.keys(environment).sort()
79
- : [];
80
- if (keys.length !== expected.length || keys.some((key, index) => key !== expected[index])) {
81
- invalidContext(file, "environment keys do not match the scheduler context v1 schema");
82
- }
83
- for (const key of CONTEXT_KEYS) {
84
- const value = environment[key];
85
- if (
86
- typeof value !== "string" ||
87
- value.trim() === "" ||
88
- CONTROL_CHARACTER.test(value) ||
89
- (!path.posix.isAbsolute(value) && !path.win32.isAbsolute(value))
90
- ) {
91
- invalidContext(file, `${key} must be an absolute path without control characters`);
92
- }
93
- }
94
- if (typeof environment.PATH !== "string" || CONTROL_CHARACTER.test(environment.PATH)) {
95
- invalidContext(file, "PATH must be a string without control characters");
96
- }
97
- return environment;
36
+ };
37
+ // `.once`, not `.on`: Node/Bun suppress a signal's default
38
+ // (process-terminating) disposition for as long as ANY listener stays
39
+ // registered for it. A persistent `.on` listener would still be registered
40
+ // when the `process.kill(process.pid, result.signal)` re-raise below runs at
41
+ // shutdown, swallowing it and leaving this launcher exiting 0 instead of
42
+ // reflecting the child's signal. `.once` consumes only the
43
+ // externally-delivered signal that triggers the forward, so the re-raise
44
+ // correctly falls through to the OS default.
45
+ for (const signal of ["SIGTERM", "SIGINT", "SIGHUP"]) {
46
+ const handler = () => forwardSignal(signal);
47
+ forwardHandlers.set(signal, handler);
48
+ process.once(signal, handler);
98
49
  }
99
50
 
100
- const contextIndex = process.argv.indexOf(CONTEXT_ARG);
101
- let contextValid = true;
102
- if (contextIndex !== -1) {
103
- try {
104
- const contextPath = process.argv[contextIndex + 1];
105
- if (!contextPath) throw new Error(`${CONTEXT_ARG} requires an absolute path.`);
106
- const environment = readSchedulerContext(contextPath);
107
- const expected = [...CONTEXT_KEYS, "PATH"].sort();
108
- for (const key of expected) process.env[key] = environment[key];
109
- process.argv.splice(contextIndex, 2);
110
- } catch (error) {
111
- console.error(`akm: ${error instanceof Error ? error.message : String(error)}`);
112
- process.exitCode = 78;
113
- contextValid = false;
114
- }
115
- }
51
+ // A scheduled row sets its environment itself (a cron `VAR=value` prefix, a
52
+ // launchd plist's EnvironmentVariables), and the scheduler supplies PATH, so
53
+ // runtime selection below needs nothing from it. A row written by 0.9.0 –
54
+ // 0.9.17-alpha.6 passes `--scheduler-context <descriptor>` instead; it passes
55
+ // through untouched, and the CLI applies it (`consumeSchedulerContextArg` in
56
+ // src/cli.ts). This launcher used to re-validate the descriptor with its own
57
+ // copy of the schema, and that copy rejected every descriptor 0.9.17 wrote.
116
58
 
117
- if (contextValid) {
118
- process.env.AKM_LAUNCHER_NODE = process.execPath;
119
- process.env.AKM_LAUNCHER_PATH = fileURLToPath(import.meta.url);
120
- // #956: lets the child (and its lock payloads) name the launcher pid
121
- // alongside its own, and lets the child's parent-death watchdog tell a
122
- // real launcher-managed run apart from a direct `bun src/cli.ts` run.
123
- process.env.AKM_LAUNCHER_PID = String(process.pid);
59
+ process.env.AKM_LAUNCHER_NODE = process.execPath;
60
+ process.env.AKM_LAUNCHER_PATH = fileURLToPath(import.meta.url);
61
+ // #956: lets the child (and its lock payloads) name the launcher pid
62
+ // alongside its own, and lets the child's parent-death watchdog tell a
63
+ // real launcher-managed run apart from a direct `bun src/cli.ts` run.
64
+ process.env.AKM_LAUNCHER_PID = String(process.pid);
124
65
 
125
- if (!process.versions.bun) {
126
- const [major = 0, minor = 0] = process.versions.node.split(".").map(Number);
127
- if (major < 22) {
128
- console.error("The akm-cli npm package requires Node.js >= 22 to bootstrap.");
129
- process.exit(1);
130
- }
66
+ if (!process.versions.bun) {
67
+ const [major = 0, minor = 0] = process.versions.node.split(".").map(Number);
68
+ if (major < 22) {
69
+ console.error("The akm-cli npm package requires Node.js >= 22 to bootstrap.");
70
+ process.exit(1);
131
71
  }
72
+ }
132
73
 
133
- const bunProbe = process.versions.bun
134
- ? { status: 0, stdout: process.versions.bun }
135
- : spawnSync("bun", ["--version"], {
136
- encoding: "utf8",
137
- stdio: ["ignore", "pipe", "ignore"],
138
- timeout: 5_000,
139
- });
140
- const [bunMajor = 0] = (bunProbe.status === 0 ? bunProbe.stdout.trim() : "").split(".").map(Number);
141
- const useBun = bunMajor >= 1;
142
- const bunEntry = fileURLToPath(new URL("./cli.js", import.meta.url));
143
- const nodeEntry = fileURLToPath(new URL("./cli-node.mjs", import.meta.url));
74
+ const bunProbe = process.versions.bun
75
+ ? { status: 0, stdout: process.versions.bun }
76
+ : spawnSync("bun", ["--version"], {
77
+ encoding: "utf8",
78
+ stdio: ["ignore", "pipe", "ignore"],
79
+ timeout: 5_000,
80
+ });
81
+ const [bunMajor = 0] = (bunProbe.status === 0 ? bunProbe.stdout.trim() : "").split(".").map(Number);
82
+ const useBun = bunMajor >= 1;
83
+ const bunEntry = fileURLToPath(new URL("./cli.js", import.meta.url));
84
+ const nodeEntry = fileURLToPath(new URL("./cli-node.mjs", import.meta.url));
144
85
 
145
- if (!useBun && !process.versions.bun) {
146
- await import("./cli-node.mjs");
147
- } else {
148
- const command = useBun ? (process.versions.bun ? process.execPath : "bun") : "node";
149
- const entry = useBun ? bunEntry : nodeEntry;
150
- const runtime = useBun ? "Bun" : "Node.js";
151
- const result = await new Promise((resolve) => {
152
- const child = spawn(command, [entry, ...process.argv.slice(2)], {
153
- stdio: "inherit",
154
- env: process.env,
155
- // #956: give the child its OWN process group on POSIX (`setsid()` —
156
- // does not touch its inherited stdio; see `spawnsOwnProcessGroup` in
157
- // src/core/subprocess.ts for the Windows caveat that rules this out
158
- // there). Without this, a spawned child shares the launcher's
159
- // process group by default, so a signal delivered to that GROUP (a
160
- // terminal's Ctrl-C, or `kill -SIGINT -<pgid>`) reaches the child
161
- // directly AND the launcher, which then also forwards it — a real
162
- // second signal lands microseconds after the first. The child's
163
- // `process.once(signal, ...)` handler has already unregistered
164
- // itself for its first (direct) copy, so the second falls through
165
- // to the runtime's default disposition (immediate termination) and
166
- // the child's graceful shutdown (lock release, in-flight abort)
167
- // never runs. Detaching the child's process group makes the
168
- // launcher's forward below the SOLE delivery path to the child, so
169
- // it is always exactly one signal.
170
- detached: process.platform !== "win32",
171
- });
172
- // A `kill <launcher-pid>` (a scheduler timeout, a supervisor, an
173
- // operator) used to end only this wrapper, orphaning the bun child —
174
- // it kept running (and holding locks) for as long as its own work took.
175
- // Forward the same signal so the child dies with its parent. Never
176
- // forward once the child has already exited: forwarding to a
177
- // dead/replaced pid would be at best a no-op and at worst a signal to
178
- // an unrelated process that reused the pid.
179
- let childExited = false;
180
- child.once("exit", () => {
181
- childExited = true;
182
- });
183
- const forwardSignal = (signal) => {
184
- if (childExited) return;
185
- try {
186
- child.kill(signal);
187
- } catch {
188
- // Child exited in the race between the check above and here.
189
- }
190
- };
191
- // `.once`, not `.on`: Node/Bun suppress a signal's default
192
- // (process-terminating) disposition for as long as ANY listener stays
193
- // registered for it. A persistent `.on` listener would still be
194
- // registered when the `process.kill(process.pid, result.signal)`
195
- // re-raise below runs at shutdown, swallowing it and leaving this
196
- // launcher exiting 0 instead of reflecting the child's signal. `.once`
197
- // consumes only the externally-delivered signal that triggers the
198
- // forward, so the re-raise correctly falls through to the OS default.
199
- for (const signal of ["SIGTERM", "SIGINT", "SIGHUP"]) {
200
- process.once(signal, () => forwardSignal(signal));
201
- }
202
- child.once("error", (error) => resolve({ error }));
203
- child.once("exit", (code, signal) => resolve({ code, signal }));
86
+ if (!useBun && !process.versions.bun) {
87
+ // No child is ever spawned on this path — the imported module runs
88
+ // in-process, so it IS the work, and the runtime's ordinary default signal
89
+ // disposition is exactly correct for it. Hand that back (the forwarding
90
+ // listeners above no longer apply here), re-raising anything that already
91
+ // arrived so it is not silently swallowed by a listener that now does
92
+ // nothing.
93
+ for (const [signal, handler] of forwardHandlers) process.removeListener(signal, handler);
94
+ if (pendingSignals.length > 0) process.kill(process.pid, pendingSignals[0]);
95
+ else await import("./cli-node.mjs");
96
+ } else {
97
+ const command = useBun ? (process.versions.bun ? process.execPath : "bun") : "node";
98
+ const entry = useBun ? bunEntry : nodeEntry;
99
+ const runtime = useBun ? "Bun" : "Node.js";
100
+ const result = await new Promise((resolve) => {
101
+ child = spawn(command, [entry, ...process.argv.slice(2)], {
102
+ stdio: "inherit",
103
+ env: process.env,
104
+ // #956: give the child its OWN process group on POSIX (`setsid()` —
105
+ // does not touch its inherited stdio; see `spawnsOwnProcessGroup` in
106
+ // src/core/subprocess.ts for the Windows caveat that rules this out
107
+ // there). Without this, a spawned child shares the launcher's
108
+ // process group by default, so a signal delivered to that GROUP (a
109
+ // terminal's Ctrl-C, or `kill -SIGINT -<pgid>`) reaches the child
110
+ // directly AND the launcher, which then also forwards it — a real
111
+ // second signal lands microseconds after the first. The child's
112
+ // `process.once(signal, ...)` handler has already unregistered
113
+ // itself for its first (direct) copy, so the second falls through
114
+ // to the runtime's default disposition (immediate termination) and
115
+ // the child's graceful shutdown (lock release, in-flight abort)
116
+ // never runs. Detaching the child's process group makes the
117
+ // launcher's forward below the SOLE delivery path to the child, so
118
+ // it is always exactly one signal.
119
+ detached: process.platform !== "win32",
204
120
  });
121
+ // A `kill <launcher-pid>` (a scheduler timeout, a supervisor, an
122
+ // operator) used to end only this wrapper, orphaning the bun child —
123
+ // it kept running (and holding locks) for as long as its own work took.
124
+ // Forward the same signal so the child dies with its parent. Never
125
+ // forward once the child has already exited: forwarding to a
126
+ // dead/replaced pid would be at best a no-op and at worst a signal to
127
+ // an unrelated process that reused the pid.
128
+ child.once("exit", () => {
129
+ childExited = true;
130
+ });
131
+ // Flush whatever arrived in the (now much smaller) window between the
132
+ // listeners going up and the child existing to receive them.
133
+ for (const signal of pendingSignals.splice(0)) forwardSignal(signal);
134
+ child.once("error", (error) => resolve({ error }));
135
+ child.once("exit", (code, signal) => resolve({ code, signal }));
136
+ });
205
137
 
206
- if (result.error) {
207
- console.error(`akm launcher could not start ${runtime}: ${result.error.message}`);
208
- process.exitCode = 127;
209
- } else if (result.signal) {
210
- process.kill(process.pid, result.signal);
211
- } else {
212
- process.exitCode = result.code ?? 1;
213
- }
138
+ if (result.error) {
139
+ console.error(`akm launcher could not start ${runtime}: ${result.error.message}`);
140
+ process.exitCode = 127;
141
+ } else if (result.signal) {
142
+ process.kill(process.pid, result.signal);
143
+ } else {
144
+ process.exitCode = result.code ?? 1;
214
145
  }
215
146
  }
package/dist/akm-migrate CHANGED
@@ -6,6 +6,40 @@
6
6
  import { spawn, spawnSync } from "node:child_process";
7
7
  import { fileURLToPath } from "node:url";
8
8
 
9
+ // #956 round 3: install the signal-forwarding scaffolding before ANYTHING
10
+ // else in this process — the Node-version check, the bun-version probe,
11
+ // spawning the child — gets a chance to run. See the matching fix and
12
+ // comment in scripts/node-runtime/akm: the three `process.once` listeners
13
+ // used to go up only after spawn() (below) returned; a scheduler preemption
14
+ // right after that syscall was enough for a signal to arrive with no
15
+ // listener yet, and the runtime's default (process-terminating) disposition
16
+ // killed the launcher outright, never reaching the child at all. `child`
17
+ // starts unset: a signal that arrives before it exists is queued and
18
+ // flushed the moment it does.
19
+ let child;
20
+ let childExited = false;
21
+ const pendingSignals = [];
22
+ const forwardSignal = (signal) => {
23
+ if (childExited) return;
24
+ if (!child) {
25
+ pendingSignals.push(signal);
26
+ return;
27
+ }
28
+ try {
29
+ child.kill(signal);
30
+ } catch {
31
+ // Child exited in the race between the check above and here.
32
+ }
33
+ };
34
+ // `.once`, not `.on`: see the matching comment in scripts/node-runtime/akm —
35
+ // a persistent `.on` listener would still be registered when the
36
+ // `process.kill(process.pid, result.signal)` re-raise below runs,
37
+ // suppressing the OS default disposition and leaving this launcher exiting
38
+ // 0 instead of reflecting the child's signal.
39
+ for (const signal of ["SIGTERM", "SIGINT", "SIGHUP"]) {
40
+ process.once(signal, () => forwardSignal(signal));
41
+ }
42
+
9
43
  if (!process.versions.bun) {
10
44
  const [major = 0, minor = 0] = process.versions.node.split(".").map(Number);
11
45
  if (major < 22) {
@@ -34,7 +68,7 @@ const nodeEntry = fileURLToPath(new URL("./scripts/akm-migrate-node.js", import.
34
68
  const command = process.versions.bun ? process.execPath : useBun ? "bun" : process.execPath;
35
69
  const entry = process.versions.bun || useBun ? bunEntry : nodeEntry;
36
70
  const result = await new Promise((resolve) => {
37
- const child = spawn(command, [entry, ...process.argv.slice(2)], {
71
+ child = spawn(command, [entry, ...process.argv.slice(2)], {
38
72
  stdio: "inherit",
39
73
  env,
40
74
  // #956: own process group on POSIX so the launcher's forward below is
@@ -43,27 +77,12 @@ const nodeEntry = fileURLToPath(new URL("./scripts/akm-migrate-node.js", import.
43
77
  // directly — see the matching comment in scripts/node-runtime/akm.
44
78
  detached: process.platform !== "win32",
45
79
  });
46
- let childExited = false;
47
80
  child.once("exit", () => {
48
81
  childExited = true;
49
82
  });
50
- const forwardSignal = (signal) => {
51
- if (childExited) return;
52
- try {
53
- child.kill(signal);
54
- } catch {
55
- // Child exited in the race between the check above and here.
56
- }
57
- };
58
- // `.once`, not `.on`: see the matching comment in
59
- // scripts/node-runtime/akm — a persistent `.on` listener would still be
60
- // registered when the `process.kill(process.pid, result.signal)`
61
- // re-raise below runs, suppressing the OS default disposition and
62
- // leaving this launcher exiting 0 instead of reflecting the child's
63
- // signal.
64
- for (const signal of ["SIGTERM", "SIGINT", "SIGHUP"]) {
65
- process.once(signal, () => forwardSignal(signal));
66
- }
83
+ // Flush whatever arrived in the (now much smaller) window between the
84
+ // listeners going up and the child existing to receive them.
85
+ for (const signal of pendingSignals.splice(0)) forwardSignal(signal);
67
86
  child.once("error", (error) => resolve({ error }));
68
87
  child.once("exit", (code, signal) => resolve({ code, signal }));
69
88
  });
@@ -245,10 +245,9 @@ akm improve --no-push # commit but skip push for this ru
245
245
  akm improve --sync # force sync even on strategies that disable it
246
246
  ```
247
247
 
248
- Strategy sync defaults: `catchup`, `consolidate`, `default`,
249
- `graph-refresh`, `quick`, and `thorough` auto-commit + push;
250
- `proactive-maintenance` and `reflect-distill` skip sync entirely. Override
251
- with `--sync` / `--no-sync` flags.
248
+ Strategy sync defaults: `catchup`, `consolidate`, `default`, `quick`, and
249
+ `thorough` auto-commit + push; `proactive-maintenance` and `reflect-distill`
250
+ skip sync entirely. Override with `--sync` / `--no-sync` flags.
252
251
 
253
252
  The `--writable` flag on `akm bundle add` opts a remote git bundle into push-on-sync:
254
253
 
@@ -308,8 +307,8 @@ akm bundle create # Initialize working bund
308
307
  akm setup # Interactive wizard: bundle + LLM/embedding + agent + registry config
309
308
  akm setup --dir ~/custom-bundle # Run the wizard against a custom bundle path
310
309
  akm setup --yes # Non-interactive, accepts all defaults
311
- akm index # Rebuild search index (metadata enrichment when configured)
312
- akm index --full # Full reindex (metadata enrichment when configured)
310
+ akm index # Rebuild search index
311
+ akm index --full # Full reindex
313
312
  akm bundle list # List all sources
314
313
  akm lint # Structural lint over the bundle; exits 0 regardless of findings
315
314
  akm lint --fix # Auto-fix Tier 1 issues
@@ -399,7 +398,7 @@ akm agent --model sonnet --prompt "..." # Model override (aliases or exa
399
398
  ```sh
400
399
  akm info # Capabilities, bundle dir, index stats, semantic-search status
401
400
  akm health # Runtime diagnostics; exit 0 ok / 4 warn / 1 fail
402
- akm health --report # Adds accept-rate and graph-coverage metrics
401
+ akm health --report # Adds accept-rate metrics
403
402
  akm log # Append-only event stream (mutations, feedback, indexing)
404
403
  akm log --ref <ref> # One asset's event trail
405
404
  akm log --since @offset:<id> # Durable row-id cursor — poll this to follow the stream
@@ -16,9 +16,6 @@
16
16
  "memoryInference": {
17
17
  "enabled": false
18
18
  },
19
- "graphExtraction": {
20
- "enabled": false
21
- },
22
19
  "extract": {
23
20
  "enabled": false
24
21
  },
@@ -5,7 +5,6 @@
5
5
  "distill": { "enabled": false },
6
6
  "consolidate": { "enabled": true, "allowedTypes": ["memory"], "maxChunkSize": 25 },
7
7
  "memoryInference": { "enabled": false },
8
- "graphExtraction": { "enabled": false },
9
8
  "extract": { "enabled": false },
10
9
  "triage": { "enabled": false },
11
10
  "validation": { "enabled": false },
@@ -1,5 +1,5 @@
1
1
  {
2
- "description": "Standard improve pass — reflect, distill, advisory consolidation, graph extraction, and validation. Memory inference is listed below but only runs when experimental.improveAutonomy is set; improve-stage extract and proactive maintenance off.",
2
+ "description": "Standard improve pass — reflect, distill, consolidation (promotion plus the reviewed pair-pass retire/supersede proposals), and validation. Memory inference is listed below but only runs when experimental.improveAutonomy is set; improve-stage extract and proactive maintenance off.",
3
3
  "processes": {
4
4
  "reflect": {
5
5
  "enabled": true,
@@ -9,7 +9,6 @@
9
9
  "distill": { "enabled": true, "allowedTypes": ["memory"], "requirePlannedRefs": true },
10
10
  "consolidate": { "enabled": true, "allowedTypes": ["memory"] },
11
11
  "memoryInference": { "enabled": true },
12
- "graphExtraction": { "enabled": true },
13
12
  "extract": { "enabled": false, "triage": { "enabled": true, "minScore": 2 } },
14
13
  "validation": { "enabled": true },
15
14
  "proactiveMaintenance": { "enabled": false, "dueDays": 30, "maxPerRun": 15 },
@@ -1,5 +1,5 @@
1
1
  {
2
- "description": "Opt-in proactive-maintenance pass — reflect, distill, proposal triage (promote, high budget), and the proactive-maintenance lane (maxPerRun 100); consolidate/memoryInference/graphExtraction/extract off. Sync disabled: an interrupted run would otherwise leave an uncommitted backlog.",
2
+ "description": "Opt-in proactive-maintenance pass — reflect, distill, proposal triage (promote, high budget), and the proactive-maintenance lane (maxPerRun 100); consolidate/memoryInference/extract off. Sync disabled: an interrupted run would otherwise leave an uncommitted backlog.",
3
3
  "processes": {
4
4
  "reflect": {
5
5
  "enabled": true,
@@ -8,7 +8,6 @@
8
8
  "distill": { "enabled": true, "allowedTypes": ["memory"] },
9
9
  "consolidate": { "enabled": false },
10
10
  "memoryInference": { "enabled": false },
11
- "graphExtraction": { "enabled": false },
12
11
  "extract": { "enabled": false },
13
12
  "validation": { "enabled": false },
14
13
  "triage": {
@@ -1,5 +1,5 @@
1
1
  {
2
- "description": "Reflect-only pass — no extract, distill, consolidate, memoryInference, or graphExtraction.",
2
+ "description": "Reflect-only pass — no extract, distill, consolidate, or memoryInference.",
3
3
  "processes": {
4
4
  "reflect": {
5
5
  "enabled": true,
@@ -9,7 +9,6 @@
9
9
  "distill": { "enabled": false },
10
10
  "consolidate": { "enabled": false },
11
11
  "memoryInference": { "enabled": false },
12
- "graphExtraction": { "enabled": false },
13
12
  "triage": { "enabled": false },
14
13
  "validation": { "enabled": false },
15
14
  "proactiveMaintenance": { "enabled": false }
@@ -1,5 +1,5 @@
1
1
  {
2
- "description": "Reflect + distill pass — reflect, distill, memoryInference, and proposal triage (promote); proactiveMaintenance/consolidate/graphExtraction/extract off. Sync disabled: an interrupted run would otherwise leave an uncommitted backlog.",
2
+ "description": "Reflect + distill pass — reflect, distill, memoryInference, and proposal triage (promote); proactiveMaintenance/consolidate/extract off. Sync disabled: an interrupted run would otherwise leave an uncommitted backlog.",
3
3
  "processes": {
4
4
  "reflect": {
5
5
  "enabled": true,
@@ -8,7 +8,6 @@
8
8
  "distill": { "enabled": true, "allowedTypes": ["memory"], "requirePlannedRefs": false },
9
9
  "consolidate": { "enabled": false },
10
10
  "memoryInference": { "enabled": true },
11
- "graphExtraction": { "enabled": false },
12
11
  "extract": {
13
12
  "enabled": false,
14
13
  "timeoutMs": 300000,
@@ -18,9 +18,6 @@
18
18
  "memoryInference": {
19
19
  "enabled": true
20
20
  },
21
- "graphExtraction": {
22
- "enabled": true
23
- },
24
21
  "extract": {
25
22
  "enabled": false,
26
23
  "triage": {
@@ -0,0 +1,20 @@
1
+ You compare two assets from one person's agent-memory library (memories and knowledge notes an AI coding agent reads). Asset A is the OLDER one and asset B the NEWER one, by the dates shown.
2
+
3
+ Classify the relation between them as exactly one of:
4
+
5
+ - "duplicate": they state the same durable facts. Wording, title or formatting may differ, but neither adds a claim a reader would need that the other lacks.
6
+ - "subsumed": one of them contains every durable claim of the other, plus more. The smaller one is redundant.
7
+ - "supersedes": B updates, corrects, reverses or replaces a claim in A (a newer version, a changed decision, a fixed bug, a new value). A is now stale or wrong on that point.
8
+ - "contradicts": they make logically exclusive claims about the same thing and nothing shows which one is current.
9
+ - "overlap": same subject, but each has durable claims the other lacks. Keeping both loses nothing; merging them would keep both sets of claims.
10
+ - "unrelated": different subjects or different facts that happen to share words.
11
+
12
+ Rules:
13
+ - A durable claim is a fact, decision, value, command, path, number or rule someone would act on. Ignore dates, headings, tags and phrasing.
14
+ - Prefer "overlap" over "duplicate" when either asset has a specific detail (a number, command, file, version or condition) that the other lacks.
15
+ - "supersedes" needs a specific claim in A that B changes. Being newer or longer is not enough.
16
+ - "contradicts" needs two claims that cannot both be true. Different scope, project or time is not a contradiction.
17
+
18
+ Set "redundant" to "A" or "B" when that asset could be removed with no loss (only for "duplicate" or "subsumed"; for "duplicate" name the less complete or older one), else null. Set "stale" to "A" when the relation is "supersedes", else null.
19
+
20
+ Answer ONLY with JSON: {"relation": "...", "redundant": "A"|"B"|null, "stale": "A"|null, "confidence": 0.0-1.0, "reason": "<at most 25 words>"}