akm-cli 0.9.0-rc.0 → 0.9.0-rc.13

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 (598) hide show
  1. package/CHANGELOG.md +1283 -22
  2. package/README.md +62 -37
  3. package/SECURITY.md +46 -31
  4. package/dist/akm +162 -38
  5. package/dist/akm-migrate +44 -0
  6. package/dist/assets/backends/schtasks-template.xml +2 -1
  7. package/dist/assets/hints/cli-hints-full.md +268 -118
  8. package/dist/assets/hints/cli-hints-short.md +87 -24
  9. package/dist/assets/{profiles → improve-strategies}/catchup.json +3 -1
  10. package/dist/assets/{profiles → improve-strategies}/consolidate.json +3 -1
  11. package/dist/assets/{profiles → improve-strategies}/default.json +6 -7
  12. package/dist/assets/improve-strategies/frequent.json +15 -0
  13. package/dist/assets/{profiles → improve-strategies}/graph-refresh.json +4 -2
  14. package/dist/assets/{profiles → improve-strategies}/memory-focus.json +4 -1
  15. package/dist/assets/{profiles → improve-strategies}/proactive-maintenance.json +5 -5
  16. package/dist/assets/{profiles → improve-strategies}/quick.json +4 -2
  17. package/dist/assets/improve-strategies/reflect-distill.json +30 -0
  18. package/dist/assets/{profiles → improve-strategies}/thorough.json +1 -1
  19. package/dist/assets/prompts/consolidate-system.md +5 -5
  20. package/dist/assets/prompts/extract-session.md +2 -6
  21. package/dist/assets/prompts/memory-infer-user.md +2 -3
  22. package/dist/assets/prompts/reflect-llm-framed-contract.md +11 -0
  23. package/dist/assets/prompts/reflect-llm-schema-contract.md +3 -0
  24. package/dist/assets/prompts/reflect-output-repair.md +3 -0
  25. package/dist/assets/prompts/workflow-unit-preamble.md +26 -0
  26. package/dist/assets/stash-skeleton/README.md +38 -10
  27. package/dist/assets/stash-skeleton/facts/conventions/assets/agent.md +8 -0
  28. package/dist/assets/stash-skeleton/facts/conventions/assets/command.md +8 -0
  29. package/dist/assets/stash-skeleton/facts/conventions/assets/fact.md +14 -1
  30. package/dist/assets/stash-skeleton/facts/conventions/assets/knowledge.md +13 -1
  31. package/dist/assets/stash-skeleton/facts/conventions/assets/lesson.md +9 -1
  32. package/dist/assets/stash-skeleton/facts/conventions/assets/memory.md +11 -0
  33. package/dist/assets/stash-skeleton/facts/conventions/assets/script.md +9 -0
  34. package/dist/assets/stash-skeleton/facts/conventions/assets/skill.md +9 -0
  35. package/dist/assets/stash-skeleton/facts/conventions/assets/workflow.md +8 -0
  36. package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +100 -0
  37. package/dist/assets/stash-skeleton/facts/conventions/domains.md +64 -0
  38. package/dist/assets/stash-skeleton/facts/conventions/organization.md +136 -0
  39. package/dist/assets/tasks/core/extract.yml +3 -2
  40. package/dist/assets/tasks/core/improve.yml +2 -1
  41. package/dist/assets/tasks/core/index-refresh.yml +1 -0
  42. package/dist/assets/tasks/core/sync.yml +1 -0
  43. package/dist/assets/tasks/core/version-check.yml +2 -1
  44. package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +5 -0
  45. package/dist/assets/tasks/improve/akm-improve-catchup.yml +8 -0
  46. package/dist/assets/tasks/improve/akm-improve-consolidate.yml +5 -0
  47. package/dist/assets/tasks/improve/akm-improve-frequent.yml +5 -0
  48. package/dist/assets/tasks/improve/akm-improve-nightly.yml +5 -0
  49. package/dist/assets/templates/html/health.html +5 -4
  50. package/dist/assets/workflows/workflow-template.md +31 -15
  51. package/dist/cli/invocation.js +279 -0
  52. package/dist/cli/parse-args.js +5 -90
  53. package/dist/cli/retired-commands.js +78 -0
  54. package/dist/cli/shared.js +158 -48
  55. package/dist/cli-node.mjs +2 -1
  56. package/dist/cli.js +747 -293
  57. package/dist/commands/agent/agent-dispatch.js +19 -18
  58. package/dist/commands/agent/agent-support.js +0 -24
  59. package/dist/commands/agent/contribute-cli.js +43 -97
  60. package/dist/commands/completions.js +80 -23
  61. package/dist/commands/config-cli.js +44 -281
  62. package/dist/commands/env/env-binding.js +99 -0
  63. package/dist/commands/env/env-cli.js +84 -224
  64. package/dist/commands/env/env.js +12 -163
  65. package/dist/commands/env/marker-path.js +6 -0
  66. package/dist/commands/env/secret-cli.js +45 -61
  67. package/dist/commands/env/secret.js +32 -62
  68. package/dist/commands/feedback-cli.js +179 -85
  69. package/dist/commands/health/accept-rate.js +58 -0
  70. package/dist/commands/health/advisories.js +7 -8
  71. package/dist/commands/health/checks.js +279 -94
  72. package/dist/commands/health/html-report.js +197 -578
  73. package/dist/commands/health/improve-metrics.js +277 -246
  74. package/dist/commands/health/llm-usage.js +19 -19
  75. package/dist/commands/health/md-report.js +16 -7
  76. package/dist/commands/health/metrics.js +67 -32
  77. package/dist/commands/health/renderers.js +47 -0
  78. package/dist/commands/health/report-view-model.js +508 -0
  79. package/dist/commands/health/stash-exposure.js +1 -1
  80. package/dist/commands/health/surfaces.js +16 -56
  81. package/dist/commands/health/task-runs.js +3 -67
  82. package/dist/{migrate-storage-node.mjs → commands/health/types-checks.js} +1 -5
  83. package/dist/commands/health/types-improve.js +29 -0
  84. package/dist/{output/text/save.js → commands/health/types-metrics.js} +1 -2
  85. package/dist/commands/health/types-result.js +7 -0
  86. package/dist/commands/health/types-runs.js +4 -0
  87. package/dist/commands/health/types-session-log.js +4 -0
  88. package/dist/commands/health/types-windows.js +4 -0
  89. package/dist/commands/health/types.js +26 -21
  90. package/dist/commands/health/windows.js +2 -3
  91. package/dist/commands/health.js +296 -167
  92. package/dist/commands/improve/anti-collapse.js +5 -5
  93. package/dist/commands/improve/autonomy-gate.js +68 -0
  94. package/dist/commands/improve/collapse-detector.js +65 -52
  95. package/dist/commands/improve/consolidate/chunking.js +9 -7
  96. package/dist/commands/improve/consolidate/eligibility.js +1 -23
  97. package/dist/commands/improve/consolidate/merge.js +4 -0
  98. package/dist/commands/improve/consolidate.js +454 -1354
  99. package/dist/commands/improve/content-hash.js +39 -0
  100. package/dist/commands/improve/distill/content-repair.js +4 -10
  101. package/dist/commands/improve/distill/promote-memory.js +89 -64
  102. package/dist/commands/improve/distill/quality-gate.js +118 -42
  103. package/dist/commands/improve/distill-guards.js +1 -1
  104. package/dist/commands/improve/distill-promotion-policy.js +33 -888
  105. package/dist/commands/improve/distill.js +607 -363
  106. package/dist/commands/improve/eligibility.js +165 -79
  107. package/dist/commands/improve/extract-cli.js +35 -126
  108. package/dist/commands/improve/extract-prompt.js +6 -35
  109. package/dist/commands/improve/extract.js +640 -391
  110. package/dist/commands/improve/feedback-valence.js +2 -12
  111. package/dist/commands/improve/improve-cli.js +134 -135
  112. package/dist/commands/improve/improve-result-file.js +30 -50
  113. package/dist/commands/improve/improve-run-types.js +4 -0
  114. package/dist/commands/improve/improve-strategies.js +135 -0
  115. package/dist/commands/improve/improve.js +904 -701
  116. package/dist/commands/improve/locks.js +64 -111
  117. package/dist/commands/improve/loop-stages.js +1110 -923
  118. package/dist/commands/improve/memory/derived-ref.js +124 -0
  119. package/dist/commands/improve/memory/memory-belief.js +79 -7
  120. package/dist/commands/improve/memory/memory-contradiction-detect.js +49 -52
  121. package/dist/commands/improve/memory/memory-improve.js +25 -37
  122. package/dist/commands/improve/outcome-loop.js +25 -88
  123. package/dist/commands/improve/preparation.js +1034 -813
  124. package/dist/commands/improve/proactive-maintenance.js +34 -9
  125. package/dist/commands/improve/proposal-envelope.js +31 -0
  126. package/dist/commands/improve/reflect.js +983 -794
  127. package/dist/commands/improve/run-context.js +119 -0
  128. package/dist/commands/improve/salience.js +24 -127
  129. package/dist/commands/improve/session-asset.js +7 -3
  130. package/dist/commands/improve/shared.js +14 -34
  131. package/dist/commands/improve/source-identity.js +28 -0
  132. package/dist/commands/improve/triage.js +20 -17
  133. package/dist/commands/lint/base-linter.js +340 -313
  134. package/dist/commands/lint/env-key-rules.js +31 -47
  135. package/dist/commands/lint/index.js +185 -30
  136. package/dist/commands/{events.js → log.js} +28 -38
  137. package/dist/commands/migrate-cli.js +54 -0
  138. package/dist/commands/migration-tool.js +55 -0
  139. package/dist/commands/observability-cli.js +70 -208
  140. package/dist/commands/proposal/diff-format.js +50 -0
  141. package/dist/commands/proposal/drain-policies.js +0 -6
  142. package/dist/commands/proposal/drain.js +91 -40
  143. package/dist/commands/proposal/proposal-cli.js +134 -132
  144. package/dist/commands/proposal/proposal-types.js +56 -0
  145. package/dist/commands/proposal/proposal.js +83 -65
  146. package/dist/commands/proposal/propose-cli.js +88 -0
  147. package/dist/commands/proposal/propose.js +105 -88
  148. package/dist/commands/proposal/repository.js +1303 -278
  149. package/dist/commands/proposal/validators/proposal-quality-validators.js +16 -6
  150. package/dist/commands/proposal/validators/proposal-validators.js +61 -12
  151. package/dist/commands/proposal/validators/proposals.js +6 -8
  152. package/dist/commands/read/curate.js +78 -73
  153. package/dist/commands/read/knowledge.js +510 -13
  154. package/dist/commands/read/registry-search.js +2 -2
  155. package/dist/commands/read/remember-cli.js +84 -15
  156. package/dist/commands/read/search-cli.js +203 -96
  157. package/dist/commands/read/search.js +126 -94
  158. package/dist/commands/read/show.js +226 -250
  159. package/dist/commands/registry-cli.js +34 -60
  160. package/dist/commands/remember.js +18 -57
  161. package/dist/commands/sources/add-cli.js +104 -49
  162. package/dist/commands/sources/bundle-cli.js +166 -0
  163. package/dist/commands/sources/bundle-config-ops.js +63 -0
  164. package/dist/commands/sources/info.js +27 -15
  165. package/dist/commands/sources/init.js +30 -40
  166. package/dist/commands/sources/installed-stashes.js +469 -172
  167. package/dist/commands/sources/migration-help.js +7 -4
  168. package/dist/commands/sources/schema-repair.js +10 -9
  169. package/dist/commands/sources/self-update.js +182 -121
  170. package/dist/commands/sources/source-add.js +169 -178
  171. package/dist/commands/sources/source-clone.js +144 -41
  172. package/dist/commands/sources/source-manage.js +94 -59
  173. package/dist/commands/sources/sources-cli.js +64 -205
  174. package/dist/commands/sources/stash-cli.js +91 -54
  175. package/dist/commands/sources/stash-skeleton.js +1 -1
  176. package/dist/commands/tasks/tasks-cli.js +106 -104
  177. package/dist/commands/tasks/tasks.js +445 -262
  178. package/dist/commands/workflow-cli.js +232 -121
  179. package/dist/core/action-contributors.js +1 -1
  180. package/dist/core/activation-policy.js +49 -0
  181. package/dist/core/adapter/adapters/agent-skills-adapter.js +181 -0
  182. package/dist/core/adapter/adapters/akm-adapter.js +528 -0
  183. package/dist/core/adapter/adapters/akm-lint.js +392 -0
  184. package/dist/core/adapter/adapters/akm-metadata.js +387 -0
  185. package/dist/core/adapter/adapters/akm-task-adapter.js +149 -0
  186. package/dist/core/adapter/adapters/akm-workflow-adapter.js +180 -0
  187. package/dist/core/adapter/adapters/claude-adapter.js +61 -0
  188. package/dist/core/adapter/adapters/dotenv-adapter.js +187 -0
  189. package/dist/core/adapter/adapters/generic-files-adapter.js +119 -0
  190. package/dist/core/adapter/adapters/index.js +80 -0
  191. package/dist/core/adapter/adapters/llm-wiki-adapter.js +419 -0
  192. package/dist/core/adapter/adapters/okf-adapter.js +391 -0
  193. package/dist/core/adapter/adapters/opencode-adapter.js +68 -0
  194. package/dist/core/adapter/adapters/shared.js +286 -0
  195. package/dist/core/adapter/adapters/tool-dir-shared.js +217 -0
  196. package/dist/core/adapter/adapters/website-snapshot-adapter.js +155 -0
  197. package/dist/core/adapter/bundle-adapter.js +4 -0
  198. package/dist/core/adapter/detect-adapter.js +17 -0
  199. package/dist/core/adapter/recognize-match.js +44 -0
  200. package/dist/core/adapter/registry.js +56 -0
  201. package/dist/core/adapter/types.js +4 -0
  202. package/dist/core/asset/akm-markdown.js +30 -0
  203. package/dist/core/asset/asset-placement.js +243 -0
  204. package/dist/core/asset/asset-ref.js +110 -79
  205. package/dist/core/asset/asset-serialize.js +20 -0
  206. package/dist/core/asset/frontmatter.js +28 -12
  207. package/dist/core/asset/markdown.js +40 -51
  208. package/dist/core/asset/resolve-ref.js +274 -0
  209. package/dist/core/asset/stash-meta.js +2 -2
  210. package/dist/core/bundle-id.js +51 -0
  211. package/dist/core/common.js +281 -86
  212. package/dist/core/config/config-io.js +42 -128
  213. package/dist/core/config/config-schema.js +233 -834
  214. package/dist/core/config/config-sources.js +162 -39
  215. package/dist/core/config/config-types.js +16 -11
  216. package/dist/core/config/config-version.js +29 -0
  217. package/dist/core/config/config-walker.js +126 -37
  218. package/dist/core/config/config.js +154 -331
  219. package/dist/core/config/deep-merge.js +41 -0
  220. package/dist/core/config/engine-semantics.js +28 -0
  221. package/dist/core/config/experimental.js +21 -0
  222. package/dist/core/config/schema/embedding.js +38 -0
  223. package/dist/core/config/schema/engines.js +116 -0
  224. package/dist/core/config/schema/experimental.js +47 -0
  225. package/dist/core/config/schema/feedback.js +31 -0
  226. package/dist/core/config/schema/improve-processes.js +389 -0
  227. package/dist/core/config/schema/improve.js +94 -0
  228. package/dist/core/config/schema/index-config.js +176 -0
  229. package/dist/core/config/schema/output.js +18 -0
  230. package/dist/core/config/schema/primitives.js +94 -0
  231. package/dist/core/config/schema/search.js +30 -0
  232. package/dist/core/config/schema/setup.js +18 -0
  233. package/dist/core/config/schema/sources-bundles.js +169 -0
  234. package/dist/core/config/schema/workflow.js +29 -0
  235. package/dist/core/env-secret-ref.js +155 -20
  236. package/dist/core/errors.js +17 -15
  237. package/dist/core/events-types.js +4 -0
  238. package/dist/core/events.js +46 -128
  239. package/dist/core/extra-params.js +62 -0
  240. package/dist/core/file-change.js +17 -0
  241. package/dist/core/file-lock.js +202 -57
  242. package/dist/core/fs-txn.js +392 -0
  243. package/dist/core/git-message.js +59 -0
  244. package/dist/core/improve-result.js +167 -0
  245. package/dist/core/json-schema.js +142 -0
  246. package/dist/core/lesson-lint.js +1 -17
  247. package/dist/core/logs-db.js +1 -1
  248. package/dist/core/maintenance-barrier.js +135 -0
  249. package/dist/core/migration-operation.js +44 -0
  250. package/dist/core/mutation-target.js +78 -0
  251. package/dist/core/paths.js +22 -25
  252. package/dist/core/platform.js +10 -0
  253. package/dist/core/recognition-util.js +128 -0
  254. package/dist/core/redaction.js +392 -0
  255. package/dist/core/standards/resolve-standards-context.js +36 -65
  256. package/dist/core/standards/resolve-stash-standards.js +2 -2
  257. package/dist/core/standards/resolve-type-conventions.js +5 -5
  258. package/dist/core/state/migrations.js +242 -11
  259. package/dist/core/state-db.js +98 -10
  260. package/dist/core/structured.js +1 -1
  261. package/dist/core/subprocess.js +303 -0
  262. package/dist/core/text-truncation.js +9 -5
  263. package/dist/core/time.js +20 -0
  264. package/dist/core/type-presentation.js +130 -0
  265. package/dist/core/warn.js +0 -3
  266. package/dist/core/write-source.js +834 -118
  267. package/dist/indexer/bundle-identity-guard.js +92 -0
  268. package/dist/indexer/db/graph-db.js +1 -25
  269. package/dist/indexer/db/llm-cache.js +1 -1
  270. package/dist/indexer/ensure-index.js +30 -9
  271. package/dist/indexer/graph/graph-boost.js +9 -30
  272. package/dist/indexer/graph/graph-extraction.js +41 -27
  273. package/dist/indexer/graph/graph-types.js +4 -0
  274. package/dist/indexer/index-writer-lock.js +93 -49
  275. package/dist/indexer/index-written-assets.js +100 -53
  276. package/dist/indexer/indexer.js +746 -329
  277. package/dist/indexer/init.js +18 -25
  278. package/dist/indexer/installations.js +142 -0
  279. package/dist/indexer/passes/dir-staleness.js +18 -10
  280. package/dist/indexer/passes/memory-inference.js +25 -15
  281. package/dist/indexer/passes/metadata.js +412 -243
  282. package/dist/indexer/scan/doc-to-entry.js +160 -0
  283. package/dist/indexer/scan/drain-dir.js +134 -0
  284. package/dist/indexer/search/db-search.js +292 -108
  285. package/dist/indexer/search/fts-query.js +64 -0
  286. package/dist/indexer/search/ranking-contributors.js +145 -25
  287. package/dist/indexer/search/ranking-types.js +4 -0
  288. package/dist/indexer/search/ranking.js +28 -71
  289. package/dist/indexer/search/search-attribution.js +67 -0
  290. package/dist/indexer/search/search-fields.js +18 -3
  291. package/dist/indexer/search/search-hit-enrichers.js +30 -40
  292. package/dist/indexer/search/search-source.js +157 -111
  293. package/dist/indexer/search/semantic-status.js +4 -1
  294. package/dist/indexer/usage/usage-events.js +10 -30
  295. package/dist/indexer/walk/file-context.js +3 -45
  296. package/dist/indexer/walk/matchers.js +42 -34
  297. package/dist/indexer/walk/path-resolver.js +11 -5
  298. package/dist/indexer/walk/walker.js +42 -14
  299. package/dist/integrations/agent/builder-shared.js +7 -0
  300. package/dist/integrations/agent/builders.js +5 -56
  301. package/dist/integrations/agent/config.js +3 -143
  302. package/dist/integrations/agent/detect.js +17 -2
  303. package/dist/integrations/agent/engine-resolution.js +231 -0
  304. package/dist/integrations/agent/index.js +1 -2
  305. package/dist/integrations/agent/model-aliases.js +16 -2
  306. package/dist/integrations/agent/profiles.js +36 -62
  307. package/dist/integrations/agent/prompts.js +46 -18
  308. package/dist/integrations/agent/runner-dispatch.js +93 -4
  309. package/dist/integrations/agent/runner.js +76 -208
  310. package/dist/integrations/agent/spawn.js +88 -196
  311. package/dist/integrations/harnesses/aider/agent-builder.js +114 -0
  312. package/dist/integrations/harnesses/aider/index.js +48 -0
  313. package/dist/integrations/harnesses/aider/result-extractor.js +53 -0
  314. package/dist/integrations/harnesses/amazonq/agent-builder.js +147 -0
  315. package/dist/integrations/harnesses/amazonq/index.js +45 -0
  316. package/dist/integrations/harnesses/amazonq/result-extractor.js +48 -0
  317. package/dist/integrations/harnesses/claude/agent-builder.js +46 -8
  318. package/dist/integrations/harnesses/claude/config-import.js +1 -3
  319. package/dist/integrations/harnesses/claude/index.js +24 -35
  320. package/dist/integrations/harnesses/claude/result-extractor.js +52 -0
  321. package/dist/integrations/harnesses/claude/session-log.js +27 -75
  322. package/dist/integrations/harnesses/codex/agent-builder.js +138 -0
  323. package/dist/integrations/harnesses/codex/index.js +52 -0
  324. package/dist/integrations/harnesses/codex/result-extractor.js +73 -0
  325. package/dist/integrations/harnesses/copilot/agent-builder.js +122 -0
  326. package/dist/integrations/harnesses/copilot/index.js +48 -0
  327. package/dist/integrations/harnesses/copilot/result-extractor.js +151 -0
  328. package/dist/integrations/harnesses/gemini/agent-builder.js +120 -0
  329. package/dist/integrations/harnesses/gemini/index.js +48 -0
  330. package/dist/integrations/harnesses/gemini/result-extractor.js +121 -0
  331. package/dist/integrations/harnesses/ids.js +24 -0
  332. package/dist/integrations/harnesses/index.js +54 -34
  333. package/dist/integrations/harnesses/opencode/agent-builder.js +23 -5
  334. package/dist/integrations/harnesses/opencode/config-import.js +1 -3
  335. package/dist/integrations/harnesses/opencode/index.js +14 -32
  336. package/dist/integrations/harnesses/opencode/session-log.js +67 -125
  337. package/dist/integrations/harnesses/opencode-sdk/harness.js +51 -0
  338. package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +681 -108
  339. package/dist/integrations/harnesses/openhands/agent-builder.js +128 -0
  340. package/dist/integrations/harnesses/openhands/index.js +48 -0
  341. package/dist/integrations/harnesses/openhands/result-extractor.js +103 -0
  342. package/dist/integrations/harnesses/pi/agent-builder.js +97 -0
  343. package/dist/integrations/harnesses/pi/index.js +45 -0
  344. package/dist/integrations/harnesses/pi/result-extractor.js +135 -0
  345. package/dist/integrations/harnesses/shared.js +17 -0
  346. package/dist/integrations/harnesses/types.js +43 -32
  347. package/dist/integrations/lockfile.js +211 -24
  348. package/dist/integrations/session-logs/index.js +36 -39
  349. package/dist/integrations/session-logs/provider-base.js +113 -0
  350. package/dist/llm/client.js +182 -110
  351. package/dist/llm/embedders/deterministic.js +2 -2
  352. package/dist/llm/embedders/remote.js +21 -9
  353. package/dist/llm/feature-gate.js +17 -57
  354. package/dist/llm/graph-extract.js +12 -13
  355. package/dist/llm/index-passes.js +8 -42
  356. package/dist/llm/memory-infer.js +144 -1
  357. package/dist/llm/metadata-enhance.js +45 -30
  358. package/dist/llm/structured-call.js +16 -8
  359. package/dist/llm/usage-persist.js +30 -5
  360. package/dist/llm/usage-telemetry.js +59 -6
  361. package/dist/output/cli-hints.js +1 -2
  362. package/dist/output/command-registry.js +27 -0
  363. package/dist/output/context.js +22 -7
  364. package/dist/output/format-exempt.js +80 -0
  365. package/dist/output/generic-render.js +251 -0
  366. package/dist/output/html-render.js +11 -16
  367. package/dist/output/render-registry.js +57 -0
  368. package/dist/output/renderers.js +14 -279
  369. package/dist/output/shapes/curate.js +10 -1
  370. package/dist/output/shapes/events.js +12 -7
  371. package/dist/output/shapes/helpers.js +58 -84
  372. package/dist/output/shapes/passthrough.js +11 -39
  373. package/dist/output/shapes/proposal/producer.js +15 -7
  374. package/dist/output/shapes/registry.js +12 -6
  375. package/dist/output/shapes.js +0 -9
  376. package/dist/output/text/{init.js → bundle-create.js} +3 -1
  377. package/dist/output/text/bundle-show.js +7 -0
  378. package/dist/output/text/command-format.js +562 -0
  379. package/dist/output/text/env.js +1 -3
  380. package/dist/output/text/events.js +8 -7
  381. package/dist/output/text/helpers.js +15 -1164
  382. package/dist/output/text/proposal/producer.js +4 -2
  383. package/dist/output/text/proposal-format.js +202 -0
  384. package/dist/output/text/registry-commands.js +1 -2
  385. package/dist/output/text/registry.js +12 -6
  386. package/dist/output/text/show-directives.js +117 -0
  387. package/dist/output/text/show-format.js +103 -0
  388. package/dist/output/text/sync.js +5 -0
  389. package/dist/output/text/workflow-format.js +332 -0
  390. package/dist/output/text/workflow.js +3 -2
  391. package/dist/output/text.js +10 -19
  392. package/dist/registry/factory.js +4 -6
  393. package/dist/registry/origin-resolve.js +16 -27
  394. package/dist/registry/providers/skills-sh.js +3 -3
  395. package/dist/registry/providers/static-index.js +15 -25
  396. package/dist/registry/resolve.js +43 -94
  397. package/dist/registry/semver.js +43 -0
  398. package/dist/runtime.js +81 -12
  399. package/dist/scripts/akm-migrate.js +35529 -0
  400. package/dist/setup/detect.js +5 -7
  401. package/dist/setup/detected-engines.js +136 -0
  402. package/dist/setup/engine-config.js +100 -0
  403. package/dist/setup/registry-stash-loader.js +3 -3
  404. package/dist/setup/semantic-assets.js +12 -9
  405. package/dist/setup/setup.js +444 -208
  406. package/dist/setup/steps/connection-shared.js +120 -0
  407. package/dist/setup/steps/connection.js +108 -305
  408. package/dist/setup/steps/platforms.js +13 -12
  409. package/dist/setup/steps/semantic.js +15 -3
  410. package/dist/setup/steps/sources.js +21 -15
  411. package/dist/setup/steps/stashdir.js +6 -4
  412. package/dist/setup/steps/tasks.js +236 -119
  413. package/dist/setup/steps.js +3 -2
  414. package/dist/sources/freshness.js +39 -0
  415. package/dist/sources/provider-factory.js +11 -17
  416. package/dist/sources/providers/filesystem.js +2 -3
  417. package/dist/sources/providers/git-install.js +278 -34
  418. package/dist/sources/providers/git-provider.js +54 -56
  419. package/dist/sources/providers/git-stash.js +420 -91
  420. package/dist/sources/providers/git.js +2 -2
  421. package/dist/sources/providers/npm.js +16 -19
  422. package/dist/sources/providers/provider-utils.js +47 -22
  423. package/dist/sources/providers/sync-from-ref.js +3 -9
  424. package/dist/sources/providers/website.js +2 -2
  425. package/dist/sources/resolve.js +11 -10
  426. package/dist/sources/snapshot-fetchers/types.js +4 -0
  427. package/dist/sources/{website-ingest.js → snapshot-fetchers/website-ingest.js} +110 -41
  428. package/dist/storage/database.js +60 -4
  429. package/dist/storage/engines/sqlite-migrations.js +156 -5
  430. package/dist/storage/locations.js +1 -2
  431. package/dist/storage/repositories/canaries-repository.js +1 -1
  432. package/dist/storage/repositories/events-repository.js +51 -11
  433. package/dist/storage/repositories/improve-runs-repository.js +6 -32
  434. package/dist/storage/repositories/index-connection.js +79 -0
  435. package/dist/storage/repositories/index-db.js +4 -3
  436. package/dist/storage/repositories/index-entries-repository.js +863 -0
  437. package/dist/{indexer/db/entry-mapper.js → storage/repositories/index-entry-mapper.js} +19 -2
  438. package/dist/storage/repositories/index-entry-types.js +4 -0
  439. package/dist/storage/repositories/index-fts-repository.js +167 -0
  440. package/dist/storage/repositories/index-llm-cache-repository.js +108 -0
  441. package/dist/storage/repositories/index-meta-repository.js +49 -0
  442. package/dist/{indexer/db/schema.js → storage/repositories/index-schema.js} +226 -100
  443. package/dist/storage/repositories/index-sql.js +12 -0
  444. package/dist/storage/repositories/index-utility-repository.js +356 -0
  445. package/dist/storage/repositories/index-vec-repository.js +250 -0
  446. package/dist/storage/repositories/outcome-repository.js +119 -0
  447. package/dist/storage/repositories/proposals-repository.js +317 -75
  448. package/dist/storage/repositories/registry-cache.js +1 -1
  449. package/dist/storage/repositories/salience-repository.js +172 -0
  450. package/dist/storage/repositories/task-history-repository.js +110 -3
  451. package/dist/storage/repositories/workflow-runs-repository.js +240 -19
  452. package/dist/tasks/backends/cron.js +169 -46
  453. package/dist/tasks/backends/exec-utils.js +76 -3
  454. package/dist/tasks/backends/index.js +6 -9
  455. package/dist/tasks/backends/launchd.js +292 -55
  456. package/dist/tasks/backends/schtasks.js +557 -70
  457. package/dist/tasks/backends/types.js +4 -0
  458. package/dist/tasks/command-executable.js +93 -0
  459. package/dist/tasks/embedded.js +56 -38
  460. package/dist/tasks/parser.js +156 -64
  461. package/dist/tasks/resolve-akm-bin.js +144 -51
  462. package/dist/tasks/runner.js +377 -209
  463. package/dist/tasks/schedule.js +108 -19
  464. package/dist/tasks/scheduler-invocation.js +296 -0
  465. package/dist/tasks/schema.js +1 -1
  466. package/dist/tasks/task-id.js +35 -0
  467. package/dist/tasks/validator.js +30 -16
  468. package/dist/text-import-hook.mjs +1 -1
  469. package/dist/workflows/authoring/authoring.js +104 -43
  470. package/dist/workflows/authoring/scope-key.js +1 -1
  471. package/dist/workflows/cli.js +0 -16
  472. package/dist/workflows/concurrency-policy.js +15 -0
  473. package/dist/workflows/exec/brief.js +450 -0
  474. package/dist/workflows/exec/frozen-judge.js +47 -0
  475. package/dist/workflows/exec/native-executor.js +1038 -0
  476. package/dist/workflows/exec/param-secrets.js +115 -0
  477. package/dist/workflows/exec/report.js +1460 -0
  478. package/dist/workflows/exec/run-workflow.js +602 -0
  479. package/dist/workflows/exec/scheduler.js +71 -0
  480. package/dist/workflows/exec/step-work.js +1190 -0
  481. package/dist/workflows/exec/unit-writer.js +23 -0
  482. package/dist/workflows/exec/workflow-engine-gate.js +67 -0
  483. package/dist/workflows/exec/worktree.js +171 -0
  484. package/dist/workflows/ir/compile.js +246 -0
  485. package/dist/workflows/ir/freeze.js +233 -0
  486. package/dist/workflows/ir/params.js +54 -0
  487. package/dist/workflows/ir/plan-hash.js +68 -0
  488. package/dist/workflows/ir/schema.js +540 -0
  489. package/dist/workflows/parser.js +878 -304
  490. package/dist/workflows/program/expressions.js +181 -0
  491. package/dist/workflows/program/schema.js +51 -0
  492. package/dist/workflows/renderer.js +100 -45
  493. package/dist/workflows/resource-limits.js +22 -0
  494. package/dist/workflows/runtime/agent-identity.js +59 -14
  495. package/dist/workflows/runtime/checkin.js +1 -1
  496. package/dist/workflows/runtime/plan-classifier.js +131 -0
  497. package/dist/workflows/runtime/runs.js +376 -119
  498. package/dist/workflows/runtime/unit-checkin.js +45 -0
  499. package/dist/workflows/runtime/unit-phases.js +20 -0
  500. package/dist/workflows/runtime/workflow-asset-loader.js +241 -40
  501. package/dist/workflows/schema.js +1 -11
  502. package/dist/workflows/validate-summary.js +2 -3
  503. package/dist/workflows/validator.js +52 -30
  504. package/docs/README.md +42 -78
  505. package/docs/migration/README.md +8 -0
  506. package/docs/migration/release-notes/0.6.0.md +1 -1
  507. package/docs/migration/release-notes/0.7.0.md +9 -8
  508. package/docs/migration/release-notes/0.9.0.md +158 -14
  509. package/docs/migration/v0.7-to-v0.8.md +46 -47
  510. package/docs/migration/v0.8-to-v0.9.md +844 -0
  511. package/docs/reference/README.md +12 -0
  512. package/docs/reference/data-and-telemetry.md +333 -0
  513. package/package.json +21 -17
  514. package/schemas/akm-asset-envelope.json +93 -0
  515. package/schemas/akm-config.json +4636 -0
  516. package/schemas/akm-task.json +87 -0
  517. package/schemas/akm-workflow.json +373 -0
  518. package/dist/akm-migrate-storage +0 -38
  519. package/dist/assets/help/help-accept.md +0 -12
  520. package/dist/assets/help/help-improve.md +0 -84
  521. package/dist/assets/help/help-proposals.md +0 -17
  522. package/dist/assets/help/help-propose.md +0 -17
  523. package/dist/assets/help/help-reject.md +0 -11
  524. package/dist/assets/profiles/frequent.json +0 -13
  525. package/dist/assets/profiles/recombine-only.json +0 -21
  526. package/dist/assets/profiles/reflect-distill.json +0 -30
  527. package/dist/assets/profiles/synthesize.json +0 -15
  528. package/dist/assets/prompts/procedural-system.md +0 -44
  529. package/dist/assets/prompts/recombine-system.md +0 -40
  530. package/dist/assets/prompts/staleness-detect-system.md +0 -6
  531. package/dist/assets/tasks/core/backup.yml +0 -4
  532. package/dist/assets/tasks/graph-refresh-weekly.yml +0 -10
  533. package/dist/assets/templates/html/default.html +0 -78
  534. package/dist/assets/templates/html/vendor/echarts.min.js +0 -45
  535. package/dist/assets/wiki/index-template.md +0 -12
  536. package/dist/assets/wiki/ingest-workflow-template.md +0 -83
  537. package/dist/assets/wiki/log-template.md +0 -8
  538. package/dist/assets/wiki/schema-template.md +0 -61
  539. package/dist/cli/config-migrate.js +0 -150
  540. package/dist/cli/config-validate.js +0 -39
  541. package/dist/commands/graph/graph-cli.js +0 -124
  542. package/dist/commands/graph/graph.js +0 -487
  543. package/dist/commands/improve/calibration.js +0 -161
  544. package/dist/commands/improve/dedup.js +0 -482
  545. package/dist/commands/improve/extract-watch.js +0 -140
  546. package/dist/commands/improve/hot-probation.js +0 -45
  547. package/dist/commands/improve/improve-auto-accept.js +0 -276
  548. package/dist/commands/improve/improve-profiles.js +0 -168
  549. package/dist/commands/improve/procedural.js +0 -398
  550. package/dist/commands/improve/recombine.js +0 -818
  551. package/dist/commands/improve/schema-similarity-gate.js +0 -168
  552. package/dist/commands/lint/agent-linter.js +0 -44
  553. package/dist/commands/lint/command-linter.js +0 -44
  554. package/dist/commands/lint/default-linter.js +0 -16
  555. package/dist/commands/lint/fact-linter.js +0 -39
  556. package/dist/commands/lint/knowledge-linter.js +0 -16
  557. package/dist/commands/lint/memory-linter.js +0 -61
  558. package/dist/commands/lint/registry.js +0 -41
  559. package/dist/commands/lint/skill-linter.js +0 -45
  560. package/dist/commands/lint/task-linter.js +0 -50
  561. package/dist/commands/lint/workflow-linter.js +0 -81
  562. package/dist/commands/proposal/legacy-import.js +0 -115
  563. package/dist/commands/sources/history.js +0 -196
  564. package/dist/commands/tasks/default-tasks.js +0 -186
  565. package/dist/commands/wiki-cli.js +0 -292
  566. package/dist/core/asset/asset-registry.js +0 -76
  567. package/dist/core/asset/asset-spec.js +0 -259
  568. package/dist/core/config/config-migration.js +0 -602
  569. package/dist/core/deep-merge.js +0 -38
  570. package/dist/core/eval/rank-metrics.js +0 -113
  571. package/dist/core/ripgrep/install.js +0 -163
  572. package/dist/core/ripgrep/resolve.js +0 -81
  573. package/dist/indexer/db/db.js +0 -1413
  574. package/dist/indexer/manifest.js +0 -170
  575. package/dist/indexer/passes/metadata-contributors.js +0 -31
  576. package/dist/indexer/usage/unmigrated-vaults-guard.js +0 -94
  577. package/dist/integrations/harnesses/opencode-sdk/index.js +0 -49
  578. package/dist/llm/call-ai.js +0 -62
  579. package/dist/llm/memory-infer-impl.js +0 -138
  580. package/dist/output/shapes/distill.js +0 -14
  581. package/dist/output/shapes/history.js +0 -11
  582. package/dist/output/text/distill.js +0 -6
  583. package/dist/output/text/enable-disable.js +0 -8
  584. package/dist/output/text/history.js +0 -6
  585. package/dist/output/text/wiki.js +0 -16
  586. package/dist/registry/build-index.js +0 -386
  587. package/dist/scripts/migrate-storage.js +0 -19108
  588. package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +0 -9411
  589. package/dist/scripts/migrations/v16-to-v17.js +0 -141
  590. package/dist/setup/legacy-config.js +0 -106
  591. package/dist/storage/repositories/consolidation-repository.js +0 -38
  592. package/dist/storage/repositories/recombine-repository.js +0 -213
  593. package/dist/wiki/wiki-templates.js +0 -15
  594. package/dist/wiki/wiki.js +0 -1012
  595. package/dist/workflows/db.js +0 -215
  596. package/docs/data-and-telemetry.md +0 -226
  597. /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/registry.js +0 -0
  598. /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/youtube.js +0 -0
