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
@@ -0,0 +1,92 @@
1
+ // This Source Code Form is subject to the terms of the Mozilla Public
2
+ // License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
+ /**
5
+ * §11.5 bundle-rename startup guard.
6
+ *
7
+ * Renaming a workspace bundle id is a mass identity migration (every ref in the
8
+ * bundle changes without any file moving) and MUST go through the future
9
+ * explicit `akm bundle rename <old> <new>` command, which rekeys the index +
10
+ * every ref-keyed state table atomically. If a user instead hand-edits the
11
+ * `bundles` KEY in config.json, the durable index/state rows still carry the OLD
12
+ * bundle prefix while the config names the NEW id. Silently re-minting fresh
13
+ * state under the new id would strand the old rows; §11.5 requires we detect this
14
+ * and refuse-or-warn.
15
+ *
16
+ * This guard implements the cheap heuristic form (WARN, never silently re-mint):
17
+ * it compares the configured bundle ids against the DISTINCT `bundle_id`
18
+ * (item_ref bundle prefix) values already persisted in the index — and, by
19
+ * cutover construction, the same prefixes key the state.db usage/salience rows.
20
+ * The hand-rename signature is: a configured bundle id with NO indexed rows
21
+ * co-existing with indexed rows under a bundle id that is no longer configured.
22
+ *
23
+ * SEAM CHOICE: invoked from `ensureIndex` — the single funnel every read/index
24
+ * path passes through before consuming or (re)building the index, so the guard
25
+ * fires BEFORE a stale-index rebuild could re-mint fresh rows under the new id.
26
+ * It has a handful of call sites (vs. `loadConfig`'s hundreds), reads a cached
27
+ * config plus one indexed `DISTINCT` query, and settles after the first
28
+ * comparison over a non-empty index so the steady-state cost is a boolean check.
29
+ */
30
+ import fs from "node:fs";
31
+ import { loadConfig } from "../core/config/config.js";
32
+ import { getDbPath } from "../core/paths.js";
33
+ import { warn } from "../core/warn.js";
34
+ import { openDatabase } from "../storage/database.js";
35
+ let guardSettled = false;
36
+ /** TEST-ONLY: re-arm the once-per-process guard between cases. */
37
+ export function resetBundleIdentityGuardForTests() {
38
+ guardSettled = false;
39
+ }
40
+ /** Distinct non-empty `bundle_id` prefixes persisted in the index, or `undefined` when unreadable. */
41
+ function indexBundlePrefixes(dbPath) {
42
+ if (!fs.existsSync(dbPath))
43
+ return undefined;
44
+ let db;
45
+ try {
46
+ db = openDatabase(dbPath, { readonly: true });
47
+ if (!db.prepare("SELECT 1 FROM sqlite_master WHERE type='table' AND name='entries'").get())
48
+ return undefined;
49
+ return db
50
+ .prepare("SELECT DISTINCT bundle_id AS b FROM entries WHERE bundle_id IS NOT NULL AND bundle_id != ''")
51
+ .all().map((row) => row.b);
52
+ }
53
+ catch {
54
+ return undefined;
55
+ }
56
+ finally {
57
+ db?.close();
58
+ }
59
+ }
60
+ /**
61
+ * Warn (once per process) when the config's bundle ids and the index's bundle
62
+ * prefixes show the hand-rename signature (§11.5). No-op for an old-shape config
63
+ * (no `bundles`), an absent/empty index, or when the guard already settled.
64
+ */
65
+ export function warnOnBundleRenameDrift(config = loadConfig()) {
66
+ if (guardSettled)
67
+ return;
68
+ const bundles = config.bundles;
69
+ if (!bundles)
70
+ return; // old-shape config — no bundle identity to guard (do not settle)
71
+ const configIds = new Set(Object.keys(bundles));
72
+ if (configIds.size === 0)
73
+ return;
74
+ const indexIds = indexBundlePrefixes(getDbPath());
75
+ if (indexIds === undefined || indexIds.length === 0)
76
+ return; // nothing indexed yet — re-check later
77
+ // A real comparison happened over a populated index: settle so the steady
78
+ // state is one boolean check.
79
+ guardSettled = true;
80
+ const indexIdSet = new Set(indexIds);
81
+ const configuredMissingFromIndex = [...configIds].filter((id) => !indexIdSet.has(id));
82
+ const indexedNotConfigured = indexIds.filter((id) => !configIds.has(id));
83
+ if (configuredMissingFromIndex.length === 0 || indexedNotConfigured.length === 0)
84
+ return;
85
+ warn("WARNING: bundle identity drift detected. " +
86
+ `Configured bundle(s) with no indexed content: ${configuredMissingFromIndex.map((id) => `"${id}"`).join(", ")}; ` +
87
+ `indexed content under unconfigured bundle id(s): ${indexedNotConfigured.map((id) => `"${id}"`).join(", ")}. ` +
88
+ "This is the signature of a hand-renamed bundle id (spec §11.5). AKM will NOT silently re-mint fresh state " +
89
+ "under the new id. There is no rekey command in 0.9.0: either restore the previous bundle id in config.json " +
90
+ "to reattach the existing rows, or keep the new id and run `akm index --full` to re-mint under it, accepting " +
91
+ "that learned state (utility, salience, outcomes, usage history) keyed to the old id is left behind.");
92
+ }
@@ -4,7 +4,7 @@
4
4
  import fs from "node:fs";
