akm-cli 0.9.16 → 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 (403) hide show
  1. package/CHANGELOG.md +2101 -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/consolidate-system.md +4 -11
  15. package/dist/assets/prompts/retrieval-relevance-judge.md +6 -0
  16. package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +20 -20
  17. package/dist/assets/stash-skeleton/facts/conventions/domains.md +2 -2
  18. package/dist/assets/templates/html/health.html +3 -5
  19. package/dist/cli/retired-commands.js +1 -1
  20. package/dist/cli/shared.js +6 -2
  21. package/dist/cli/unknown-flags.js +24 -1
  22. package/dist/cli.js +68 -10
  23. package/dist/commands/agent/agent-dispatch.js +1 -1
  24. package/dist/commands/command/command-execution.js +24 -62
  25. package/dist/commands/feedback-cli.js +0 -1
  26. package/dist/commands/health/accept-rate.js +6 -0
  27. package/dist/commands/health/archive-usage.js +92 -0
  28. package/dist/commands/health/checks.js +83 -74
  29. package/dist/commands/health/config-skew.js +38 -0
  30. package/dist/commands/health/data-dir-usage.js +25 -13
  31. package/dist/commands/health/egress.js +54 -0
  32. package/dist/commands/health/html-report.js +1 -42
  33. package/dist/commands/health/improve-metrics.js +136 -591
  34. package/dist/commands/health/md-report.js +1 -6
  35. package/dist/commands/health/plugin-staleness.js +53 -3
  36. package/dist/commands/health/renderers.js +12 -4
  37. package/dist/commands/health/report-view-model.js +14 -120
  38. package/dist/commands/health/types-improve.js +4 -19
  39. package/dist/commands/health/windows.js +64 -74
  40. package/dist/commands/health.js +145 -143
  41. package/dist/commands/improve/consolidate/chunking.js +26 -117
  42. package/dist/commands/improve/consolidate/continuity-check.js +137 -0
  43. package/dist/commands/improve/consolidate/pair-pass.js +791 -0
  44. package/dist/commands/improve/consolidate/sanitize.js +54 -149
  45. package/dist/commands/improve/consolidate.js +589 -1127
  46. package/dist/commands/improve/content-hash.js +16 -24
  47. package/dist/commands/improve/distill/content-repair.js +18 -100
  48. package/dist/commands/improve/distill-guards.js +20 -81
  49. package/dist/commands/improve/distill-promotion-policy.js +23 -243
  50. package/dist/commands/improve/distill.js +608 -1041
  51. package/dist/commands/improve/eligibility.js +126 -390
  52. package/dist/commands/improve/execution.js +8 -10
  53. package/dist/commands/improve/extract-prompt.js +1 -2
  54. package/dist/commands/improve/extract.js +487 -1046
  55. package/dist/commands/improve/feedback-valence.js +0 -25
  56. package/dist/commands/improve/improve-cli.js +75 -169
  57. package/dist/commands/improve/improve-result-file.js +10 -66
  58. package/dist/commands/improve/improve-strategies.js +52 -4
  59. package/dist/commands/improve/improve-usage-report.js +18 -64
  60. package/dist/commands/improve/improve.js +480 -1074
  61. package/dist/commands/improve/ledger.js +119 -0
  62. package/dist/commands/improve/locks.js +2 -8
  63. package/dist/commands/improve/loop-stages.js +415 -1073
  64. package/dist/commands/improve/memory/derived-ref.js +12 -77
  65. package/dist/commands/improve/memory/memory-belief.js +16 -118
  66. package/dist/commands/improve/memory/memory-improve.js +266 -14
  67. package/dist/commands/improve/outcome-loop.js +28 -156
  68. package/dist/commands/improve/planner.js +5 -15
  69. package/dist/commands/improve/preparation.js +779 -2319
  70. package/dist/commands/improve/proactive-maintenance.js +34 -101
  71. package/dist/commands/improve/reflect-noise.js +104 -280
  72. package/dist/commands/improve/reflect.js +642 -1353
  73. package/dist/commands/improve/retrieval-gate.js +127 -0
  74. package/dist/commands/improve/retrieval-scope.js +92 -0
  75. package/dist/commands/improve/salience.js +41 -240
  76. package/dist/commands/improve/session-asset.js +19 -100
  77. package/dist/commands/improve/stage.js +322 -0
  78. package/dist/commands/lint/base-linter.js +37 -15
  79. package/dist/commands/proposal/drain.js +261 -578
  80. package/dist/commands/proposal/proposal-cli.js +19 -20
  81. package/dist/commands/proposal/proposal-types.js +31 -24
  82. package/dist/commands/proposal/proposal.js +38 -8
  83. package/dist/commands/proposal/propose.js +134 -160
  84. package/dist/commands/proposal/repository.js +1097 -1394
  85. package/dist/commands/proposal/validators/proposal-quality-validators.js +71 -174
  86. package/dist/commands/proposal/validators/proposal-validators.js +1 -1
  87. package/dist/commands/proposal/validators/proposals.js +22 -89
  88. package/dist/commands/read/curate.js +105 -462
  89. package/dist/commands/read/knowledge.js +3 -2
  90. package/dist/commands/read/search-cli.js +16 -33
  91. package/dist/commands/read/search.js +17 -23
  92. package/dist/commands/read/show.js +57 -108
  93. package/dist/commands/sources/bundle-cli.js +25 -2
  94. package/dist/commands/sources/bundle-config-ops.js +4 -0
  95. package/dist/commands/sources/dangerous-env-audit.js +1 -2
  96. package/dist/commands/sources/info.js +127 -29
  97. package/dist/commands/sources/installed-stashes.js +197 -746
  98. package/dist/commands/sources/schema-repair.js +98 -129
  99. package/dist/commands/sources/source-add.js +62 -12
  100. package/dist/commands/sources/source-manage.js +9 -2
  101. package/dist/commands/sources/stash-cli.js +24 -4
  102. package/dist/commands/tasks/explain.js +10 -13
  103. package/dist/commands/tasks/tasks-cli.js +12 -13
  104. package/dist/commands/tasks/tasks.js +350 -936
  105. package/dist/commands/tasks/validate.js +26 -24
  106. package/dist/commands/workflow/plan.js +22 -29
  107. package/dist/commands/workflow-cli.js +4 -4
  108. package/dist/core/adapter/adapters/akm-adapter.js +2 -1
  109. package/dist/core/adapter/adapters/akm-lint.js +2 -3
  110. package/dist/core/adapter/adapters/akm-metadata.js +42 -12
  111. package/dist/core/adapter/adapters/akm-task-adapter.js +29 -8
  112. package/dist/core/adapter/adapters/akm-workflow-adapter.js +1 -1
  113. package/dist/core/adapter/execution-source.js +17 -29
  114. package/dist/core/asset/asset-placement.js +4 -13
  115. package/dist/core/asset/frontmatter.js +106 -1
  116. package/dist/core/asset/resolve-ref.js +1 -1
  117. package/dist/core/bundle-id.js +42 -5
  118. package/dist/core/bundle-rename.js +285 -0
  119. package/dist/core/config/config-io.js +1 -2
  120. package/dist/core/config/config-schema.js +9 -34
  121. package/dist/core/config/config-walker.js +1 -1
  122. package/dist/core/config/config.js +184 -111
  123. package/dist/core/config/engine-semantics.js +0 -2
  124. package/dist/core/config/legacy-source-shape-shim.js +38 -9
  125. package/dist/core/config/schema/embedding.js +20 -5
  126. package/dist/core/config/schema/engines.js +5 -0
  127. package/dist/core/config/schema/execution.js +1 -1
  128. package/dist/core/config/schema/experimental.js +1 -1
  129. package/dist/core/config/schema/improve-processes.js +54 -125
  130. package/dist/core/config/schema/improve.js +4 -42
  131. package/dist/core/config/schema/index-config.js +9 -48
  132. package/dist/core/config/schema/scheduler.js +12 -12
  133. package/dist/core/config/schema/search.js +6 -22
  134. package/dist/core/env-secret-ref.js +0 -1
  135. package/dist/core/errors.js +8 -9
  136. package/dist/core/file-change.js +13 -5
  137. package/dist/core/file-lock.js +76 -173
  138. package/dist/core/improve-result.js +35 -7
  139. package/dist/core/improve-types.js +0 -1
  140. package/dist/core/logs-db.js +2 -2
  141. package/dist/core/loopback.js +7 -12
  142. package/dist/core/non-task-input.js +20 -0
  143. package/dist/core/parse.js +13 -16
  144. package/dist/core/paths.js +0 -24
  145. package/dist/core/redaction.js +109 -2
  146. package/dist/core/run-lock.js +2 -5
  147. package/dist/core/spawn-env.js +1 -1
  148. package/dist/core/state/migrations.js +123 -61
  149. package/dist/core/state-db-scope.js +2 -4
  150. package/dist/core/state-db.js +126 -692
  151. package/dist/core/time.js +0 -20
  152. package/dist/core/type-presentation.js +1 -9
  153. package/dist/core/write-source.js +294 -1005
  154. package/dist/execution/input-contract.js +1 -1
  155. package/dist/execution/resolved-request.js +135 -689
  156. package/dist/execution/source.js +63 -257
  157. package/dist/execution/target-ref.js +1 -1
  158. package/dist/indexer/bundle-identity-guard.js +2 -2
  159. package/dist/indexer/db/llm-cache.js +2 -2
  160. package/dist/indexer/ensure-index.js +77 -73
  161. package/dist/indexer/index-rebuild-lock.js +3 -11
  162. package/dist/indexer/index-writer-lock.js +8 -17
  163. package/dist/indexer/index-written-assets.js +141 -154
  164. package/dist/indexer/indexer.js +400 -1124
  165. package/dist/indexer/links/declared-links.js +90 -0
  166. package/dist/indexer/materialize-embeddings.js +60 -397
  167. package/dist/indexer/passes/memory-inference.js +96 -90
  168. package/dist/indexer/passes/metadata.js +132 -219
  169. package/dist/indexer/read-preflight.js +0 -7
  170. package/dist/indexer/scan/doc-to-entry.js +2 -3
  171. package/dist/indexer/scan/drain-dir.js +1 -1
  172. package/dist/indexer/search/db-search.js +190 -590
  173. package/dist/indexer/search/fts-query.js +30 -41
  174. package/dist/indexer/search/ranking.js +28 -154
  175. package/dist/indexer/search/search-attribution.js +12 -32
  176. package/dist/indexer/search/search-fields.js +11 -15
  177. package/dist/indexer/search/search-hit-enrichers.js +54 -85
  178. package/dist/indexer/search/search-source.js +1 -4
  179. package/dist/indexer/usage/usage-events.js +36 -7
  180. package/dist/indexer/walk/walker.js +3 -4
  181. package/dist/integrations/agent/engine-fallback.js +23 -40
  182. package/dist/integrations/agent/engine-resolution.js +93 -183
  183. package/dist/integrations/agent/execution.js +507 -0
  184. package/dist/integrations/agent/model-map.js +28 -156
  185. package/dist/integrations/agent/request-lowering.js +66 -141
  186. package/dist/integrations/agent/runner-dispatch.js +143 -321
  187. package/dist/integrations/agent/runner.js +54 -14
  188. package/dist/integrations/lockfile.js +53 -101
  189. package/dist/llm/client.js +18 -6
  190. package/dist/llm/embedders/deterministic.js +2 -3
  191. package/dist/llm/embedders/profile.js +71 -0
  192. package/dist/llm/embedders/remote.js +11 -17
  193. package/dist/llm/feature-gate.js +0 -8
  194. package/dist/llm/index-passes.js +3 -5
  195. package/dist/llm/memory-infer.js +1 -2
  196. package/dist/llm/structured-call.js +5 -24
  197. package/dist/output/generic-render.js +23 -11
  198. package/dist/output/html-render.js +13 -10
  199. package/dist/output/render-registry.js +3 -32
  200. package/dist/output/shapes/helpers.js +25 -38
  201. package/dist/output/shapes/passthrough.js +1 -9
  202. package/dist/{indexer/graph/graph-types.js → output/text/bundle-rename.js} +4 -1
  203. package/dist/output/text/command-format.js +69 -31
  204. package/dist/output/text/helpers.js +1 -1
  205. package/dist/output/text/migrate.js +5 -14
  206. package/dist/output/text/proposal-format.js +48 -3
  207. package/dist/output/text/show-format.js +13 -17
  208. package/dist/output/text/workflow-format.js +0 -32
  209. package/dist/output/text.js +2 -0
  210. package/dist/registry/factory.js +4 -19
  211. package/dist/registry/network.js +66 -220
  212. package/dist/registry/providers/index.js +0 -2
  213. package/dist/registry/providers/skills-sh.js +3 -14
  214. package/dist/registry/providers/static-index.js +24 -26
  215. package/dist/registry/resolve.js +55 -131
  216. package/dist/scripts/akm-migrate-node.js +42948 -92369
  217. package/dist/scripts/akm-migrate.js +42935 -92354
  218. package/dist/setup/registry-stash-loader.js +4 -13
  219. package/dist/setup/semantic-assets.js +3 -44
  220. package/dist/setup/setup.js +1 -1
  221. package/dist/setup/steps/connection.js +5 -6
  222. package/dist/setup/steps/platforms.js +2 -2
  223. package/dist/setup/steps/tasks.js +25 -15
  224. package/dist/sources/provider-factory.js +17 -18
  225. package/dist/sources/providers/filesystem.js +2 -3
  226. package/dist/sources/providers/git-install.js +7 -1
  227. package/dist/sources/providers/git-provider.js +0 -3
  228. package/dist/sources/providers/git-stash.js +83 -21
  229. package/dist/sources/providers/npm.js +2 -4
  230. package/dist/sources/providers/provider-utils.js +5 -10
  231. package/dist/sources/providers/website.js +0 -2
  232. package/dist/sources/snapshot-fetchers/website-ingest.js +1 -1
  233. package/dist/sources/website-url.js +2 -2
  234. package/dist/storage/database.js +9 -35
  235. package/dist/storage/repositories/improve-ledger-repository.js +209 -0
  236. package/dist/storage/repositories/index-connection.js +39 -72
  237. package/dist/storage/repositories/index-entries-repository.js +131 -129
  238. package/dist/storage/repositories/index-entry-mapper.js +1 -2
  239. package/dist/storage/repositories/index-entry-schema.js +101 -268
  240. package/dist/storage/repositories/index-fts-repository.js +86 -256
  241. package/dist/storage/repositories/index-links-repository.js +143 -0
  242. package/dist/storage/repositories/index-llm-cache-repository.js +7 -9
  243. package/dist/storage/repositories/index-meta-repository.js +6 -4
  244. package/dist/storage/repositories/index-schema.js +257 -325
  245. package/dist/storage/repositories/index-utility-repository.js +8 -29
  246. package/dist/storage/repositories/index-vec-repository.js +133 -414
  247. package/dist/storage/repositories/outcome-repository.js +2 -1
  248. package/dist/storage/repositories/proposals-repository.js +104 -1
  249. package/dist/storage/repositories/registry-index-cache-repository.js +100 -0
  250. package/dist/storage/repositories/salience-repository.js +1 -19
  251. package/dist/storage/repositories/task-history-repository.js +26 -4
  252. package/dist/storage/repositories/workflow-runs-repository.js +53 -244
  253. package/dist/storage/sqlite-migrations.js +136 -0
  254. package/dist/storage/sqlite-pragmas.js +11 -9
  255. package/dist/storage/sqlite-transaction.js +170 -0
  256. package/dist/storage/state-db-integrity.js +130 -0
  257. package/dist/tasks/activation-config.js +134 -62
  258. package/dist/tasks/backends/cron.js +191 -302
  259. package/dist/tasks/backends/exec-utils.js +2 -5
  260. package/dist/tasks/backends/launchd.js +141 -748
  261. package/dist/tasks/backends/schtasks.js +119 -623
  262. package/dist/tasks/prepare/prepare-support.js +5 -15
  263. package/dist/tasks/prepare/prepare.js +0 -2
  264. package/dist/tasks/resolve-akm-bin.js +20 -79
  265. package/dist/tasks/run/attempt-lifecycle.js +0 -1
  266. package/dist/tasks/run/load-task.js +1 -1
  267. package/dist/tasks/scheduler-binding.js +20 -238
  268. package/dist/tasks/scheduler-invocation.js +136 -244
  269. package/dist/tasks/scheduler-lock.js +53 -0
  270. package/dist/tasks/scheduler-sync.js +368 -679
  271. package/dist/tasks/source/parse-task-source.js +55 -9
  272. package/dist/tasks/source/task-source-v3-frozen.js +3 -4
  273. package/dist/tasks/source/task-to-v4.js +464 -88
  274. package/dist/workflows/authoring/authoring.js +3 -12
  275. package/dist/workflows/compile.js +211 -0
  276. package/dist/workflows/concurrency-policy.js +13 -74
  277. package/dist/workflows/exec/child-invocation.js +3 -17
  278. package/dist/workflows/exec/child-workflow.js +32 -141
  279. package/dist/workflows/exec/dispatch-redaction.js +13 -53
  280. package/dist/workflows/exec/environment.js +98 -0
  281. package/dist/workflows/exec/exec-unit.js +33 -140
  282. package/dist/workflows/exec/frozen-judge.js +7 -59
  283. package/dist/workflows/exec/native-executor.js +82 -341
  284. package/dist/workflows/exec/param-secrets.js +29 -47
  285. package/dist/workflows/exec/run-workflow.js +154 -387
  286. package/dist/workflows/exec/scheduler.js +9 -36
  287. package/dist/workflows/exec/step-work.js +127 -430
  288. package/dist/workflows/exec/unit-dispatch.js +11 -63
  289. package/dist/workflows/exec/unit-writer.js +8 -52
  290. package/dist/workflows/exec/worktree.js +39 -273
  291. package/dist/workflows/freeze/child-output-references.js +4 -15
  292. package/dist/workflows/freeze/environment.js +99 -92
  293. package/dist/workflows/freeze/freeze.js +172 -0
  294. package/dist/workflows/freeze/step-values.js +19 -21
  295. package/dist/workflows/freeze/targets/child-workflow.js +23 -92
  296. package/dist/workflows/freeze/targets/command.js +10 -33
  297. package/dist/workflows/freeze/targets/script.js +5 -12
  298. package/dist/workflows/freeze/targets/shell.js +3 -6
  299. package/dist/workflows/freeze/targets/task.js +25 -80
  300. package/dist/workflows/freeze/task-bindings.js +20 -67
  301. package/dist/workflows/{source-ir/github-yaml.js → github-yaml.js} +88 -206
  302. package/dist/workflows/ir/params.js +6 -51
  303. package/dist/workflows/ir/plan-hash.js +2 -34
  304. package/dist/workflows/parser.js +140 -43
  305. package/dist/{commands/improve/consolidate/types.js → workflows/plan.js} +2 -1
  306. package/dist/workflows/renderer.js +36 -69
  307. package/dist/workflows/resource-limits.js +12 -120
  308. package/dist/workflows/runtime/agent-identity.js +8 -40
  309. package/dist/workflows/runtime/run-outputs.js +3 -6
  310. package/dist/workflows/runtime/run-plan.js +316 -0
  311. package/dist/workflows/runtime/runs.js +48 -200
  312. package/dist/workflows/runtime/workflow-asset-loader.js +24 -57
  313. package/dist/workflows/{source-ir/semantics.js → source-semantics.js} +16 -20
  314. package/dist/workflows/validate-summary.js +2 -7
  315. package/docs/integration/bundling-akm.md +49 -42
  316. package/docs/migration/README.md +1 -0
  317. package/docs/migration/release-notes/0.9.17.md +43 -0
  318. package/docs/migration/v0.9.1-to-v0.9.2.md +23 -7
  319. package/docs/reference/cli.md +232 -135
  320. package/docs/reference/configuration.md +71 -57
  321. package/docs/reference/data-and-telemetry.md +20 -21
  322. package/docs/reference/tasks.md +105 -39
  323. package/docs/reference/workflow-schema.md +14 -18
  324. package/docs/reference/workflows.md +6 -9
  325. package/package.json +1 -1
  326. package/schemas/akm-config.json +115 -738
  327. package/schemas/akm-workflow.json +1 -0
  328. package/dist/assets/improve-strategies/graph-refresh.json +0 -15
  329. package/dist/assets/prompts/contradiction-judge.md +0 -33
  330. package/dist/assets/prompts/graph-extract-system.md +0 -1
  331. package/dist/assets/prompts/graph-extract-user-prompt.md +0 -35
  332. package/dist/assets/prompts/metadata-enhance-system.md +0 -1
  333. package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +0 -4
  334. package/dist/commands/health/advisories.js +0 -150
  335. package/dist/commands/health/metrics.js +0 -329
  336. package/dist/commands/health/surfaces.js +0 -102
  337. package/dist/commands/improve/anti-collapse.js +0 -83
  338. package/dist/commands/improve/collapse-detector.js +0 -432
  339. package/dist/commands/improve/consolidate/eligibility.js +0 -48
  340. package/dist/commands/improve/consolidate/merge.js +0 -149
  341. package/dist/commands/improve/distill/promote-memory.js +0 -291
  342. package/dist/commands/improve/distill/quality-gate.js +0 -337
  343. package/dist/commands/improve/eval-cases.js +0 -52
  344. package/dist/commands/improve/memory/memory-contradiction-detect.js +0 -291
  345. package/dist/commands/improve/proposal-envelope.js +0 -31
  346. package/dist/commands/improve/run-context.js +0 -123
  347. package/dist/commands/improve/shared.js +0 -31
  348. package/dist/commands/improve/source-identity.js +0 -28
  349. package/dist/commands/improve/triage.js +0 -96
  350. package/dist/commands/proposal/drain-policies.js +0 -151
  351. package/dist/commands/sources/update-transaction.js +0 -220
  352. package/dist/core/action-contributors.js +0 -28
  353. package/dist/core/config/config-version-shim.js +0 -101
  354. package/dist/core/fs-txn.js +0 -405
  355. package/dist/core/lexical-score.js +0 -25
  356. package/dist/core/maintenance-barrier.js +0 -167
  357. package/dist/execution/executable-identity.js +0 -105
  358. package/dist/execution/guarded-source.js +0 -427
  359. package/dist/indexer/db/graph-db.js +0 -444
  360. package/dist/indexer/graph/graph-boost.js +0 -427
  361. package/dist/indexer/graph/graph-dedup.js +0 -95
  362. package/dist/indexer/graph/graph-extraction.js +0 -1108
  363. package/dist/indexer/search/name-match.js +0 -35
  364. package/dist/indexer/search/ranking-contributors.js +0 -515
  365. package/dist/indexer/search/ranking-types.js +0 -4
  366. package/dist/indexer/walk/project-context.js +0 -192
  367. package/dist/integrations/agent/execution-cascade.js +0 -566
  368. package/dist/integrations/agent/execution-definitions.js +0 -202
  369. package/dist/integrations/agent/execution-lowering.js +0 -841
  370. package/dist/integrations/agent/execution-preparation.js +0 -98
  371. package/dist/integrations/agent/inline-execution.js +0 -74
  372. package/dist/llm/graph-extract.js +0 -728
  373. package/dist/llm/metadata-enhance.js +0 -96
  374. package/dist/registry/create-provider-registry.js +0 -29
  375. package/dist/registry/pinned-request-helper.js +0 -247
  376. package/dist/registry/pinned-transport.js +0 -717
  377. package/dist/sources/providers/index.js +0 -14
  378. package/dist/storage/engines/sqlite-migrations.js +0 -271
  379. package/dist/storage/repositories/canaries-repository.js +0 -107
  380. package/dist/storage/repositories/embedding-salvage-repository.js +0 -184
  381. package/dist/storage/repositories/registry-cache.js +0 -113
  382. package/dist/tasks/scheduler-sync-preview.js +0 -52
  383. package/dist/tasks/source/task-to-v3.js +0 -507
  384. package/dist/workflows/freeze/resolve-steps.js +0 -86
  385. package/dist/workflows/freeze/source-freeze.js +0 -64
  386. package/dist/workflows/ir/compile.js +0 -321
  387. package/dist/workflows/ir/environment-v4.js +0 -330
  388. package/dist/workflows/ir/freeze-v4.js +0 -153
  389. package/dist/workflows/ir/schema-v4.js +0 -745
  390. package/dist/workflows/ir/schema.js +0 -354
  391. package/dist/workflows/program/schema.js +0 -77
  392. package/dist/workflows/runtime/checkin.js +0 -57
  393. package/dist/workflows/runtime/plan-classifier.js +0 -196
  394. package/dist/workflows/runtime/unit-checkin.js +0 -45
  395. package/dist/workflows/runtime/unit-phases.js +0 -20
  396. package/dist/workflows/schema.js +0 -4
  397. package/dist/workflows/source-ir/compile.js +0 -200
  398. package/dist/workflows/source-ir/program.js +0 -50
  399. package/dist/workflows/source-ir/result.js +0 -26
  400. package/dist/workflows/source-ir/schema.js +0 -786
  401. package/dist/workflows/source-ir/triggers.js +0 -79
  402. package/dist/workflows/source-ir/uses.js +0 -40
  403. 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>"}