@@ -3,17 +3,25 @@
3
3
  // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
4
  import fs from "node:fs";
5
5
  import { defineJsonCommand, output, parseAllFlagValues } from "../cli/shared.js";
6
- import { parseAssetRef } from "../core/asset/asset-ref.js";
6
+ import { makeBundleRef, parseBundleRef } from "../core/asset/asset-ref.js";
7
7
  import { assembleAsset } from "../core/asset/asset-serialize.js";
8
8
  import { parseFrontmatter, parseFrontmatterBlock } from "../core/asset/frontmatter.js";
9
- import { writeFileAtomic } from "../core/common.js";
9
+ import { conceptIdFromTypeName, parseRefInput } from "../core/asset/resolve-ref.js";
10
+ import { isWithin, writeFileAtomic } from "../core/common.js";
10
11
  import { FEEDBACK_FAILURE_MODES, loadConfig } from "../core/config/config.js";
11
12
  import { UsageError } from "../core/errors.js";
12
13
  import { appendEvent } from "../core/events.js";
14
+ import { resolveMutationTarget } from "../core/mutation-target.js";
13
15
  import { getDbPath } from "../core/paths.js";
16
+ import { withStateDb } from "../core/state-db.js";
14
17
  import { warn } from "../core/warn.js";
15
- import { applyFeedbackToUtilityScore, closeDatabase, findEntryIdByRef, getEntryFilePathById, openExistingDatabase, } from "../indexer/db/db.js";
16
- import { countFeedbackSignals, insertUsageEvent } from "../indexer/usage/usage-events.js";
18
+ import { withWriteTargetMutation } from "../core/write-source.js";
19
+ import { resolveSourceEntries } from "../indexer/search/search-source.js";
20
+ import { countFeedbackSignals, insertUsageEvent, resolveUsageEventSource } from "../indexer/usage/usage-events.js";
21
+ import { resolveSourcesForOrigin } from "../registry/origin-resolve.js";
22
+ import { closeDatabase, openExistingDatabase } from "../storage/repositories/index-connection.js";
23
+ import { findEntryIdByRef, getEntryFilePathById, getItemRefById, } from "../storage/repositories/index-entries-repository.js";
24
+ import { applyFeedbackToUtilityScore } from "../storage/repositories/index-utility-repository.js";
17
25
  // ── Tag validation ────────────────────────────────────────────────────────────
