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
@@ -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;