akm-cli 0.9.0-rc.1 → 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 (587) hide show
  1. package/CHANGELOG.md +1190 -52
  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/stash-skeleton/README.md +38 -10
  26. package/dist/assets/stash-skeleton/facts/conventions/assets/agent.md +8 -0
  27. package/dist/assets/stash-skeleton/facts/conventions/assets/command.md +8 -0
  28. package/dist/assets/stash-skeleton/facts/conventions/assets/fact.md +14 -1
  29. package/dist/assets/stash-skeleton/facts/conventions/assets/knowledge.md +13 -1
  30. package/dist/assets/stash-skeleton/facts/conventions/assets/lesson.md +9 -1
  31. package/dist/assets/stash-skeleton/facts/conventions/assets/memory.md +11 -0
  32. package/dist/assets/stash-skeleton/facts/conventions/assets/script.md +9 -0
  33. package/dist/assets/stash-skeleton/facts/conventions/assets/skill.md +9 -0
  34. package/dist/assets/stash-skeleton/facts/conventions/assets/workflow.md +8 -0
  35. package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +100 -0
  36. package/dist/assets/stash-skeleton/facts/conventions/domains.md +64 -0
  37. package/dist/assets/stash-skeleton/facts/conventions/organization.md +136 -0
  38. package/dist/assets/tasks/core/extract.yml +3 -2
  39. package/dist/assets/tasks/core/improve.yml +2 -1
  40. package/dist/assets/tasks/core/index-refresh.yml +1 -0
  41. package/dist/assets/tasks/core/sync.yml +1 -0
  42. package/dist/assets/tasks/core/version-check.yml +2 -1
  43. package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +5 -0
  44. package/dist/assets/tasks/improve/akm-improve-catchup.yml +8 -0
  45. package/dist/assets/tasks/improve/akm-improve-consolidate.yml +5 -0
  46. package/dist/assets/tasks/improve/akm-improve-frequent.yml +5 -0
  47. package/dist/assets/tasks/improve/akm-improve-nightly.yml +5 -0
  48. package/dist/assets/templates/html/health.html +5 -4
  49. package/dist/assets/workflows/workflow-template.md +31 -15
  50. package/dist/cli/invocation.js +279 -0
  51. package/dist/cli/parse-args.js +5 -90
  52. package/dist/cli/retired-commands.js +78 -0
  53. package/dist/cli/shared.js +158 -48
  54. package/dist/cli-node.mjs +2 -1
  55. package/dist/cli.js +747 -293
  56. package/dist/commands/agent/agent-dispatch.js +19 -18
  57. package/dist/commands/agent/agent-support.js +0 -24
  58. package/dist/commands/agent/contribute-cli.js +43 -97
  59. package/dist/commands/completions.js +80 -23
  60. package/dist/commands/config-cli.js +44 -281
  61. package/dist/commands/env/env-binding.js +13 -9
  62. package/dist/commands/env/env-cli.js +76 -159
  63. package/dist/commands/env/env.js +12 -163
  64. package/dist/commands/env/marker-path.js +6 -0
  65. package/dist/commands/env/secret-cli.js +45 -61
  66. package/dist/commands/env/secret.js +32 -62
  67. package/dist/commands/feedback-cli.js +179 -85
  68. package/dist/commands/health/accept-rate.js +58 -0
  69. package/dist/commands/health/advisories.js +7 -8
  70. package/dist/commands/health/checks.js +279 -94
  71. package/dist/commands/health/html-report.js +197 -578
  72. package/dist/commands/health/improve-metrics.js +277 -246
  73. package/dist/commands/health/llm-usage.js +19 -19
  74. package/dist/commands/health/md-report.js +16 -7
  75. package/dist/commands/health/metrics.js +67 -32
  76. package/dist/commands/health/renderers.js +47 -0
  77. package/dist/commands/health/report-view-model.js +508 -0
  78. package/dist/commands/health/stash-exposure.js +1 -1
  79. package/dist/commands/health/surfaces.js +16 -56
  80. package/dist/commands/health/task-runs.js +3 -67
  81. package/dist/{migrate-storage-node.mjs → commands/health/types-checks.js} +1 -5
  82. package/dist/commands/health/types-improve.js +29 -0
  83. package/dist/{output/text/save.js → commands/health/types-metrics.js} +1 -2
  84. package/dist/commands/health/types-result.js +7 -0
  85. package/dist/commands/health/types-runs.js +4 -0
  86. package/dist/commands/health/types-session-log.js +4 -0
  87. package/dist/commands/health/types-windows.js +4 -0
  88. package/dist/commands/health/types.js +26 -21
  89. package/dist/commands/health/windows.js +2 -3
  90. package/dist/commands/health.js +296 -167
  91. package/dist/commands/improve/anti-collapse.js +5 -5
  92. package/dist/commands/improve/autonomy-gate.js +68 -0
  93. package/dist/commands/improve/collapse-detector.js +65 -52
  94. package/dist/commands/improve/consolidate/chunking.js +9 -7
  95. package/dist/commands/improve/consolidate/eligibility.js +1 -23
  96. package/dist/commands/improve/consolidate/merge.js +4 -0
  97. package/dist/commands/improve/consolidate.js +454 -1354
  98. package/dist/commands/improve/content-hash.js +39 -0
  99. package/dist/commands/improve/distill/content-repair.js +4 -10
  100. package/dist/commands/improve/distill/promote-memory.js +89 -64
  101. package/dist/commands/improve/distill/quality-gate.js +118 -42
  102. package/dist/commands/improve/distill-guards.js +1 -1
  103. package/dist/commands/improve/distill-promotion-policy.js +33 -888
  104. package/dist/commands/improve/distill.js +607 -363
  105. package/dist/commands/improve/eligibility.js +165 -79
  106. package/dist/commands/improve/extract-cli.js +35 -126
  107. package/dist/commands/improve/extract-prompt.js +6 -35
  108. package/dist/commands/improve/extract.js +640 -391
  109. package/dist/commands/improve/feedback-valence.js +2 -12
  110. package/dist/commands/improve/improve-cli.js +134 -135
  111. package/dist/commands/improve/improve-result-file.js +30 -50
  112. package/dist/commands/improve/improve-run-types.js +4 -0
  113. package/dist/commands/improve/improve-strategies.js +135 -0
  114. package/dist/commands/improve/improve.js +904 -701
  115. package/dist/commands/improve/locks.js +64 -111
  116. package/dist/commands/improve/loop-stages.js +1110 -923
  117. package/dist/commands/improve/memory/derived-ref.js +124 -0
  118. package/dist/commands/improve/memory/memory-belief.js +79 -7
  119. package/dist/commands/improve/memory/memory-contradiction-detect.js +49 -52
  120. package/dist/commands/improve/memory/memory-improve.js +25 -37
  121. package/dist/commands/improve/outcome-loop.js +25 -88
  122. package/dist/commands/improve/preparation.js +1034 -813
  123. package/dist/commands/improve/proactive-maintenance.js +34 -9
  124. package/dist/commands/improve/proposal-envelope.js +31 -0
  125. package/dist/commands/improve/reflect.js +983 -794
  126. package/dist/commands/improve/run-context.js +119 -0
  127. package/dist/commands/improve/salience.js +24 -127
  128. package/dist/commands/improve/session-asset.js +7 -3
  129. package/dist/commands/improve/shared.js +14 -34
  130. package/dist/commands/improve/source-identity.js +28 -0
  131. package/dist/commands/improve/triage.js +20 -17
  132. package/dist/commands/lint/base-linter.js +340 -313
  133. package/dist/commands/lint/env-key-rules.js +31 -47
  134. package/dist/commands/lint/index.js +185 -30
  135. package/dist/commands/{events.js → log.js} +28 -38
  136. package/dist/commands/migrate-cli.js +54 -0
  137. package/dist/commands/migration-tool.js +55 -0
  138. package/dist/commands/observability-cli.js +70 -208
  139. package/dist/commands/proposal/diff-format.js +50 -0
  140. package/dist/commands/proposal/drain-policies.js +0 -6
  141. package/dist/commands/proposal/drain.js +91 -40
  142. package/dist/commands/proposal/proposal-cli.js +134 -132
  143. package/dist/commands/proposal/proposal-types.js +56 -0
  144. package/dist/commands/proposal/proposal.js +83 -65
  145. package/dist/commands/proposal/propose-cli.js +88 -0
  146. package/dist/commands/proposal/propose.js +105 -88
  147. package/dist/commands/proposal/repository.js +1303 -278
  148. package/dist/commands/proposal/validators/proposal-quality-validators.js +16 -6
  149. package/dist/commands/proposal/validators/proposal-validators.js +61 -12
  150. package/dist/commands/proposal/validators/proposals.js +6 -8
  151. package/dist/commands/read/curate.js +78 -73
  152. package/dist/commands/read/knowledge.js +510 -13
  153. package/dist/commands/read/registry-search.js +2 -2
  154. package/dist/commands/read/remember-cli.js +84 -15
  155. package/dist/commands/read/search-cli.js +203 -96
  156. package/dist/commands/read/search.js +126 -94
  157. package/dist/commands/read/show.js +226 -250
  158. package/dist/commands/registry-cli.js +34 -60
  159. package/dist/commands/remember.js +18 -57
  160. package/dist/commands/sources/add-cli.js +104 -49
  161. package/dist/commands/sources/bundle-cli.js +166 -0
  162. package/dist/commands/sources/bundle-config-ops.js +63 -0
  163. package/dist/commands/sources/info.js +27 -15
  164. package/dist/commands/sources/init.js +30 -40
  165. package/dist/commands/sources/installed-stashes.js +469 -172
  166. package/dist/commands/sources/schema-repair.js +10 -9
  167. package/dist/commands/sources/self-update.js +182 -121
  168. package/dist/commands/sources/source-add.js +169 -178
  169. package/dist/commands/sources/source-clone.js +144 -41
  170. package/dist/commands/sources/source-manage.js +94 -59
  171. package/dist/commands/sources/sources-cli.js +64 -205
  172. package/dist/commands/sources/stash-cli.js +91 -54
  173. package/dist/commands/sources/stash-skeleton.js +1 -1
  174. package/dist/commands/tasks/tasks-cli.js +106 -104
  175. package/dist/commands/tasks/tasks.js +445 -262
  176. package/dist/commands/workflow-cli.js +75 -228
  177. package/dist/core/action-contributors.js +1 -1
  178. package/dist/core/activation-policy.js +49 -0
  179. package/dist/core/adapter/adapters/agent-skills-adapter.js +181 -0
  180. package/dist/core/adapter/adapters/akm-adapter.js +528 -0
  181. package/dist/core/adapter/adapters/akm-lint.js +392 -0
  182. package/dist/core/adapter/adapters/akm-metadata.js +387 -0
  183. package/dist/core/adapter/adapters/akm-task-adapter.js +149 -0
  184. package/dist/core/adapter/adapters/akm-workflow-adapter.js +180 -0
  185. package/dist/core/adapter/adapters/claude-adapter.js +61 -0
  186. package/dist/core/adapter/adapters/dotenv-adapter.js +187 -0
  187. package/dist/core/adapter/adapters/generic-files-adapter.js +119 -0
  188. package/dist/core/adapter/adapters/index.js +80 -0
  189. package/dist/core/adapter/adapters/llm-wiki-adapter.js +419 -0
  190. package/dist/core/adapter/adapters/okf-adapter.js +391 -0
  191. package/dist/core/adapter/adapters/opencode-adapter.js +68 -0
  192. package/dist/core/adapter/adapters/shared.js +286 -0
  193. package/dist/core/adapter/adapters/tool-dir-shared.js +217 -0
  194. package/dist/core/adapter/adapters/website-snapshot-adapter.js +155 -0
  195. package/dist/core/adapter/bundle-adapter.js +4 -0
  196. package/dist/core/adapter/detect-adapter.js +17 -0
  197. package/dist/core/adapter/recognize-match.js +44 -0
  198. package/dist/core/adapter/registry.js +56 -0
  199. package/dist/core/adapter/types.js +4 -0
  200. package/dist/core/asset/akm-markdown.js +30 -0
  201. package/dist/core/asset/asset-placement.js +243 -0
  202. package/dist/core/asset/asset-ref.js +110 -79
  203. package/dist/core/asset/asset-serialize.js +20 -0
  204. package/dist/core/asset/frontmatter.js +28 -12
  205. package/dist/core/asset/markdown.js +40 -51
  206. package/dist/core/asset/resolve-ref.js +274 -0
  207. package/dist/core/asset/stash-meta.js +2 -2
  208. package/dist/core/bundle-id.js +51 -0
  209. package/dist/core/common.js +281 -86
  210. package/dist/core/config/config-io.js +42 -128
  211. package/dist/core/config/config-schema.js +233 -855
  212. package/dist/core/config/config-sources.js +162 -39
  213. package/dist/core/config/config-types.js +16 -11
  214. package/dist/core/config/config-version.js +29 -0
  215. package/dist/core/config/config-walker.js +126 -37
  216. package/dist/core/config/config.js +154 -331
  217. package/dist/core/config/deep-merge.js +41 -0
  218. package/dist/core/config/engine-semantics.js +28 -0
  219. package/dist/core/config/experimental.js +21 -0
  220. package/dist/core/config/schema/embedding.js +38 -0
  221. package/dist/core/config/schema/engines.js +116 -0
  222. package/dist/core/config/schema/experimental.js +47 -0
  223. package/dist/core/config/schema/feedback.js +31 -0
  224. package/dist/core/config/schema/improve-processes.js +389 -0
  225. package/dist/core/config/schema/improve.js +94 -0
  226. package/dist/core/config/schema/index-config.js +176 -0
  227. package/dist/core/config/schema/output.js +18 -0
  228. package/dist/core/config/schema/primitives.js +94 -0
  229. package/dist/core/config/schema/search.js +30 -0
  230. package/dist/core/config/schema/setup.js +18 -0
  231. package/dist/core/config/schema/sources-bundles.js +169 -0
  232. package/dist/core/config/schema/workflow.js +29 -0
  233. package/dist/core/env-secret-ref.js +155 -20
  234. package/dist/core/errors.js +17 -15
  235. package/dist/core/events-types.js +4 -0
  236. package/dist/core/events.js +46 -128
  237. package/dist/core/extra-params.js +62 -0
  238. package/dist/core/file-change.js +17 -0
  239. package/dist/core/file-lock.js +202 -57
  240. package/dist/core/fs-txn.js +392 -0
  241. package/dist/core/git-message.js +59 -0
  242. package/dist/core/improve-result.js +167 -0
  243. package/dist/core/lesson-lint.js +1 -17
  244. package/dist/core/logs-db.js +1 -1
  245. package/dist/core/maintenance-barrier.js +135 -0
  246. package/dist/core/migration-operation.js +44 -0
  247. package/dist/core/mutation-target.js +78 -0
  248. package/dist/core/paths.js +22 -25
  249. package/dist/core/platform.js +10 -0
  250. package/dist/core/recognition-util.js +128 -0
  251. package/dist/core/redaction.js +392 -0
  252. package/dist/core/standards/resolve-standards-context.js +36 -65
  253. package/dist/core/standards/resolve-stash-standards.js +2 -2
  254. package/dist/core/standards/resolve-type-conventions.js +5 -5
  255. package/dist/core/state/migrations.js +242 -11
  256. package/dist/core/state-db.js +98 -10
  257. package/dist/core/structured.js +1 -1
  258. package/dist/core/subprocess.js +303 -0
  259. package/dist/core/text-truncation.js +9 -5
  260. package/dist/core/time.js +20 -0
  261. package/dist/core/type-presentation.js +130 -0
  262. package/dist/core/warn.js +0 -3
  263. package/dist/core/write-source.js +834 -118
  264. package/dist/indexer/bundle-identity-guard.js +92 -0
  265. package/dist/indexer/db/graph-db.js +1 -25
  266. package/dist/indexer/db/llm-cache.js +1 -1
  267. package/dist/indexer/ensure-index.js +30 -9
  268. package/dist/indexer/graph/graph-boost.js +9 -30
  269. package/dist/indexer/graph/graph-extraction.js +41 -27
  270. package/dist/indexer/graph/graph-types.js +4 -0
  271. package/dist/indexer/index-writer-lock.js +93 -49
  272. package/dist/indexer/index-written-assets.js +100 -53
  273. package/dist/indexer/indexer.js +746 -329
  274. package/dist/indexer/init.js +18 -25
  275. package/dist/indexer/installations.js +142 -0
  276. package/dist/indexer/passes/dir-staleness.js +18 -10
  277. package/dist/indexer/passes/memory-inference.js +25 -15
  278. package/dist/indexer/passes/metadata.js +412 -243
  279. package/dist/indexer/scan/doc-to-entry.js +160 -0
  280. package/dist/indexer/scan/drain-dir.js +134 -0
  281. package/dist/indexer/search/db-search.js +292 -108
  282. package/dist/indexer/search/fts-query.js +64 -0
  283. package/dist/indexer/search/ranking-contributors.js +145 -25
  284. package/dist/indexer/search/ranking-types.js +4 -0
  285. package/dist/indexer/search/ranking.js +28 -71
  286. package/dist/indexer/search/search-attribution.js +67 -0
  287. package/dist/indexer/search/search-fields.js +18 -3
  288. package/dist/indexer/search/search-hit-enrichers.js +30 -40
  289. package/dist/indexer/search/search-source.js +157 -111
  290. package/dist/indexer/search/semantic-status.js +4 -1
  291. package/dist/indexer/usage/usage-events.js +10 -30
  292. package/dist/indexer/walk/file-context.js +3 -45
  293. package/dist/indexer/walk/matchers.js +42 -73
  294. package/dist/indexer/walk/path-resolver.js +11 -5
  295. package/dist/indexer/walk/walker.js +42 -14
  296. package/dist/integrations/agent/builder-shared.js +7 -0
  297. package/dist/integrations/agent/builders.js +5 -58
  298. package/dist/integrations/agent/config.js +3 -143
  299. package/dist/integrations/agent/detect.js +17 -2
  300. package/dist/integrations/agent/engine-resolution.js +231 -0
  301. package/dist/integrations/agent/index.js +1 -2
  302. package/dist/integrations/agent/model-aliases.js +8 -3
  303. package/dist/integrations/agent/profiles.js +6 -99
  304. package/dist/integrations/agent/prompts.js +46 -18
  305. package/dist/integrations/agent/runner-dispatch.js +78 -13
  306. package/dist/integrations/agent/runner.js +76 -208
  307. package/dist/integrations/agent/spawn.js +48 -279
  308. package/dist/integrations/harnesses/aider/agent-builder.js +9 -8
  309. package/dist/integrations/harnesses/aider/index.js +2 -12
  310. package/dist/integrations/harnesses/amazonq/agent-builder.js +10 -16
  311. package/dist/integrations/harnesses/amazonq/index.js +3 -17
  312. package/dist/integrations/harnesses/claude/agent-builder.js +2 -3
  313. package/dist/integrations/harnesses/claude/config-import.js +1 -3
  314. package/dist/integrations/harnesses/claude/index.js +1 -14
  315. package/dist/integrations/harnesses/claude/session-log.js +27 -75
  316. package/dist/integrations/harnesses/codex/agent-builder.js +8 -7
  317. package/dist/integrations/harnesses/codex/index.js +2 -13
  318. package/dist/integrations/harnesses/copilot/agent-builder.js +9 -9
  319. package/dist/integrations/harnesses/copilot/index.js +1 -13
  320. package/dist/integrations/harnesses/gemini/agent-builder.js +8 -9
  321. package/dist/integrations/harnesses/gemini/index.js +1 -13
  322. package/dist/integrations/harnesses/ids.js +24 -0
  323. package/dist/integrations/harnesses/index.js +31 -33
  324. package/dist/integrations/harnesses/opencode/agent-builder.js +23 -5
  325. package/dist/integrations/harnesses/opencode/config-import.js +1 -3
  326. package/dist/integrations/harnesses/opencode/index.js +1 -18
  327. package/dist/integrations/harnesses/opencode/session-log.js +67 -125
  328. package/dist/integrations/harnesses/opencode-sdk/harness.js +3 -17
  329. package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +274 -191
  330. package/dist/integrations/harnesses/openhands/agent-builder.js +12 -10
  331. package/dist/integrations/harnesses/openhands/index.js +2 -12
  332. package/dist/integrations/harnesses/pi/agent-builder.js +11 -18
  333. package/dist/integrations/harnesses/pi/index.js +3 -16
  334. package/dist/integrations/harnesses/shared.js +17 -0
  335. package/dist/integrations/harnesses/types.js +38 -34
  336. package/dist/integrations/lockfile.js +211 -24
  337. package/dist/integrations/session-logs/index.js +24 -40
  338. package/dist/integrations/session-logs/provider-base.js +113 -0
  339. package/dist/llm/client.js +182 -110
  340. package/dist/llm/embedders/deterministic.js +2 -2
  341. package/dist/llm/embedders/remote.js +21 -9
  342. package/dist/llm/feature-gate.js +17 -57
  343. package/dist/llm/graph-extract.js +12 -13
  344. package/dist/llm/index-passes.js +8 -42
  345. package/dist/llm/memory-infer.js +144 -1
  346. package/dist/llm/metadata-enhance.js +45 -30
  347. package/dist/llm/structured-call.js +16 -8
  348. package/dist/llm/usage-persist.js +30 -5
  349. package/dist/llm/usage-telemetry.js +59 -6
  350. package/dist/output/cli-hints.js +1 -2
  351. package/dist/output/command-registry.js +27 -0
  352. package/dist/output/context.js +22 -7
  353. package/dist/output/format-exempt.js +80 -0
  354. package/dist/output/generic-render.js +251 -0
  355. package/dist/output/html-render.js +11 -16
  356. package/dist/output/render-registry.js +57 -0
  357. package/dist/output/renderers.js +15 -281
  358. package/dist/output/shapes/curate.js +10 -1
  359. package/dist/output/shapes/events.js +12 -7
  360. package/dist/output/shapes/helpers.js +58 -84
  361. package/dist/output/shapes/passthrough.js +8 -40
  362. package/dist/output/shapes/proposal/producer.js +15 -7
  363. package/dist/output/shapes/registry.js +12 -6
  364. package/dist/output/shapes.js +0 -9
  365. package/dist/output/text/{init.js → bundle-create.js} +3 -1
  366. package/dist/output/text/bundle-show.js +7 -0
  367. package/dist/output/text/command-format.js +562 -0
  368. package/dist/output/text/env.js +1 -3
  369. package/dist/output/text/events.js +8 -7
  370. package/dist/output/text/helpers.js +15 -1375
  371. package/dist/output/text/proposal/producer.js +4 -2
  372. package/dist/output/text/proposal-format.js +202 -0
  373. package/dist/output/text/registry-commands.js +1 -2
  374. package/dist/output/text/registry.js +12 -6
  375. package/dist/output/text/show-directives.js +117 -0
  376. package/dist/output/text/show-format.js +103 -0
  377. package/dist/output/text/sync.js +5 -0
  378. package/dist/output/text/workflow-format.js +332 -0
  379. package/dist/output/text/workflow.js +1 -2
  380. package/dist/output/text.js +10 -19
  381. package/dist/registry/factory.js +4 -6
  382. package/dist/registry/origin-resolve.js +16 -27
  383. package/dist/registry/providers/skills-sh.js +3 -3
  384. package/dist/registry/providers/static-index.js +15 -25
  385. package/dist/registry/resolve.js +43 -94
  386. package/dist/registry/semver.js +43 -0
  387. package/dist/runtime.js +81 -12
  388. package/dist/scripts/akm-migrate.js +35529 -0
  389. package/dist/setup/detect.js +5 -7
  390. package/dist/setup/detected-engines.js +136 -0
  391. package/dist/setup/engine-config.js +100 -0
  392. package/dist/setup/registry-stash-loader.js +3 -3
  393. package/dist/setup/semantic-assets.js +12 -9
  394. package/dist/setup/setup.js +444 -208
  395. package/dist/setup/steps/connection-shared.js +120 -0
  396. package/dist/setup/steps/connection.js +108 -305
  397. package/dist/setup/steps/platforms.js +13 -12
  398. package/dist/setup/steps/semantic.js +15 -3
  399. package/dist/setup/steps/sources.js +21 -15
  400. package/dist/setup/steps/stashdir.js +6 -4
  401. package/dist/setup/steps/tasks.js +236 -119
  402. package/dist/setup/steps.js +3 -2
  403. package/dist/sources/freshness.js +39 -0
  404. package/dist/sources/provider-factory.js +11 -17
  405. package/dist/sources/providers/filesystem.js +2 -3
  406. package/dist/sources/providers/git-install.js +278 -34
  407. package/dist/sources/providers/git-provider.js +54 -56
  408. package/dist/sources/providers/git-stash.js +420 -91
  409. package/dist/sources/providers/git.js +2 -2
  410. package/dist/sources/providers/npm.js +16 -19
  411. package/dist/sources/providers/provider-utils.js +47 -22
  412. package/dist/sources/providers/sync-from-ref.js +3 -9
  413. package/dist/sources/providers/website.js +2 -2
  414. package/dist/sources/resolve.js +11 -10
  415. package/dist/sources/snapshot-fetchers/types.js +4 -0
  416. package/dist/sources/{website-ingest.js → snapshot-fetchers/website-ingest.js} +110 -41
  417. package/dist/storage/database.js +60 -4
  418. package/dist/storage/engines/sqlite-migrations.js +156 -5
  419. package/dist/storage/locations.js +1 -2
  420. package/dist/storage/repositories/canaries-repository.js +1 -1
  421. package/dist/storage/repositories/events-repository.js +51 -11
  422. package/dist/storage/repositories/improve-runs-repository.js +6 -32
  423. package/dist/storage/repositories/index-connection.js +79 -0
  424. package/dist/storage/repositories/index-db.js +4 -3
  425. package/dist/storage/repositories/index-entries-repository.js +863 -0
  426. package/dist/{indexer/db/entry-mapper.js → storage/repositories/index-entry-mapper.js} +19 -2
  427. package/dist/storage/repositories/index-entry-types.js +4 -0
  428. package/dist/storage/repositories/index-fts-repository.js +167 -0
  429. package/dist/storage/repositories/index-llm-cache-repository.js +108 -0
  430. package/dist/storage/repositories/index-meta-repository.js +49 -0
  431. package/dist/{indexer/db/schema.js → storage/repositories/index-schema.js} +226 -100
  432. package/dist/storage/repositories/index-sql.js +12 -0
  433. package/dist/storage/repositories/index-utility-repository.js +356 -0
  434. package/dist/storage/repositories/index-vec-repository.js +250 -0
  435. package/dist/storage/repositories/outcome-repository.js +119 -0
  436. package/dist/storage/repositories/proposals-repository.js +317 -75
  437. package/dist/storage/repositories/registry-cache.js +1 -1
  438. package/dist/storage/repositories/salience-repository.js +172 -0
  439. package/dist/storage/repositories/task-history-repository.js +110 -3
  440. package/dist/storage/repositories/workflow-runs-repository.js +68 -35
  441. package/dist/tasks/backends/cron.js +169 -46
  442. package/dist/tasks/backends/exec-utils.js +76 -3
  443. package/dist/tasks/backends/index.js +6 -9
  444. package/dist/tasks/backends/launchd.js +292 -55
  445. package/dist/tasks/backends/schtasks.js +557 -70
  446. package/dist/tasks/backends/types.js +4 -0
  447. package/dist/tasks/command-executable.js +93 -0
  448. package/dist/tasks/embedded.js +56 -38
  449. package/dist/tasks/parser.js +156 -64
  450. package/dist/tasks/resolve-akm-bin.js +144 -51
  451. package/dist/tasks/runner.js +377 -209
  452. package/dist/tasks/schedule.js +108 -19
  453. package/dist/tasks/scheduler-invocation.js +296 -0
  454. package/dist/tasks/schema.js +1 -1
  455. package/dist/tasks/task-id.js +35 -0
  456. package/dist/tasks/validator.js +30 -16
  457. package/dist/workflows/authoring/authoring.js +96 -148
  458. package/dist/workflows/authoring/scope-key.js +1 -1
  459. package/dist/workflows/cli.js +0 -20
  460. package/dist/workflows/concurrency-policy.js +15 -0
  461. package/dist/workflows/exec/brief.js +25 -59
  462. package/dist/workflows/exec/frozen-judge.js +47 -0
  463. package/dist/workflows/exec/native-executor.js +157 -94
  464. package/dist/workflows/exec/report.js +365 -200
  465. package/dist/workflows/exec/run-workflow.js +46 -40
  466. package/dist/workflows/exec/scheduler.js +12 -41
  467. package/dist/workflows/exec/step-work.js +239 -205
  468. package/dist/workflows/exec/workflow-engine-gate.js +67 -0
  469. package/dist/workflows/ir/compile.js +141 -283
  470. package/dist/workflows/ir/freeze.js +233 -0
  471. package/dist/workflows/ir/plan-hash.js +40 -5
  472. package/dist/workflows/ir/schema.js +537 -1
  473. package/dist/workflows/parser.js +878 -306
  474. package/dist/workflows/program/expressions.js +20 -208
  475. package/dist/workflows/program/schema.js +7 -10
  476. package/dist/workflows/renderer.js +99 -121
  477. package/dist/workflows/resource-limits.js +22 -0
  478. package/dist/workflows/runtime/checkin.js +1 -1
  479. package/dist/workflows/runtime/plan-classifier.js +131 -0
  480. package/dist/workflows/runtime/runs.js +200 -113
  481. package/dist/workflows/runtime/unit-checkin.js +1 -1
  482. package/dist/workflows/runtime/unit-phases.js +20 -0
  483. package/dist/workflows/runtime/workflow-asset-loader.js +235 -97
  484. package/dist/workflows/schema.js +1 -11
  485. package/dist/workflows/validate-summary.js +4 -26
  486. package/dist/workflows/validator.js +52 -30
  487. package/docs/README.md +42 -78
  488. package/docs/migration/README.md +8 -0
  489. package/docs/migration/release-notes/0.6.0.md +1 -1
  490. package/docs/migration/release-notes/0.7.0.md +9 -8
  491. package/docs/migration/release-notes/0.9.0.md +158 -14
  492. package/docs/migration/v0.7-to-v0.8.md +46 -47
  493. package/docs/migration/v0.8-to-v0.9.md +844 -0
  494. package/docs/reference/README.md +12 -0
  495. package/docs/reference/data-and-telemetry.md +333 -0
  496. package/package.json +21 -17
  497. package/schemas/akm-asset-envelope.json +93 -0
  498. package/schemas/akm-config.json +4636 -0
  499. package/schemas/akm-task.json +87 -0
  500. package/{dist/schemas → schemas}/akm-workflow.json +127 -82
  501. package/dist/akm-migrate-storage +0 -38
  502. package/dist/assets/help/help-accept.md +0 -12
  503. package/dist/assets/help/help-improve.md +0 -84
  504. package/dist/assets/help/help-proposals.md +0 -17
  505. package/dist/assets/help/help-propose.md +0 -17
  506. package/dist/assets/help/help-reject.md +0 -11
  507. package/dist/assets/profiles/frequent.json +0 -13
  508. package/dist/assets/profiles/recombine-only.json +0 -21
  509. package/dist/assets/profiles/reflect-distill.json +0 -30
  510. package/dist/assets/profiles/synthesize.json +0 -15
  511. package/dist/assets/prompts/procedural-system.md +0 -44
  512. package/dist/assets/prompts/recombine-system.md +0 -40
  513. package/dist/assets/prompts/staleness-detect-system.md +0 -6
  514. package/dist/assets/tasks/core/backup.yml +0 -4
  515. package/dist/assets/tasks/graph-refresh-weekly.yml +0 -10
  516. package/dist/assets/templates/html/default.html +0 -78
  517. package/dist/assets/templates/html/vendor/echarts.min.js +0 -45
  518. package/dist/assets/wiki/index-template.md +0 -12
  519. package/dist/assets/wiki/ingest-workflow-template.md +0 -83
  520. package/dist/assets/wiki/log-template.md +0 -8
  521. package/dist/assets/wiki/schema-template.md +0 -61
  522. package/dist/cli/config-migrate.js +0 -150
  523. package/dist/cli/config-validate.js +0 -39
  524. package/dist/commands/graph/graph-cli.js +0 -124
  525. package/dist/commands/graph/graph.js +0 -487
  526. package/dist/commands/improve/calibration.js +0 -161
  527. package/dist/commands/improve/dedup.js +0 -482
  528. package/dist/commands/improve/extract-watch.js +0 -140
  529. package/dist/commands/improve/hot-probation.js +0 -45
  530. package/dist/commands/improve/improve-auto-accept.js +0 -276
  531. package/dist/commands/improve/improve-profiles.js +0 -168
  532. package/dist/commands/improve/procedural.js +0 -398
  533. package/dist/commands/improve/recombine.js +0 -818
  534. package/dist/commands/improve/schema-similarity-gate.js +0 -168
  535. package/dist/commands/lint/agent-linter.js +0 -44
  536. package/dist/commands/lint/command-linter.js +0 -44
  537. package/dist/commands/lint/default-linter.js +0 -16
  538. package/dist/commands/lint/fact-linter.js +0 -39
  539. package/dist/commands/lint/knowledge-linter.js +0 -16
  540. package/dist/commands/lint/memory-linter.js +0 -61
  541. package/dist/commands/lint/registry.js +0 -41
  542. package/dist/commands/lint/skill-linter.js +0 -45
  543. package/dist/commands/lint/task-linter.js +0 -50
  544. package/dist/commands/lint/workflow-linter.js +0 -81
  545. package/dist/commands/proposal/legacy-import.js +0 -115
  546. package/dist/commands/sources/history.js +0 -196
  547. package/dist/commands/tasks/default-tasks.js +0 -186
  548. package/dist/commands/wiki-cli.js +0 -292
  549. package/dist/core/asset/asset-registry.js +0 -76
  550. package/dist/core/asset/asset-spec.js +0 -316
  551. package/dist/core/config/config-migration.js +0 -602
  552. package/dist/core/deep-merge.js +0 -38
  553. package/dist/core/eval/rank-metrics.js +0 -113
  554. package/dist/core/ripgrep/install.js +0 -163
  555. package/dist/core/ripgrep/resolve.js +0 -81
  556. package/dist/indexer/db/db.js +0 -1414
  557. package/dist/indexer/manifest.js +0 -170
  558. package/dist/indexer/passes/metadata-contributors.js +0 -31
  559. package/dist/indexer/usage/unmigrated-vaults-guard.js +0 -94
  560. package/dist/integrations/harnesses/opencode-sdk/index.js +0 -25
  561. package/dist/llm/call-ai.js +0 -62
  562. package/dist/llm/memory-infer-impl.js +0 -138
  563. package/dist/output/shapes/distill.js +0 -14
  564. package/dist/output/shapes/history.js +0 -11
  565. package/dist/output/text/distill.js +0 -6
  566. package/dist/output/text/enable-disable.js +0 -8
  567. package/dist/output/text/history.js +0 -6
  568. package/dist/output/text/wiki.js +0 -16
  569. package/dist/registry/build-index.js +0 -386
  570. package/dist/schemas/akm-config.json +0 -14225
  571. package/dist/scripts/migrate-storage.js +0 -13169
  572. package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +0 -10169
  573. package/dist/scripts/migrations/v16-to-v17.js +0 -141
  574. package/dist/setup/legacy-config.js +0 -106
  575. package/dist/storage/repositories/consolidation-repository.js +0 -38
  576. package/dist/storage/repositories/recombine-repository.js +0 -213
  577. package/dist/wiki/wiki-templates.js +0 -15
  578. package/dist/wiki/wiki.js +0 -1012
  579. package/dist/workflows/authoring/workflow-program-template.yaml +0 -31
  580. package/dist/workflows/db.js +0 -350
  581. package/dist/workflows/exec/watch.js +0 -116
  582. package/dist/workflows/program/parser.js +0 -760
  583. package/dist/workflows/program/project.js +0 -105
  584. package/docs/data-and-telemetry.md +0 -227
  585. package/docs/migration/release-notes/0.9.0-beta.60.md +0 -19
  586. /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/registry.js +0 -0
  587. /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/youtube.js +0 -0
