akm-cli 0.9.0-rc.8 → 0.9.0

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 (450) hide show
  1. package/CHANGELOG.md +1063 -44
  2. package/README.md +51 -25
  3. package/SECURITY.md +14 -1
  4. package/STABILITY.md +497 -0
  5. package/dist/akm +148 -35
  6. package/dist/{akm-migrate-storage → akm-migrate} +6 -9
  7. package/dist/assets/hints/cli-hints-full.md +223 -95
  8. package/dist/assets/hints/cli-hints-short.md +85 -22
  9. package/dist/assets/improve-strategies/default.json +1 -1
  10. package/dist/assets/improve-strategies/reflect-distill.json +1 -1
  11. package/dist/assets/prompts/memory-infer-user.md +2 -3
  12. package/dist/assets/stash-skeleton/README.md +6 -5
  13. package/dist/assets/stash-skeleton/facts/conventions/assets/agent.md +2 -0
  14. package/dist/assets/stash-skeleton/facts/conventions/assets/command.md +2 -0
  15. package/dist/assets/stash-skeleton/facts/conventions/assets/fact.md +2 -0
  16. package/dist/assets/stash-skeleton/facts/conventions/assets/knowledge.md +2 -0
  17. package/dist/assets/stash-skeleton/facts/conventions/assets/lesson.md +2 -0
  18. package/dist/assets/stash-skeleton/facts/conventions/assets/memory.md +2 -0
  19. package/dist/assets/stash-skeleton/facts/conventions/assets/script.md +2 -0
  20. package/dist/assets/stash-skeleton/facts/conventions/assets/skill.md +2 -0
  21. package/dist/assets/stash-skeleton/facts/conventions/assets/workflow.md +2 -0
  22. package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +2 -0
  23. package/dist/assets/stash-skeleton/facts/conventions/domains.md +2 -0
  24. package/dist/assets/stash-skeleton/facts/conventions/organization.md +20 -9
  25. package/dist/assets/tasks/core/extract.yml +1 -1
  26. package/dist/assets/tasks/core/version-check.yml +1 -1
  27. package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +5 -0
  28. package/dist/assets/tasks/improve/akm-improve-catchup.yml +8 -0
  29. package/dist/assets/tasks/improve/akm-improve-consolidate.yml +5 -0
  30. package/dist/assets/tasks/improve/akm-improve-frequent.yml +5 -0
  31. package/dist/assets/tasks/improve/akm-improve-nightly.yml +5 -0
  32. package/dist/assets/templates/html/health.html +1 -3
  33. package/dist/assets/workflows/workflow-template.md +32 -15
  34. package/dist/cli/invocation.js +40 -15
  35. package/dist/cli/parse-args.js +0 -22
  36. package/dist/cli/retired-commands.js +121 -0
  37. package/dist/cli/shared.js +154 -22
  38. package/dist/cli/unknown-flags.js +236 -0
  39. package/dist/cli-node.mjs +2 -1
  40. package/dist/cli.js +696 -258
  41. package/dist/commands/agent/agent-dispatch.js +14 -3
  42. package/dist/commands/agent/contribute-cli.js +73 -88
  43. package/dist/commands/completions.js +79 -22
  44. package/dist/commands/config-cli.js +17 -150
  45. package/dist/commands/env/env-cli.js +59 -143
  46. package/dist/commands/env/env.js +12 -163
  47. package/dist/commands/env/marker-path.js +6 -0
  48. package/dist/commands/env/secret-cli.js +36 -66
  49. package/dist/commands/env/secret.js +24 -57
  50. package/dist/commands/feedback-cli.js +141 -87
  51. package/dist/commands/health/accept-rate.js +58 -0
  52. package/dist/commands/health/advisories.js +3 -4
  53. package/dist/commands/health/checks.js +85 -23
  54. package/dist/commands/health/html-report.js +7 -10
  55. package/dist/commands/health/improve-metrics.js +25 -83
  56. package/dist/commands/health/md-report.js +5 -9
  57. package/dist/commands/health/metrics.js +62 -20
  58. package/dist/commands/health/renderers.js +47 -0
  59. package/dist/commands/health/report-view-model.js +4 -5
  60. package/dist/commands/health/stash-exposure.js +1 -1
  61. package/dist/commands/health/surfaces.js +3 -48
  62. package/dist/commands/health/task-runs.js +3 -67
  63. package/dist/commands/health/types-improve.js +7 -0
  64. package/dist/commands/health.js +99 -28
  65. package/dist/commands/improve/anti-collapse.js +2 -2
  66. package/dist/commands/improve/autonomy-gate.js +68 -0
  67. package/dist/commands/improve/collapse-detector.js +41 -40
  68. package/dist/commands/improve/consolidate/eligibility.js +1 -23
  69. package/dist/commands/improve/consolidate/merge.js +4 -0
  70. package/dist/commands/improve/consolidate.js +140 -1000
  71. package/dist/commands/improve/distill/promote-memory.js +12 -12
  72. package/dist/commands/improve/distill/quality-gate.js +6 -6
  73. package/dist/commands/improve/distill.js +58 -69
  74. package/dist/commands/improve/eligibility.js +105 -57
  75. package/dist/commands/improve/extract-cli.js +14 -133
  76. package/dist/commands/improve/improve-cli.js +98 -114
  77. package/dist/commands/improve/improve-result-file.js +1 -28
  78. package/dist/commands/improve/improve-strategies.js +8 -5
  79. package/dist/commands/improve/improve.js +128 -91
  80. package/dist/commands/improve/loop-stages.js +182 -20
  81. package/dist/commands/improve/memory/derived-ref.js +45 -43
  82. package/dist/commands/improve/memory/memory-belief.js +1 -1
  83. package/dist/commands/improve/memory/memory-contradiction-detect.js +4 -12
  84. package/dist/commands/improve/memory/memory-improve.js +6 -5
  85. package/dist/commands/improve/outcome-loop.js +22 -65
  86. package/dist/commands/improve/preparation.js +114 -123
  87. package/dist/commands/improve/proactive-maintenance.js +2 -5
  88. package/dist/commands/improve/reflect.js +56 -160
  89. package/dist/commands/improve/salience.js +11 -122
  90. package/dist/commands/improve/source-identity.js +10 -38
  91. package/dist/commands/lint/base-linter.js +20 -124
  92. package/dist/commands/lint/env-key-rules.js +31 -47
  93. package/dist/commands/lint/index.js +249 -43
  94. package/dist/commands/{events.js → log.js} +33 -38
  95. package/dist/commands/migrate-cli.js +92 -12
  96. package/dist/commands/migration-tool.js +46 -0
  97. package/dist/commands/observability-cli.js +70 -209
  98. package/dist/commands/proposal/drain.js +101 -29
  99. package/dist/commands/proposal/proposal-cli.js +76 -48
  100. package/dist/commands/proposal/proposal.js +54 -18
  101. package/dist/commands/proposal/propose-cli.js +88 -0
  102. package/dist/commands/proposal/propose.js +23 -15
  103. package/dist/commands/proposal/repository.js +701 -278
  104. package/dist/commands/proposal/validators/proposal-quality-validators.js +2 -8
  105. package/dist/commands/proposal/validators/proposal-validators.js +55 -7
  106. package/dist/commands/proposal/validators/proposals.js +4 -7
  107. package/dist/commands/read/curate.js +34 -53
  108. package/dist/commands/read/knowledge.js +150 -95
  109. package/dist/commands/read/registry-search.js +2 -2
  110. package/dist/commands/read/remember-cli.js +42 -15
  111. package/dist/commands/read/search-cli.js +180 -78
  112. package/dist/commands/read/search.js +58 -43
  113. package/dist/commands/read/show.js +197 -141
  114. package/dist/commands/registry-cli.js +12 -51
  115. package/dist/commands/remember.js +14 -57
  116. package/dist/commands/sources/add-cli.js +100 -31
  117. package/dist/commands/sources/bundle-cli.js +166 -0
  118. package/dist/commands/sources/bundle-config-ops.js +7 -2
  119. package/dist/commands/sources/info.js +18 -5
  120. package/dist/commands/sources/init.js +12 -12
  121. package/dist/commands/sources/installed-stashes.js +382 -98
  122. package/dist/commands/sources/schema-repair.js +3 -2
  123. package/dist/commands/sources/self-update.js +131 -38
  124. package/dist/commands/sources/source-add.js +72 -17
  125. package/dist/commands/sources/source-clone.js +129 -45
  126. package/dist/commands/sources/source-manage.js +43 -23
  127. package/dist/commands/sources/sources-cli.js +57 -208
  128. package/dist/commands/sources/stash-cli.js +46 -53
  129. package/dist/commands/tasks/tasks-cli.js +91 -97
  130. package/dist/commands/tasks/tasks.js +276 -421
  131. package/dist/commands/workflow-cli.js +175 -450
  132. package/dist/core/adapter/adapters/akm-adapter.js +47 -28
  133. package/dist/core/adapter/adapters/akm-lint.js +42 -27
  134. package/dist/core/adapter/adapters/akm-metadata.js +15 -44
  135. package/dist/core/adapter/adapters/akm-task-adapter.js +15 -13
  136. package/dist/core/adapter/adapters/akm-workflow-adapter.js +55 -71
  137. package/dist/core/adapter/adapters/dotenv-adapter.js +1 -1
  138. package/dist/core/adapter/adapters/generic-files-adapter.js +2 -0
  139. package/dist/core/adapter/adapters/index.js +6 -6
  140. package/dist/core/adapter/adapters/llm-wiki-adapter.js +14 -8
  141. package/dist/core/adapter/adapters/okf-adapter.js +187 -19
  142. package/dist/core/adapter/adapters/shared.js +3 -19
  143. package/dist/core/adapter/adapters/tool-dir-shared.js +8 -3
  144. package/dist/core/adapter/adapters/website-snapshot-adapter.js +1 -0
  145. package/dist/core/adapter/detect-adapter.js +17 -0
  146. package/dist/core/adapter/recognize-match.js +6 -4
  147. package/dist/core/adapter/validate-context.js +214 -0
  148. package/dist/core/asset/akm-markdown.js +63 -0
  149. package/dist/core/asset/asset-placement.js +20 -6
  150. package/dist/core/asset/asset-ref.js +11 -9
  151. package/dist/core/asset/frontmatter-lint.js +30 -0
  152. package/dist/core/asset/frontmatter.js +37 -9
  153. package/dist/core/asset/markdown.js +40 -51
  154. package/dist/core/asset/resolve-ref.js +89 -18
  155. package/dist/core/asset/stash-meta.js +1 -1
  156. package/dist/core/bundle-id.js +51 -0
  157. package/dist/core/common.js +152 -38
  158. package/dist/core/config/config-io.js +12 -1
  159. package/dist/core/config/config-schema.js +35 -8
  160. package/dist/core/config/config-sources.js +55 -11
  161. package/dist/core/config/config-walker.js +25 -9
  162. package/dist/core/config/config.js +9 -48
  163. package/dist/core/config/experimental.js +21 -0
  164. package/dist/core/config/schema/embedding.js +5 -1
  165. package/dist/core/config/schema/experimental.js +30 -0
  166. package/dist/core/config/schema/improve-processes.js +0 -6
  167. package/dist/core/config/schema/improve.js +21 -3
  168. package/dist/core/config/schema/index-config.js +8 -15
  169. package/dist/core/config/schema/output.js +4 -1
  170. package/dist/core/config/schema/setup.js +9 -18
  171. package/dist/core/config/schema/sources-bundles.js +49 -33
  172. package/dist/core/config/schema/workflow.js +3 -3
  173. package/dist/core/env-secret-ref.js +76 -46
  174. package/dist/core/errors.js +18 -12
  175. package/dist/core/events.js +46 -128
  176. package/dist/core/file-change.js +6 -5
  177. package/dist/core/fs-txn.js +83 -7
  178. package/dist/core/git-message.js +2 -2
  179. package/dist/core/improve-result.js +1 -100
  180. package/dist/core/lesson-lint.js +1 -17
  181. package/dist/core/logs-db.js +2 -1
  182. package/dist/core/migration-operation.js +16 -0
  183. package/dist/core/mutation-target.js +78 -0
  184. package/dist/core/parse.js +4 -1
  185. package/dist/core/paths.js +17 -20
  186. package/dist/core/recognition-util.js +12 -14
  187. package/dist/core/redaction.js +34 -0
  188. package/dist/core/standards/resolve-standards-context.js +2 -14
  189. package/dist/core/standards/resolve-stash-standards.js +2 -2
  190. package/dist/core/standards/resolve-type-conventions.js +2 -2
  191. package/dist/core/state/migrations.js +41 -18
  192. package/dist/core/state-db.js +5 -14
  193. package/dist/core/structured.js +1 -1
  194. package/dist/core/subprocess.js +6 -4
  195. package/dist/core/text-truncation.js +9 -5
  196. package/dist/core/type-presentation.js +3 -3
  197. package/dist/core/warn.js +0 -3
  198. package/dist/core/write-source.js +771 -95
  199. package/dist/indexer/bundle-identity-guard.js +3 -2
  200. package/dist/indexer/db/graph-db.js +0 -24
  201. package/dist/indexer/ensure-index.js +1 -0
  202. package/dist/indexer/graph/graph-boost.js +9 -34
  203. package/dist/indexer/graph/graph-extraction.js +8 -5
  204. package/dist/indexer/index-writer-lock.js +53 -17
  205. package/dist/indexer/index-written-assets.js +16 -22
  206. package/dist/indexer/indexer.js +497 -239
  207. package/dist/indexer/installations.js +14 -96
  208. package/dist/indexer/passes/dir-staleness.js +16 -9
  209. package/dist/indexer/passes/memory-inference.js +11 -9
  210. package/dist/indexer/passes/metadata.js +113 -47
  211. package/dist/indexer/scan/doc-to-entry.js +38 -1
  212. package/dist/indexer/scan/drain-dir.js +13 -23
  213. package/dist/indexer/search/db-search.js +99 -54
  214. package/dist/indexer/search/fts-query.js +47 -24
  215. package/dist/indexer/search/ranking-contributors.js +42 -20
  216. package/dist/indexer/search/ranking.js +18 -99
  217. package/dist/indexer/search/search-fields.js +7 -2
  218. package/dist/indexer/search/search-source.js +82 -93
  219. package/dist/indexer/usage/usage-events.js +0 -89
  220. package/dist/indexer/walk/file-context.js +2 -1
  221. package/dist/indexer/walk/matchers.js +30 -43
  222. package/dist/indexer/walk/path-resolver.js +7 -2
  223. package/dist/indexer/walk/walker.js +38 -12
  224. package/dist/integrations/agent/builders.js +0 -6
  225. package/dist/integrations/agent/config.js +2 -2
  226. package/dist/integrations/agent/detect.js +49 -19
  227. package/dist/integrations/agent/engine-fallback.js +76 -0
  228. package/dist/integrations/agent/profiles.js +14 -0
  229. package/dist/integrations/agent/prompts.js +12 -8
  230. package/dist/integrations/agent/runner-dispatch.js +4 -2
  231. package/dist/integrations/agent/runner.js +0 -1
  232. package/dist/integrations/agent/spawn.js +5 -6
  233. package/dist/integrations/github.js +1 -1
  234. package/dist/integrations/harnesses/aider/agent-builder.js +6 -4
  235. package/dist/integrations/harnesses/amazonq/agent-builder.js +7 -4
  236. package/dist/integrations/harnesses/claude/session-log.js +0 -10
  237. package/dist/integrations/harnesses/codex/agent-builder.js +5 -2
  238. package/dist/integrations/harnesses/copilot/agent-builder.js +5 -3
  239. package/dist/integrations/harnesses/gemini/agent-builder.js +5 -3
  240. package/dist/integrations/harnesses/index.js +3 -7
  241. package/dist/integrations/harnesses/opencode/agent-builder.js +21 -2
  242. package/dist/integrations/harnesses/opencode/session-log.js +0 -15
  243. package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +13 -4
  244. package/dist/integrations/harnesses/openhands/agent-builder.js +9 -6
  245. package/dist/integrations/harnesses/pi/agent-builder.js +6 -4
  246. package/dist/integrations/lockfile.js +101 -6
  247. package/dist/integrations/session-logs/index.js +3 -28
  248. package/dist/llm/client.js +136 -100
  249. package/dist/llm/embedders/remote.js +13 -5
  250. package/dist/llm/feature-gate.js +4 -12
  251. package/dist/llm/graph-extract.js +5 -11
  252. package/dist/llm/memory-infer.js +144 -1
  253. package/dist/llm/metadata-enhance.js +5 -7
  254. package/dist/llm/structured-call.js +1 -1
  255. package/dist/llm/usage-persist.js +26 -5
  256. package/dist/llm/usage-telemetry.js +25 -2
  257. package/dist/output/cli-hints.js +1 -2
  258. package/dist/output/context.js +22 -7
  259. package/dist/output/format-exempt.js +80 -0
  260. package/dist/output/generic-render.js +259 -0
  261. package/dist/output/render-registry.js +57 -0
  262. package/dist/output/renderers.js +14 -36
  263. package/dist/output/shapes/curate.js +10 -1
  264. package/dist/output/shapes/events.js +12 -7
  265. package/dist/output/shapes/helpers.js +56 -83
  266. package/dist/output/shapes/migrate.js +8 -0
  267. package/dist/output/shapes/passthrough.js +7 -41
  268. package/dist/output/shapes/proposal/producer.js +15 -7
  269. package/dist/output/shapes.js +2 -9
  270. package/dist/output/text/{init.js → bundle-create.js} +3 -1
  271. package/dist/output/text/bundle-show.js +7 -0
  272. package/dist/output/text/command-format.js +164 -96
  273. package/dist/output/text/env.js +1 -3
  274. package/dist/output/text/events.js +8 -7
  275. package/dist/output/text/health-format.js +103 -0
  276. package/dist/output/text/health.js +7 -0
  277. package/dist/output/text/helpers.js +10 -8
  278. package/dist/output/text/lint-format.js +43 -0
  279. package/dist/output/text/{save.js → lint.js} +2 -2
  280. package/dist/output/text/migrate.js +88 -0
  281. package/dist/output/text/proposal/producer.js +4 -2
  282. package/dist/output/text/proposal-format.js +44 -72
  283. package/dist/output/text/registry-commands.js +1 -2
  284. package/dist/output/text/show-directives.js +15 -7
  285. package/dist/output/text/status-list.js +32 -0
  286. package/dist/output/text/sync.js +5 -0
  287. package/dist/output/text/workflow-format.js +24 -203
  288. package/dist/output/text/workflow.js +1 -7
  289. package/dist/output/text.js +16 -17
  290. package/dist/registry/factory.js +4 -6
  291. package/dist/registry/origin-resolve.js +16 -27
  292. package/dist/registry/providers/skills-sh.js +3 -3
  293. package/dist/registry/providers/static-index.js +13 -23
  294. package/dist/registry/resolve.js +42 -7
  295. package/dist/registry/semver.js +34 -84
  296. package/dist/runtime.js +2 -23
  297. package/dist/scripts/akm-migrate-node.js +60290 -0
  298. package/dist/scripts/akm-migrate.js +59628 -0
  299. package/dist/setup/detect.js +42 -15
  300. package/dist/setup/registry-stash-loader.js +2 -2
  301. package/dist/setup/setup.js +236 -136
  302. package/dist/setup/steps/connection.js +7 -9
  303. package/dist/setup/steps/platforms.js +9 -9
  304. package/dist/setup/steps/semantic.js +15 -3
  305. package/dist/setup/steps/sources.js +12 -13
  306. package/dist/setup/steps/stashdir.js +2 -3
  307. package/dist/setup/steps/tasks.js +237 -120
  308. package/dist/sources/freshness.js +1 -1
  309. package/dist/sources/provider-factory.js +11 -17
  310. package/dist/sources/providers/filesystem.js +2 -3
  311. package/dist/sources/providers/git-install.js +278 -34
  312. package/dist/sources/providers/git-provider.js +25 -23
  313. package/dist/sources/providers/git-stash.js +395 -106
  314. package/dist/sources/providers/git.js +2 -2
  315. package/dist/sources/providers/npm.js +16 -19
  316. package/dist/sources/providers/provider-utils.js +7 -4
  317. package/dist/sources/providers/sync-from-ref.js +3 -9
  318. package/dist/sources/providers/website.js +6 -1
  319. package/dist/sources/resolve.js +6 -5
  320. package/dist/sources/snapshot-fetchers/bluesky.js +146 -0
  321. package/dist/sources/snapshot-fetchers/content-extract.js +566 -0
  322. package/dist/sources/snapshot-fetchers/fetcher-util.js +41 -0
  323. package/dist/sources/snapshot-fetchers/github.js +100 -0
  324. package/dist/sources/snapshot-fetchers/host-guard.js +291 -0
  325. package/dist/sources/snapshot-fetchers/registry.js +17 -1
  326. package/dist/sources/snapshot-fetchers/robots.js +348 -0
  327. package/dist/sources/snapshot-fetchers/rss.js +282 -0
  328. package/dist/sources/snapshot-fetchers/secret-seam.js +42 -0
  329. package/dist/sources/snapshot-fetchers/website-ingest.js +566 -268
  330. package/dist/sources/snapshot-fetchers/x.js +910 -0
  331. package/dist/storage/database.js +7 -0
  332. package/dist/storage/engines/sqlite-migrations.js +23 -111
  333. package/dist/storage/managed-db.js +2 -2
  334. package/dist/storage/repositories/canaries-repository.js +1 -1
  335. package/dist/storage/repositories/events-repository.js +27 -11
  336. package/dist/storage/repositories/improve-runs-repository.js +6 -12
  337. package/dist/storage/repositories/index-connection.js +17 -6
  338. package/dist/storage/repositories/index-entries-repository.js +151 -240
  339. package/dist/storage/repositories/index-entry-mapper.js +15 -11
  340. package/dist/storage/repositories/index-fts-repository.js +5 -2
  341. package/dist/storage/repositories/index-llm-cache-repository.js +0 -1
  342. package/dist/storage/repositories/index-meta-repository.js +2 -3
  343. package/dist/storage/repositories/index-schema.js +10 -25
  344. package/dist/storage/repositories/index-utility-repository.js +15 -28
  345. package/dist/storage/repositories/index-vec-repository.js +6 -1
  346. package/dist/storage/repositories/outcome-repository.js +119 -0
  347. package/dist/storage/repositories/proposals-repository.js +296 -59
  348. package/dist/storage/repositories/registry-cache.js +19 -0
  349. package/dist/storage/repositories/salience-repository.js +172 -0
  350. package/dist/storage/repositories/task-history-repository.js +15 -13
  351. package/dist/storage/repositories/workflow-runs-repository.js +52 -40
  352. package/dist/tasks/backends/cron.js +105 -15
  353. package/dist/tasks/backends/index.js +1 -1
  354. package/dist/tasks/backends/launchd.js +85 -38
  355. package/dist/tasks/backends/schtasks.js +135 -15
  356. package/dist/tasks/embedded.js +56 -40
  357. package/dist/tasks/parser.js +7 -157
  358. package/dist/tasks/resolve-akm-bin.js +137 -59
  359. package/dist/tasks/runner.js +79 -42
  360. package/dist/tasks/scheduler-invocation.js +220 -10
  361. package/dist/tasks/schema.js +24 -1
  362. package/dist/tasks/task-id.js +1 -3
  363. package/dist/tasks/validator.js +20 -6
  364. package/dist/workflows/authoring/authoring.js +94 -143
  365. package/dist/workflows/authoring/scope-key.js +1 -1
  366. package/dist/workflows/exec/frozen-judge.js +28 -2
  367. package/dist/workflows/exec/native-executor.js +77 -57
  368. package/dist/workflows/exec/param-secrets.js +9 -9
  369. package/dist/workflows/exec/run-workflow.js +133 -79
  370. package/dist/workflows/exec/step-work.js +219 -346
  371. package/dist/{migrate-storage-node.mjs → workflows/exec/unit-dispatch.js} +1 -5
  372. package/dist/workflows/ir/compile.js +141 -270
  373. package/dist/workflows/ir/freeze.js +40 -30
  374. package/dist/workflows/ir/params.js +135 -11
  375. package/dist/workflows/ir/plan-hash.js +1 -1
  376. package/dist/workflows/ir/schema.js +25 -26
  377. package/dist/workflows/parser.js +872 -307
  378. package/dist/workflows/program/expressions.js +20 -208
  379. package/dist/workflows/program/schema.js +7 -10
  380. package/dist/workflows/renderer.js +95 -68
  381. package/dist/workflows/resource-limits.js +2 -0
  382. package/dist/workflows/runtime/checkin.js +3 -3
  383. package/dist/workflows/runtime/plan-classifier.js +16 -75
  384. package/dist/workflows/runtime/runs.js +186 -127
  385. package/dist/workflows/runtime/unit-checkin.js +1 -1
  386. package/dist/workflows/runtime/unit-phases.js +2 -2
  387. package/dist/workflows/runtime/workflow-asset-loader.js +232 -83
  388. package/dist/workflows/schema.js +1 -11
  389. package/dist/workflows/validate-summary.js +30 -36
  390. package/dist/workflows/validator.js +21 -62
  391. package/docs/README.md +68 -0
  392. package/docs/migration/README.md +8 -0
  393. package/docs/migration/release-notes/0.7.0.md +11 -11
  394. package/docs/migration/release-notes/0.9.0.md +208 -27
  395. package/docs/migration/v0.7-to-v0.8.md +46 -47
  396. package/docs/migration/v0.8-to-v0.9.md +564 -208
  397. package/docs/migration/v0.9.0-troubleshooting.md +561 -0
  398. package/docs/reference/README.md +12 -0
  399. package/docs/reference/cli.md +2253 -0
  400. package/docs/reference/configuration.md +358 -0
  401. package/docs/reference/data-and-telemetry.md +105 -42
  402. package/docs/reference/workflows.md +647 -0
  403. package/package.json +22 -11
  404. package/schemas/akm-asset-envelope.json +93 -0
  405. package/schemas/akm-config.json +81 -128
  406. package/schemas/akm-workflow.json +74 -73
  407. package/dist/assets/tasks/core/backup.yml +0 -5
  408. package/dist/assets/tasks/graph-refresh-weekly.yml +0 -10
  409. package/dist/cli/config-migrate.js +0 -1806
  410. package/dist/cli/config-validate.js +0 -41
  411. package/dist/commands/backup-cli.js +0 -56
  412. package/dist/commands/bundle/bundle-cli.js +0 -68
  413. package/dist/commands/bundle/bundle.js +0 -219
  414. package/dist/commands/graph/graph-cli.js +0 -124
  415. package/dist/commands/graph/graph.js +0 -489
  416. package/dist/commands/improve/extract-watch.js +0 -140
  417. package/dist/commands/mv-cli.js +0 -1221
  418. package/dist/commands/sources/history.js +0 -201
  419. package/dist/commands/tasks/default-tasks.js +0 -186
  420. package/dist/core/migration-backup.js +0 -1234
  421. package/dist/indexer/usage/unmigrated-vaults-guard.js +0 -95
  422. package/dist/llm/memory-infer-impl.js +0 -138
  423. package/dist/migrate/legacy/config-source-migration.js +0 -223
  424. package/dist/migrate/legacy/content-migration.js +0 -305
  425. package/dist/migrate/legacy/legacy-layout.js +0 -779
  426. package/dist/migrate/legacy/legacy-paths.js +0 -25
  427. package/dist/migrate/legacy/legacy-stash-json.js +0 -72
  428. package/dist/migrate/legacy/proposal-fs-import.js +0 -168
  429. package/dist/migrate/legacy/task-target-ref-migration.js +0 -272
  430. package/dist/migrate/legacy/three-db-cutover.js +0 -841
  431. package/dist/migrate/legacy/workflow-migrations-bodies.js +0 -52
  432. package/dist/migrate/legacy/workflow-migrations-frozen.js +0 -21
  433. package/dist/migrate/legacy-ref-grammar.js +0 -214
  434. package/dist/output/shapes/distill.js +0 -14
  435. package/dist/output/shapes/history.js +0 -11
  436. package/dist/output/text/distill.js +0 -6
  437. package/dist/output/text/enable-disable.js +0 -8
  438. package/dist/output/text/history.js +0 -6
  439. package/dist/registry/build-index.js +0 -382
  440. package/dist/schemas/akm-config.json +0 -4704
  441. package/dist/schemas/akm-task.json +0 -87
  442. package/dist/schemas/akm-workflow.json +0 -372
  443. package/dist/scripts/migrate-storage.js +0 -3816
  444. package/dist/workflows/authoring/workflow-program-template.yaml +0 -31
  445. package/dist/workflows/cli.js +0 -53
  446. package/dist/workflows/exec/brief.js +0 -481
  447. package/dist/workflows/exec/report.js +0 -1460
  448. package/dist/workflows/exec/watch.js +0 -116
  449. package/dist/workflows/program/parser.js +0 -813
  450. package/dist/workflows/program/project.js +0 -104
