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
@@ -59,7 +59,17 @@
59
59
  */
60
60
  // ── Reflect-size guard ───────────────────────────────────────────────────────
61
61
  import { parseFrontmatter } from "../../../core/asset/frontmatter.js";
62
+ import { parseRefInput } from "../../../core/asset/resolve-ref.js";
62
63
  import { DESCRIPTION_MAX_CHARS, DESCRIPTION_MIN_CHARS, WHEN_TO_USE_MAX_CHARS, WHEN_TO_USE_MIN_CHARS, } from "../../../core/authoring-rules.js";
64
+ import { proposalContent } from "../../../core/file-change.js";
65
+ /**
66
+ * The canonical asset NAME an inputRef names, lower-cased — the tail the
67
+ * "just restates the ref" heuristics compare against. WI-8.5c: the ref is the
68
+ * conceptId (`<subdir>/<name>`), so the name is parsed off the conceptId.
69
+ */
70
+ function refNameTail(inputRef) {
71
+ return parseRefInput(inputRef).name.toLowerCase();
72
+ }
63
73
  import { detectTruncatedDescription, TRUNCATION_TRAILING_WORDS } from "../../../core/text-truncation.js";
64
74
  // ── Description / when_to_use shape ─────────────────────────────────────────
65
75
  export const HEADING_FRAGMENT_PATTERNS = [
@@ -122,7 +132,7 @@ export function isValidDescription(value, inputRef, options = {}) {
122
132
  severity: "warn",
123
133
  };
124
134
  if (!options.skipRefTailCheck) {
125
- const refTail = inputRef.split(":").pop()?.toLowerCase() ?? "";
135
+ const refTail = refNameTail(inputRef);
126
136
  if (refTail.length >= 6 && v.toLowerCase().includes(refTail) && v.length < refTail.length + 40)
127
137
  return { ok: false, reason: "description appears to just name the input ref" };
128
138
  }
@@ -140,7 +150,7 @@ export function isValidWhenToUse(value, inputRef) {
140
150
  return { ok: false, reason: `when_to_use is too long (${v.length} chars; max ${WHEN_TO_USE_MAX_CHARS})` };
141
151
  if (/^when working with\b/i.test(v))
142
152
  return { ok: false, reason: "when_to_use is the circular 'When working with ...' fallback" };
143
- const refTail = inputRef.split(":").pop()?.toLowerCase() ?? "";
153
+ const refTail = refNameTail(inputRef);
144
154
  if (refTail.length >= 6 && v.toLowerCase().includes(refTail) && v.length < refTail.length + 25)
145
155
  return { ok: false, reason: "when_to_use appears to just name the input ref" };
146
156
  return { ok: true };
@@ -267,7 +277,7 @@ const descriptionQualityValidator = {
267
277
  return [];
268
278
  let fm;
269
279
  try {
270
- fm = parseFrontmatter(proposal.payload.content).data;
280
+ fm = parseFrontmatter(proposalContent(proposal)).data;
271
281
  }
272
282
  catch {
273
283
  return [];
@@ -293,7 +303,7 @@ const lessonContentQualityValidator = {
293
303
  return [];
294
304
  let fm;
295
305
  try {
296
- fm = parseFrontmatter(proposal.payload.content).data;
306
+ fm = parseFrontmatter(proposalContent(proposal)).data;
297
307
  }
298
308
  catch {
299
309
  return [];
@@ -322,7 +332,7 @@ const lessonContentQualityValidator = {
322
332
  message: `Lesson proposal ${proposal.id} (${proposal.ref}) has identical description and when_to_use.`,
323
333
  });
324
334
  }
325
- const dfm = detectDoubleFrontmatter(proposal.payload.content);
335
+ const dfm = detectDoubleFrontmatter(proposalContent(proposal));
326
336
  if (dfm)
327
337
  findings.push({ kind: dfm.kind, message: `Lesson proposal ${proposal.id} (${proposal.ref}): ${dfm.message}` });
328
338
  return findings;
@@ -356,7 +366,7 @@ const reflectSizeGuardValidator = {
356
366
  },
357
367
  validate(proposal, ctx) {
358
368
  const sourceBody = stripFrontmatterBody(ctx.source?.content ?? "");
359
- const proposedBody = typeof proposal.payload?.content === "string" ? stripFrontmatterBody(proposal.payload.content) : "";
369
+ const proposedBody = typeof proposal.payload?.content === "string" ? stripFrontmatterBody(proposalContent(proposal)) : "";
360
370
  const outcome = checkReflectSize(sourceBody, proposedBody);
361
371
  if (outcome.ok)
362
372
  return [];
@@ -1,9 +1,12 @@
1
1
  // This Source Code Form is subject to the terms of the Mozilla Public
2
2
  // License, v. 2.0. If a copy of the MPL was not distributed with this
3
3
  // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
- import { parseAssetRef } from "../../../core/asset/asset-ref.js";
5
4
  import { parseFrontmatter } from "../../../core/asset/frontmatter.js";
5
+ import { parseRefInput } from "../../../core/asset/resolve-ref.js";
6
+ import { proposalContent } from "../../../core/file-change.js";
6
7
  import { lintLessonContent } from "../../../core/lesson-lint.js";
8
+ import { parseTaskDocument } from "../../../tasks/parser.js";
9
+ import { parseWorkflow } from "../../../workflows/parser.js";
7
10
  import { defaultProposalQualityValidators } from "./proposal-quality-validators.js";
8
11
  const genericProposalValidator = {
9
12
  name: "generic-proposal-validator",
@@ -14,7 +17,7 @@ const genericProposalValidator = {
14
17
  findings.push({ kind: "empty-content", message: `Proposal ${proposal.id} has empty content.` });
15
18
  }
16
19
  try {
17
- ctx.parsedRef = parseAssetRef(proposal.ref);
20
+ ctx.parsedRef = parseRefInput(proposal.ref);
18
21
  }
19
22
  catch (err) {
20
23
  findings.push({
@@ -24,9 +27,9 @@ const genericProposalValidator = {
24
27
  ctx.stop = true;
25
28
  return findings;
26
29
  }
27
- if (proposal.payload.content.startsWith("---")) {
30
+ if (proposalContent(proposal).startsWith("---")) {
28
31
  try {
29
- parseFrontmatter(proposal.payload.content);
32
+ parseFrontmatter(proposalContent(proposal));
30
33
  }
31
34
  catch (err) {
32
35
  findings.push({
@@ -38,21 +41,67 @@ const genericProposalValidator = {
38
41
  return findings;
39
42
  },
40
43
  };
41
- const lessonProposalValidator = {
42
- name: "lesson-proposal-validator",
43
- appliesTo(_proposal, ctx) {
44
- return ctx.parsedRef?.type === "lesson";
45
- },
46
- validate(proposal) {
47
- return lintLessonContent(proposal.payload.content, `proposal:${proposal.id}`).findings.map((finding) => ({
44
+ const canonicalProposalValidators = {
45
+ lesson(proposal) {
46
+ return lintLessonContent(proposalContent(proposal), `proposal:${proposal.id}`).findings.map((finding) => ({
48
47
  kind: finding.kind,
49
48
  message: finding.message,
50
49
  }));
51
50
  },
51
+ task(proposal, ctx) {
52
+ const name = ctx.parsedRef?.name;
53
+ if (!name)
54
+ return [];
55
+ parseTaskDocument({
56
+ yaml: proposalContent(proposal),
57
+ filePath: proposal.changes[0]?.path || proposal.ref,
58
+ id: name,
59
+ });
60
+ return [];
61
+ },
62
+ workflow(proposal) {
63
+ const content = proposalContent(proposal);
64
+ if (!content.trim())
65
+ return [];
66
+ const changePath = proposal.changes[0]?.path ?? "";
67
+ const result = parseWorkflow(content, { path: changePath || proposal.ref });
68
+ if (result.ok)
69
+ return [];
70
+ return result.errors.map((error) => ({
71
+ kind: "invalid-workflow-structure",
72
+ message: `Workflow proposal ${proposal.id} (${proposal.ref}) is invalid at line ${error.line}: ${error.message}`,
73
+ }));
74
+ },
75
+ };
76
+ export function hasCanonicalProposalValidator(type) {
77
+ return Object.hasOwn(canonicalProposalValidators, type);
78
+ }
79
+ const canonicalProposalValidator = {
80
+ name: "canonical-asset-proposal-validator",
81
+ appliesTo(_proposal, ctx) {
82
+ return ctx.parsedRef !== undefined && hasCanonicalProposalValidator(ctx.parsedRef.type);
83
+ },
84
+ validate(proposal, ctx) {
85
+ const type = ctx.parsedRef?.type;
86
+ const validator = type ? canonicalProposalValidators[type] : undefined;
87
+ if (!validator)
88
+ return [];
89
+ try {
90
+ return validator(proposal, ctx);
91
+ }
92
+ catch (error) {
93
+ return [
94
+ {
95
+ kind: `invalid-${type}-structure`,
96
+ message: `${type} proposal ${proposal.id} (${proposal.ref}) is invalid: ${error instanceof Error ? error.message : String(error)}`,
97
+ },
98
+ ];
99
+ }
100
+ },
52
101
  };
53
102
  export const defaultProposalValidators = [
54
103
  genericProposalValidator,
55
- lessonProposalValidator,
104
+ canonicalProposalValidator,
56
105
  ...defaultProposalQualityValidators,
57
106
  ];
58
107
  export function runProposalValidators(proposal, validators = defaultProposalValidators, initialContext = {}) {
@@ -4,19 +4,17 @@
4
4
  /**
5
5
  * Proposal validation and content repair.
6
6
  *
7
- * The proposal repository, domain service, and legacy filesystem import moved
8
- * to `../repository.ts` and `../legacy-import.ts` (#578 storage consolidation).
9
- * This module keeps only the two proposal *validators* — {@link validateProposal}
10
- * and {@link repairProposalContent}.
7
+ * The proposal repository and domain service moved to `../repository.ts` (#578
8
+ * storage consolidation). This module keeps only the two proposal *validators* — {@link validateProposal} and
9
+ * {@link repairProposalContent}.
11
10
  */
12
11
  import { repairTruncatedDescription } from "../../../core/text-truncation.js";
13
12
  import { runProposalValidators } from "./proposal-validators.js";
14
13
  /**
15
14
  * Validate a proposal payload before promotion. Generic by default — any
16
- * proposal must parse cleanly and carry a non-empty body. Lessons get the
17
- * extra per-type lint from {@link lintLessonContent} so the contract documented
18
- * in v1 spec §13 is enforced at promotion time. Other asset types can hook
19
- * here in the future without changing call sites.
15
+ * proposal must parse cleanly and carry a non-empty body. Asset types in the
16
+ * fail-closed canonical registry run their existing parser or validator; types
17
+ * without one remain on generic validation.
20
18
  */
21
19
  export function validateProposal(proposal) {
22
20
  return runProposalValidators(proposal);
@@ -14,17 +14,20 @@
14
14
  * `mergeCurateSearchResponses`) by importing them directly.
15
15
  */
16
16
  import fs from "node:fs";
17
- import { parseAssetRef } from "../../core/asset/asset-ref.js";
18
17
  import { parseFrontmatter } from "../../core/asset/frontmatter.js";
18
+ import { parseRefInput } from "../../core/asset/resolve-ref.js";
19
19
  import { getIndexPassConfig, loadConfig } from "../../core/config/config.js";
20
20
  import { rethrowIfTestIsolationError, UsageError } from "../../core/errors.js";
21
21
  import { appendEvent } from "../../core/events.js";
22
- import { computeBodyHash } from "../../indexer/db/db.js";
22
+ import { withStateDbTelemetry } from "../../core/state-db.js";
23
23
  import { enqueueGraphExtraction, hasGraphData } from "../../indexer/db/graph-db.js";
24
+ import { copySearchHitAttribution, getSearchHitAttribution, usageEventAttributionMetadata, } from "../../indexer/search/search-attribution.js";
24
25
  import { findSourceForPath, resolveSourceEntries } from "../../indexer/search/search-source.js";
25
26
  import { insertUsageEvent } from "../../indexer/usage/usage-events.js";
26
- import { truncateDescription } from "../../output/shapes.js";
27
+ import { truncateDescription } from "../../output/shapes/helpers.js";
27
28
  import { TELEMETRY_BUSY_TIMEOUT_MS, withIndexDb } from "../../storage/repositories/index-db.js";
29
+ import { findEntryIdByRef, getItemRefById } from "../../storage/repositories/index-entries-repository.js";
30
+ import { computeBodyHash } from "../../storage/repositories/index-llm-cache-repository.js";
28
31
  import { akmSearch, parseSearchSource } from "./search.js";
29
32
  import { akmShowUnified } from "./show.js";
30
33
  const CURATE_FALLBACK_FILTER_WORDS = new Set([
@@ -58,7 +61,7 @@ const CURATE_REFERENCE_QUERY_RE = /\b(?:reference|docs?|guide|how|explain|learn|
58
61
  * Fire-and-forget: log a curate event to the usage_events table and events.jsonl.
59
62
  * Never blocks the caller; errors are silently ignored.
60
63
  */
61
- function logCurateEvent(query, result, eventSource = "user") {
64
+ function logCurateEvent(query, result, eventSource = "user", attributionProjection = "full") {
62
65
  const itemRefs = result.items.map((item) => ("ref" in item ? item.ref : `registry:${item.id}`));
63
66
  appendEvent({
64
67
  eventType: "curate",
@@ -66,25 +69,39 @@ function logCurateEvent(query, result, eventSource = "user") {
66
69
  });
67
70
  try {
68
71
  withIndexDb((db) => {
69
- insertUsageEvent(db, {
70
- event_type: "curate",
71
- query,
72
- metadata: JSON.stringify({
73
- itemCount: result.items.length,
74
- itemRefs,
75
- }),
76
- source: eventSource,
72
+ // Resolve each curated item's DURABLE fully-qualified `item_ref` (D-R3)
73
+ // + entry_id from index.db (`db`); the usage_events writes land in
74
+ // state.db (Chunk-8 WI-8.3).
75
+ const perItem = result.items
76
+ .filter((item) => "ref" in item && typeof item.ref === "string")
77
+ .flatMap((item) => {
78
+ const entryId = findEntryIdByRef(db, item.ref);
79
+ if (entryId === undefined)
80
+ return [];
81
+ const itemRef = getItemRefById(db, entryId);
82
+ return itemRef ? [{ entryRef: itemRef, entryId, item }] : [];
77
83
  });
78
- for (const item of result.items) {
79
- if (!("ref" in item) || typeof item.ref !== "string")
80
- continue;
81
- insertUsageEvent(db, {
84
+ withStateDbTelemetry((stateDb) => {
85
+ insertUsageEvent(stateDb, {
82
86
  event_type: "curate",
83
87
  query,
84
- entry_ref: item.ref,
88
+ metadata: JSON.stringify({
89
+ itemCount: result.items.length,
90
+ itemRefs,
91
+ }),
85
92
  source: eventSource,
86
93
  });
87
- }
94
+ for (const { entryRef, entryId, item } of perItem) {
95
+ insertUsageEvent(stateDb, {
96
+ event_type: "curate",
97
+ query,
98
+ entry_ref: entryRef,
99
+ entry_id: entryId,
100
+ metadata: usageEventAttributionMetadata(getSearchHitAttribution(item), entryRef, attributionProjection),
101
+ source: eventSource,
102
+ });
103
+ }
104
+ }, TELEMETRY_BUSY_TIMEOUT_MS);
88
105
  }, { busyTimeoutMs: TELEMETRY_BUSY_TIMEOUT_MS });
89
106
  }
90
107
  catch (err) {
@@ -97,7 +114,7 @@ export async function akmCurate(options) {
97
114
  throw new UsageError('A curation query is required. Usage: akm curate "<task or prompt>" [--type <type>] [--limit <n>]', "MISSING_REQUIRED_ARGUMENT");
98
115
  }
99
116
  const limit = options.limit && options.limit > 0 ? options.limit : DEFAULT_CURATE_LIMIT;
100
- const source = options.source ?? parseSearchSource("stash");
117
+ const source = options.source ?? parseSearchSource("local");
101
118
  const searchResponse = options.searchResponse ??
102
119
  (await searchForCuration({
103
120
  query: options.query,
@@ -105,30 +122,36 @@ export async function akmCurate(options) {
105
122
  limit: Math.max(limit * CURATE_SEARCH_LIMIT_MULTIPLIER, MIN_CURATE_SEARCH_LIMIT),
106
123
  source,
107
124
  }));
108
- const result = await curateSearchResults(options.query, searchResponse, limit, options.type);
109
- logCurateEvent(options.query, result, options.eventSource);
125
+ const result = await curateSearchResults(options.query, searchResponse, limit, options.type, options.eventSource);
126
+ if (!options.skipLogging) {
127
+ logCurateEvent(options.query, result, options.eventSource, options.attributionProjection);
128
+ }
110
129
  return result;
111
130
  }
112
- export async function curateSearchResults(query, result, limit, selectedType) {
113
- const stashHits = result.hits.filter((hit) => hit.type !== "registry");
131
+ export async function curateSearchResults(query, result, limit, selectedType, eventSource) {
132
+ const allStashHits = result.hits.filter((hit) => hit.type !== "registry");
114
133
  const registryHits = result.registryHits ?? [];
115
- let selectedStashHits;
116
- let supportRefsByRef = new Map();
117
- if (selectedType && selectedType !== "any") {
118
- selectedStashHits = stashHits.slice(0, limit);
119
- }
120
- else {
121
- const selected = selectCuratedStashHits(query, stashHits, limit);
122
- const preferred = preferBroadRootRepresentative(query, selected.selected, stashHits, selected.supportRefsByRef);
123
- selectedStashHits = preferred.selected;
124
- supportRefsByRef = preferred.supportRefsByRef;
125
- }
126
- const selectedRegistryHits = selectedStashHits.length >= limit ? [] : registryHits.slice(0, Math.min(2, limit - selectedStashHits.length));
134
+ // F3/R-018: `--type` must NARROW the candidate pool, not bypass curation.
135
+ // Previously a set `selectedType` skipped `selectCuratedStashHits` (ranking,
136
+ // intent nudges, score floor) entirely, taking the raw top-N of whatever
137
+ // order the hits arrived in. Filtering the pool down to the requested type up front and
138
+ // then running the SAME pipeline over it gives `--type` its intended
139
+ // "narrow, don't disable" semantics — and matters even when the caller's
140
+ // search already applied a type filter at the DB layer, because
141
+ // `curateSearchResults` is also driven directly (tests, `searchResponse`
142
+ // fixtures) with a `SearchResponse` that was never type-filtered.
143
+ const stashHits = selectedType && selectedType !== "any" ? allStashHits.filter((hit) => hit.type === selectedType) : allStashHits;
144
+ const selected = selectCuratedStashHits(query, stashHits, limit);
145
+ const selectedStashHits = selected.selected;
146
+ const supportRefsByRef = selected.supportRefsByRef;
147
+ // F4/R-019: respect `--limit` for registry fill instead of hard-capping it
148
+ // at a bare literal 2 — the remaining slots after stash hits ARE the cap.
149
+ const selectedRegistryHits = selectedStashHits.length >= limit ? [] : registryHits.slice(0, limit - selectedStashHits.length);
127
150
  const selectedRefs = new Set(selectedStashHits.map((hit) => hit.ref));
128
151
  const items = [
129
152
  ...(await Promise.all(selectedStashHits
130
153
  .slice(0, limit)
131
- .map((hit) => enrichCuratedStashHit(query, hit, supportRefsByRef.get(hit.ref) ?? [], selectedRefs)))),
154
+ .map((hit) => enrichCuratedStashHit(query, hit, supportRefsByRef.get(hit.ref) ?? [], selectedRefs, eventSource)))),
132
155
  ...selectedRegistryHits.map((hit) => buildCuratedRegistryItem(query, hit)),
133
156
  ].slice(0, limit);
134
157
  return {
@@ -139,10 +162,10 @@ export async function curateSearchResults(query, result, limit, selectedType) {
139
162
  ...(result.tip ? { tip: result.tip } : {}),
140
163
  };
141
164
  }
142
- async function enrichCuratedStashHit(query, hit, supportRefs, selectedRefs) {
165
+ async function enrichCuratedStashHit(query, hit, supportRefs, selectedRefs, eventSource) {
143
166
  let shown;
144
167
  try {
145
- shown = await akmShowUnified({ ref: hit.ref });
168
+ shown = await akmShowUnified({ ref: hit.ref, eventSource, skipLogging: true });
146
169
  }
147
170
  catch {
148
171
  shown = undefined;
@@ -155,11 +178,16 @@ async function enrichCuratedStashHit(query, hit, supportRefs, selectedRefs) {
155
178
  const description = shown?.description ?? hit.description;
156
179
  const preview = buildCuratedPreview(shown, hit);
157
180
  const mergedSupportRefs = mergeCurateSupportRefs(supportRefs, shown?.related?.hits, selectedRefs, hit.ref);
158
- return {
159
- source: "stash",
181
+ const item = {
182
+ source: "local",
160
183
  type: shown?.type ?? hit.type,
161
184
  name: shown?.name ?? hit.name,
162
185
  ref: hit.ref,
186
+ path: shown?.path ?? hit.path,
187
+ editable: shown?.editable ?? hit.editable ?? false,
188
+ ...((shown?.editable ?? hit.editable ?? false) === false
189
+ ? { editHint: shown?.editHint ?? hit.editHint ?? `This asset is read-only. Inspect it with: akm show ${hit.ref}` }
190
+ : {}),
163
191
  ...(description ? { description } : {}),
164
192
  ...(preview ? { preview } : {}),
165
193
  ...(shown?.keys?.length ? { keys: shown.keys } : {}),
@@ -170,6 +198,8 @@ async function enrichCuratedStashHit(query, hit, supportRefs, selectedRefs) {
170
198
  reason: buildCuratedReason(query, shown?.type ?? hit.type),
171
199
  ...(hit.score !== undefined ? { score: hit.score } : {}),
172
200
  };
201
+ copySearchHitAttribution(hit, item, item.description);
202
+ return item;
173
203
  }
174
204
  /**
175
205
  * #624-P3 — enqueue an ungraphed asset for lazy graph extraction when the
@@ -216,7 +246,7 @@ function buildCuratedRegistryItem(query, hit) {
216
246
  name: hit.name,
217
247
  id: hit.id,
218
248
  ...(hit.description ? { description: hit.description } : {}),
219
- followUp: hit.action ?? `akm add ${hit.id}`,
249
+ followUp: hit.action ?? `akm bundle add ${hit.id}`,
220
250
  reason: `Useful external source to explore for ${query}.`,
221
251
  ...(hit.score !== undefined ? { score: hit.score } : {}),
222
252
  };
@@ -254,7 +284,9 @@ function buildCurateSummary(query, items) {
254
284
  if (items.length === 0) {
255
285
  return `No curated assets were selected for "${query}".`;
256
286
  }
257
- const labels = items.map((item) => `${item.type}:${item.name}`);
287
+ // F4b: emit the flipped conceptId ref for stash items (registry items have no
288
+ // ref — keep their `registry:<name>` label).
289
+ const labels = items.map((item) => ("ref" in item ? item.ref : `${item.type}:${item.name}`));
258
290
  return `Selected ${items.length} curated result${items.length === 1 ? "" : "s"}: ${labels.join(", ")}.`;
259
291
  }
260
292
  export function deriveCurateFallbackQueries(query) {
@@ -423,7 +455,10 @@ function computeCurateTypeNudge(type, intent) {
423
455
  }
424
456
  function getCurateFamily(ref) {
425
457
  try {
426
- const parsed = parseAssetRef(ref);
458
+ // F4b: `ref` is a search-hit ref in the 0.9.0 conceptId grammar — parse via
459
+ // the new-grammar `parseRefInput` so skill/reference family grouping still
460
+ // recognizes it.
461
+ const parsed = parseRefInput(ref);
427
462
  if (parsed.type === "skill") {
428
463
  return { key: parsed.name, role: "root" };
429
464
  }
@@ -556,36 +591,6 @@ function collapseCurateFamilies(query, hits) {
556
591
  supportRefsByRef,
557
592
  };
558
593
  }
559
- function preferBroadRootRepresentative(query, selected, allHits, supportRefsByRef) {
560
- const first = selected[0];
561
- if (!first)
562
- return { selected, supportRefsByRef };
563
- const match = /^knowledge:skills\/(.+?)\/references\/(.+)$/.exec(first.ref);
564
- if (!match)
565
- return { selected, supportRefsByRef };
566
- const lower = query.toLowerCase();
567
- const topicTokens = match[2].split(/[^a-z0-9]+/i).filter(Boolean);
568
- const wantsReference = CURATE_REFERENCE_QUERY_RE.test(lower) ||
569
- topicTokens.some((token) => token.length >= 3 && lower.includes(token.toLowerCase()));
570
- if (wantsReference)
571
- return { selected, supportRefsByRef };
572
- const rootRef = `skill:${match[1]}`;
573
- const rootHit = allHits.find((hit) => hit.ref === rootRef);
574
- if (!rootHit)
575
- return { selected, supportRefsByRef };
576
- const next = [rootHit, ...selected.filter((hit) => hit.ref !== first.ref && hit.ref !== rootRef)];
577
- const merged = new Map(supportRefsByRef);
578
- const priorSupport = merged.get(first.ref) ?? [];
579
- for (const entry of priorSupport)
580
- appendCurateSupportRef(merged, rootRef, entry);
581
- appendCurateSupportRef(merged, rootRef, {
582
- ref: first.ref,
583
- type: first.type,
584
- reason: "Related family asset to inspect next.",
585
- });
586
- merged.delete(first.ref);
587
- return { selected: next, supportRefsByRef: merged };
588
- }
589
594
  function mergeCurateSupportRefs(seeded, relatedHits, selectedRefs, ownerRef) {
590
595
  const merged = [];
591
596
  for (const entry of seeded) {