5
5
  import { rethrowIfTestIsolationError } from "../../core/errors.js";
6
6
  import { getDbPath } from "../../core/paths.js";
7
- import { closeDatabase, openExistingDatabase } from "./db.js";
7
+ import { closeDatabase, openExistingDatabase } from "../../storage/repositories/index-connection.js";
8
8
  function withReadableGraphDb(db, fn) {
9
9
  if (db)
10
10
  return fn(db);
@@ -215,13 +215,6 @@ export function drainExtractionQueue(db, stashRoot, limit) {
215
215
  return [];
216
216
  }
217
217
  }
218
- /**
219
- * Scoped loader — only the graph_meta row for a stash. Used by callers that
220
- * only need summary numbers (e.g. `akm graph summary`).
221
- */
222
- export function loadGraphMetaOnly(stashPath, db) {
223
- return loadStoredGraphMeta(stashPath, db);
224
- }
225
218
  /**
226
219
  * Scoped loader — graph_files rows without entities/relations. Used for
227
220
  * orphan detection and entity overview commands.
@@ -256,23 +249,6 @@ export function loadGraphFilesOnly(stashPath, db) {
256
249
  return [];
257
250
  }
258
251
  }
259
- /**
260
- * Scoped loader — entities for a single file, keyed on the #624-P1 composite
261
- * (stash_root, file_path, body_hash). Used by per-asset show/curate lookups.
262
- */
263
- export function loadGraphEntitiesByPath(db, stashRoot, filePath, bodyHash) {
264
- try {
265
- const rows = db
266
- .prepare(`SELECT entity FROM graph_file_entities
267
- WHERE stash_root = ? AND file_path = ? AND body_hash = ?
268
- ORDER BY entity_order`)
269
- .all(stashRoot, filePath, bodyHash);
270
- return rows.map((r) => r.entity);
271
- }
272
- catch {
273
- return [];
274
- }
275
- }
276
252
  export function loadStoredGraphMeta(stashPath, db) {
277
253
  try {
278
254
  return withReadableGraphDb(db, (readDb) => {
@@ -9,7 +9,7 @@
9
9
  * duplicating the hash-compute → lookup → write pattern inline.
10
10
  */
11
11
  import { bestEffort } from "../../core/best-effort.js";
12
- import { computeBodyHash, getLlmCacheEntry, upsertLlmCacheEntry } from "./db.js";
12
+ import { computeBodyHash, getLlmCacheEntry, upsertLlmCacheEntry, } from "../../storage/repositories/index-llm-cache-repository.js";
13
13
  /**
14
14
  * Generic LLM cache wrapper. Returns cached result if body unchanged,
15
15
  * otherwise calls llmFn(), caches the result, and returns it.
@@ -14,17 +14,20 @@
14
14
  * populated index exists. The previous design — a staleness walk plus a
15
15
  * detached background reindex per read — made every read on an actively
16
16
  * written stash spawn a writer that the read's own telemetry then queued
17
- * behind (see docs/design/read-path-reindex-contention-findings.md).
17
+ * behind (the 2026-07 read-path reindex-contention findings).
18
18
  *
19
19
  * `mode: "blocking"` (improve) still checks staleness and rebuilds inline,
20
20
  * because its planning logic needs a current `entries` table in-process.
21
21
  */
22
22
  import fs from "node:fs";
23
23
  import path from "node:path";
24
- import { ASSET_SPECS, TYPE_DIRS } from "../core/asset/asset-spec.js";
24
+ import { placementSpecList } from "../core/asset/asset-placement.js";
25
25
  import { getDbPath } from "../core/paths.js";
26
26
  import { warn } from "../core/warn.js";
27
- import { closeDatabase, getEntryCount, getIndexedFilePaths, getMeta, openExistingDatabase } from "./db/db.js";
27
+ import { closeDatabase, openExistingDatabase } from "../storage/repositories/index-connection.js";
28
+ import { getEntryCount, getIndexedFilePaths } from "../storage/repositories/index-entries-repository.js";
29
+ import { getMeta } from "../storage/repositories/index-meta-repository.js";
30
+ import { warnOnBundleRenameDrift } from "./bundle-identity-guard.js";
28
31
  function getIndexableFiles(root, spec) {
29
32
  if (!fs.existsSync(root))
30
33
  return [];
@@ -80,8 +83,8 @@ function getIndexableFiles(root, spec) {
80
83
  function hasNewerIndexableFiles(stashDir, builtAt, indexedPaths) {
81
84
  const builtAtMs = builtAt ? new Date(builtAt).getTime() : Number.NaN;
82
85
  const builtAtUsable = Number.isFinite(builtAtMs);
83
- for (const [type, spec] of Object.entries(ASSET_SPECS)) {
84
- const typeRoot = path.join(stashDir, TYPE_DIRS[type] ?? spec.stashDir);
86
+ for (const spec of placementSpecList()) {
87
+ const typeRoot = path.join(stashDir, spec.stashDir);
85
88
  const files = getIndexableFiles(typeRoot, spec);
86
89
  for (const file of files) {
87
90
  if (!indexedPaths.has(file))
@@ -177,13 +180,20 @@ function indexCanServeStash(stashDir) {
177
180
  closeDatabase(db);
178
181
  }
179
182
  }
180
- async function runInlineReindex(stashDir) {
183
+ async function runInlineReindex(stashDir, options = {}) {
181
184
  try {
182
185
  const { akmIndex } = await import("./indexer.js");
183
- await akmIndex({ stashDir });
186
+ await akmIndex({
187
+ stashDir,
188
+ implicit: true,
189
+ ...(options.signal ? { signal: options.signal } : {}),
190
+ ...(options.hydrateSources === false ? { hydrateSources: false } : {}),
191
+ });
184
192
  return true;
185
193
  }
186
194
  catch (error) {
195
+ if (options.signal?.aborted)
196
+ throw error;
187
197
  warn("Auto-index failed, proceeding with existing index:", error instanceof Error ? error.message : String(error));
188
198
  return false;
189
199
  }
@@ -204,12 +214,23 @@ async function runInlineReindex(stashDir) {
204
214
  * A rebuild attempt that fails (throws) resolves to `false`.
205
215
  */
206
216
  export async function ensureIndex(stashDir, options = {}) {
217
+ // §11.5: warn (once) if the configured bundle ids drifted from the persisted
218
+ // index prefixes (hand-renamed bundle key) BEFORE any rebuild could re-mint.
219
+ warnOnBundleRenameDrift();
207
220
  if (options.mode === "blocking") {
221
+ // Blocking callers (improve's planning preflight) are a sanctioned
222
+ // materialization point — hydrate cache-backed sources as usual.
208
223
  if (!isIndexStale(stashDir))
209
224
  return false;
210
- return runInlineReindex(stashDir);
225
+ return runInlineReindex(stashDir, { ...(options.signal ? { signal: options.signal } : {}) });
211
226
  }
227
+ // Background = the READ path (`show` auto-index): query time must never clone/
228
+ // pull/fetch (spec §14.3 / D11). Build from already-materialized content only;
229
+ // absent source caches are skipped with a warning, not fetched.
212
230
  if (indexCanServeStash(stashDir))
213
231
  return false;
214
- return runInlineReindex(stashDir);
232
+ return runInlineReindex(stashDir, {
233
+ ...(options.signal ? { signal: options.signal } : {}),
234
+ hydrateSources: false,
235
+ });
215
236
  }
@@ -249,10 +249,9 @@ export function collectGraphRelatedHit(context, filePath) {
249
249
  * NOT entries.id — so candidates are identified by file_path (the unique index
250
250
  * idx_graph_files_path guarantees one graph_files row per path).
251
251
  *
252
- * The returned `ref` field carries the canonical asset ref (`type:name`)
253
- * resolved from entries.entry_key when the file is indexed. Callers should
254
- * fall back to formatting `path` when `ref` is undefined (graph row with no
255
- * matching entries row).
252
+ * The returned `ref` field carries the canonical indexed `concept_id`, never a
253
+ * value re-derived from presentation fields or `entry_key`. It is undefined
254
+ * when the graph row has no matching entry with current indexed provenance.
256
255
  */
257
256
  export function listRelatedPathsForFile(stashRoot, filePath, limit = 5, db) {
258
257
  if (!db) {
@@ -343,20 +342,17 @@ export function listRelatedPathsForFile(stashRoot, filePath, limit = 5, db) {
343
342
  relationCountByPath.set(row.file_path, (relationCountByPath.get(row.file_path) ?? 0) + 1);
344
343
  }
345
344
  }
346
- // Optional: ref lookup via entries.entry_key. entry_key is stored as
347
- // `${stash_dir}:${type}:${name}` — strip the stash-dir prefix to get the
348
- // user-facing `type:name`. Resolve by (stash_dir, file_path) now that the
349
- // graph rows are no longer keyed on entries.id.
345
+ // This related list is scoped to one source root, so the user-facing ref is
346
+ // the indexed bundle-less conceptId.
350
347
  const refByPath = new Map();
351
348
  try {
352
349
  const entryRows = db
353
- .prepare(`SELECT entry_key, stash_dir, file_path FROM entries
354
- WHERE file_path IN (${placeholders}) AND stash_dir = ?`)
350
+ .prepare(`SELECT file_path, concept_id FROM entries
351
+ WHERE file_path IN (${placeholders}) AND stash_dir = ?
352
+ AND item_ref IS NOT NULL AND concept_id IS NOT NULL`)
355
353
  .all(...candidatePaths, stashRoot);
356
354
  for (const row of entryRows) {
357
- const ref = stripStashPrefix(row.entry_key, row.stash_dir);
358
- if (ref)
359
- refByPath.set(row.file_path, ref);
355
+ refByPath.set(row.file_path, row.concept_id);
360
356
  }
361
357
  }
362
358
  catch {
@@ -375,23 +371,6 @@ export function listRelatedPathsForFile(stashRoot, filePath, limit = 5, db) {
375
371
  };
376
372
  });
377
373
  }
378
- /**
379
- * Convert an entries.entry_key to a user-facing asset ref. Entry keys are
380
- * stored as `${stash_dir}:${type}:${name}`; strip the stash-dir prefix.
381
- */
382
- function stripStashPrefix(entryKey, stashDir) {
383
- const prefix = `${stashDir}:`;
384
- if (entryKey.startsWith(prefix))
385
- return entryKey.slice(prefix.length);
386
- // Fall back to last two colon-separated segments.
387
- const lastColon = entryKey.lastIndexOf(":");
388
- if (lastColon < 0)
389
- return entryKey;
390
- const prevColon = entryKey.lastIndexOf(":", lastColon - 1);
391
- if (prevColon < 0)
392
- return entryKey;
393
- return entryKey.slice(prevColon + 1);
394
- }
395
374
  /**
396
375
  * Load and normalize graph data from SQLite once, then reuse it across all
397
376
  * per-entry boost lookups in the current query.
@@ -8,7 +8,7 @@
8
8
  * configured LLM to extract entities and relations from each one, and
9
9
  * persists the result to stash-local SQLite graph tables keyed by stash root.
10
10
  * The artifact is consumed by the search
11
- * pipeline (see `src/indexer/graph-boost.ts`) as a single boost component
11
+ * pipeline (see `src/indexer/graph/graph-boost.ts`) as a single boost component
12
12
  * inside the existing FTS5+boosts loop — there is NO second SearchHit
13
13
  * scorer and no parallel ranking track.
14
14
  *
@@ -16,7 +16,7 @@
16
16
  * 1. An LLM profile must be configured (no provider = no extraction). When
17
17
  * absent, `resolveIndexPassLLM("graph", config)` returns `undefined`
18
18
  * and the pass short-circuits.
19
- * 2. `profiles.improve.default.processes.graphExtraction.enabled !== false`
19
+ * 2. The selected strategy's `processes.graphExtraction.enabled !== false`
20
20
  * — the feature-gate layer (historically v1 spec §14, since superseded by
21
21
  * the 0.8.0 profile shape). Set to `false` to block the pass at the
22
22
  * feature-gate layer (no network call may ever issue).
@@ -31,13 +31,16 @@
31
31
  * - LLM access is exclusively via `resolveIndexPassLLM("graph", config)`.
32
32
  * - The graph rows are an indexer artifact, NOT a user-visible
33
33
  * asset. It does not have an asset ref, does not appear in search
34
- * hits, and is not addressable via `akm show`. Direct `fs.writeFile`
35
- * is therefore the correct primitive — `writeAssetToSource` is
34
+ * hits, and is not addressable via `akm show`. The persisted artifact
35
+ * lives in indexer-owned SQLite tables (`replaceStoredGraph` /
36
+ * `loadStoredGraphSnapshot` in `../db/graph-db.ts`), NOT as a file on
37
+ * disk (R-065 #3 — this comment previously described a retired
38
+ * `fs.writeFile`-based storage layout) — `writeAssetToSource` is
36
39
  * reserved for asset writes (CLAUDE.md / spec §10 step 5).
37
40
  */
38
41
  import fs from "node:fs";
39
42
  import path from "node:path";
40
- import { TYPE_DIRS } from "../../core/asset/asset-spec.js";
43
+ import { stashDirFor } from "../../core/asset/asset-placement.js";
41
44
  import { parseFrontmatter } from "../../core/asset/frontmatter.js";
42
45
  import { concurrentMap } from "../../core/concurrent.js";
43
46
  import { getIndexPassConfig, loadConfig, resolveBatchSize } from "../../core/config/config.js";
@@ -46,9 +49,9 @@ import { warn, warnVerbose } from "../../core/warn.js";
46
49
  import { isProcessEnabled } from "../../llm/feature-gate.js";
47
50
  import * as graphExtract from "../../llm/graph-extract.js";
48
51
  import { resolveIndexPassLLM } from "../../llm/index-passes.js";
49
- import { computeBodyHash, getLlmCacheEntriesByRefs, getLlmCacheEntry, upsertLlmCacheEntry, } from "../db/db.js";
52
+ import { computeBodyHash, getLlmCacheEntriesByRefs, getLlmCacheEntry, upsertLlmCacheEntry, } from "../../storage/repositories/index-llm-cache-repository.js";
53
+ import { GRAPH_SCHEMA_VERSION } from "../../storage/repositories/index-schema.js";
50
54
  import { drainExtractionQueue, loadStoredGraphSnapshot, replaceStoredGraph } from "../db/graph-db.js";
51
- import { GRAPH_SCHEMA_VERSION } from "../db/schema.js";
52
55
  import { walkMarkdownFiles } from "../walk/walker.js";
53
56
  import { deduplicateGraph } from "./graph-dedup.js";
54
57
  /** Schema version for the persisted artifact — bumps trigger a full rebuild. */
@@ -109,7 +112,6 @@ const SUPPORTED_GRAPH_EXTRACTION_INCLUDE_TYPES = new Set([
109
112
  "workflow",
110
113
  "lesson",
111
114
  "task",
112
- "wiki",
113
115
  ]);
114
116
  const GRAPH_CACHE_VARIANT_PREFIX = "graph-extraction";
115
117
  function normalizeConfidence(raw) {
@@ -260,7 +262,7 @@ function reuseGraphNode(previousNodes, candidate, bodyHash) {
260
262
  * 1. **Provider configured** — an LLM profile must be selectable. Without a
261
263
  * configured provider, `resolveIndexPassLLM("graph", config)` returns
262
264
  * `undefined` (the pass cannot run because there is no model to call).
263
- * 2. **Feature gate** — `profiles.improve.default.processes.graphExtraction.enabled`
265
+ * 2. **Feature gate** — the selected strategy's `processes.graphExtraction.enabled`
264
266
  * (defaults to `true`). When `false`, no network call may issue regardless
265
267
  * of per-pass settings.
266
268
  * 3. **Per-pass gate** — `index.graph.llm` (defaults to `true`). When
@@ -276,21 +278,25 @@ function reuseGraphNode(previousNodes, candidate, bodyHash) {
276
278
  */
277
279
  export async function runGraphExtractionPass(ctx) {
278
280
  const { config, sources, signal, db, reEnrich, onProgress, options = {} } = ctx;
281
+ const invocationOwnsConnection = Object.hasOwn(ctx, "llmConfig");
279
282
  // Gate 1 — feature gate via isProcessEnabled, which reads the 0.8.0 path
280
- // (profiles.improve.default.processes.graphExtraction.enabled). Defaults to
283
+ // (selected strategy's processes.graphExtraction.enabled). Defaults to
281
284
  // enabled when the key is absent.
282
- if (!isProcessEnabled("index", "graph_extraction", config))
285
+ if (!invocationOwnsConnection && !isProcessEnabled("index", "graph_extraction", config))
283
286
  return { ...EMPTY_RESULT };
284
287
  // Gate 2 — per-pass opt-out (#208). Returns the resolved llm config or
285
288
  // `undefined` when the pass should not run.
286
- const llmConfig = resolveIndexPassLLM("graph", config);
289
+ const llmConfig = Object.hasOwn(ctx, "llmConfig") ? ctx.llmConfig : resolveIndexPassLLM("graph", config);
287
290
  if (!llmConfig) {
288
- const reason = getIndexPassConfig(config.index, "graph")?.llm === false
289
- ? "index.graph.llm is false"
290
- : "no default LLM profile is configured";
291
+ const reason = getIndexPassConfig(config.index, "graph")?.enabled === false
292
+ ? "index.graph.enabled is false"
293
+ : "no LLM engine is configured";
291
294
  warnVerbose(`graph extraction: skipped because ${reason}.`);
292
295
  return { ...EMPTY_RESULT };
293
296
  }
297
+ const featureConfig = invocationOwnsConnection
298
+ ? { ...config, index: { ...config.index, graph: { ...config.index?.graph, enabled: true } } }
299
+ : config;
294
300
  // The pass only writes to the primary (working) stash. Read-only caches
295
301
  // (git, npm, website) are deliberately untouched — the graph artifact for
296
302
  // those sources would be clobbered by the next sync().
@@ -309,10 +315,14 @@ export async function runGraphExtractionPass(ctx) {
309
315
  for (const queued of drained) {
310
316
  if (signal?.aborted)
311
317
  break;
312
- await extractGraphForSingleFile(db, primary.path, queued.filePath, queued.bodyHash, { config, signal });
318
+ await extractGraphForSingleFile(db, primary.path, queued.filePath, queued.bodyHash, {
319
+ config: featureConfig,
320
+ signal,
321
+ llmConfig,
322
+ });
313
323
  }
314
324
  }
315
- const includeTypes = getGraphExtractionIncludeTypes(config);
325
+ const includeTypes = options.includeTypes ?? getGraphExtractionIncludeTypes(config);
316
326
  let eligible = collectEligibleFiles(primary.path, includeTypes).filter((candidate) => !options.candidatePaths || options.candidatePaths.has(candidate.absPath));
317
327
  // P2 (#624): when topN is set and a DB is available, rank the (already
318
328
  // candidate-filtered) eligible set by utility_scores DESC and keep only the
@@ -357,7 +367,7 @@ export async function runGraphExtractionPass(ctx) {
357
367
  // Resolve the effective batch size. Falls back to
358
368
  // DEFAULT_GRAPH_EXTRACTION_BATCH_SIZE (4) when unset, and clamps against
359
369
  // `llm.contextLength` if the model's context window is configured.
360
- const batchSize = resolveBatchSize(getIndexPassConfig(config.index, "graph")?.graphExtractionBatchSize, llmConfig.contextLength);
370
+ const batchSize = resolveBatchSize(options.batchSize ?? getIndexPassConfig(config.index, "graph")?.graphExtractionBatchSize, llmConfig.contextLength);
361
371
  const extractionRunId = crypto.randomUUID();
362
372
  const extractorId = getGraphExtractorId({ model: llmConfig.model, batchSize, includeTypes });
363
373
  const cacheVariant = extractorId;
@@ -438,7 +448,7 @@ export async function runGraphExtractionPass(ctx) {
438
448
  }
439
449
  if (!cached) {
440
450
  telemetry.cacheMisses += 1;
441
- const extraction = await graphExtract.extractGraphFromBody(llmConfig, candidate.body, signal, config, onFallback, { batchState, telemetry: runtimeTelemetry });
451
+ const extraction = await graphExtract.extractGraphFromBody(llmConfig, candidate.body, signal, featureConfig, onFallback, { batchState, telemetry: runtimeTelemetry });
442
452
  cached = {
443
453
  entities: extraction.entities,
444
454
  relations: extraction.relations,
@@ -463,8 +473,8 @@ export async function runGraphExtractionPass(ctx) {
463
473
  reportProgress(candidate.absPath, result);
464
474
  return result;
465
475
  },
466
- // Default concurrency of 4 for cloud APIs. Set `llm.concurrency: 1`
467
- // in config.json for local model servers (LM Studio, Ollama).
476
+ // Caller-set connection concurrency or 1: `resolveLlmEngineUse` does
477
+ // not forward `engines.<name>.concurrency`, so config cannot raise this.
468
478
  llmConfig.concurrency ?? 1);
469
479
  }
470
480
  else {
@@ -562,7 +572,7 @@ export async function runGraphExtractionPass(ctx) {
562
572
  telemetry.cacheMisses += uncachedChunk.length;
563
573
  // extractGraphFromBodies always returns an array of the same length
564
574
  // as bodies (it falls back per-asset for any missing indices).
565
- const batchExtractions = await graphExtract.extractGraphFromBodies(llmConfig, bodies, signal, config, onFallback, { batchState, telemetry: runtimeTelemetry });
575
+ const batchExtractions = await graphExtract.extractGraphFromBodies(llmConfig, bodies, signal, featureConfig, onFallback, { batchState, telemetry: runtimeTelemetry });
566
576
  // Map LLM results back to original positions and write cache entries.
567
577
  let llmIdx = 0;
568
578
  for (let j = 0; j < chunk.length; j++) {
@@ -670,7 +680,7 @@ function inferGraphTypeForPath(stashRoot, absPath) {
670
680
  if (!firstSeg)
671
681
  return undefined;
672
682
  for (const type of SUPPORTED_GRAPH_EXTRACTION_INCLUDE_TYPES) {
673
- if (TYPE_DIRS[type] === firstSeg)
683
+ if (stashDirFor(type) === firstSeg)
674
684
  return type;
675
685
  }
676
686
  return undefined;
@@ -718,12 +728,16 @@ export async function extractGraphForSingleFile(db, stashRoot, filePath, bodyHas
718
728
  }
719
729
  else {
720
730
  const config = opts?.config ?? loadConfig();
721
- if (!isProcessEnabled("index", "graph_extraction", config))
731
+ const invocationOwnsConnection = Object.hasOwn(opts ?? {}, "llmConfig");
732
+ if (!invocationOwnsConnection && !isProcessEnabled("index", "graph_extraction", config))
722
733
  return false;
723
- const llmConfig = resolveIndexPassLLM("graph", config);
734
+ const llmConfig = Object.hasOwn(opts ?? {}, "llmConfig") ? opts?.llmConfig : resolveIndexPassLLM("graph", config);
724
735
  if (!llmConfig)
725
736
  return false; // model-available guard
726
- const result = await graphExtract.extractGraphFromBody(llmConfig, body, opts?.signal, config);
737
+ const featureConfig = invocationOwnsConnection
738
+ ? { ...config, index: { ...config.index, graph: { ...config.index?.graph, enabled: true } } }
739
+ : config;
740
+ const result = await graphExtract.extractGraphFromBody(llmConfig, body, opts?.signal, featureConfig);
727
741
  extraction = {
728
742
  entities: result.entities,
729
743
  relations: result.relations,
@@ -848,7 +862,7 @@ export function collectEligibleFiles(stashRoot, includeTypes = [...DEFAULT_GRAPH
848
862
  const type = rawType.trim().toLowerCase();
849
863
  if (!SUPPORTED_GRAPH_EXTRACTION_INCLUDE_TYPES.has(type))
850
864
  continue;
851
- const stashDir = TYPE_DIRS[type];
865
+ const stashDir = stashDirFor(type);
852
866
  if (!stashDir)
853
867
  continue;
854
868
  const dir = path.join(stashRoot, stashDir);
@@ -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 {};