@@ -3,6 +3,7 @@
3
3
  // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
4
  import fs from "node:fs";
5
5
  import path from "node:path";
6
+ import { makeBundleRef } from "../../core/asset/asset-ref.js";
6
7
  import { parseFrontmatter } from "../../core/asset/frontmatter.js";
7
8
  import { typeNameFromConceptId } from "../../core/asset/resolve-ref.js";
8
9
  import { daysToMs } from "../../core/common.js";
@@ -21,6 +22,7 @@ import { getRetrievalCounts } from "../../storage/repositories/index-utility-rep
21
22
  import { listStateProposals } from "../../storage/repositories/proposals-repository.js";
22
23
  import { akmLint } from "../lint/index.js";
23
24
  import { runSchemaRepairPass } from "../sources/schema-repair.js";
25
+ import { isAutonomyLaneAllowed } from "./autonomy-gate.js";
24
26
  import { akmConsolidate } from "./consolidate.js";
25
27
  // Eligibility / candidate-selection predicates live in ./eligibility.
26
28
  import { buildLatestFeedbackTsMap, buildLatestProposalTsMap, buildUtilityMap, dedupeRefs, findAssetFilePath, isDistillCandidateRef, isLessonCandidate, isSignalDeltaEligible, } from "./eligibility.js";