@@ -1,8 +1,20 @@
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 { isKnownType } from "../../core/recognition-util.js";
4
5
  import { computeGraphBoost } from "../graph/graph-boost.js";
5
- const TYPE_BOOST = {
6
+ import { attachSearchHitAttribution } from "./search-attribution.js";
7
+ /**
8
+ * Chunk 1.5 (D1.5-5) — retyped from `Record<string, number>` to a FULL
9
+ * `Record<KnownType, number>`. Only 8/14 types carried an entry before this
10
+ * chunk (`env`, `secret`, `wiki`, `lesson`, `task`, `session` silently fell
11
+ * through to the `?? 0` fallback at the sole consumer,
12
+ * {@link typeRankingContributor}). The 6 additions below are explicit `0`
13
+ * entries — behavior-preserving (they already defaulted to `0`), but now
14
+ * compile-time-exhaustive: adding a new `KNOWN_TYPE` forces an explicit
15
+ * boost decision instead of silently defaulting.
16
+ */
17
+ export const TYPE_BOOST = {
6
18
  skill: 0.4,
7
19
  command: 0.35,
8
20
  workflow: 0.35,
@@ -12,19 +24,46 @@ const TYPE_BOOST = {
12
24
  // Facts are authoritative, durable declarations about the stash — rank them
13
25
  // alongside knowledge so they surface reliably when relevant.
14
26
  fact: 0.22,
27
+ // Instruction files (CLAUDE.md / AGENTS.md) are project instructions read
28
+ // like knowledge (maintainer resolution 2026-07) — rank them alongside
29
+ // knowledge so they surface reliably when relevant.
30
+ instruction: 0.22,
15
31
  memory: -0.02,
32
+ // Chunk 1.5: previously-absent entries, all defaulted to 0 pre-chunk —
33
+ // explicit now, unchanged in effect.
34
+ env: 0,
35
+ secret: 0,
36
+ lesson: 0,
37
+ task: 0,
38
+ session: 0,
16
39
  };
40
+ /**
41
+ * Open-string accessor over {@link TYPE_BOOST} (plan §2.3 "ranking
42
+ * accessor"). Foreign/unknown types (outside `KNOWN_TYPES`) fall back to `0`
43
+ * — identical to the old `TYPE_BOOST[item.entry.type] ?? 0` behavior on a
44
+ * loosely-typed `Record<string, number>`, now expressed safely over the
45
+ * exhaustive `Record<KnownType, number>`.
46
+ */
47
+ export function typeBoostFor(type) {
48
+ return isKnownType(type) ? TYPE_BOOST[type] : 0;
49
+ }
17
50
  const MAX_BOOST_SUM = 3.0;
18
51
  const UTILITY_WEIGHT = 0.5;
19
52
  const UTILITY_MAX_BOOST = 1.5;
20
53
  /**
21
- * R2 (docs/design/improve-self-learning-analysis.md) — weight of the improve
22
- * loop's `asset_salience.rank_score` in user-facing ranking. Bounded well
23
- * below the utility boost so the composed signal refines, never dominates,
24
- * lexical/semantic relevance. rank_score ∈ [0,1] → boost ∈ [1, 1.2].
54
+ * R2 / #692 — weight of the improve loop's `asset_salience.rank_score`.
55
+ * rank_score ∈ [0,1] → boost ∈ [1, 1.2]. Bounded well below the utility boost
56
+ * so the composed signal would refine, never dominate, lexical/semantic
57
+ * relevance.
58
+ *
59
+ * As of #692 this is NOT wired into default user-facing ranking — see
60
+ * {@link salienceRankingContributor}'s doc comment. Kept exported (with the
61
+ * contributor) for a future gated experiment; do not reintroduce it into
62
+ * {@link defaultUtilityRankingContributors} without a measured
63
+ * curate-golden-bench delta and an explicit config gate.
25
64
  */
26
- const SALIENCE_WEIGHT = 0.2;
27
- const SALIENCE_MAX_BOOST = 1.2;
65
+ export const SALIENCE_WEIGHT = 0.2;
66
+ export const SALIENCE_MAX_BOOST = 1.2;
28
67
  /**
29
68
  * Phase 2A / Rec 5: default recency half-life (days) used when no
30
69
  * `utilityDecayConfig` is supplied to the ranking pipeline. Matches the
@@ -61,6 +100,54 @@ function beliefStateBoost(item) {
61
100
  return 0.06;
62
101
  return 0;
63
102
  }
103
+ /**
104
+ * Post-boost score ceilings for the demoting belief states (SPEC-5,
105
+ * stash-conventions-code-spec.md — corrections demotion).
106
+ *
107
+ * Why the additive {@link beliefStateBoost} penalties alone are not enough:
108
+ * keyword base scores are min-max normalized into [0.3, 1.0]
109
+ * (`normalizeFtsScores`), so the spread between the best FTS hit and its
110
+ * runner-up can be as large as 0.7 — and the boost sum then MULTIPLIES the
111
+ * base (`score *= 1 + boostSum`, {@link applyScoreContributors}). A
112
+ * superseded incumbent that is the best keyword match for a query therefore
113
+ * stays clamp-pinned at 1.0 above its own correction no matter what additive
114
+ * penalty it receives — defeating the corrections pattern's point ("so the
115
+ * ranker demotes the stale version instead of letting it outrank your fix").
116
+ *
117
+ * The ceilings guarantee the demotion while keeping flagged entries VISIBLE:
118
+ * un-demoted keyword hits floor at a 0.3 base, so any un-demoted hit outranks
119
+ * a ceilinged one; demoted entries still list (belief FILTERING stays a
120
+ * separate opt-in axis, `--belief`), and scores already below a ceiling keep
121
+ * their relative ordering. Ceiling order mirrors the additive-penalty
122
+ * severity order pinned in tests/integration/belief-state-phase1a.test.ts:
123
+ * deprecated (mildest) > superseded > contradicted > archived.
124
+ */
125
+ const BELIEF_STATE_SCORE_CEILINGS = {
126
+ deprecated: 0.28,
127
+ superseded: 0.25,
128
+ contradicted: 0.2,
129
+ archived: 0.15,
130
+ };
131
+ /**
132
+ * Clamp a ranked entry's FINAL score (after every additive and utility boost)
133
+ * to its demoting belief state's ceiling. No-op for `asserted`/`active`/unset
134
+ * entries. Applied once per item at the end of `applyRankingRules` so sort
135
+ * order and displayed scores stay consistent (single scoring pipeline).
136
+ *
137
+ * When the ceiling clamps, the pre-clamp score is recorded as
138
+ * `preCeilingScore` so db-search's semantic-only `minScore` floor can judge
139
+ * the hit by what it would have scored WITHOUT the demotion — a ceiling below
140
+ * the floor (archived 0.15 < default minScore 0.2) must demote a hit to last
141
+ * place, never silently drop it from the results.
142
+ */
143
+ export function applyBeliefStateScoreCeiling(item) {
144
+ const state = item.entry.beliefState;
145
+ const ceiling = state !== undefined ? BELIEF_STATE_SCORE_CEILINGS[state] : undefined;
146
+ if (ceiling !== undefined && item.score > ceiling) {
147
+ item.preCeilingScore = item.score;
148
+ item.score = ceiling;
149
+ }
150
+ }
64
151
  const exactNameRankingContributor = {
65
152
  name: "exact-name-ranking",
66
153
  appliesTo: () => true,
@@ -86,7 +173,7 @@ const typeRankingContributor = {
86
173
  name: "type-ranking",
87
174
  appliesTo: () => true,
88
175
  adjust(item) {
89
- return TYPE_BOOST[item.entry.type] ?? 0;
176
+ return typeBoostFor(item.entry.type);
90
177
  },
91
178
  };
92
179
  const beliefStateRankingContributor = {
@@ -189,13 +276,27 @@ const graphRankingContributor = {
189
276
  adjust(item, ctx) {
190
277
  return ctx.graphContext ? computeGraphBoost(ctx.graphContext, item.filePath) : 0;
191
278
  },
279
+ applied(item, ctx, contribution) {
280
+ if (!ctx.graphContext || contribution <= 0)
281
+ return;
282
+ const graphNode = ctx.graphContext.nodesByPath.get(item.filePath);
283
+ attachSearchHitAttribution(item, {
284
+ graphExtraction: {
285
+ boost: contribution,
286
+ ...(graphNode?.bodyHash ? { bodyHash: graphNode.bodyHash } : {}),
287
+ ...((graphNode?.extractionRunId ?? ctx.graphContext.graph.telemetry?.extractionRunId)
288
+ ? { extractionRunId: graphNode?.extractionRunId ?? ctx.graphContext.graph.telemetry?.extractionRunId }
289
+ : {}),
290
+ },
291
+ });
292
+ },
192
293
  };
193
294
  /**
194
295
  * Capture-mode boost — Phase 1B / Rec 7.
195
296
  *
196
297
  * Memories captured via the hot path (`akm remember`) get a modest additive
197
298
  * boost so they outrank otherwise-equal background-derived memories. Memories
198
- * without `captureMode` (legacy) return 0 and rank exactly as before.
299
+ * without `captureMode` return 0.
199
300
  */
200
301
  const captureModeRankingContributor = {
201
302
  name: "capture-mode-ranking",
@@ -227,7 +328,7 @@ const lessonStrengthContributor = {
227
328
  * Pinned-fact boost.
228
329
  *
229
330
  * Facts marked `pinned: true` form the small always-injected "core context"
230
- * (see docs/design/fact-asset-type.md). The fact metadata contributor records
331
+ * (see docs/architecture/specs/fact-asset-type.md). The fact metadata contributor records
231
332
  * a `pinned` search hint; here we give those facts a modest additive boost so
232
333
  * the core outranks ordinary facts on otherwise-equal queries. Capped small so
233
334
  * it cannot overpower an exact-name match.
@@ -309,7 +410,7 @@ const utilityRankingContributor = {
309
410
  *
310
411
  * Skipped entirely when `projectContext` is absent or has no tokens (e.g.
311
412
  * when running from home dir, /tmp, or when disabled via
312
- * `--no-project-context` / `AKM_DISABLE_PROJECT_CONTEXT=1`).
413
+ * `--no-project-context`).
313
414
  */
314
415
  const projectContextRankingContributor = {
315
416
  name: "project-context-ranking",
@@ -349,15 +450,31 @@ export const defaultRankingContributors = [
349
450
  projectContextRankingContributor,
350
451
  ];
351
452
  /**
352
- * R2 — compose the improve loop's salience core into user-facing ranking.
453
+ * R2 — the improve loop's salience core, as a bounded multiplicative ranking
454
+ * boost. `asset_salience.rank_score` (encoding + outcome + retrieval
455
+ * projection, maintained every improve run) otherwise drives only improve's
456
+ * INTERNAL maintenance selection.
353
457
  *
354
- * `asset_salience.rank_score` (encoding + outcome + retrieval projection,
355
- * maintained every improve run) previously drove only improve's INTERNAL
356
- * maintenance selection — the "better assets surface more" loop ran solely
357
- * through the utility EMA. This bounded multiplicative boost closes the outer
358
- * loop: usage/outcome-reinforced assets rank higher in `search`/`curate`.
458
+ * **#692 — NOT in {@link defaultUtilityRankingContributors}.** Removed from
459
+ * default user-facing ranking (search/curate): the boost was
460
+ * retrieval-dominated (`w_r = 0.60` in salience.ts, with no source filter, so
461
+ * it double-counted the same `usage_events` the utility EMA contributor
462
+ * already reinforces), warm-started non-zero with no outcome evidence, had
463
+ * zero pack coverage (favoring only self-generated personal assets), and
464
+ * measured as noise on live data (max observed multiplier ×1.071). Removing
465
+ * its default state.db load also deleted a confirmed hot-path defect — see
466
+ * the now-deleted `loadSalienceRankScores` in `ranking.ts` git history.
467
+ *
468
+ * `rank_score` itself is UNCHANGED as improve's internal selection signal.
469
+ * This contributor, and its weight/cap constants, stay exported so a FUTURE
470
+ * gated experiment (config-gated, outcome-gated) can wire it back in
471
+ * explicitly — see `RankEntriesOptions.salienceRankScores`'s doc comment in
472
+ * `ranking.ts`. Reachable today only via explicit contributor-list injection
473
+ * (tests / eval harnesses calling `applyUtilityContributors` directly with a
474
+ * list that includes it) — never through `applyRankingRules` / `akm search` /
475
+ * `akm curate`.
359
476
  */
360
- const salienceRankingContributor = {
477
+ export const salienceRankingContributor = {
361
478
  name: "salience-ranking",
362
479
  appliesTo(item, ctx) {
363
480
  const rank = ctx.salienceRankScores?.get(item.id);
@@ -369,10 +486,10 @@ const salienceRankingContributor = {
369
486
  item.score *= Math.min(rawBoost, SALIENCE_MAX_BOOST);
370
487
  },
371
488
  };
372
- export const defaultUtilityRankingContributors = [
373
- utilityRankingContributor,
374
- salienceRankingContributor,
375
- ];
489
+ // #692 — salienceRankingContributor deliberately excluded; see its doc
490
+ // comment. Do not add it back here without a config gate + a measured
491
+ // curate-golden-bench delta justifying it.
492
+ export const defaultUtilityRankingContributors = [utilityRankingContributor];
376
493
  /**
377
494
  * EVAL/DEBUG ONLY — remove named ranking contributors from a list.
378
495
  *
@@ -380,11 +497,10 @@ export const defaultUtilityRankingContributors = [
380
497
  * `name`s). A no-op — returns the input list unchanged (same reference) — when
381
498
  * the env value is unset/empty, so production ranking is never affected unless
382
499
  * the operator opts in. Its sole purpose is per-contributor ablation for the
383
- * curate ablation harness (see `docs/technical/ranking-ablation-and-saturation-analysis.md`
384
- * and `scripts/akm-eval/`): run the same fixture with and without a contributor
500
+ * curate ablation harness (`scripts/akm-eval/`): run the same fixture with and without a contributor
385
501
  * and diff the ranked results to measure whether that contributor is load-bearing.
386
502
  *
387
- * NOTE (see the analysis doc): a contributor's ablation delta is only observable
503
+ * NOTE (from the 2026-06 ablation analysis): a contributor's ablation delta is only observable
388
504
  * in the UNSATURATED score regime — once entries saturate at the `displayScore`
389
505
  * ceiling their contributor deltas are absorbed and ablation reads Δ=0.
390
506
  */
@@ -404,7 +520,11 @@ export function applyScoreContributors(item, ctx, contributors = defaultRankingC
404
520
  for (const contributor of contributors) {
405
521
  if (!contributor.appliesTo(item, ctx))
406
522
  continue;
523
+ const cappedBefore = Math.min(boostSum, MAX_BOOST_SUM);
407
524
  boostSum += contributor.adjust(item, ctx);
525
+ // Attribution receives only the share admitted by the common boost cap,
526
+ // never a raw contributor value that scoring discarded.
527
+ contributor.applied?.(item, ctx, Math.min(boostSum, MAX_BOOST_SUM) - cappedBefore);
408
528
  }
409
529
  item.score *= 1 + Math.min(boostSum, MAX_BOOST_SUM);
410
530
  }
@@ -0,0 +1,4 @@
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
+ export {};
@@ -1,68 +1,8 @@
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 fs from "node:fs";
5
- import { makeAssetRef } from "../../core/asset/asset-ref.js";
6
- import { getStateDbPath } from "../../core/state-db.js";
7
- import { openDatabase } from "../../storage/database.js";
8
- import { getUtilityScoresByIds } from "../db/db.js";
9
- import { applyContributorAblation, applyScoreContributors, applyUtilityContributors, defaultRankingContributors, defaultUtilityRankingContributors, } from "./ranking-contributors.js";
10
- /**
11
- * R2 — best-effort load of `asset_salience.rank_score` from state.db for the
12
- * ranked items. Fail-open: any error (state.db locked by a concurrent improve
13
- * run, missing table, unreadable path) returns an empty map, which makes the
14
- * salience contributor a no-op — byte-identical to pre-R2 ranking.
15
- *
16
- * Deliberately NOT `openStateDatabase()`: that helper runs migrations and sets
17
- * a 30 s busy timeout — too heavy for a search hot path. This opens read-only,
18
- * never creates or migrates state.db (missing file / missing table = empty
19
- * map), and caps lock waits at 250 ms so a concurrent improve run can only
20
- * ever cost the search a quarter second, not a stall.
21
- */
22
- export function loadSalienceRankScores(items) {
23
- const result = new Map();
24
- if (items.length === 0)
25
- return result;
26
- try {
27
- const dbPath = getStateDbPath();
28
- if (!fs.existsSync(dbPath))
29
- return result; // improve loop has never run here
30
- const idByRef = new Map();
31
- for (const item of items) {
32
- idByRef.set(makeAssetRef(item.entry.type, item.entry.name), item.id);
33
- }
34
- const stateDb = openDatabase(dbPath, { readonly: true });
35
- try {
36
- try {
37
- stateDb.exec("PRAGMA busy_timeout = 250");
38
- }
39
- catch {
40
- // pragma failure on a readonly handle is fine — default timeout applies
41
- }
42
- const refs = [...idByRef.keys()];
43
- const CHUNK = 500;
44
- for (let i = 0; i < refs.length; i += CHUNK) {
45
- const chunk = refs.slice(i, i + CHUNK);
46
- const placeholders = chunk.map(() => "?").join(",");
47
- const rows = stateDb
48
- .prepare(`SELECT asset_ref, rank_score FROM asset_salience WHERE asset_ref IN (${placeholders})`)
49
- .all(...chunk);
50
- for (const row of rows) {
51
- const id = idByRef.get(row.asset_ref);
52
- if (id !== undefined)
53
- result.set(id, row.rank_score);
54
- }
55
- }
56
- }
57
- finally {
58
- stateDb.close();
59
- }
60
- }
61
- catch {
62
- // Fail open — search must never break because state.db is unavailable.
63
- }
64
- return result;
65
- }
4
+ import { getUtilityScoresByIds } from "../../storage/repositories/index-utility-repository.js";
5
+ import { applyBeliefStateScoreCeiling, applyContributorAblation, applyScoreContributors, applyUtilityContributors, defaultRankingContributors, defaultUtilityRankingContributors, } from "./ranking-contributors.js";
66
6
  export function normalizeFtsScores(results) {
67
7
  const ftsScoreMap = new Map();
68
8
  if (results.length === 0)
@@ -93,6 +33,9 @@ export function combineSearchScores(options) {
93
33
  filePath: result.filePath,
94
34
  score: combinedScore,
95
35
  rankingMode: embedScore !== undefined ? "hybrid" : "fts",
36
+ itemRef: result.itemRef,
37
+ bundleId: result.bundleId,
38
+ conceptId: result.conceptId,
96
39
  });
97
40
  }
98
41
  for (const [id, cosine] of options.embedScoreMap) {
@@ -112,6 +55,9 @@ export function combineSearchScores(options) {
112
55
  filePath: found.filePath,
113
56
  score: cosine * VEC_WEIGHT,
114
57
  rankingMode: "semantic",
58
+ itemRef: found.itemRef,
59
+ bundleId: found.bundleId,
60
+ conceptId: found.conceptId,
115
61
  });
116
62
  }
117
63
  return scored;
@@ -127,21 +73,26 @@ export function applyRankingRules(options) {
127
73
  graphContext: options.graphContext,
128
74
  projectContext: options.projectContext,
129
75
  };
130
- // Eval/debug only: AKM_ABLATE_CONTRIBUTORS lets the ablation harness drop
131
- // named contributors to measure their effect. Resolved once per query;
132
- // a no-op (full lists) when the env var is unset — see applyContributorAblation.
133
- const ablateEnv = process.env.AKM_ABLATE_CONTRIBUTORS;
76
+ // Eval/debug only: lets the ablation harness drop named contributors to
77
+ // measure their effect. Resolved once per query; a no-op (full lists) when
78
+ // unset — see applyContributorAblation. C9: DI via
79
+ // `options.ablateContributors` is now the primary path (see the field's
80
+ // doc comment on RankEntriesOptions); AKM_ABLATE_CONTRIBUTORS is a
81
+ // temporary fallback for the one caller that cannot yet thread the option
82
+ // through (see that doc comment for why).
83
+ const ablateEnv = options.ablateContributors ?? process.env.AKM_ABLATE_CONTRIBUTORS;
134
84
  const activeScoreContributors = applyContributorAblation(defaultRankingContributors, ablateEnv);
135
85
  const activeUtilityContributors = applyContributorAblation(defaultUtilityRankingContributors, ablateEnv);
136
86
  for (const item of options.items) {
137
87
  applyScoreContributors(item, rankingContext, activeScoreContributors);
138
88
  }
139
89
  const { global: utilScoresMap, scoped: scopedUtilScoresMap } = getUtilityScoresByIds(options.db, options.items.map((item) => item.id), options.scopeKey);
140
- // R2 — compose the improve loop's salience into user-facing ranking.
141
- // undefined = load from state.db (default); null = explicitly disabled.
142
- const salienceRankScores = options.salienceRankScores === null
143
- ? new Map()
144
- : (options.salienceRankScores ?? loadSalienceRankScores(options.items));
90
+ // R2 / #692 — salience-ranking is not in defaultUtilityRankingContributors
91
+ // (see ranking-contributors.ts), so this is never consumed by the default
92
+ // ranking path below; it exists only for a caller that explicitly builds a
93
+ // contributor list including salienceRankingContributor. undefined/null
94
+ // both normalize to "no data" — there is no state.db fallback load.
95
+ const salienceRankScores = options.salienceRankScores ?? new Map();
145
96
  const utilityContext = {
146
97
  ...rankingContext,
147
98
  utilityScores: utilScoresMap,
@@ -152,6 +103,12 @@ export function applyRankingRules(options) {
152
103
  };
153
104
  for (const item of options.items) {
154
105
  applyUtilityContributors(item, utilityContext, activeUtilityContributors);
106
+ // SPEC-5: demoting belief states (superseded/contradicted/archived/
107
+ // deprecated) cap the FINAL score. The additive belief penalty inside the
108
+ // multiplicative boost sum cannot overcome the FTS min-max normalization
109
+ // spread, so without the ceiling a superseded incumbent that is the best
110
+ // keyword match outranks its own correction forever.
111
+ applyBeliefStateScoreCeiling(item);
155
112
  }
156
113
  return options.items;
157
114
  }
@@ -0,0 +1,67 @@
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
+ const ATTRIBUTION = Symbol("search-hit-attribution");
5
+ export function attachSearchHitAttribution(target, attribution) {
6
+ const host = target;
7
+ host[ATTRIBUTION] = {
8
+ ...host[ATTRIBUTION],
9
+ ...attribution,
10
+ };
11
+ }
12
+ export function copySearchHitAttribution(from, to, outputDescription) {
13
+ const attribution = from[ATTRIBUTION];
14
+ if (!attribution)
15
+ return;
16
+ const memoryInference = attribution.memoryInference;
17
+ const memorySurvives = memoryInference?.exposure !== "surface" ||
18
+ (memoryInference.surfaceDescription !== undefined && memoryInference.surfaceDescription === outputDescription);
19
+ const applicable = {
20
+ ...(memorySurvives && memoryInference ? { memoryInference } : {}),
21
+ ...(attribution.graphExtraction ? { graphExtraction: attribution.graphExtraction } : {}),
22
+ };
23
+ if (applicable.memoryInference || applicable.graphExtraction)
24
+ attachSearchHitAttribution(to, applicable);
25
+ }
26
+ export function getSearchHitAttribution(target) {
27
+ return target[ATTRIBUTION];
28
+ }
29
+ export function buildUsageEventAttribution(attribution, entryRef, projection = "full") {
30
+ if (!attribution)
31
+ return undefined;
32
+ const memoryInference = attribution.memoryInference;
33
+ const childRef = memoryInference?.exposure === "direct" ? entryRef : memoryInference?.childRef;
34
+ const graphExtraction = attribution.graphExtraction;
35
+ const graphApplies = graphExtraction !== undefined && Number.isFinite(graphExtraction.boost) && graphExtraction.boost > 0;
36
+ const surfaceFields = memoryInference?.surfaceFields ?? [];
37
+ const surfaceVisible = memoryInference?.exposure !== "surface" ||
38
+ (projection === "full"
39
+ ? surfaceFields.length > 0
40
+ : projection === "normal" || projection === "agent"
41
+ ? surfaceFields.includes("description")
42
+ : false);
43
+ const memoryApplies = memoryInference !== undefined && childRef?.includes("//") === true && surfaceVisible;
44
+ if (!memoryApplies && !graphApplies)
45
+ return undefined;
46
+ return {
47
+ ...(memoryApplies
48
+ ? {
49
+ memoryInference: {
50
+ exposure: memoryInference.exposure,
51
+ childRef,
52
+ },
53
+ }
54
+ : {}),
55
+ ...(graphApplies ? { graphExtraction } : {}),
56
+ };
57
+ }
58
+ export function usageEventAttributionMetadata(attribution, entryRef, projection = "full") {
59
+ const applicable = buildUsageEventAttribution(attribution, entryRef, projection);
60
+ return JSON.stringify({
61
+ downstreamAttribution: {
62
+ version: 1,
63
+ control: applicable === undefined,
64
+ ...applicable,
65
+ },
66
+ });
67
+ }
@@ -9,14 +9,16 @@
9
9
  * - description: entry description
10
10
  * - tags: tags + aliases joined
11
11
  * - hints: searchHints + examples + usage + intent fields
12
- * - content: TOC headings (lowest-weight catch-all)
12
+ * - content: TOC headings + parameters + the config-gated body opening
13
+ * (lowest-weight catch-all)
13
14
  */
14
15
  // NOTE (R5): the collapse detector's frozen canary queries are built from the
15
16
  // same surface this function indexes (name tokens / tags / description) and
16
17
  // scored via FTS against it. Changing what buildSearchFields includes shifts
17
18
  // the detector's recall baseline for ALL existing canary sets — coordinate
18
19
  // with src/commands/improve/collapse-detector.ts (buildCanaryQuery) and expect
19
- // operators to re-mint via `akm improve canary --refresh` after such a change.
20
+ // operators to re-mint via `bun scripts/refresh-canary-set.ts --refresh` after
21
+ // such a change.
20
22
  export function buildSearchFields(entry) {
21
23
  const name = entry.name.replace(/[-_]/g, " ").toLowerCase();
22
24
  const description = (entry.description ?? "").toLowerCase();
@@ -27,6 +29,8 @@ export function buildSearchFields(entry) {
27
29
  tagParts.push(entry.aliases.join(" "));
28
30
  const tags = tagParts.join(" ").toLowerCase();
29
31
  const hintParts = [];
32
+ if (entry.hints)
33
+ hintParts.push(entry.hints.join(" "));
30
34
  if (entry.searchHints)
31
35
  hintParts.push(entry.searchHints.join(" "));
32
36
  if (entry.examples)
@@ -49,6 +53,8 @@ export function buildSearchFields(entry) {
49
53
  hintParts.push(entry.whenToUse);
50
54
  const hints = hintParts.join(" ").toLowerCase();
51
55
  const contentParts = [];
56
+ if (entry.content)
57
+ contentParts.push(entry.content);
52
58
  if (entry.toc) {
53
59
  contentParts.push(entry.toc.map((h) => h.text).join(" "));
54
60
  }
@@ -59,12 +65,21 @@ export function buildSearchFields(entry) {
59
65
  contentParts.push(param.description);
60
66
  }
61
67
  }
68
+ // Stash-organization conventions (SPEC-8): the self-situating body opening
69
+ // (captured by the metadata pass only when `index.indexBodyOpening` is on)
70
+ // folds into the lowest-weight catch-all column — never name/description/
71
+ // tags/hints — so orientation prose is retrievable without outranking
72
+ // structured-field matches. The fold is unconditional on the entry field:
73
+ // `rebuildFts` rebuilds FTS rows from stored entry_json and must reproduce
74
+ // the same fields without re-reading config.
75
+ if (entry.bodyOpening)
76
+ contentParts.push(entry.bodyOpening);
62
77
  const content = contentParts.join(" ").toLowerCase();
63
78
  return { name, description, tags, hints, content };
64
79
  }
65
80
  /**
66
81
  * Build a single concatenated search text string for an entry.
67
- * Used for the `search_text` column in the entries table (backward compat)
82
+ * Used for the `search_text` column in the entries table.
68
83
  * and for generating embedding text.
69
84
  */
70
85
  export function buildSearchText(entry) {
@@ -1,9 +1,10 @@
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 { makeAssetRef } from "../../core/asset/asset-ref.js";
5
- import { getDerivedForParent } from "../db/db.js";
4
+ import { displayRef } from "../../core/asset/resolve-ref.js";
5
+ import { getDerivedForParent, getItemRefById } from "../../storage/repositories/index-entries-repository.js";
6
6
  import { getRenderer } from "../walk/file-context.js";
7
+ import { attachSearchHitAttribution } from "./search-attribution.js";
7
8
  const rendererSearchHitEnricher = {
8
9
  name: "renderer-search-hit-enricher",
9
10
  appliesTo(ctx) {
@@ -46,16 +47,23 @@ export const derivedMemoryEnricher = {
46
47
  // it untouched also avoids `<parent>.derived.derived` chains.
47
48
  if (hit.name.toLowerCase().endsWith(".derived"))
48
49
  return;
49
- // Parent ref shape: `memory:<name>`. Re-build from the entry's name
50
- // so we don't depend on whatever wiki/registry prefix `hit.ref` carries.
51
- const parentRef = makeAssetRef("memory", hit.name);
52
- const derived = getDerivedForParent(ctx.db, parentRef);
50
+ // Parent ref shape: the 0.9.0 `memories/<name>` conceptId. Re-build from the
51
+ // entry's name so we don't depend on whatever wiki/registry prefix `hit.ref`
52
+ // carries. INTERNAL lookup key into `getDerivedForParent`: the `derived_from`
53
+ // column now stores this same conceptId grammar (Group-C item 2 flip — the
54
+ // metadata producer + this consumer move together).
55
+ const parentRef = `memories/${hit.name}`;
56
+ const derived = getDerivedForParent(ctx.db, parentRef, ctx.stashDir);
53
57
  if (!derived)
54
58
  return;
55
59
  // Swap description / searchHints / tags from the derived child.
56
60
  // The parent ref itself is preserved — only the surface text is swapped.
61
+ const surfaceFields = [];
62
+ let surfaceDescription;
57
63
  if (typeof derived.entry.description === "string" && derived.entry.description.length > 0) {
58
64
  hit.description = derived.entry.description;
65
+ surfaceDescription = derived.entry.description;
66
+ surfaceFields.push("description");
59
67
  }
60
68
  if (Array.isArray(derived.entry.searchHints) && derived.entry.searchHints.length > 0) {
61
69
  // We don't have a `searchHints` field on SourceSearchHit today — it's
@@ -65,44 +73,26 @@ export const derivedMemoryEnricher = {
65
73
  }
66
74
  if (Array.isArray(derived.entry.tags) && derived.entry.tags.length > 0) {
67
75
  hit.tags = derived.entry.tags;
76
+ surfaceFields.push("tags");
77
+ }
78
+ // F4b output-spelling flip: `expandTo` is a user-facing `akm show <ref>`
79
+ // target, so emit the 0.9.0 short conceptId grammar (`memories/<name>`).
80
+ hit.expandTo = displayRef({ type: "memory", name: derived.entry.name });
81
+ const childRef = getItemRefById(ctx.db, derived.id);
82
+ if (childRef && surfaceFields.length > 0) {
83
+ attachSearchHitAttribution(hit, {
84
+ memoryInference: {
85
+ exposure: "surface",
86
+ childRef,
87
+ surfaceFields,
88
+ ...(surfaceDescription ? { surfaceDescription } : {}),
89
+ },
90
+ });
68
91
  }
69
- hit.expandTo = makeAssetRef("memory", derived.entry.name);
70
92
  },
71
93
  };
72
- /**
73
- * Registry of additional enrichers — populated by
74
- * {@link registerSearchHitEnricher} and consumed in addition to
75
- * {@link defaultSearchHitEnrichers} when `enrichSearchHit` is invoked
76
- * without an explicit enricher list.
77
- *
78
- * Kept module-local so callers must use `registerSearchHitEnricher` rather
79
- * than mutating the array directly.
80
- */
81
- const additionalEnrichers = [];
82
94
  export const defaultSearchHitEnrichers = [rendererSearchHitEnricher, derivedMemoryEnricher];
83
- /**
84
- * Register an additional enricher to be applied alongside the defaults.
85
- *
86
- * Idempotent on `name`: subsequent calls with the same name replace the
87
- * previously-registered enricher (so tests can re-register cleanly without
88
- * stacking duplicates).
89
- */
90
- export function registerSearchHitEnricher(enricher) {
91
- const existingIndex = additionalEnrichers.findIndex((e) => e.name === enricher.name);
92
- if (existingIndex >= 0) {
93
- additionalEnrichers[existingIndex] = enricher;
94
- }
95
- else {
96
- additionalEnrichers.push(enricher);
97
- }
98
- }
99
- /**
100
- * Test-only: clear the registered-enrichers list. Not part of the public API.
101
- */
102
- export function _resetRegisteredSearchHitEnrichers() {
103
- additionalEnrichers.length = 0;
104
- }
105
- export async function enrichSearchHit(hit, ctx, enrichers = [...defaultSearchHitEnrichers, ...additionalEnrichers]) {
95
+ export async function enrichSearchHit(hit, ctx, enrichers = defaultSearchHitEnrichers) {
106
96
  for (const enricher of enrichers) {
107
97
  if (!enricher.appliesTo(ctx))
108
98
  continue;