18
26
  const TAG_KEY_RE = /^[a-z_][a-z0-9_]*$/;
19
27
  const MAX_FEEDBACK_TAGS = 10;
@@ -52,31 +60,68 @@ function validateFeedbackTags(raw) {
52
60
  * an existing asset — the same pattern memory-inference uses for
53
61
  * `inferenceProcessed`.
54
62
  */
55
- function appendLessonStrength(type, name, feedbackRef) {
56
- const ref = `${type}:${name}`;
63
+ function appendLessonStrength(refInput, feedbackRef) {
64
+ // Canonical conceptId (`lessons/<name>`, D-R3): `findEntryIdByRef` keys on
65
+ // the stored `item_ref`.
66
+ const conceptId = conceptIdFromTypeName(refInput.type, refInput.name);
67
+ const config = loadConfig();
57
68
  let filePath;
69
+ let bundleId;
58
70
  const db = openExistingDatabase();
59
71
  try {
60
- const entryId = findEntryIdByRef(db, ref);
61
- if (entryId === undefined) {
62
- warn(`[feedback] --applied-to: lesson ${ref} is not in the index.`);
63
- return null;
72
+ const entryId = findEntryIdByRef(db, makeBundleRef(refInput.origin, conceptId));
73
+ if (entryId !== undefined) {
74
+ const itemRef = getItemRefById(db, entryId);
75
+ const parsedItemRef = itemRef ? parseBundleRef(itemRef) : undefined;
76
+ filePath = getEntryFilePathById(db, entryId) ?? undefined;
77
+ bundleId = parsedItemRef?.bundle;
64
78
  }
65
- const resolvedPath = getEntryFilePathById(db, entryId);
66
- if (!resolvedPath) {
67
- warn(`[feedback] --applied-to: cannot resolve file path for ${ref}.`);
68
- return null;
69
- }
70
- filePath = resolvedPath;
71
79
  }
72
80
  finally {
73
81
  closeDatabase(db);
74
82
  }
75
- if (!filePath || !fs.existsSync(filePath)) {
76
- warn(`[feedback] --applied-to: lesson file missing on disk for ${ref}.`);
83
+ const requestedRef = makeBundleRef(refInput.origin, conceptId);
84
+ if (!filePath || !bundleId || !fs.existsSync(filePath)) {
85
+ warn(`[feedback] --applied-to: lesson ${requestedRef} is not in the index or is missing on disk.`);
86
+ return null;
87
+ }
88
+ const resolved = resolveMutationTarget(config, { ...refInput, origin: bundleId });
89
+ if (!isWithin(filePath, resolved.target.source.path)) {
90
+ throw new UsageError(`Resolved lesson ${requestedRef} is outside bundle "${bundleId}".`);
91
+ }
92
+ fs.lstatSync(filePath);
93
+ const initialUpdate = buildLessonStrengthUpdate(fs.readFileSync(filePath), feedbackRef);
94
+ if (!initialUpdate.nextBytes) {
95
+ return { ref: makeBundleRef(bundleId, conceptId), strength: initialUpdate.strength };
96
+ }
97
+ let strength = initialUpdate.strength;
98
+ let mutationStarted = false;
99
+ try {
100
+ withWriteTargetMutation(resolved.target, [filePath], {
101
+ ignored: "reject",
102
+ purpose: "feedback-lesson-credit",
103
+ message: `Update ${makeBundleRef(bundleId, conceptId)}`,
104
+ }, () => {
105
+ const stat = fs.lstatSync(filePath);
106
+ const update = buildLessonStrengthUpdate(fs.readFileSync(filePath), feedbackRef);
107
+ strength = update.strength;
108
+ if (!update.nextBytes)
109
+ return;
110
+ mutationStarted = true;
111
+ // Preserve the existing file's permission bits (markdown assets are typically 0o644).
112
+ writeFileAtomic(filePath, update.nextBytes, stat.mode & 0o777);
113
+ });
114
+ }
115
+ catch (err) {
116
+ if (mutationStarted)
117
+ throw err;
118
+ warn(`[feedback] --applied-to: failed to write ${filePath}: ${err instanceof Error ? err.message : String(err)}`);
77
119
  return null;
78
120
  }
79
- const raw = fs.readFileSync(filePath, "utf8");
121
+ return { ref: makeBundleRef(bundleId, conceptId), strength };
122
+ }
123
+ function buildLessonStrengthUpdate(rawBytes, feedbackRef) {
124
+ const raw = rawBytes.toString("utf8");
80
125
  const parsed = parseFrontmatter(raw);
81
126
  const data = { ...parsed.data };
82
127
  const existing = data.lessonStrength;
@@ -86,7 +131,6 @@ function appendLessonStrength(type, name, feedbackRef) {
86
131
  ? [existing.trim()]
87
132
  : [];
88
133
  if (strengthList.includes(feedbackRef)) {
89
- // Already credited — idempotent no-op.
90
134
  return { strength: strengthList.length };
91
135
  }
92
136
  strengthList.push(feedbackRef);
@@ -94,40 +138,76 @@ function appendLessonStrength(type, name, feedbackRef) {
94
138
  const block = parseFrontmatterBlock(raw);
95
139
  const body = block?.content ?? raw;
96
140
  const next = assembleAsset(data, body);
97
- try {
98
- // Preserve the existing file's permission bits (markdown assets are
99
- // typically 0o644); writeFileAtomic defaults to 0o600 otherwise.
100
- const mode = fs.statSync(filePath).mode & 0o777;
101
- writeFileAtomic(filePath, next, mode);
102
- }
103
- catch (err) {
104
- warn(`[feedback] --applied-to: failed to write ${filePath}: ${err instanceof Error ? err.message : String(err)}`);
105
- return null;
106
- }
107
- return { strength: strengthList.length };
141
+ const nextBytes = Buffer.from(next);
142
+ return rawBytes.equals(nextBytes) ? { strength: strengthList.length } : { strength: strengthList.length, nextBytes };
143
+ }
144
+ /**
145
+ * Persist the feedback usage-event (state.db) and immediately fold it into the
146
+ * entry's MemRL utility score (index.db). Chunk-8 WI-8.3: usage_events lives in
147
+ * state.db; entries + utility_scores stay in `indexDb`. BOTH positive and
148
+ * negative signals apply the EMA utility update unconditionally and
149
+ * immediately when the source is user-attributed — no `akm index` run is
150
+ * required for either signal to affect search ranking. Uses the bounded-step
151
+ * EMA policy (F-5 / #386, arXiv:2601.03192).
152
+ *
153
+ * The update is intentionally SKIPPED for non-`user` event sources (`improve`,
154
+ * `task`, `audit`, `unknown`) — an anti-self-reinforcement guard that stops an
155
+ * agent or automated pipeline from boosting its own picks. This is by design
156
+ * and must not be removed; R-034 only asks that the skip be surfaced to the
157
+ * caller rather than passing silently. Best-effort: a utility-update failure
158
+ * never fails the feedback record.
159
+ */
160
+ function recordFeedbackUsage(indexDb, entryId, durableEntryRef, signal, metadataStr) {
161
+ let utilityResult;
162
+ let rankingUpdateApplied = false;
163
+ let rankingUpdateSkippedReason;
164
+ const eventSource = resolveUsageEventSource();
165
+ withStateDb((stateDb) => {
166
+ insertUsageEvent(stateDb, {
167
+ event_type: "feedback",
168
+ entry_ref: durableEntryRef,
169
+ entry_id: entryId,
170
+ signal,
171
+ metadata: metadataStr,
172
+ source: eventSource,
173
+ });
174
+ if (eventSource !== "user") {
175
+ rankingUpdateSkippedReason =
176
+ `feedback source is "${eventSource}", not "user" — ranking updates only apply to user-attributed ` +
177
+ "feedback (anti-self-reinforcement guard; set AKM_EVENT_SOURCE=user to record as user demand).";
178
+ return;
179
+ }
180
+ try {
181
+ const { pos, neg } = countFeedbackSignals(stateDb, entryId);
182
+ utilityResult = applyFeedbackToUtilityScore(indexDb, entryId, pos, neg);
183
+ rankingUpdateApplied = true;
184
+ }
185
+ catch (err) {
186
+ // best-effort — feedback recording succeeds even if utility update fails
187
+ rankingUpdateSkippedReason = `utility update failed: ${err instanceof Error ? err.message : String(err)}`;
188
+ }
189
+ });
190
+ return { utilityResult, rankingUpdateApplied, rankingUpdateSkippedReason };
108
191
  }
109
192
  // ── Command definition ────────────────────────────────────────────────────────
110
193
  export const feedbackCommand = defineJsonCommand({
111
194
  meta: {
112
195
  name: "feedback",
113
- description: "Record positive or negative feedback for any indexed stash asset.\n\n" +
114
- "Positive feedback boosts an asset's EMA utility score, making it rank higher\n" +
115
- "in future searches without requiring a full reindex.\n\n" +
116
- "Negative feedback records a negative signal in usage_events and state.db events.\n" +
117
- "It does NOT immediately lower the asset's ranking — the EMA utility score is\n" +
118
- "updated the next time `akm index` runs (incremental or full). Run `akm index`\n" +
119
- "after recording negative feedback to have it reflected in search results.",
196
+ description: "Record positive or negative feedback for any indexed bundle asset.\n\n" +
197
+ "Both signals adjust the asset's usefulness score right away, in the same\n" +
198
+ "process: positive feedback raises it, negative lowers it, and recent\n" +
199
+ "feedback counts for more than old feedback. No reindex is needed — the new\n" +
200
+ "score affects ranking starting with the very next `akm search`.",
120
201
  },
121
202
  args: {
122
203
  // Optional in citty so run() is invoked even when omitted; we re-validate
123
204
  // and throw a structured UsageError below so exit code is 2 (USAGE) rather
124
205
  // than citty's default 0 (help banner).
125
- ref: { type: "positional", description: "Asset ref (type:name)", required: false },
206
+ ref: { type: "positional", description: "Asset ref ([bundle//]conceptId, e.g. lessons/deploy)", required: false },
126
207
  positive: { type: "boolean", description: "Record positive feedback (boosts ranking immediately)", default: false },
127
208
  negative: {
128
209
  type: "boolean",
129
- description: "Record negative feedback (suppresses ranking after next `akm index`). " +
130
- "Reindexing is required for the signal to affect search results.",
210
+ description: "Record negative feedback (lowers ranking immediately, no reindex needed).",
131
211
  default: false,
132
212
  },
133
213
  reason: {
@@ -136,7 +216,7 @@ export const feedbackCommand = defineJsonCommand({
136
216
  },
137
217
  "failure-mode": {
138
218
  type: "string",
139
- description: `Structured failure-mode taxonomy for negative feedback (F-3 / #384). ` +
219
+ description: "Structured failure-mode taxonomy for negative feedback. " +
140
220
  `Accepted values: ${FEEDBACK_FAILURE_MODES.join(", ")}. ` +
141
221
  "Stored alongside --reason in event metadata for aggregation by the distill pipeline.",
142
222
  },
@@ -146,17 +226,18 @@ export const feedbackCommand = defineJsonCommand({
146
226
  },
147
227
  "applied-to": {
148
228
  type: "string",
149
- description: "Credit a lesson that helped resolve this task. Accepts a `lesson:<name>` ref. " +
229
+ description: "Credit a lesson that helped resolve this task. Accepts a `lessons/<name>` ref. " +
150
230
  "When combined with --positive, appends this feedback ref to the target lesson's " +
151
- "`lessonStrength[]` frontmatter array (dedup, idempotent). Ignored on non-lesson targets.",
231
+ "`lessonStrength[]` frontmatter array (dedup, idempotent). A non-lesson target or a " +
232
+ "missing --positive produces a warning rather than silently doing nothing.",
152
233
  },
153
234
  },
154
235
  async run({ args }) {
155
236
  const ref = (args.ref ?? "").trim();
156
237
  if (!ref) {
157
- throw new UsageError("Asset ref is required. Usage: akm feedback <ref> --positive|--negative", "MISSING_REQUIRED_ARGUMENT", "Pass a ref like `skill:deploy` and either --positive or --negative.");
238
+ throw new UsageError("Asset ref is required. Usage: akm feedback <ref> --positive|--negative", "MISSING_REQUIRED_ARGUMENT", "Pass a ref like `skills/deploy` and either --positive or --negative.");
158
239
  }
159
- parseAssetRef(ref);
240
+ const parsedRef = parseBundleRef(ref);
160
241
  if (args.positive && args.negative) {
161
242
  throw new UsageError("Specify either --positive or --negative, not both.");
162
243
  }
@@ -216,44 +297,46 @@ export const feedbackCommand = defineJsonCommand({
216
297
  // background reindex it spawned — now that ensureIndex is removed, holding
217
298
  // the lock only causes feedback to block for the full improve run duration.
218
299
  let utilityResult;
300
+ let rankingUpdateApplied = false;
301
+ let rankingUpdateSkippedReason;
302
+ let durableRef = ref;
219
303
  const db = openExistingDatabase();
220
304
  try {
221
- const entryId = findEntryIdByRef(db, ref);
305
+ const config = loadConfig();
306
+ const sources = resolveSourceEntries(undefined, config);
307
+ const requestedSource = parsedRef.bundle ? resolveSourcesForOrigin(parsedRef.bundle, sources)[0] : undefined;
308
+ if (parsedRef.bundle && !requestedSource) {
309
+ throw new UsageError(`Source "${parsedRef.bundle}" is not configured.`, "INVALID_FLAG_VALUE");
310
+ }
311
+ const lookupRef = makeBundleRef(parsedRef.bundle, parsedRef.conceptId);
312
+ const entryId = findEntryIdByRef(db, lookupRef, requestedSource?.path);
222
313
  if (entryId === undefined) {
223
314
  throw new UsageError(`Ref "${ref}" is not in the index. ` +
224
315
  "Run 'akm search' to verify the asset exists, then 'akm index' if it was recently added.");
225
316
  }
226
- // Persist the feedback signal into usage_events. For positive signals,
227
- // the EMA utility score is updated immediately on the next read path.
228
- // For negative signals, the score is adjusted the next time `akm index`
229
- // runs — the signal is durable in the DB but does NOT suppress ranking
230
- // in search results until after reindexing.
231
- insertUsageEvent(db, {
232
- event_type: "feedback",
233
- entry_ref: ref,
234
- entry_id: entryId,
235
- signal,
236
- metadata: metadataStr,
237
- });
238
- // Apply feedback-derived utility score adjustment immediately so that
239
- // positive/negative signals influence search ranking without requiring
240
- // a full reindex. We query the total accumulated feedback counts from
241
- // usage_events so the delta reflects the entire signal history.
242
- // Uses MemRL bounded-step EMA (F-5 / #386, arXiv:2601.03192).
243
- try {
244
- const { pos, neg } = countFeedbackSignals(db, entryId);
245
- utilityResult = applyFeedbackToUtilityScore(db, entryId, pos, neg);
246
- }
247
- catch {
248
- // best-effort — feedback recording succeeds even if utility update fails
249
- }
317
+ // Persist the feedback signal into usage_events. Both positive and
318
+ // negative signals apply the EMA utility update immediately — no
319
+ // `akm index` run is required for either signal to affect ranking in
320
+ // search results (see recordFeedbackUsage / applyFeedbackToUtilityScore).
321
+ // WI-8.5b: the `feedback` / `improve_review_needed` events key on the
322
+ // resolved entry's fully-qualified item_ref — the SAME durable key the
323
+ // usage_events row carries and the SAME spelling the signal-delta
324
+ // correlation reads (buildLatestFeedbackTsMap, collapsed to [item_ref]).
325
+ const itemRef = getItemRefById(db, entryId);
326
+ if (!itemRef)
327
+ throw new UsageError(`Indexed ref "${ref}" has no durable item ref.`, "INVALID_PROPOSAL");
328
+ durableRef = itemRef;
329
+ const recordResult = recordFeedbackUsage(db, entryId, itemRef, signal, metadataStr);
330
+ utilityResult = recordResult.utilityResult;
331
+ rankingUpdateApplied = recordResult.rankingUpdateApplied;
332
+ rankingUpdateSkippedReason = recordResult.rankingUpdateSkippedReason;
250
333
  }
251
334
  finally {
252
335
  closeDatabase(db);
253
336
  }
254
337
  appendEvent({
255
338
  eventType: "feedback",
256
- ref,
339
+ ref: durableRef,
257
340
  metadata: metadataObj,
258
341
  });
259
342
  // F-5 / #386: When a high-utility asset crosses below the review threshold,
@@ -262,13 +345,13 @@ export const feedbackCommand = defineJsonCommand({
262
345
  // the improve loop. Best-effort — failure is logged but does not fail the
263
346
  // feedback command.
264
347
  // Emit a structured event rather than a proposal so the review-needed
265
- // signal is queryable via `akm events list --type improve_review_needed`
266
- // without risking accidental asset overwrite if the proposal is accepted.
348
+ // signal doesn't risk an accidental asset overwrite if the proposal is
349
+ // accepted.
267
350
  if (utilityResult?.crossedReviewThreshold) {
268
351
  try {
269
352
  appendEvent({
270
353
  eventType: "improve_review_needed",
271
- ref,
354
+ ref: durableRef,
272
355
  metadata: {
273
356
  previousUtility: utilityResult.previousUtility,
274
357
  nextUtility: utilityResult.nextUtility,
@@ -282,25 +365,33 @@ export const feedbackCommand = defineJsonCommand({
282
365
  }
283
366
  }
284
367
  // Phase 7A / Advantage D4b: --applied-to credits a lesson. When the
285
- // target is a `lesson:<name>` ref and the signal is positive, append
368
+ // target is a `lessons/<name>` ref and the signal is positive, append
286
369
  // the feedback ref to the target lesson's `lessonStrength[]`
287
- // frontmatter array (dedup, idempotent). Non-lesson targets are
288
- // ignored. Failures here are warnings — feedback recording is the
289
- // primary contract and must not regress on lesson-write errors.
370
+ // frontmatter array (dedup, idempotent). Non-lesson targets are REJECTED
371
+ // with a loud warning (R-033b) rather than silently doing nothing.
372
+ // Failures here are warnings — feedback recording is the primary
373
+ // contract and must not regress on lesson-write errors.
290
374
  const appliedToRaw = args["applied-to"]?.trim();
291
375
  let appliedToResult = null;
292
376
  if (appliedToRaw && signal === "positive") {
377
+ let parsedApplied;
293
378
  try {
294
- const parsedApplied = parseAssetRef(appliedToRaw);
379
+ parsedApplied = parseRefInput(appliedToRaw);
380
+ }
381
+ catch (err) {
382
+ warn(`[feedback] --applied-to failed for ${appliedToRaw}: ${err instanceof Error ? err.message : String(err)}`);
383
+ }
384
+ if (parsedApplied) {
295
385
  if (parsedApplied.type === "lesson") {
296
- const updated = appendLessonStrength(parsedApplied.type, parsedApplied.name, ref);
386
+ const updated = appendLessonStrength(parsedApplied, durableRef);
297
387
  if (updated) {
298
- appliedToResult = { lessonRef: appliedToRaw, strength: updated.strength };
388
+ appliedToResult = { lessonRef: updated.ref, strength: updated.strength };
299
389
  }
300
390
  }
301
- }
302
- catch (err) {
303
- warn(`[feedback] --applied-to failed for ${appliedToRaw}: ${err instanceof Error ? err.message : String(err)}`);
391
+ else {
392
+ warn(`[feedback] --applied-to ${appliedToRaw} was ignored: it resolves to a "${parsedApplied.type}" asset, ` +
393
+ "not a lesson. Only `lessons/<name>` refs can be credited via --applied-to.");
394
+ }
304
395
  }
305
396
  }
306
397
  else if (appliedToRaw && signal !== "positive") {
@@ -313,6 +404,9 @@ export const feedbackCommand = defineJsonCommand({
313
404
  reason: reason?.trim() ?? null,
314
405
  failureMode: failureMode ?? null,
315
406
  tags: validatedTags,
407
+ rankingUpdate: rankingUpdateApplied
408
+ ? { applied: true }
409
+ : { applied: false, reason: rankingUpdateSkippedReason ?? "unknown" },
316
410
  ...(appliedToResult
317
411
  ? { appliedTo: { ref: appliedToResult.lessonRef, lessonStrength: appliedToResult.strength } }
318
412
  : {}),
@@ -0,0 +1,58 @@
1
+ // This Source Code Form is subject to the terms of the Mozilla Public
2
+ // License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
+ /**
5
+ * Per-proposal-source accept-rate metrics, folded into `akm health --report`
6
+ * (0.9.0 CLI overhaul, S3).
7
+ *
8
+ * Provides the core self-measurement metric for recursive self-improvement:
9
+ * if reflect proposals are accepted at 20% and distill proposals at 60%,
10
+ * that guides resource allocation to higher-ROI generators.
11
+ *
12
+ * Previously exposed as the removed `akm history --accept-rate-by-source`
13
+ * flag (src/commands/sources/history.ts, F-4 / #385); `health` already reads
14
+ * the pending proposal queue for its own `--report` dataset, so this is the
15
+ * same read extended to the accepted/rejected archive.
16
+ */
17
+ import { resolveStashDir } from "../../core/common.js";
18
+ import { listProposals } from "../proposal/repository.js";
19
+ /**
20
+ * Compute accept-rate-per-source metrics from the proposal store. Defaults to
21
+ * the configured default stash when `stashDir` is omitted (same resolution
22
+ * `akm health` already uses for the rest of its report).
23
+ */
24
+ export function computeAcceptRateBySource(stashDir) {
25
+ const stash = stashDir ?? resolveStashDir();
26
+ const bySource = new Map();
27
+ const countProposals = (statuses, includeArchive) => {
28
+ for (const status of statuses) {
29
+ const proposals = listProposals(stash, { status, includeArchive });
30
+ for (const p of proposals) {
31
+ const src = p.source || "(unknown)";
32
+ const entry = bySource.get(src) ?? { accepted: 0, rejected: 0, pending: 0 };
33
+ if (status === "accepted")
34
+ entry.accepted++;
35
+ else if (status === "rejected")
36
+ entry.rejected++;
37
+ else
38
+ entry.pending++;
39
+ bySource.set(src, entry);
40
+ }
41
+ }
42
+ };
43
+ countProposals(["pending"], false);
44
+ countProposals(["accepted", "rejected"], true);
45
+ return Array.from(bySource.entries())
46
+ .map(([source, counts]) => {
47
+ const decided = counts.accepted + counts.rejected;
48
+ return {
49
+ source,
50
+ total: decided + counts.pending,
51
+ accepted: counts.accepted,
52
+ rejected: counts.rejected,
53
+ pending: counts.pending,
54
+ acceptRate: decided > 0 ? counts.accepted / decided : null,
55
+ };
56
+ })
57
+ .sort((a, b) => b.total - a.total); // Most active source first
58
+ }
@@ -77,7 +77,7 @@ export function collectImproveAdvisories(db, stateDbPath, since, improveSummary)
77
77
  confidence: "high",
78
78
  message: `Enrichment lanes minted ${minting.minted} NEW asset(s) vs ${minting.updated} update(s) ` +
79
79
  `(${Math.round(minting.share * 100)}% minted, threshold ${Math.round(ENRICHMENT_MINTED_WARN_SHARE * 100)}%). ` +
80
- "Enrichment-classed lanes (proactive/high-salience/high-retrieval/signal-delta) are ratified to edit " +
80
+ "Enrichment-classed lanes (proactive/high-salience/signal-delta) are ratified to edit " +
81
81
  "existing assets only — new-asset generation belongs to the signal-gated minting lanes.",
82
82
  });
83
83
  }
@@ -98,7 +98,7 @@ export function collectImproveAdvisories(db, stateDbPath, since, improveSummary)
98
98
  // R5 collapse/churn detector: surface any collapse_detector_alert events
99
99
  // in the health window, plus the latest cycle row's headline numbers so
100
100
  // the operator can act without opening the DB. `unknown` when the detector
101
- // has never produced a cycle row (no consolidate/recombine work yet).
101
+ // has never produced a cycle row (no consolidate work yet).
102
102
  try {
103
103
  // Reuse the already-open state.db handle (readEvents supports a
104
104
  // borrowed connection) — no extra open/migrate/close per health call.
@@ -106,8 +106,7 @@ export function collectImproveAdvisories(db, stateDbPath, since, improveSummary)
106
106
  const latestCycle = getLatestCycleMetrics(db);
107
107
  const cycleSummary = latestCycle
108
108
  ? `Latest cycle (${latestCycle.ts}, ${latestCycle.pass}): mean canary recall ${latestCycle.mean_recall.toFixed(3)}, ` +
109
- `distinct-content ratio ${latestCycle.distinct_content_ratio.toFixed(3)}, ` +
110
- `${latestCycle.accepted_actions} accepted action(s).`
109
+ `distinct-content ratio ${latestCycle.distinct_content_ratio.toFixed(3)}.`
111
110
  : "";
112
111
  if (collapseAlertEvents.length > 0) {
113
112
  const kinds = [...new Set(collapseAlertEvents.map((e) => String(e.metadata?.kind ?? "unknown")))];
@@ -116,11 +115,11 @@ export function collectImproveAdvisories(db, stateDbPath, since, improveSummary)
116
115
  name: "collapse-churn-detector",
117
116
  status: "warn",
118
117
  kind: "deterministic",
119
- // Collapse kinds are measured, not inferred; churn/merge-floor
120
- // volume thresholds are still being tuned (design doc §7).
118
+ // Collapse kinds are measured, not inferred; the merge-floor
119
+ // volume threshold is still being tuned (design doc §7).
121
120
  confidence: collapseKinds.length > 0 ? "high" : "medium",
122
121
  message: `R5 detector fired ${collapseAlertEvents.length} alert(s) in window (kinds: ${kinds.join(", ")}). ` +
123
- `${cycleSummary} See docs/design/improve-collapse-churn-detector-design.md §6.3 runbook queries.`,
122
+ `${cycleSummary} See docs/architecture/specs/improve-collapse-churn-detector-design.md §6.3 runbook queries.`,
124
123
  });
125
124
  }
126
125
  else if (latestCycle) {
@@ -139,7 +138,7 @@ export function collectImproveAdvisories(db, stateDbPath, since, improveSummary)
139
138
  kind: "deterministic",
140
139
  confidence: "high",
141
140
  message: "No detector cycle rows yet — the collapse/churn detector runs only on improve cycles " +
142
- "where consolidate/recombine did work (synthesis lanes may be idle).",
141
+ "where consolidate did work.",
143
142
  });
144
143
  }
145
144
  }