@@ -31,34 +33,26 @@ import { computeProxyAdequacy, getAllAssetOutcomes, getOutcomeScoresByRef, OUTCO
31
33
  import { DEFAULT_DUE_DAYS, DEFAULT_MAX_PER_RUN, selectProactiveMaintenanceRefs } from "./proactive-maintenance.js";
32
34
  import { buildRankChangeReport, computeSalience, getAllRankScores, getAssetSalience, getLastUseMsByRef, isContentEncodingRow, SALIENCE_NO_OP_DAMPEN_FACTOR, SALIENCE_NO_OP_DAMPEN_THRESHOLD, upsertAssetSalience, } from "./salience.js";
33
35
  import { bareImproveRef, improveStateReadRefs } from "./source-identity.js";
34
- function readAssetSalienceForImproveRef(db, ref, sourceName, includeLegacyBare = false, itemRef) {
35
- // Chunk-5 flip F5e probe [itemRef, durable, bare] so a row written under
36
- // EITHER grammar is found during the transition window (source-identity.ts).
37
- for (const key of improveStateReadRefs(ref, sourceName, includeLegacyBare, itemRef)) {
36
+ function readAssetSalienceForImproveRef(db, ref, itemRef) {
37
+ for (const key of improveStateReadRefs(ref, itemRef)) {
38
38
  const row = getAssetSalience(db, key);
39
39
  if (row)
40
40
  return row;
41
41
  }
42
42
  return undefined;
43
43
  }
44
- function readConsecutiveNoOpsForImproveRef(db, ref, sourceName, includeLegacyBare = false, itemRef) {
45
- return readAssetSalienceForImproveRef(db, ref, sourceName, includeLegacyBare, itemRef)?.consecutive_no_ops ?? 0;
44
+ function readConsecutiveNoOpsForImproveRef(db, ref, itemRef) {
45
+ return readAssetSalienceForImproveRef(db, ref, itemRef)?.consecutive_no_ops ?? 0;
46
46
  }
47
- // ── Durable-state write keys (Chunk-8 WI-8.5c: collapsed onto the item_ref) ────
47
+ // ── Durable-state write keys ──────────────────────────────────────────────────
48
48
  //
49
49
  // The durable improve-state writers (salience + outcome) key by the resolved
50
- // index entry's `item_ref` (`<bundle>//<conceptId>`, D-R3) WHEN the planner
51
- // resolved one (`ImproveEligibleRef.itemRef`). The pre-flip source-qualified /
52
- // bare fallbacks were retired here: both writers now share ONE key expression,
50
+ // index entry's `item_ref` (`<bundle>//<conceptId>`) when the planner resolved
51
+ // one (`ImproveEligibleRef.itemRef`). Both writers share one key expression,
53
52
  // `itemRefByRef.get(ref) ?? ref`.
54
53
  //
55
- // THE ONE SURVIVING FALLBACK (`?? ref`): a `--scope <ref>` candidate is targeted
56
- // directly by the user and never flows through `collectEligibleRefsFromIndex`,
57
- // so the planner never resolves an `item_ref` for it. Its `ref` (the caller's
58
- // scope string) IS the write key. Every planner-resolved candidate carries its
59
- // item_ref (or, for a provenance-NULL / write-back index row, the SHORT
60
- // conceptId `ref` the WI-8.5c flip now assigns) — both are final new-grammar
61
- // spellings the one-time state.db re-key leaves untouched.
54
+ // A direct `--scope <ref>` candidate does not flow through
55
+ // `collectEligibleRefsFromIndex`, so its conceptId `ref` is the write key.
62
56
  //
63
57
  // itemRefByRef is `ref → item_ref | undefined`, built once per pass from the
64
58
  // candidate set.
@@ -77,17 +71,9 @@ function salienceWriteKey(ref, itemRefByRef) {
77
71
  function outcomeWriteKey(ref, itemRefByRef) {
78
72
  return itemRefByRef.get(ref) ?? ref;
79
73
  }
80
- /**
81
- * Recover the legacy asset type from a ref in EITHER grammar (Chunk-5 flip F5e):
82
- * the `type:` prefix of a bare/source-qualified `type:name`, or the D-R2
83
- * stash-subdir of a `[bundle//]conceptId`. "" when neither applies (a foreign
84
- * bare-name conceptId). Byte-identical to the prior `ref.slice(0, indexOf(":"))`
85
- * guard for the bare `type:name` refs the salience vector actually iterates.
86
- */
87
- function legacyTypeOf(ref) {
74
+ /** Resolve an AKM asset type from a short or bundle-qualified conceptId. */
75
+ function assetTypeOf(ref) {
88
76
  const tail = ref.includes("//") ? ref.slice(ref.indexOf("//") + 2) : ref;
89
- if (tail.includes(":"))
90
- return tail.slice(0, tail.indexOf(":"));
91
77
  return typeNameFromConceptId(tail)?.type ?? "";
92
78
  }
93
79
  /**
@@ -105,11 +91,14 @@ function evaluateConsolidationEligibility(args) {
105
91
  // consolidate_completed event. Time-based cooldowns produced the same
106
92
  // synchronised-wave failure mode the reflect/distill cooldowns did; the
107
93
  // pool-delta gate ties consolidation to actual work-to-do.
94
+ const sourceName = options.sourceName ?? options.writeTarget?.source.name ?? options.config?.defaultBundle ?? "stash";
108
95
  const recentConsolidations = readEvents({ type: "consolidate_completed" });
109
96
  const lastConsolidation = recentConsolidations.events
110
- .filter((e) => e.metadata?.processed && Number(e.metadata.processed) > 0)
97
+ .filter((e) => e.metadata?.source === sourceName && Number(e.metadata?.processed) > 0)
111
98
  .sort((a, b) => new Date(b.ts ?? 0).getTime() - new Date(a.ts ?? 0).getTime())[0];
112
- const lastConsolidateTs = lastConsolidation?.ts;
99
+ const lastConsolidateTs = typeof lastConsolidation?.metadata?.completedThrough === "string"
100
+ ? lastConsolidation.metadata.completedThrough
101
+ : lastConsolidation?.ts;
113
102
  // #551 smarter gate: build the set of memory asset paths whose only delta
114
103
  // since the last consolidate is their OWN promotion. Those files
115
104
  // have not had a full improve cycle to settle, so they offer no merge /
@@ -154,21 +143,29 @@ function evaluateConsolidationEligibility(args) {
154
143
  if (!fs.existsSync(memoriesDir))
155
144
  return false;
156
145
  try {
157
- return fs.readdirSync(memoriesDir).some((f) => {
158
- if (!f.endsWith(".md"))
159
- return false;
160
- const filePath = path.join(memoriesDir, f);
161
- // #551: skip files that were only touched by their own promotion this
162
- // cohort — they have no settled merge/contradiction candidates yet.
163
- if (promotedSinceConsolidate.has(path.resolve(filePath)))
164
- return false;
165
- try {
166
- return fs.statSync(filePath).mtime.toISOString() > lastConsolidateTs;
167
- }
168
- catch {
169
- return false;
146
+ const pending = [memoriesDir];
147
+ while (pending.length > 0) {
148
+ const current = pending.pop();
149
+ for (const entry of fs.readdirSync(current, { withFileTypes: true })) {
150
+ const filePath = path.join(current, entry.name);
151
+ if (entry.isDirectory()) {
152
+ pending.push(filePath);
153
+ continue;
154
+ }
155
+ if (!entry.isFile() || !entry.name.endsWith(".md"))
156
+ continue;
157
+ if (promotedSinceConsolidate.has(path.resolve(filePath)))
158
+ continue;
159
+ try {
160
+ if (fs.statSync(filePath).mtime.toISOString() > lastConsolidateTs)
161
+ return true;
162
+ }
163
+ catch {
164
+ // Ignore files that disappear during the scan.
165
+ }
170
166
  }
171
- });
167
+ }
168
+ return false;
172
169
  }
173
170
  catch {
174
171
  return false;
@@ -240,9 +237,11 @@ export async function runConsolidationPass(args) {
240
237
  info(`[improve] consolidation skipped (pool ${eligiblePoolSize} < minPoolSize ${minPoolSize})`);
241
238
  }
242
239
  else if (!consolidationOnCooldown) {
240
+ const consolidationStartedAt = new Date().toISOString();
243
241
  consolidation = await withLlmStage("consolidate", () => akmConsolidate({
244
242
  ...options.consolidateOptions,
245
243
  config: consolidationConfig,
244
+ dryRun: options.dryRun ?? false,
246
245
  stashDir: options.stashDir,
247
246
  // Active profile for this improve run — lets consolidate's secondary
248
247
  // process-config reads honor `--profile <name>` instead of `default`.
@@ -258,17 +257,9 @@ export async function runConsolidationPass(args) {
258
257
  // recently-changed memories + graph neighbours — use this for frequent
259
258
  // passes (quick-shredder). Leave absent in the nightly default profile for
260
259
  // a full-pool sweep that catches stale-but-unmerged duplicates.
261
- incrementalSince: improveProfile?.processes?.consolidate?.incrementalSince,
262
260
  limit: improveProfile?.processes?.consolidate?.limit,
263
261
  neighborsPerChanged: improveProfile?.processes?.consolidate?.neighborsPerChanged,
264
262
  maxChunkSize: improveProfile?.processes?.consolidate?.maxChunkSize,
265
- // The improve pipeline is an automated batch flow: it must never
266
- // block on consolidate's interactive HTTP-path confirm prompt, and
267
- // scheduled runs must keep APPLYING the consolidation plan (the
268
- // shipped tasks previously got this via `--auto-accept safe`'s
269
- // prompt-bypass role; the confidence gate itself died in 0.9.0).
270
- // An explicit caller-provided consolidateOptions.assumeYes wins.
271
- assumeYes: options.consolidateOptions?.assumeYes ?? true,
272
263
  // WS-3a: forward budget signal for graceful abort on timeout, and pass
273
264
  // the profile's p90 estimate for cold-start budget reduction.
274
265
  signal: budgetSignal,
@@ -277,12 +268,24 @@ export async function runConsolidationPass(args) {
277
268
  // can flag when consolidation alone exceeded the budget.
278
269
  runBudgetMs,
279
270
  }), { engine: resolvedPlan.processes.consolidate.runner?.engine, process: "consolidate" });
280
- if (consolidation.processed > 0) {
271
+ const sourceName = options.sourceName ?? options.writeTarget?.source.name ?? baseConfig.defaultBundle ?? "stash";
272
+ const complete = (consolidation.failedChunks ?? 0) === 0 &&
273
+ (consolidation.failedChunkMemories ?? 0) === 0 &&
274
+ (consolidation.failedPromotions ?? 0) === 0 &&
275
+ (consolidation.deferredMemories ?? 0) === 0;
276
+ const hasUnappliedAdvisoryOperations = consolidation.planned?.some((op) => op.op !== "promote") ?? false;
277
+ if (consolidation.ok &&
278
+ !consolidation.dryRun &&
279
+ complete &&
280
+ !hasUnappliedAdvisoryOperations &&
281
+ consolidation.processed > 0) {
281
282
  appendEvent({
282
283
  eventType: "consolidate_completed",
283
- ref: "memories/_consolidation",
284
+ ref: makeBundleRef(sourceName, "memories/_consolidation"),
284
285
  metadata: {
285
286
  processed: consolidation.processed,
287
+ source: sourceName,
288
+ completedThrough: consolidationStartedAt,
286
289
  merged: consolidation.merged,
287
290
  deleted: consolidation.deleted,
288
291
  contradicted: consolidation.contradicted,
@@ -304,7 +307,11 @@ export async function runConsolidationPass(args) {
304
307
  info("[improve] consolidation skipped (no memory updates since last run)");
305
308
  }
306
309
  // D9: track whether consolidation wrote any data so graph extraction can reindex if needed
307
- const consolidationRan = !consolidateDisabledByProfile && !poolBelowMinSize && !consolidationOnCooldown && consolidation.processed > 0;
310
+ const consolidationRan = !consolidateDisabledByProfile &&
311
+ !poolBelowMinSize &&
312
+ !consolidationOnCooldown &&
313
+ !consolidation.previewOnly &&
314
+ consolidation.processed > 0;
308
315
  return { consolidation, consolidationRan };
309
316
  }
310
317
  /**
@@ -570,7 +577,14 @@ export async function runImprovePreparationStage(args) {
570
577
  // eligible-ref query sees a populated `entries` table on the very first
571
578
  // pass after a DB version upgrade (#339). Any failure messages from that
572
579
  // earlier call were threaded in via args.initialCleanupWarnings.
573
- const cleanup = await applyCleanupPass({ primaryStashDir, memoryCleanupPlan, plannedRefs, reindexFn, budgetSignal });
580
+ const cleanup = await applyCleanupPass({
581
+ primaryStashDir,
582
+ memoryCleanupPlan,
583
+ plannedRefs,
584
+ reindexFn,
585
+ budgetSignal,
586
+ allowApply: isAutonomyLaneAllowed("memoryCleanup", options.config ?? loadConfig()),
587
+ });
574
588
  const appliedCleanup = cleanup.appliedCleanup;
575
589
  const postCleanupRefs = cleanup.postCleanupRefs;
576
590
  actions.push(...cleanup.pruneActions);
@@ -588,7 +602,7 @@ export async function runImprovePreparationStage(args) {
588
602
  let lintSummary;
589
603
  if (primaryStashDir) {
590
604
  try {
591
- const lintResult = akmLint({ fix: true, dir: primaryStashDir });
605
+ const lintResult = await akmLint({ fix: false, dir: primaryStashDir });
592
606
  lintSummary = { fixed: lintResult.summary.fixed, flagged: lintResult.summary.flagged };
593
607
  }
594
608
  catch {
@@ -596,7 +610,7 @@ export async function runImprovePreparationStage(args) {
596
610
  }
597
611
  }
598
612
  const recentErrors = seedRecentErrorWindows(schemaRepairs);
599
- const snapshot = buildSnapshotManifest({ postCleanupRefs, validationFailureRefs, options });
613
+ const snapshot = buildSnapshotManifest({ postCleanupRefs, validationFailureRefs });
600
614
  const gathered = gatherCandidates({
601
615
  scope,
602
616
  options,
@@ -614,7 +628,6 @@ export async function runImprovePreparationStage(args) {
614
628
  options,
615
629
  primaryStashDir,
616
630
  eventsCtx,
617
- improveProfile,
618
631
  mergedRefs: gathered.mergedRefs,
619
632
  eligibilitySourceByRef: gathered.eligibilitySourceByRef,
620
633
  feedbackSummary: gathered.feedbackSummary,
@@ -707,13 +720,15 @@ function assessMemoryIndexBudget(primaryStashDir) {
707
720
  * orchestrator to fold (same order as the old inline pushes).
708
721
  */
709
722
  async function applyCleanupPass(args) {
710
- const { primaryStashDir, memoryCleanupPlan, plannedRefs, reindexFn, budgetSignal } = args;
723
+ const { primaryStashDir, memoryCleanupPlan, plannedRefs, reindexFn, budgetSignal, allowApply } = args;
711
724
  const pruneActions = [];
712
725
  const warnings = [];
713
726
  let appliedCleanup;
714
727
  try {
715
728
  appliedCleanup =
716
- primaryStashDir && memoryCleanupPlan ? applyMemoryCleanup(primaryStashDir, memoryCleanupPlan) : undefined;
729
+ primaryStashDir && memoryCleanupPlan && allowApply
730
+ ? applyMemoryCleanup(primaryStashDir, memoryCleanupPlan)
731
+ : undefined;
717
732
  }
718
733
  catch (err) {
719
734
  warnings.push(`applyMemoryCleanup failed: ${err instanceof Error ? err.message : String(err)}`);
@@ -775,7 +790,7 @@ function seedRecentErrorWindows(schemaRepairs) {
775
790
  }
776
791
  /** Pass: snapshot-manifest — the three timestamp maps + the 30-day signal window. */
777
792
  export function buildSnapshotManifest(args) {
778
- const { postCleanupRefs, validationFailureRefs, options } = args;
793
+ const { postCleanupRefs, validationFailureRefs } = args;
779
794
  // ── Phase 2: signal-delta eligibility sets built EARLY ────────────────────
780
795
  // 0.8.0 replaces the flat time-based cooldowns (which produced synchronised
781
796
  // waves whenever many refs cooled at the same instant — see the 2026-05-26
@@ -798,12 +813,11 @@ export function buildSnapshotManifest(args) {
798
813
  // Per-ref queries would be N+1 and the planner is already the hottest path
799
814
  // in `akm improve`.
800
815
  const candidateRefs = postCleanupRefs.filter((r) => !validationFailureRefs.has(r.ref)).map((r) => r.ref);
801
- // Chunk-5 flip F5e — carry each candidate's item_ref so the feedback/proposal
802
- // ts readers dual-arm their reverse maps on [item_ref, durable, bare].
816
+ // Carry each candidate's item_ref into the feedback/proposal timestamp reads.
803
817
  const itemRefByRef = buildItemRefByRef(postCleanupRefs);
804
- const latestFeedbackTs = buildLatestFeedbackTsMap(candidateRefs, feedbackSinceCutoff, options.sourceName, options.legacyBareState, itemRefByRef);
805
- const lastReflectProposalTs = buildLatestProposalTsMap(candidateRefs, "reflect", options.sourceName, options.legacyBareState, itemRefByRef);
806
- const lastDistillProposalTs = buildLatestProposalTsMap(candidateRefs, "distill", options.sourceName, options.legacyBareState, itemRefByRef);
818
+ const latestFeedbackTs = buildLatestFeedbackTsMap(candidateRefs, feedbackSinceCutoff, itemRefByRef);
819
+ const lastReflectProposalTs = buildLatestProposalTsMap(candidateRefs, "reflect", itemRefByRef);
820
+ const lastDistillProposalTs = buildLatestProposalTsMap(candidateRefs, "distill", itemRefByRef);
807
821
  return { feedbackSinceCutoff, latestFeedbackTs, lastReflectProposalTs, lastDistillProposalTs };
808
822
  }
809
823
  /**
@@ -835,7 +849,6 @@ function gatherCandidates(args) {
835
849
  const feedbackSummary = buildFeedbackSummaryMap({
836
850
  processableRefs,
837
851
  noFeedbackPool,
838
- options,
839
852
  eventsCtx,
840
853
  feedbackSinceCutoff,
841
854
  });
@@ -1089,7 +1102,7 @@ export function partitionBySignalDelta(args) {
1089
1102
  }
1090
1103
  /** Bulk per-ref feedback summary in a SINGLE readEvents pass (candidate-gather). */
1091
1104
  function buildFeedbackSummaryMap(args) {
1092
- const { processableRefs, noFeedbackPool, options, eventsCtx, feedbackSinceCutoff } = args;
1105
+ const { processableRefs, noFeedbackPool, eventsCtx, feedbackSinceCutoff } = args;
1093
1106
  // Gap 6: only surface feedback signals from the last 30 days so that
1094
1107
  // ancient one-off feedback events don't permanently lock an asset into
1095
1108
  // every improve run. Assets with only stale signals fall through to the
@@ -1111,10 +1124,8 @@ function buildFeedbackSummaryMap(args) {
1111
1124
  {
1112
1125
  const feedbackCandidates = [...processableRefs, ...noFeedbackPool];
1113
1126
  const feedbackCandidateSet = new Set(feedbackCandidates.map((r) => r.ref));
1114
- // Chunk-5 flip F5e dual-arm the reverse map on [item_ref, durable, bare]
1115
- // so an item_ref-keyed feedback event resolves back to its candidate ref
1116
- // once the writers emit item_ref. // Chunk-8: collapse to [item_ref].
1117
- const feedbackRefByDurableKey = new Map(feedbackCandidates.flatMap((r) => improveStateReadRefs(r.ref, options.sourceName, options.legacyBareState, r.itemRef).map((key) => [key, r.ref])));
1127
+ // Map each candidate's single durable event key back to its display ref.
1128
+ const feedbackRefByDurableKey = new Map(feedbackCandidates.flatMap((r) => improveStateReadRefs(r.ref, r.itemRef).map((key) => [key, r.ref])));
1118
1129
  if (feedbackCandidateSet.size > 0) {
1119
1130
  // Fetch ALL feedback events in one query (no ref filter, no since filter =
1120
1131
  // single full table scan). Filtering per-ref in memory avoids N sequential
@@ -1180,7 +1191,6 @@ function fetchRetrievalSignals(args) {
1180
1191
  retrievalCounts = getRetrievalCounts(dbForRetrievalIndex, stateDb, allCandidateRefs, {
1181
1192
  sourceName: options.sourceName,
1182
1193
  stashDir: primaryStashDir,
1183
- includeLegacyBare: options.legacyBareState,
1184
1194
  });
1185
1195
  });
1186
1196
  lastUseMsForProactive = getLastUseMsByRef(dbForRetrieval, noFeedbackCandidates.map((r) => r.ref), primaryStashDir);
@@ -1315,9 +1325,9 @@ function selectHighSalienceLane(args) {
1315
1325
  // found later in the scan lost its slot to an earlier lower-scoring one.
1316
1326
  const qualifying = [];
1317
1327
  for (const r of candidates) {
1318
- const row = readAssetSalienceForImproveRef(dbForHighSalience, r.ref, options.sourceName, options.legacyBareState, r.itemRef);
1328
+ const row = readAssetSalienceForImproveRef(dbForHighSalience, r.ref, r.itemRef);
1319
1329
  if (row &&
1320
- isContentEncodingRow(row, legacyTypeOf(r.ref)) &&
1330
+ isContentEncodingRow(row) &&
1321
1331
  row.encoding_salience >= salienceThreshold &&
1322
1332
  !lastReflectProposalTs.has(r.ref)) {
1323
1333
  qualifying.push({ ref: r, score: row.encoding_salience });
@@ -1348,31 +1358,23 @@ function selectHighSalienceLane(args) {
1348
1358
  * attribution identity is load-bearing (see the candidate-gather comments).
1349
1359
  */
1350
1360
  function scoreSalience(args) {
1351
- const { scope, options, primaryStashDir, eventsCtx, improveProfile, eligibilitySourceByRef, feedbackSummary, retrievalCounts, signalFiltered, proactiveRefs, highSalienceRefs, } = args;
1361
+ const { scope, options, primaryStashDir, eventsCtx, eligibilitySourceByRef, feedbackSummary, retrievalCounts, signalFiltered, proactiveRefs, highSalienceRefs, } = args;
1352
1362
  const mergedRefs = args.mergedRefs;
1353
1363
  // Chunk-5 flip F5e — resolve each candidate's durable item_ref ONCE for this
1354
1364
  // pass (the write/read key source for the outcome + salience state writers).
1355
1365
  const itemRefByRef = buildItemRefByRef(mergedRefs);
1356
1366
  // WS-1 — Unified salience vector (S1 seam).
1357
1367
  //
1358
- // The legacy sort combined three independent formulas (utility EMA, negative-only
1359
- // ratio / symmetric-valence magnitude, and the proactive-maintenance priority
1360
- // formula). WS-1 converges them into one `computeSalience()` call per ref, with
1368
+ // WS-1 converges utility, valence, and proactive-maintenance signals into one
1369
+ // `computeSalience()` call per ref, with
1361
1370
  // three independently-stored sub-scores and one documented rankScore projection.
1362
1371
  //
1363
- // Migration note: if a profile still has `symmetricValence` set, emit a one-time
1364
- // warning — its behaviour (symmetric |valence| attention) is now always-on as
1365
- // part of the salience vector, so the knob is a no-op and will be removed in 0.10.
1366
- if (improveProfile.symmetricValence === true) {
1367
- warn("[improve] Profile option 'symmetricValence' is deprecated (WS-1 salience vector). " +
1368
- "Symmetric valence is now always active; remove the option from your improve profile.");
1369
- }
1370
1372
  // Fetch last-use timestamps from the index DB for the full merged set so the
1371
1373
  // recency term in retrievalSalience is genuinely decayable (plan §WS-1 step 2).
1372
1374
  // This reuses the index DB opened earlier for retrieval counts; a separate
1373
1375
  // lightweight open is used here to avoid holding the connection longer than needed.
1374
1376
  let lastUseMsByRef = new Map();
1375
- // utilityMap is kept for backward-compatible observability (health report reads it).
1377
+ // Health and outcome reporting consume the utility projection.
1376
1378
  const utilityMap = buildUtilityMap(mergedRefs);
1377
1379
  let dbForSalience;
1378
1380
  try {
@@ -1471,9 +1473,8 @@ function updateOutcomeScores(args) {
1471
1473
  const valenceResult = computeValenceScore(fb);
1472
1474
  try {
1473
1475
  const result = updateAssetOutcome(outcomeDb, {
1474
- // Chunk-5 flip F5e — key by item_ref when resolved, else the bare
1475
- // pre-flip outcome spelling. rawOutcomeScores stays keyed by the
1476
- // bare `r.ref` (its in-memory identity for the salience vector).
1476
+ // Key by item_ref when resolved, else by the conceptId. Keep
1477
+ // rawOutcomeScores keyed by r.ref, its in-memory identity.
1477
1478
  ref: outcomeWriteKey(r.ref, itemRefByRef),
1478
1479
  currentRetrievalCount: retrievalCounts.get(r.ref) ?? 0,
1479
1480
  lastRetrievedAt: lastUseMsByRef.get(r.ref) ?? 0,
@@ -1499,10 +1500,7 @@ function updateOutcomeScores(args) {
1499
1500
  if (row.outcome_score > maxOutcomeScore)
1500
1501
  maxOutcomeScore = row.outcome_score;
1501
1502
  }
1502
- // Read-clip: legacy rows written before the OUTCOME_SCORE_MAX write-clip
1503
- // existed can sit above the ceiling (live max was 3.13). Without this
1504
- // clip they inflate the normalisation denominator and floor everyone
1505
- // else's outcomeSalience (#691 follow-up).
1503
+ // Keep the normalization denominator within the writer's score bounds.
1506
1504
  maxOutcomeScore = Math.min(maxOutcomeScore, OUTCOME_SCORE_MAX);
1507
1505
  // Proxy-adequacy tripwire (two-tailed): inverted (corr < −0.3) and
1508
1506
  // dead (|corr| < 0.1 at n ≥ 500) both emit health events.
@@ -1590,9 +1588,8 @@ function computeSalienceVectors(args) {
1590
1588
  try {
1591
1589
  withStateDb((dbForStoredEncoding) => {
1592
1590
  for (const r of mergedRefs) {
1593
- const type = legacyTypeOf(r.ref);
1594
- const row = readAssetSalienceForImproveRef(dbForStoredEncoding, r.ref, options.sourceName, options.legacyBareState, itemRefByRef.get(r.ref));
1595
- if (row && isContentEncodingRow(row, type)) {
1591
+ const row = readAssetSalienceForImproveRef(dbForStoredEncoding, r.ref, itemRefByRef.get(r.ref));
1592
+ if (row && isContentEncodingRow(row)) {
1596
1593
  storedEncodingByRef.set(r.ref, row.encoding_salience);
1597
1594
  }
1598
1595
  }
@@ -1603,7 +1600,7 @@ function computeSalienceVectors(args) {
1603
1600
  // best-effort: if DB unavailable, fall back to type-weight stub (prior behaviour)
1604
1601
  }
1605
1602
  for (const r of mergedRefs) {
1606
- const type = legacyTypeOf(r.ref);
1603
+ const type = assetTypeOf(r.ref);
1607
1604
  const sizeBytes = (() => {
1608
1605
  const fp = r.filePath;
1609
1606
  if (!fp)
@@ -1641,19 +1638,19 @@ function toRankPositions(scores) {
1641
1638
  }
1642
1639
  /**
1643
1640
  * Chunk-5 flip F5e — the durable salience write-key maps for one improve pass.
1644
- * `wk(ref)` is a pool asset's write key (item_ref, else source-qualified);
1645
- * `normalizeStoredKey` folds every stored spelling ([item_ref, durable, bare])
1646
- * of an in-pool asset onto its write key (no stashSize double-count); and
1641
+ * `wk(ref)` is a pool asset's write key (item_ref, else conceptId);
1642
+ * `normalizeStoredKey` maps each in-pool asset's durable spelling to its write
1643
+ * key (no stashSize double-count); and
1647
1644
  * `refByWriteKey` reverses a write key back to its filesystem-facing bare ref.
1648
1645
  */
1649
- function buildSalienceWriteKeyMaps(itemRefByRef, sourceName) {
1646
+ function buildSalienceWriteKeyMaps(itemRefByRef) {
1650
1647
  const wk = (ref) => salienceWriteKey(ref, itemRefByRef);
1651
1648
  const normalizeStoredKey = new Map();
1652
1649
  const refByWriteKey = new Map();
1653
1650
  for (const [ref, itemRef] of itemRefByRef) {
1654
1651
  const writeKey = wk(ref);
1655
1652
  refByWriteKey.set(writeKey, ref);
1656
- for (const spelling of improveStateReadRefs(ref, sourceName, true, itemRef)) {
1653
+ for (const spelling of improveStateReadRefs(ref, itemRef)) {
1657
1654
  normalizeStoredKey.set(spelling, writeKey);
1658
1655
  }
1659
1656
  }
@@ -1663,11 +1660,9 @@ function buildSalienceWriteKeyMaps(itemRefByRef, sourceName) {
1663
1660
  function persistSalienceAndReportRanks(args) {
1664
1661
  const { salienceMap, itemRefByRef, utilityMap, feedbackSummary, options, eventsCtx, nowForSalience } = args;
1665
1662
  // Chunk-5 flip F5e — the WRITE-key space. salienceMap stays keyed by each
1666
- // candidate's own bare `r.ref`; the state.db boundary keys by the durable
1667
- // salience write key (item_ref, else source-qualified `type:name`), and every
1668
- // stored spelling of one asset folds onto that key so a seeded-legacy row and
1669
- // a fresh item_ref write can never double-count in the rank report.
1670
- const { wk, normalizeStoredKey, refByWriteKey } = buildSalienceWriteKeyMaps(itemRefByRef, options.sourceName);
1663
+ // candidate's own short `r.ref`; the state.db boundary keys by item_ref when
1664
+ // available and otherwise by conceptId.
1665
+ const { wk, normalizeStoredKey, refByWriteKey } = buildSalienceWriteKeyMaps(itemRefByRef);
1671
1666
  // Persist salience vectors to state.db (best-effort, non-blocking).
1672
1667
  // The canonical store enables WS-3 homeostatic demotion and WS-2 outcome reads.
1673
1668
  //
@@ -1720,9 +1715,8 @@ function persistSalienceAndReportRanks(args) {
1720
1715
  // Step 7: stash-wide rank-change report BEFORE overwriting the table.
1721
1716
  //
1722
1717
  // Load ALL existing rows so rank positions are stash-relative, not pool-relative.
1723
- // Chunk-5 flip F5e — source-scope by PREFIX (`<bundle|source>//…`, works
1724
- // for BOTH grammars no legacy-parser throw on an item_ref row) and
1725
- // fold each in-pool asset's stored spelling onto its single write key so
1718
+ // Source-scope by the `<bundle>//` prefix and fold each in-pool asset's
1719
+ // stored spelling onto its single write key so
1726
1720
  // the merge below never double-counts one asset across two spellings.
1727
1721
  const allStoredScores = getAllRankScores(stateDb);
1728
1722
  const existingAllScores = new Map();
@@ -1730,7 +1724,7 @@ function persistSalienceAndReportRanks(args) {
1730
1724
  if (options.sourceName) {
1731
1725
  const boundary = ref.indexOf("//");
1732
1726
  const prefix = boundary >= 0 ? ref.slice(0, boundary) : undefined;
1733
- const belongs = prefix === options.sourceName || (options.legacyBareState && prefix === undefined);
1727
+ const belongs = prefix === options.sourceName;
1734
1728
  if (!belongs)
1735
1729
  continue;
1736
1730
  }
@@ -1830,8 +1824,7 @@ function persistSalienceAndReportRanks(args) {
1830
1824
  }, eventsCtx);
1831
1825
  }
1832
1826
  for (const [ref, vector] of salienceMap) {
1833
- // Chunk-5 flip F5e persist salience under the durable WRITE key
1834
- // (item_ref when resolved, else source-qualified `type:name`).
1827
+ // Persist salience under item_ref when resolved, else the conceptId.
1835
1828
  upsertAssetSalience(stateDb, wk(ref), vector, nowForSalience);
1836
1829
  }
1837
1830
  }, { path: eventsCtx?.dbPath });
@@ -1939,7 +1932,7 @@ async function filterEligibility(args) {
1939
1932
  const ownsNoOpDb = !eventsCtx?.db;
1940
1933
  try {
1941
1934
  for (const r of mergedRefs) {
1942
- noOpMap.set(r.ref, readConsecutiveNoOpsForImproveRef(noOpDb, r.ref, options.sourceName, options.legacyBareState, r.itemRef));
1935
+ noOpMap.set(r.ref, readConsecutiveNoOpsForImproveRef(noOpDb, r.ref, r.itemRef));
1943
1936
  }
1944
1937
  }
1945
1938
  finally {
@@ -1967,9 +1960,8 @@ async function filterEligibility(args) {
1967
1960
  // suppresses repeated LLM attempts on those same assets without touching their
1968
1961
  // persisted rank_score (so they remain fully retrievable).
1969
1962
  //
1970
- // This is the ONLY ranking path negativeOnlyRatio and the legacy
1971
- // symmetricValence branch are replaced. The eligibilitySource lanes
1972
- // (signal-delta / proactive / high-salience) survive as labels (set above).
1963
+ // This is the only ranking path. The eligibilitySource lanes (signal-delta /
1964
+ // proactive / high-salience) survive as labels set above.
1973
1965
  const effectiveScore = (ref) => {
1974
1966
  const rankScore = salienceMap.get(ref)?.rankScore ?? 0;
1975
1967
  const noOps = noOpMap.get(ref) ?? 0;
@@ -2090,14 +2082,13 @@ function applyReplaySelection(args) {
2090
2082
  bareRefByItemRef.set(itemRef, bareRef);
2091
2083
  const allRankScores = options.sourceName
2092
2084
  ? (() => {
2093
- // Source-scope by PREFIX (both grammars no legacy-parser throw
2094
- // on an item_ref row), then re-key onto the bare ref: item_ref rows
2095
- // via the planned reverse map, legacy rows inline via bareImproveRef.
2085
+ // Source-scope by the bundle prefix, then re-key item_ref rows
2086
+ // onto the short conceptId used by the planned-ref pool.
2096
2087
  const m = new Map();
2097
2088
  for (const [ref, score] of storedRankScores) {
2098
2089
  const boundary = ref.indexOf("//");
2099
2090
  const prefix = boundary >= 0 ? ref.slice(0, boundary) : undefined;
2100
- const belongs = prefix === options.sourceName || (options.legacyBareState && prefix === undefined);
2091
+ const belongs = prefix === options.sourceName;
2101
2092
  if (!belongs)
2102
2093
  continue;
2103
2094
  m.set(bareRefByItemRef.get(ref) ?? bareImproveRef(ref), score);
@@ -2114,7 +2105,7 @@ function applyReplaySelection(args) {
2114
2105
  for (const [ref, rankScore] of allRankScores) {
2115
2106
  if (alreadyInPool.has(ref))
2116
2107
  continue;
2117
- const noOps = readConsecutiveNoOpsForImproveRef(replayDb, ref, options.sourceName, options.legacyBareState, itemRefByPlanned.get(ref));
2108
+ const noOps = readConsecutiveNoOpsForImproveRef(replayDb, ref, itemRefByPlanned.get(ref));
2118
2109
  if (noOps >= SALIENCE_NO_OP_DAMPEN_THRESHOLD) {
2119
2110
  convergedSkipped++;
2120
2111
  continue;
@@ -35,11 +35,8 @@ export const DEFAULT_MAX_PER_RUN = 25;
35
35
  const SIZE_FLOOR_BYTES = 200;
36
36
  /**
37
37
  * Derive the asset type from a candidate's canonical conceptId ref
38
- * (`[bundle//]<stash-subdir>/<name>`, ref-grammar decision D-R2/D-R3) via the
39
- * permanent reverse table. Returns "" when the leading segment is not a known
40
- * stash subdir. The candidate refs are the SHORT conceptId derived fresh from
41
- * the index each run (`eligibility.ts`), never a durable `type:name` row, so no
42
- * legacy colon arm is needed here.
38
+ * (`[bundle//]<stash-subdir>/<name>`) via the permanent reverse table. Returns
39
+ * "" when the leading segment is not a known stash subdir.
43
40
  */
44
41
  function refType(ref) {
45
42
  const body = ref.includes("//") ? ref.slice(ref.indexOf("//") + 2) : ref;