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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (587) hide show
  1. package/CHANGELOG.md +1190 -52
  2. package/README.md +62 -37
  3. package/SECURITY.md +46 -31
  4. package/dist/akm +162 -38
  5. package/dist/akm-migrate +44 -0
  6. package/dist/assets/backends/schtasks-template.xml +2 -1
  7. package/dist/assets/hints/cli-hints-full.md +268 -118
  8. package/dist/assets/hints/cli-hints-short.md +87 -24
  9. package/dist/assets/{profiles → improve-strategies}/catchup.json +3 -1
  10. package/dist/assets/{profiles → improve-strategies}/consolidate.json +3 -1
  11. package/dist/assets/{profiles → improve-strategies}/default.json +6 -7
  12. package/dist/assets/improve-strategies/frequent.json +15 -0
  13. package/dist/assets/{profiles → improve-strategies}/graph-refresh.json +4 -2
  14. package/dist/assets/{profiles → improve-strategies}/memory-focus.json +4 -1
  15. package/dist/assets/{profiles → improve-strategies}/proactive-maintenance.json +5 -5
  16. package/dist/assets/{profiles → improve-strategies}/quick.json +4 -2
  17. package/dist/assets/improve-strategies/reflect-distill.json +30 -0
  18. package/dist/assets/{profiles → improve-strategies}/thorough.json +1 -1
  19. package/dist/assets/prompts/consolidate-system.md +5 -5
  20. package/dist/assets/prompts/extract-session.md +2 -6
  21. package/dist/assets/prompts/memory-infer-user.md +2 -3
  22. package/dist/assets/prompts/reflect-llm-framed-contract.md +11 -0
  23. package/dist/assets/prompts/reflect-llm-schema-contract.md +3 -0
  24. package/dist/assets/prompts/reflect-output-repair.md +3 -0
  25. package/dist/assets/stash-skeleton/README.md +38 -10
  26. package/dist/assets/stash-skeleton/facts/conventions/assets/agent.md +8 -0
  27. package/dist/assets/stash-skeleton/facts/conventions/assets/command.md +8 -0
  28. package/dist/assets/stash-skeleton/facts/conventions/assets/fact.md +14 -1
  29. package/dist/assets/stash-skeleton/facts/conventions/assets/knowledge.md +13 -1
  30. package/dist/assets/stash-skeleton/facts/conventions/assets/lesson.md +9 -1
  31. package/dist/assets/stash-skeleton/facts/conventions/assets/memory.md +11 -0
  32. package/dist/assets/stash-skeleton/facts/conventions/assets/script.md +9 -0
  33. package/dist/assets/stash-skeleton/facts/conventions/assets/skill.md +9 -0
  34. package/dist/assets/stash-skeleton/facts/conventions/assets/workflow.md +8 -0
  35. package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +100 -0
  36. package/dist/assets/stash-skeleton/facts/conventions/domains.md +64 -0
  37. package/dist/assets/stash-skeleton/facts/conventions/organization.md +136 -0
  38. package/dist/assets/tasks/core/extract.yml +3 -2
  39. package/dist/assets/tasks/core/improve.yml +2 -1
  40. package/dist/assets/tasks/core/index-refresh.yml +1 -0
  41. package/dist/assets/tasks/core/sync.yml +1 -0
  42. package/dist/assets/tasks/core/version-check.yml +2 -1
  43. package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +5 -0
  44. package/dist/assets/tasks/improve/akm-improve-catchup.yml +8 -0
  45. package/dist/assets/tasks/improve/akm-improve-consolidate.yml +5 -0
  46. package/dist/assets/tasks/improve/akm-improve-frequent.yml +5 -0
  47. package/dist/assets/tasks/improve/akm-improve-nightly.yml +5 -0
  48. package/dist/assets/templates/html/health.html +5 -4
  49. package/dist/assets/workflows/workflow-template.md +31 -15
  50. package/dist/cli/invocation.js +279 -0
  51. package/dist/cli/parse-args.js +5 -90
  52. package/dist/cli/retired-commands.js +78 -0
  53. package/dist/cli/shared.js +158 -48
  54. package/dist/cli-node.mjs +2 -1
  55. package/dist/cli.js +747 -293
  56. package/dist/commands/agent/agent-dispatch.js +19 -18
  57. package/dist/commands/agent/agent-support.js +0 -24
  58. package/dist/commands/agent/contribute-cli.js +43 -97
  59. package/dist/commands/completions.js +80 -23
  60. package/dist/commands/config-cli.js +44 -281
  61. package/dist/commands/env/env-binding.js +13 -9
  62. package/dist/commands/env/env-cli.js +76 -159
  63. package/dist/commands/env/env.js +12 -163
  64. package/dist/commands/env/marker-path.js +6 -0
  65. package/dist/commands/env/secret-cli.js +45 -61
  66. package/dist/commands/env/secret.js +32 -62
  67. package/dist/commands/feedback-cli.js +179 -85
  68. package/dist/commands/health/accept-rate.js +58 -0
  69. package/dist/commands/health/advisories.js +7 -8
  70. package/dist/commands/health/checks.js +279 -94
  71. package/dist/commands/health/html-report.js +197 -578
  72. package/dist/commands/health/improve-metrics.js +277 -246
  73. package/dist/commands/health/llm-usage.js +19 -19
  74. package/dist/commands/health/md-report.js +16 -7
  75. package/dist/commands/health/metrics.js +67 -32
  76. package/dist/commands/health/renderers.js +47 -0
  77. package/dist/commands/health/report-view-model.js +508 -0
  78. package/dist/commands/health/stash-exposure.js +1 -1
  79. package/dist/commands/health/surfaces.js +16 -56
  80. package/dist/commands/health/task-runs.js +3 -67
  81. package/dist/{migrate-storage-node.mjs → commands/health/types-checks.js} +1 -5
  82. package/dist/commands/health/types-improve.js +29 -0
  83. package/dist/{output/text/save.js → commands/health/types-metrics.js} +1 -2
  84. package/dist/commands/health/types-result.js +7 -0
  85. package/dist/commands/health/types-runs.js +4 -0
  86. package/dist/commands/health/types-session-log.js +4 -0
  87. package/dist/commands/health/types-windows.js +4 -0
  88. package/dist/commands/health/types.js +26 -21
  89. package/dist/commands/health/windows.js +2 -3
  90. package/dist/commands/health.js +296 -167
  91. package/dist/commands/improve/anti-collapse.js +5 -5
  92. package/dist/commands/improve/autonomy-gate.js +68 -0
  93. package/dist/commands/improve/collapse-detector.js +65 -52
  94. package/dist/commands/improve/consolidate/chunking.js +9 -7
  95. package/dist/commands/improve/consolidate/eligibility.js +1 -23
  96. package/dist/commands/improve/consolidate/merge.js +4 -0
  97. package/dist/commands/improve/consolidate.js +454 -1354
  98. package/dist/commands/improve/content-hash.js +39 -0
  99. package/dist/commands/improve/distill/content-repair.js +4 -10
  100. package/dist/commands/improve/distill/promote-memory.js +89 -64
  101. package/dist/commands/improve/distill/quality-gate.js +118 -42
  102. package/dist/commands/improve/distill-guards.js +1 -1
  103. package/dist/commands/improve/distill-promotion-policy.js +33 -888
  104. package/dist/commands/improve/distill.js +607 -363
  105. package/dist/commands/improve/eligibility.js +165 -79
  106. package/dist/commands/improve/extract-cli.js +35 -126
  107. package/dist/commands/improve/extract-prompt.js +6 -35
  108. package/dist/commands/improve/extract.js +640 -391
  109. package/dist/commands/improve/feedback-valence.js +2 -12
  110. package/dist/commands/improve/improve-cli.js +134 -135
  111. package/dist/commands/improve/improve-result-file.js +30 -50
  112. package/dist/commands/improve/improve-run-types.js +4 -0
  113. package/dist/commands/improve/improve-strategies.js +135 -0
  114. package/dist/commands/improve/improve.js +904 -701
  115. package/dist/commands/improve/locks.js +64 -111
  116. package/dist/commands/improve/loop-stages.js +1110 -923
  117. package/dist/commands/improve/memory/derived-ref.js +124 -0
  118. package/dist/commands/improve/memory/memory-belief.js +79 -7
  119. package/dist/commands/improve/memory/memory-contradiction-detect.js +49 -52
  120. package/dist/commands/improve/memory/memory-improve.js +25 -37
  121. package/dist/commands/improve/outcome-loop.js +25 -88
  122. package/dist/commands/improve/preparation.js +1034 -813
  123. package/dist/commands/improve/proactive-maintenance.js +34 -9
  124. package/dist/commands/improve/proposal-envelope.js +31 -0
  125. package/dist/commands/improve/reflect.js +983 -794
  126. package/dist/commands/improve/run-context.js +119 -0
  127. package/dist/commands/improve/salience.js +24 -127
  128. package/dist/commands/improve/session-asset.js +7 -3
  129. package/dist/commands/improve/shared.js +14 -34
  130. package/dist/commands/improve/source-identity.js +28 -0
  131. package/dist/commands/improve/triage.js +20 -17
  132. package/dist/commands/lint/base-linter.js +340 -313
  133. package/dist/commands/lint/env-key-rules.js +31 -47
  134. package/dist/commands/lint/index.js +185 -30
  135. package/dist/commands/{events.js → log.js} +28 -38
  136. package/dist/commands/migrate-cli.js +54 -0
  137. package/dist/commands/migration-tool.js +55 -0
  138. package/dist/commands/observability-cli.js +70 -208
  139. package/dist/commands/proposal/diff-format.js +50 -0
  140. package/dist/commands/proposal/drain-policies.js +0 -6
  141. package/dist/commands/proposal/drain.js +91 -40
  142. package/dist/commands/proposal/proposal-cli.js +134 -132
  143. package/dist/commands/proposal/proposal-types.js +56 -0
  144. package/dist/commands/proposal/proposal.js +83 -65
  145. package/dist/commands/proposal/propose-cli.js +88 -0
  146. package/dist/commands/proposal/propose.js +105 -88
  147. package/dist/commands/proposal/repository.js +1303 -278
  148. package/dist/commands/proposal/validators/proposal-quality-validators.js +16 -6
  149. package/dist/commands/proposal/validators/proposal-validators.js +61 -12
  150. package/dist/commands/proposal/validators/proposals.js +6 -8
  151. package/dist/commands/read/curate.js +78 -73
  152. package/dist/commands/read/knowledge.js +510 -13
  153. package/dist/commands/read/registry-search.js +2 -2
  154. package/dist/commands/read/remember-cli.js +84 -15
  155. package/dist/commands/read/search-cli.js +203 -96
  156. package/dist/commands/read/search.js +126 -94
  157. package/dist/commands/read/show.js +226 -250
  158. package/dist/commands/registry-cli.js +34 -60
  159. package/dist/commands/remember.js +18 -57
  160. package/dist/commands/sources/add-cli.js +104 -49
  161. package/dist/commands/sources/bundle-cli.js +166 -0
  162. package/dist/commands/sources/bundle-config-ops.js +63 -0
  163. package/dist/commands/sources/info.js +27 -15
  164. package/dist/commands/sources/init.js +30 -40
  165. package/dist/commands/sources/installed-stashes.js +469 -172
  166. package/dist/commands/sources/schema-repair.js +10 -9
  167. package/dist/commands/sources/self-update.js +182 -121
  168. package/dist/commands/sources/source-add.js +169 -178
  169. package/dist/commands/sources/source-clone.js +144 -41
  170. package/dist/commands/sources/source-manage.js +94 -59
  171. package/dist/commands/sources/sources-cli.js +64 -205
  172. package/dist/commands/sources/stash-cli.js +91 -54
  173. package/dist/commands/sources/stash-skeleton.js +1 -1
  174. package/dist/commands/tasks/tasks-cli.js +106 -104
  175. package/dist/commands/tasks/tasks.js +445 -262
  176. package/dist/commands/workflow-cli.js +75 -228
  177. package/dist/core/action-contributors.js +1 -1
  178. package/dist/core/activation-policy.js +49 -0
  179. package/dist/core/adapter/adapters/agent-skills-adapter.js +181 -0
  180. package/dist/core/adapter/adapters/akm-adapter.js +528 -0
  181. package/dist/core/adapter/adapters/akm-lint.js +392 -0
  182. package/dist/core/adapter/adapters/akm-metadata.js +387 -0
  183. package/dist/core/adapter/adapters/akm-task-adapter.js +149 -0
  184. package/dist/core/adapter/adapters/akm-workflow-adapter.js +180 -0
  185. package/dist/core/adapter/adapters/claude-adapter.js +61 -0
  186. package/dist/core/adapter/adapters/dotenv-adapter.js +187 -0
  187. package/dist/core/adapter/adapters/generic-files-adapter.js +119 -0
  188. package/dist/core/adapter/adapters/index.js +80 -0
  189. package/dist/core/adapter/adapters/llm-wiki-adapter.js +419 -0
  190. package/dist/core/adapter/adapters/okf-adapter.js +391 -0
  191. package/dist/core/adapter/adapters/opencode-adapter.js +68 -0
  192. package/dist/core/adapter/adapters/shared.js +286 -0
  193. package/dist/core/adapter/adapters/tool-dir-shared.js +217 -0
  194. package/dist/core/adapter/adapters/website-snapshot-adapter.js +155 -0
  195. package/dist/core/adapter/bundle-adapter.js +4 -0
  196. package/dist/core/adapter/detect-adapter.js +17 -0
  197. package/dist/core/adapter/recognize-match.js +44 -0
  198. package/dist/core/adapter/registry.js +56 -0
  199. package/dist/core/adapter/types.js +4 -0
  200. package/dist/core/asset/akm-markdown.js +30 -0
  201. package/dist/core/asset/asset-placement.js +243 -0
  202. package/dist/core/asset/asset-ref.js +110 -79
  203. package/dist/core/asset/asset-serialize.js +20 -0
  204. package/dist/core/asset/frontmatter.js +28 -12
  205. package/dist/core/asset/markdown.js +40 -51
  206. package/dist/core/asset/resolve-ref.js +274 -0
  207. package/dist/core/asset/stash-meta.js +2 -2
  208. package/dist/core/bundle-id.js +51 -0
  209. package/dist/core/common.js +281 -86
  210. package/dist/core/config/config-io.js +42 -128
  211. package/dist/core/config/config-schema.js +233 -855
  212. package/dist/core/config/config-sources.js +162 -39
  213. package/dist/core/config/config-types.js +16 -11
  214. package/dist/core/config/config-version.js +29 -0
  215. package/dist/core/config/config-walker.js +126 -37
  216. package/dist/core/config/config.js +154 -331
  217. package/dist/core/config/deep-merge.js +41 -0
  218. package/dist/core/config/engine-semantics.js +28 -0
  219. package/dist/core/config/experimental.js +21 -0
  220. package/dist/core/config/schema/embedding.js +38 -0
  221. package/dist/core/config/schema/engines.js +116 -0
  222. package/dist/core/config/schema/experimental.js +47 -0
  223. package/dist/core/config/schema/feedback.js +31 -0
  224. package/dist/core/config/schema/improve-processes.js +389 -0
  225. package/dist/core/config/schema/improve.js +94 -0
  226. package/dist/core/config/schema/index-config.js +176 -0
  227. package/dist/core/config/schema/output.js +18 -0
  228. package/dist/core/config/schema/primitives.js +94 -0
  229. package/dist/core/config/schema/search.js +30 -0
  230. package/dist/core/config/schema/setup.js +18 -0
  231. package/dist/core/config/schema/sources-bundles.js +169 -0
  232. package/dist/core/config/schema/workflow.js +29 -0
  233. package/dist/core/env-secret-ref.js +155 -20
  234. package/dist/core/errors.js +17 -15
  235. package/dist/core/events-types.js +4 -0
  236. package/dist/core/events.js +46 -128
  237. package/dist/core/extra-params.js +62 -0
  238. package/dist/core/file-change.js +17 -0
  239. package/dist/core/file-lock.js +202 -57
  240. package/dist/core/fs-txn.js +392 -0
  241. package/dist/core/git-message.js +59 -0
  242. package/dist/core/improve-result.js +167 -0
  243. package/dist/core/lesson-lint.js +1 -17
  244. package/dist/core/logs-db.js +1 -1
  245. package/dist/core/maintenance-barrier.js +135 -0
  246. package/dist/core/migration-operation.js +44 -0
  247. package/dist/core/mutation-target.js +78 -0
  248. package/dist/core/paths.js +22 -25
  249. package/dist/core/platform.js +10 -0
  250. package/dist/core/recognition-util.js +128 -0
  251. package/dist/core/redaction.js +392 -0
  252. package/dist/core/standards/resolve-standards-context.js +36 -65
  253. package/dist/core/standards/resolve-stash-standards.js +2 -2
  254. package/dist/core/standards/resolve-type-conventions.js +5 -5
  255. package/dist/core/state/migrations.js +242 -11
  256. package/dist/core/state-db.js +98 -10
  257. package/dist/core/structured.js +1 -1
  258. package/dist/core/subprocess.js +303 -0
  259. package/dist/core/text-truncation.js +9 -5
  260. package/dist/core/time.js +20 -0
  261. package/dist/core/type-presentation.js +130 -0
  262. package/dist/core/warn.js +0 -3
  263. package/dist/core/write-source.js +834 -118
  264. package/dist/indexer/bundle-identity-guard.js +92 -0
  265. package/dist/indexer/db/graph-db.js +1 -25
  266. package/dist/indexer/db/llm-cache.js +1 -1
  267. package/dist/indexer/ensure-index.js +30 -9
  268. package/dist/indexer/graph/graph-boost.js +9 -30
  269. package/dist/indexer/graph/graph-extraction.js +41 -27
  270. package/dist/indexer/graph/graph-types.js +4 -0
  271. package/dist/indexer/index-writer-lock.js +93 -49
  272. package/dist/indexer/index-written-assets.js +100 -53
  273. package/dist/indexer/indexer.js +746 -329
  274. package/dist/indexer/init.js +18 -25
  275. package/dist/indexer/installations.js +142 -0
  276. package/dist/indexer/passes/dir-staleness.js +18 -10
  277. package/dist/indexer/passes/memory-inference.js +25 -15
  278. package/dist/indexer/passes/metadata.js +412 -243
  279. package/dist/indexer/scan/doc-to-entry.js +160 -0
  280. package/dist/indexer/scan/drain-dir.js +134 -0
  281. package/dist/indexer/search/db-search.js +292 -108
  282. package/dist/indexer/search/fts-query.js +64 -0
  283. package/dist/indexer/search/ranking-contributors.js +145 -25
  284. package/dist/indexer/search/ranking-types.js +4 -0
  285. package/dist/indexer/search/ranking.js +28 -71
  286. package/dist/indexer/search/search-attribution.js +67 -0
  287. package/dist/indexer/search/search-fields.js +18 -3
  288. package/dist/indexer/search/search-hit-enrichers.js +30 -40
  289. package/dist/indexer/search/search-source.js +157 -111
  290. package/dist/indexer/search/semantic-status.js +4 -1
  291. package/dist/indexer/usage/usage-events.js +10 -30
  292. package/dist/indexer/walk/file-context.js +3 -45
  293. package/dist/indexer/walk/matchers.js +42 -73
  294. package/dist/indexer/walk/path-resolver.js +11 -5
  295. package/dist/indexer/walk/walker.js +42 -14
  296. package/dist/integrations/agent/builder-shared.js +7 -0
  297. package/dist/integrations/agent/builders.js +5 -58
  298. package/dist/integrations/agent/config.js +3 -143
  299. package/dist/integrations/agent/detect.js +17 -2
  300. package/dist/integrations/agent/engine-resolution.js +231 -0
  301. package/dist/integrations/agent/index.js +1 -2
  302. package/dist/integrations/agent/model-aliases.js +8 -3
  303. package/dist/integrations/agent/profiles.js +6 -99
  304. package/dist/integrations/agent/prompts.js +46 -18
  305. package/dist/integrations/agent/runner-dispatch.js +78 -13
  306. package/dist/integrations/agent/runner.js +76 -208
  307. package/dist/integrations/agent/spawn.js +48 -279
  308. package/dist/integrations/harnesses/aider/agent-builder.js +9 -8
  309. package/dist/integrations/harnesses/aider/index.js +2 -12
  310. package/dist/integrations/harnesses/amazonq/agent-builder.js +10 -16
  311. package/dist/integrations/harnesses/amazonq/index.js +3 -17
  312. package/dist/integrations/harnesses/claude/agent-builder.js +2 -3
  313. package/dist/integrations/harnesses/claude/config-import.js +1 -3
  314. package/dist/integrations/harnesses/claude/index.js +1 -14
  315. package/dist/integrations/harnesses/claude/session-log.js +27 -75
  316. package/dist/integrations/harnesses/codex/agent-builder.js +8 -7
  317. package/dist/integrations/harnesses/codex/index.js +2 -13
  318. package/dist/integrations/harnesses/copilot/agent-builder.js +9 -9
  319. package/dist/integrations/harnesses/copilot/index.js +1 -13
  320. package/dist/integrations/harnesses/gemini/agent-builder.js +8 -9
  321. package/dist/integrations/harnesses/gemini/index.js +1 -13
  322. package/dist/integrations/harnesses/ids.js +24 -0
  323. package/dist/integrations/harnesses/index.js +31 -33
  324. package/dist/integrations/harnesses/opencode/agent-builder.js +23 -5
  325. package/dist/integrations/harnesses/opencode/config-import.js +1 -3
  326. package/dist/integrations/harnesses/opencode/index.js +1 -18
  327. package/dist/integrations/harnesses/opencode/session-log.js +67 -125
  328. package/dist/integrations/harnesses/opencode-sdk/harness.js +3 -17
  329. package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +274 -191
  330. package/dist/integrations/harnesses/openhands/agent-builder.js +12 -10
  331. package/dist/integrations/harnesses/openhands/index.js +2 -12
  332. package/dist/integrations/harnesses/pi/agent-builder.js +11 -18
  333. package/dist/integrations/harnesses/pi/index.js +3 -16
  334. package/dist/integrations/harnesses/shared.js +17 -0
  335. package/dist/integrations/harnesses/types.js +38 -34
  336. package/dist/integrations/lockfile.js +211 -24
  337. package/dist/integrations/session-logs/index.js +24 -40
  338. package/dist/integrations/session-logs/provider-base.js +113 -0
  339. package/dist/llm/client.js +182 -110
  340. package/dist/llm/embedders/deterministic.js +2 -2
  341. package/dist/llm/embedders/remote.js +21 -9
  342. package/dist/llm/feature-gate.js +17 -57
  343. package/dist/llm/graph-extract.js +12 -13
  344. package/dist/llm/index-passes.js +8 -42
  345. package/dist/llm/memory-infer.js +144 -1
  346. package/dist/llm/metadata-enhance.js +45 -30
  347. package/dist/llm/structured-call.js +16 -8
  348. package/dist/llm/usage-persist.js +30 -5
  349. package/dist/llm/usage-telemetry.js +59 -6
  350. package/dist/output/cli-hints.js +1 -2
  351. package/dist/output/command-registry.js +27 -0
  352. package/dist/output/context.js +22 -7
  353. package/dist/output/format-exempt.js +80 -0
  354. package/dist/output/generic-render.js +251 -0
  355. package/dist/output/html-render.js +11 -16
  356. package/dist/output/render-registry.js +57 -0
  357. package/dist/output/renderers.js +15 -281
  358. package/dist/output/shapes/curate.js +10 -1
  359. package/dist/output/shapes/events.js +12 -7
  360. package/dist/output/shapes/helpers.js +58 -84
  361. package/dist/output/shapes/passthrough.js +8 -40
  362. package/dist/output/shapes/proposal/producer.js +15 -7
  363. package/dist/output/shapes/registry.js +12 -6
  364. package/dist/output/shapes.js +0 -9
  365. package/dist/output/text/{init.js → bundle-create.js} +3 -1
  366. package/dist/output/text/bundle-show.js +7 -0
  367. package/dist/output/text/command-format.js +562 -0
  368. package/dist/output/text/env.js +1 -3
  369. package/dist/output/text/events.js +8 -7
  370. package/dist/output/text/helpers.js +15 -1375
  371. package/dist/output/text/proposal/producer.js +4 -2
  372. package/dist/output/text/proposal-format.js +202 -0
  373. package/dist/output/text/registry-commands.js +1 -2
  374. package/dist/output/text/registry.js +12 -6
  375. package/dist/output/text/show-directives.js +117 -0
  376. package/dist/output/text/show-format.js +103 -0
  377. package/dist/output/text/sync.js +5 -0
  378. package/dist/output/text/workflow-format.js +332 -0
  379. package/dist/output/text/workflow.js +1 -2
  380. package/dist/output/text.js +10 -19
  381. package/dist/registry/factory.js +4 -6
  382. package/dist/registry/origin-resolve.js +16 -27
  383. package/dist/registry/providers/skills-sh.js +3 -3
  384. package/dist/registry/providers/static-index.js +15 -25
  385. package/dist/registry/resolve.js +43 -94
  386. package/dist/registry/semver.js +43 -0
  387. package/dist/runtime.js +81 -12
  388. package/dist/scripts/akm-migrate.js +35529 -0
  389. package/dist/setup/detect.js +5 -7
  390. package/dist/setup/detected-engines.js +136 -0
  391. package/dist/setup/engine-config.js +100 -0
  392. package/dist/setup/registry-stash-loader.js +3 -3
  393. package/dist/setup/semantic-assets.js +12 -9
  394. package/dist/setup/setup.js +444 -208
  395. package/dist/setup/steps/connection-shared.js +120 -0
  396. package/dist/setup/steps/connection.js +108 -305
  397. package/dist/setup/steps/platforms.js +13 -12
  398. package/dist/setup/steps/semantic.js +15 -3
  399. package/dist/setup/steps/sources.js +21 -15
  400. package/dist/setup/steps/stashdir.js +6 -4
  401. package/dist/setup/steps/tasks.js +236 -119
  402. package/dist/setup/steps.js +3 -2
  403. package/dist/sources/freshness.js +39 -0
  404. package/dist/sources/provider-factory.js +11 -17
  405. package/dist/sources/providers/filesystem.js +2 -3
  406. package/dist/sources/providers/git-install.js +278 -34
  407. package/dist/sources/providers/git-provider.js +54 -56
  408. package/dist/sources/providers/git-stash.js +420 -91
  409. package/dist/sources/providers/git.js +2 -2
  410. package/dist/sources/providers/npm.js +16 -19
  411. package/dist/sources/providers/provider-utils.js +47 -22
  412. package/dist/sources/providers/sync-from-ref.js +3 -9
  413. package/dist/sources/providers/website.js +2 -2
  414. package/dist/sources/resolve.js +11 -10
  415. package/dist/sources/snapshot-fetchers/types.js +4 -0
  416. package/dist/sources/{website-ingest.js → snapshot-fetchers/website-ingest.js} +110 -41
  417. package/dist/storage/database.js +60 -4
  418. package/dist/storage/engines/sqlite-migrations.js +156 -5
  419. package/dist/storage/locations.js +1 -2
  420. package/dist/storage/repositories/canaries-repository.js +1 -1
  421. package/dist/storage/repositories/events-repository.js +51 -11
  422. package/dist/storage/repositories/improve-runs-repository.js +6 -32
  423. package/dist/storage/repositories/index-connection.js +79 -0
  424. package/dist/storage/repositories/index-db.js +4 -3
  425. package/dist/storage/repositories/index-entries-repository.js +863 -0
  426. package/dist/{indexer/db/entry-mapper.js → storage/repositories/index-entry-mapper.js} +19 -2
  427. package/dist/storage/repositories/index-entry-types.js +4 -0
  428. package/dist/storage/repositories/index-fts-repository.js +167 -0
  429. package/dist/storage/repositories/index-llm-cache-repository.js +108 -0
  430. package/dist/storage/repositories/index-meta-repository.js +49 -0
  431. package/dist/{indexer/db/schema.js → storage/repositories/index-schema.js} +226 -100
  432. package/dist/storage/repositories/index-sql.js +12 -0
  433. package/dist/storage/repositories/index-utility-repository.js +356 -0
  434. package/dist/storage/repositories/index-vec-repository.js +250 -0
  435. package/dist/storage/repositories/outcome-repository.js +119 -0
  436. package/dist/storage/repositories/proposals-repository.js +317 -75
  437. package/dist/storage/repositories/registry-cache.js +1 -1
  438. package/dist/storage/repositories/salience-repository.js +172 -0
  439. package/dist/storage/repositories/task-history-repository.js +110 -3
  440. package/dist/storage/repositories/workflow-runs-repository.js +68 -35
  441. package/dist/tasks/backends/cron.js +169 -46
  442. package/dist/tasks/backends/exec-utils.js +76 -3
  443. package/dist/tasks/backends/index.js +6 -9
  444. package/dist/tasks/backends/launchd.js +292 -55
  445. package/dist/tasks/backends/schtasks.js +557 -70
  446. package/dist/tasks/backends/types.js +4 -0
  447. package/dist/tasks/command-executable.js +93 -0
  448. package/dist/tasks/embedded.js +56 -38
  449. package/dist/tasks/parser.js +156 -64
  450. package/dist/tasks/resolve-akm-bin.js +144 -51
  451. package/dist/tasks/runner.js +377 -209
  452. package/dist/tasks/schedule.js +108 -19
  453. package/dist/tasks/scheduler-invocation.js +296 -0
  454. package/dist/tasks/schema.js +1 -1
  455. package/dist/tasks/task-id.js +35 -0
  456. package/dist/tasks/validator.js +30 -16
  457. package/dist/workflows/authoring/authoring.js +96 -148
  458. package/dist/workflows/authoring/scope-key.js +1 -1
  459. package/dist/workflows/cli.js +0 -20
  460. package/dist/workflows/concurrency-policy.js +15 -0
  461. package/dist/workflows/exec/brief.js +25 -59
  462. package/dist/workflows/exec/frozen-judge.js +47 -0
  463. package/dist/workflows/exec/native-executor.js +157 -94
  464. package/dist/workflows/exec/report.js +365 -200
  465. package/dist/workflows/exec/run-workflow.js +46 -40
  466. package/dist/workflows/exec/scheduler.js +12 -41
  467. package/dist/workflows/exec/step-work.js +239 -205
  468. package/dist/workflows/exec/workflow-engine-gate.js +67 -0
  469. package/dist/workflows/ir/compile.js +141 -283
  470. package/dist/workflows/ir/freeze.js +233 -0
  471. package/dist/workflows/ir/plan-hash.js +40 -5
  472. package/dist/workflows/ir/schema.js +537 -1
  473. package/dist/workflows/parser.js +878 -306
  474. package/dist/workflows/program/expressions.js +20 -208
  475. package/dist/workflows/program/schema.js +7 -10
  476. package/dist/workflows/renderer.js +99 -121
  477. package/dist/workflows/resource-limits.js +22 -0
  478. package/dist/workflows/runtime/checkin.js +1 -1
  479. package/dist/workflows/runtime/plan-classifier.js +131 -0
  480. package/dist/workflows/runtime/runs.js +200 -113
  481. package/dist/workflows/runtime/unit-checkin.js +1 -1
  482. package/dist/workflows/runtime/unit-phases.js +20 -0
  483. package/dist/workflows/runtime/workflow-asset-loader.js +235 -97
  484. package/dist/workflows/schema.js +1 -11
  485. package/dist/workflows/validate-summary.js +4 -26
  486. package/dist/workflows/validator.js +52 -30
  487. package/docs/README.md +42 -78
  488. package/docs/migration/README.md +8 -0
  489. package/docs/migration/release-notes/0.6.0.md +1 -1
  490. package/docs/migration/release-notes/0.7.0.md +9 -8
  491. package/docs/migration/release-notes/0.9.0.md +158 -14
  492. package/docs/migration/v0.7-to-v0.8.md +46 -47
  493. package/docs/migration/v0.8-to-v0.9.md +844 -0
  494. package/docs/reference/README.md +12 -0
  495. package/docs/reference/data-and-telemetry.md +333 -0
  496. package/package.json +21 -17
  497. package/schemas/akm-asset-envelope.json +93 -0
  498. package/schemas/akm-config.json +4636 -0
  499. package/schemas/akm-task.json +87 -0
  500. package/{dist/schemas → schemas}/akm-workflow.json +127 -82
  501. package/dist/akm-migrate-storage +0 -38
  502. package/dist/assets/help/help-accept.md +0 -12
  503. package/dist/assets/help/help-improve.md +0 -84
  504. package/dist/assets/help/help-proposals.md +0 -17
  505. package/dist/assets/help/help-propose.md +0 -17
  506. package/dist/assets/help/help-reject.md +0 -11
  507. package/dist/assets/profiles/frequent.json +0 -13
  508. package/dist/assets/profiles/recombine-only.json +0 -21
  509. package/dist/assets/profiles/reflect-distill.json +0 -30
  510. package/dist/assets/profiles/synthesize.json +0 -15
  511. package/dist/assets/prompts/procedural-system.md +0 -44
  512. package/dist/assets/prompts/recombine-system.md +0 -40
  513. package/dist/assets/prompts/staleness-detect-system.md +0 -6
  514. package/dist/assets/tasks/core/backup.yml +0 -4
  515. package/dist/assets/tasks/graph-refresh-weekly.yml +0 -10
  516. package/dist/assets/templates/html/default.html +0 -78
  517. package/dist/assets/templates/html/vendor/echarts.min.js +0 -45
  518. package/dist/assets/wiki/index-template.md +0 -12
  519. package/dist/assets/wiki/ingest-workflow-template.md +0 -83
  520. package/dist/assets/wiki/log-template.md +0 -8
  521. package/dist/assets/wiki/schema-template.md +0 -61
  522. package/dist/cli/config-migrate.js +0 -150
  523. package/dist/cli/config-validate.js +0 -39
  524. package/dist/commands/graph/graph-cli.js +0 -124
  525. package/dist/commands/graph/graph.js +0 -487
  526. package/dist/commands/improve/calibration.js +0 -161
  527. package/dist/commands/improve/dedup.js +0 -482
  528. package/dist/commands/improve/extract-watch.js +0 -140
  529. package/dist/commands/improve/hot-probation.js +0 -45
  530. package/dist/commands/improve/improve-auto-accept.js +0 -276
  531. package/dist/commands/improve/improve-profiles.js +0 -168
  532. package/dist/commands/improve/procedural.js +0 -398
  533. package/dist/commands/improve/recombine.js +0 -818
  534. package/dist/commands/improve/schema-similarity-gate.js +0 -168
  535. package/dist/commands/lint/agent-linter.js +0 -44
  536. package/dist/commands/lint/command-linter.js +0 -44
  537. package/dist/commands/lint/default-linter.js +0 -16
  538. package/dist/commands/lint/fact-linter.js +0 -39
  539. package/dist/commands/lint/knowledge-linter.js +0 -16
  540. package/dist/commands/lint/memory-linter.js +0 -61
  541. package/dist/commands/lint/registry.js +0 -41
  542. package/dist/commands/lint/skill-linter.js +0 -45
  543. package/dist/commands/lint/task-linter.js +0 -50
  544. package/dist/commands/lint/workflow-linter.js +0 -81
  545. package/dist/commands/proposal/legacy-import.js +0 -115
  546. package/dist/commands/sources/history.js +0 -196
  547. package/dist/commands/tasks/default-tasks.js +0 -186
  548. package/dist/commands/wiki-cli.js +0 -292
  549. package/dist/core/asset/asset-registry.js +0 -76
  550. package/dist/core/asset/asset-spec.js +0 -316
  551. package/dist/core/config/config-migration.js +0 -602
  552. package/dist/core/deep-merge.js +0 -38
  553. package/dist/core/eval/rank-metrics.js +0 -113
  554. package/dist/core/ripgrep/install.js +0 -163
  555. package/dist/core/ripgrep/resolve.js +0 -81
  556. package/dist/indexer/db/db.js +0 -1414
  557. package/dist/indexer/manifest.js +0 -170
  558. package/dist/indexer/passes/metadata-contributors.js +0 -31
  559. package/dist/indexer/usage/unmigrated-vaults-guard.js +0 -94
  560. package/dist/integrations/harnesses/opencode-sdk/index.js +0 -25
  561. package/dist/llm/call-ai.js +0 -62
  562. package/dist/llm/memory-infer-impl.js +0 -138
  563. package/dist/output/shapes/distill.js +0 -14
  564. package/dist/output/shapes/history.js +0 -11
  565. package/dist/output/text/distill.js +0 -6
  566. package/dist/output/text/enable-disable.js +0 -8
  567. package/dist/output/text/history.js +0 -6
  568. package/dist/output/text/wiki.js +0 -16
  569. package/dist/registry/build-index.js +0 -386
  570. package/dist/schemas/akm-config.json +0 -14225
  571. package/dist/scripts/migrate-storage.js +0 -13169
  572. package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +0 -10169
  573. package/dist/scripts/migrations/v16-to-v17.js +0 -141
  574. package/dist/setup/legacy-config.js +0 -106
  575. package/dist/storage/repositories/consolidation-repository.js +0 -38
  576. package/dist/storage/repositories/recombine-repository.js +0 -213
  577. package/dist/wiki/wiki-templates.js +0 -15
  578. package/dist/wiki/wiki.js +0 -1012
  579. package/dist/workflows/authoring/workflow-program-template.yaml +0 -31
  580. package/dist/workflows/db.js +0 -350
  581. package/dist/workflows/exec/watch.js +0 -116
  582. package/dist/workflows/program/parser.js +0 -760
  583. package/dist/workflows/program/project.js +0 -105
  584. package/docs/data-and-telemetry.md +0 -227
  585. package/docs/migration/release-notes/0.9.0-beta.60.md +0 -19
  586. /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/registry.js +0 -0
  587. /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/youtube.js +0 -0
@@ -0,0 +1,119 @@
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
+ * Upsert one `asset_outcome` row. Extracted verbatim from the tail of
6
+ * `updateAssetOutcome` in outcome-loop.ts — same SQL text, same bind order;
7
+ * the business logic that computes these values (warm-start seed vs.
8
+ * differential update) stays in outcome-loop.ts and calls this function.
9
+ *
10
+ * `review_pressure` is intentionally omitted from both the INSERT column list
11
+ * and the ON CONFLICT SET clause: the column's DEFAULT 0 seeds fresh rows, and
12
+ * omitting it from SET leaves an existing row's value untouched on update
13
+ * (never written going forward). The column itself is dropped in migration 018.
14
+ */
15
+ export function upsertAssetOutcome(db, values) {
16
+ db.prepare(`INSERT INTO asset_outcome
17
+ (asset_ref, last_retrieved_at, retrieval_count, expected_retrieval_rate,
18
+ negative_feedback_count, accepted_change_count,
19
+ outcome_score, updated_at)
20
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)
21
+ ON CONFLICT(asset_ref) DO UPDATE SET
22
+ last_retrieved_at = excluded.last_retrieved_at,
23
+ retrieval_count = excluded.retrieval_count,
24
+ expected_retrieval_rate= excluded.expected_retrieval_rate,
25
+ negative_feedback_count= excluded.negative_feedback_count,
26
+ accepted_change_count = excluded.accepted_change_count,
27
+ outcome_score = excluded.outcome_score,
28
+ updated_at = excluded.updated_at`).run(values.ref, values.lastRetrievedAt, values.retrievalCount, values.expectedRetrievalRate, values.negativeFeedbackCount, values.acceptedChangeCount, values.outcomeScore, values.updatedAt);
29
+ }
30
+ /**
31
+ * Load the outcome row for one asset, or `undefined` if not yet written.
32
+ */
33
+ export function getAssetOutcome(db, ref) {
34
+ const row = db
35
+ .prepare(`SELECT asset_ref, last_retrieved_at, retrieval_count, expected_retrieval_rate,
36
+ negative_feedback_count, accepted_change_count,
37
+ outcome_score, updated_at
38
+ FROM asset_outcome WHERE asset_ref = ?`)
39
+ .get(ref);
40
+ return row == null ? undefined : row;
41
+ }
42
+ /**
43
+ * Load ALL asset_outcome rows. Used for the proxy-adequacy tripwire computation.
44
+ */
45
+ export function getAllAssetOutcomes(db) {
46
+ return db
47
+ .prepare(`SELECT asset_ref, last_retrieved_at, retrieval_count, expected_retrieval_rate,
48
+ negative_feedback_count, accepted_change_count,
49
+ outcome_score, updated_at
50
+ FROM asset_outcome ORDER BY asset_ref`)
51
+ .all();
52
+ }
53
+ /**
54
+ * Build a Map<ref, outcome_score> for a set of refs in one query.
55
+ * Used by `salience.ts` to populate `outcomeSalience`.
56
+ */
57
+ export function getOutcomeScoresByRef(db, refs) {
58
+ const result = new Map();
59
+ if (refs.length === 0)
60
+ return result;
61
+ const CHUNK = 500;
62
+ for (let i = 0; i < refs.length; i += CHUNK) {
63
+ const chunk = refs.slice(i, i + CHUNK);
64
+ const placeholders = chunk.map(() => "?").join(",");
65
+ const rows = db
66
+ .prepare(`SELECT asset_ref, outcome_score FROM asset_outcome WHERE asset_ref IN (${placeholders})`)
67
+ .all(...chunk);
68
+ for (const row of rows) {
69
+ result.set(row.asset_ref, row.outcome_score);
70
+ }
71
+ }
72
+ return result;
73
+ }
74
+ /** List every `asset_outcome` ref with its current `missing_since` marker. */
75
+ export function listAssetOutcomeMissingState(db) {
76
+ return db.prepare(`SELECT asset_ref, missing_since FROM asset_outcome`).all();
77
+ }
78
+ /**
79
+ * Stamp `missing_since = now` for the given refs, but ONLY where it is
80
+ * currently NULL — a ref already stamped keeps its original timestamp so the
81
+ * grace window measures from first sighting, not last. Refs with no row at
82
+ * all are silently skipped (0 rows affected). Returns the number of rows
83
+ * actually stamped.
84
+ */
85
+ export function stampAssetOutcomeMissing(db, refs, now) {
86
+ if (refs.length === 0)
87
+ return 0;
88
+ const stmt = db.prepare(`UPDATE asset_outcome SET missing_since = ? WHERE asset_ref = ? AND missing_since IS NULL`);
89
+ let changed = 0;
90
+ for (const ref of refs)
91
+ changed += Number(stmt.run(now, ref).changes);
92
+ return changed;
93
+ }
94
+ /**
95
+ * Clear `missing_since` for refs that resolved again. Returns the number of
96
+ * rows actually cleared.
97
+ */
98
+ export function clearAssetOutcomeMissing(db, refs) {
99
+ if (refs.length === 0)
100
+ return 0;
101
+ const stmt = db.prepare(`UPDATE asset_outcome SET missing_since = NULL WHERE asset_ref = ? AND missing_since IS NOT NULL`);
102
+ let changed = 0;
103
+ for (const ref of refs)
104
+ changed += Number(stmt.run(ref).changes);
105
+ return changed;
106
+ }
107
+ /**
108
+ * Delete `asset_outcome` rows whose `missing_since` is older than
109
+ * `cutoffMs`. A single DELETE — SQLite runs it as one implicit transaction.
110
+ * Returns the number of rows deleted.
111
+ */
112
+ export function deleteAssetOutcomeMissingBefore(db, cutoffMs) {
113
+ return Number(db.prepare(`DELETE FROM asset_outcome WHERE missing_since IS NOT NULL AND missing_since < ?`).run(cutoffMs).changes);
114
+ }
115
+ /** Count `asset_outcome` rows currently marked missing (the live backlog size). */
116
+ export function countAssetOutcomeMissing(db) {
117
+ const row = db.prepare(`SELECT COUNT(*) AS n FROM asset_outcome WHERE missing_since IS NOT NULL`).get();
118
+ return row.n;
119
+ }
@@ -1,29 +1,195 @@
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
+ /**
5
+ * Repository for the state.db `proposals` table. Extracted verbatim from
6
+ * core/state-db.ts — queries and row-mapping unchanged, only relocated behind
7
+ * the repository boundary. Re-exported by core/state-db.ts so existing importers
8
+ * resolve.
9
+ *
10
+ * @module proposals-repository
11
+ */
12
+ import path from "node:path";
13
+ import { stashDirFor } from "../../core/asset/asset-placement.js";
14
+ import { bundleRefToString, isBundleSlug, parseBundleRef } from "../../core/asset/asset-ref.js";
15
+ /** Serialize `Proposal.changes` for `metadata_json` (see {@link StoredFileChange}). */
16
+ function changesToStored(changes) {
17
+ return changes.map((c, i) => ({
18
+ path: c.path,
19
+ op: c.op,
20
+ ...(i > 0 && c.after !== undefined ? { after: c.after } : {}),
21
+ }));
22
+ }
23
+ /**
24
+ * Reconstruct `Proposal.changes` from `metadata_json.changes` + the `content`
25
+ * column.
26
+ */
27
+ function storedToChanges(stored, content) {
28
+ if (!Array.isArray(stored) || stored.length === 0) {
29
+ throw new Error("Proposal metadata is missing changes.");
30
+ }
31
+ return stored.map((value, i) => {
32
+ if (typeof value !== "object" || value === null)
33
+ throw new Error("Proposal metadata has invalid changes.");
34
+ const c = value;
35
+ if (typeof c.path !== "string" ||
36
+ (c.op !== "create" && c.op !== "update" && c.op !== "delete") ||
37
+ (c.after !== undefined && typeof c.after !== "string") ||
38
+ (c.op === "delete" && c.after !== undefined) ||
39
+ (i > 0 && c.op !== "delete" && typeof c.after !== "string")) {
40
+ throw new Error("Proposal metadata has invalid changes.");
41
+ }
42
+ return {
43
+ path: c.path,
44
+ op: c.op,
45
+ ...(i === 0 ? (c.op === "delete" ? {} : { after: content }) : c.after !== undefined ? { after: c.after } : {}),
46
+ };
47
+ });
48
+ }
49
+ function currentProposalRef(ref, requireQualified = false) {
50
+ let parsed;
51
+ try {
52
+ parsed = parseBundleRef(ref);
53
+ }
54
+ catch (error) {
55
+ throw new Error(`Proposal row has an invalid current ref: ${ref}`, { cause: error });
56
+ }
57
+ const colon = parsed.conceptId.indexOf(":");
58
+ if (colon > 0 && stashDirFor(parsed.conceptId.slice(0, colon)) !== undefined) {
59
+ throw new Error(`Proposal row has an invalid current ref: ${ref}`);
60
+ }
61
+ if (parsed.fragment !== undefined)
62
+ throw new Error(`Proposal row ref contains a fragment: ${ref}`);
63
+ if (requireQualified && parsed.bundle === undefined)
64
+ throw new Error(`Proposal ref is not bundle-qualified: ${ref}`);
65
+ const canonical = bundleRefToString(parsed);
66
+ if (canonical !== ref)
67
+ throw new Error(`Proposal row ref is not canonical: ${ref}`);
68
+ return canonical;
69
+ }
70
+ function currentProposalTarget(value) {
71
+ if (typeof value !== "object" || value === null)
72
+ throw new Error("Proposal metadata is missing proposedTarget.");
73
+ const target = value;
74
+ if (typeof target.source !== "string" ||
75
+ !isBundleSlug(target.source) ||
76
+ typeof target.root !== "string" ||
77
+ !path.isAbsolute(target.root)) {
78
+ throw new Error("Proposal metadata has an invalid proposedTarget.");
79
+ }
80
+ return { source: target.source, root: path.resolve(target.root) };
81
+ }
82
+ function invalidPresentField(name) {
83
+ throw new Error(`Proposal metadata has an invalid ${name}.`);
84
+ }
85
+ const GATE_OUTCOMES = {
86
+ "auto-accepted": true,
87
+ deferred: true,
88
+ staged: true,
89
+ "auto-rejected": true,
90
+ };
91
+ function validatePresentMetadata(meta) {
92
+ const stringFields = ["sourceRun", "beforeHash", "backupContent"];
93
+ for (const field of stringFields) {
94
+ if (Object.hasOwn(meta, field) && typeof meta[field] !== "string")
95
+ invalidPresentField(field);
96
+ }
97
+ if (Object.hasOwn(meta, "confidence") &&
98
+ (typeof meta.confidence !== "number" ||
99
+ !Number.isFinite(meta.confidence) ||
100
+ meta.confidence < 0 ||
101
+ meta.confidence > 1)) {
102
+ invalidPresentField("confidence");
103
+ }
104
+ if (Object.hasOwn(meta, "review")) {
105
+ const review = meta.review;
106
+ if (typeof review !== "object" ||
107
+ review === null ||
108
+ (review.outcome !== "accepted" && review.outcome !== "rejected") ||
109
+ typeof review.decidedAt !== "string" ||
110
+ (review.reason !== undefined && typeof review.reason !== "string")) {
111
+ invalidPresentField("review");
112
+ }
113
+ }
114
+ if (Object.hasOwn(meta, "gateDecision")) {
115
+ const gate = meta.gateDecision;
116
+ if (typeof gate !== "object" ||
117
+ gate === null ||
118
+ typeof gate.outcome !== "string" ||
119
+ !Object.hasOwn(GATE_OUTCOMES, gate.outcome) ||
120
+ typeof gate.reason !== "string" ||
121
+ typeof gate.decidedAt !== "string" ||
122
+ (gate.measured !== undefined && (typeof gate.measured !== "number" || !Number.isFinite(gate.measured))) ||
123
+ (gate.contentHash !== undefined && typeof gate.contentHash !== "string") ||
124
+ (gate.gate !== undefined && typeof gate.gate !== "string")) {
125
+ invalidPresentField("gateDecision");
126
+ }
127
+ if (gate.thresholds !== undefined) {
128
+ const thresholds = gate.thresholds;
129
+ if (typeof thresholds !== "object" ||
130
+ thresholds === null ||
131
+ [thresholds.maxDiffLines, thresholds.minContentLines].some((value) => value !== undefined && (typeof value !== "number" || !Number.isFinite(value)))) {
132
+ invalidPresentField("gateDecision");
133
+ }
134
+ }
135
+ }
136
+ if (Object.hasOwn(meta, "acceptedTarget")) {
137
+ const target = meta.acceptedTarget;
138
+ if (typeof target !== "object" ||
139
+ target === null ||
140
+ typeof target.source !== "string" ||
141
+ !isBundleSlug(target.source) ||
142
+ typeof target.root !== "string" ||
143
+ !path.isAbsolute(target.root) ||
144
+ typeof target.path !== "string" ||
145
+ !path.isAbsolute(target.path) ||
146
+ typeof target.contentHash !== "string") {
147
+ invalidPresentField("acceptedTarget");
148
+ }
149
+ }
150
+ if (Object.hasOwn(meta, "eligibilitySource") && typeof meta.eligibilitySource !== "string") {
151
+ invalidPresentField("eligibilitySource");
152
+ }
153
+ }
4
154
  /**
5
155
  * Convert a raw `ProposalRow` to the public `Proposal` shape.
6
156
  */
7
157
  export function proposalRowToProposal(row) {
158
+ if (!["pending", "accepted", "rejected", "reverted"].includes(row.status)) {
159
+ throw new Error(`Proposal row has invalid status: ${row.status}`);
160
+ }
8
161
  let frontmatter;
9
- if (row.frontmatter_json) {
162
+ if (row.frontmatter_json !== null) {
10
163
  try {
11
- frontmatter = JSON.parse(row.frontmatter_json);
164
+ const parsed = JSON.parse(row.frontmatter_json);
165
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
166
+ throw new Error("Proposal frontmatter_json must contain an object.");
167
+ }
168
+ frontmatter = parsed;
12
169
  }
13
- catch {
14
- /* ignore corrupt frontmatter JSON */
170
+ catch (error) {
171
+ throw new Error("Proposal row has invalid frontmatter_json.", { cause: error });
15
172
  }
16
173
  }
17
174
  let meta = {};
18
175
  try {
19
- meta = JSON.parse(row.metadata_json);
176
+ const parsed = JSON.parse(row.metadata_json);
177
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
178
+ throw new Error("Proposal metadata_json must contain an object.");
179
+ }
180
+ meta = parsed;
20
181
  }
21
- catch {
22
- /* ignore */
182
+ catch (error) {
183
+ throw new Error("Proposal row has invalid metadata_json.", { cause: error });
23
184
  }
185
+ validatePresentMetadata(meta);
186
+ const changes = Object.hasOwn(meta, "changes")
187
+ ? storedToChanges(meta.changes, row.content)
188
+ : [{ path: "", op: "update", after: row.content }];
189
+ const proposedTarget = Object.hasOwn(meta, "proposedTarget") ? currentProposalTarget(meta.proposedTarget) : undefined;
24
190
  return {
25
191
  id: row.id,
26
- ref: row.ref,
192
+ ref: currentProposalRef(row.ref),
27
193
  status: row.status,
28
194
  source: row.source,
29
195
  ...(typeof meta.sourceRun === "string" ? { sourceRun: meta.sourceRun } : {}),
@@ -33,15 +199,123 @@ export function proposalRowToProposal(row) {
33
199
  content: row.content,
34
200
  ...(frontmatter !== undefined ? { frontmatter } : {}),
35
201
  },
202
+ changes,
203
+ ...(proposedTarget !== undefined ? { proposedTarget } : {}),
204
+ ...(typeof meta.beforeHash === "string" ? { beforeHash: meta.beforeHash } : {}),
36
205
  ...(meta.review !== undefined ? { review: meta.review } : {}),
37
206
  ...(typeof meta.confidence === "number" ? { confidence: meta.confidence } : {}),
38
207
  ...(meta.gateDecision !== undefined ? { gateDecision: meta.gateDecision } : {}),
39
208
  ...(typeof meta.backupContent === "string" ? { backupContent: meta.backupContent } : {}),
209
+ ...(meta.acceptedTarget !== undefined ? { acceptedTarget: meta.acceptedTarget } : {}),
40
210
  ...(typeof meta.eligibilitySource === "string"
41
211
  ? { eligibilitySource: meta.eligibilitySource }
42
212
  : {}),
43
213
  };
44
214
  }
215
+ /**
216
+ * Lenient counterpart to {@link proposalRowToProposal} for the terminal-status
217
+ * (reject/archive) read paths (repository.ts `archiveProposal` /
218
+ * `rejectProposalDurably`). Those paths must succeed even on legacy rows
219
+ * minted before a field was required — e.g. 0.8-era rows missing
220
+ * `proposedTarget` and/or carrying empty/missing `changes[].path` metadata —
221
+ * so an operator can reject them instead of resorting to manual SQL.
222
+ *
223
+ * Per-field decode failures are swallowed: the offending field degrades to a
224
+ * safe placeholder (matching the strict decoder's own "no changes recorded"
225
+ * fallback) and the failure is appended to `decodeWarnings` instead of
226
+ * throwing. `id` / `status` / timestamps / `source` are trusted verbatim (the
227
+ * schema guarantees they're non-null strings). The strict decoder remains the
228
+ * default everywhere else, including every other read of a `pending` or
229
+ * `accepted` proposal (accept/revert must keep failing exactly as today on a
230
+ * malformed row).
231
+ */
232
+ export function proposalRowToProposalLenient(row) {
233
+ const warnings = [];
234
+ let meta = {};
235
+ try {
236
+ const parsed = JSON.parse(row.metadata_json);
237
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
238
+ throw new Error("metadata_json must contain an object.");
239
+ }
240
+ meta = parsed;
241
+ validatePresentMetadata(meta);
242
+ }
243
+ catch (error) {
244
+ warnings.push(`metadata_json is invalid (${error instanceof Error ? error.message : String(error)}); optional fields dropped.`);
245
+ meta = {};
246
+ }
247
+ let frontmatter;
248
+ if (row.frontmatter_json !== null) {
249
+ try {
250
+ const parsed = JSON.parse(row.frontmatter_json);
251
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
252
+ throw new Error("frontmatter_json must contain an object.");
253
+ }
254
+ frontmatter = parsed;
255
+ }
256
+ catch (error) {
257
+ warnings.push(`frontmatter_json is invalid (${error instanceof Error ? error.message : String(error)}); frontmatter dropped.`);
258
+ }
259
+ }
260
+ let ref;
261
+ try {
262
+ ref = currentProposalRef(row.ref);
263
+ }
264
+ catch (error) {
265
+ warnings.push(`ref is invalid (${error instanceof Error ? error.message : String(error)}); keeping the raw stored value.`);
266
+ ref = row.ref;
267
+ }
268
+ let changes;
269
+ try {
270
+ changes = Object.hasOwn(meta, "changes")
271
+ ? storedToChanges(meta.changes, row.content)
272
+ : [{ path: "", op: "update", after: row.content }];
273
+ }
274
+ catch (error) {
275
+ warnings.push(`changes metadata is invalid (${error instanceof Error ? error.message : String(error)}); degraded to a single placeholder change.`);
276
+ changes = [{ path: "", op: "update", after: row.content }];
277
+ }
278
+ let proposedTarget;
279
+ if (Object.hasOwn(meta, "proposedTarget")) {
280
+ try {
281
+ proposedTarget = currentProposalTarget(meta.proposedTarget);
282
+ }
283
+ catch (error) {
284
+ warnings.push(`proposedTarget is invalid (${error instanceof Error ? error.message : String(error)}); omitted.`);
285
+ }
286
+ }
287
+ else {
288
+ warnings.push("proposedTarget is missing (pre-WI-6.2 legacy row).");
289
+ }
290
+ if (!["pending", "accepted", "rejected", "reverted"].includes(row.status)) {
291
+ warnings.push(`status "${row.status}" is not a recognized value.`);
292
+ }
293
+ return {
294
+ id: row.id,
295
+ ref,
296
+ status: row.status,
297
+ source: row.source,
298
+ ...(typeof meta.sourceRun === "string" ? { sourceRun: meta.sourceRun } : {}),
299
+ createdAt: row.created_at,
300
+ updatedAt: row.updated_at,
301
+ payload: {
302
+ content: row.content,
303
+ ...(frontmatter !== undefined ? { frontmatter } : {}),
304
+ },
305
+ changes,
306
+ ...(proposedTarget !== undefined ? { proposedTarget } : {}),
307
+ ...(typeof meta.beforeHash === "string" ? { beforeHash: meta.beforeHash } : {}),
308
+ ...(meta.review !== undefined ? { review: meta.review } : {}),
309
+ ...(typeof meta.confidence === "number" ? { confidence: meta.confidence } : {}),
310
+ ...(meta.gateDecision !== undefined ? { gateDecision: meta.gateDecision } : {}),
311
+ ...(typeof meta.backupContent === "string" ? { backupContent: meta.backupContent } : {}),
312
+ ...(meta.acceptedTarget !== undefined ? { acceptedTarget: meta.acceptedTarget } : {}),
313
+ ...(typeof meta.eligibilitySource === "string"
314
+ ? { eligibilitySource: meta.eligibilitySource }
315
+ : {}),
316
+ ...(warnings.length > 0 ? { decodeWarnings: warnings } : {}),
317
+ };
318
+ }
45
319
  /**
46
320
  * Convert a public `Proposal` to column values ready for an INSERT/UPDATE.
47
321
  * The `stash_dir` comes from the call site (proposals.ts has it in scope).
@@ -49,6 +323,19 @@ export function proposalRowToProposal(row) {
49
323
  export function proposalToRowValues(proposal, stashDir) {
50
324
  // Fields that have no dedicated column live in metadata_json.
51
325
  const metaObj = {};
326
+ if (!Array.isArray(proposal.changes) || proposal.changes.length === 0) {
327
+ throw new Error(`Proposal ${proposal.id} has no file changes.`);
328
+ }
329
+ if (proposal.changes.some((change) => typeof change.path !== "string" ||
330
+ change.path.length === 0 ||
331
+ !["create", "update", "delete"].includes(change.op) ||
332
+ (change.op === "delete" ? change.after !== undefined : typeof change.after !== "string"))) {
333
+ throw new Error(`Proposal ${proposal.id} has invalid file changes.`);
334
+ }
335
+ metaObj.changes = changesToStored(proposal.changes);
336
+ metaObj.proposedTarget = currentProposalTarget(proposal.proposedTarget);
337
+ if (proposal.beforeHash !== undefined)
338
+ metaObj.beforeHash = proposal.beforeHash;
52
339
  if (proposal.sourceRun !== undefined)
53
340
  metaObj.sourceRun = proposal.sourceRun;
54
341
  if (proposal.review !== undefined)
@@ -59,12 +346,15 @@ export function proposalToRowValues(proposal, stashDir) {
59
346
  metaObj.gateDecision = proposal.gateDecision;
60
347
  if (proposal.backupContent !== undefined)
61
348
  metaObj.backupContent = proposal.backupContent;
349
+ if (proposal.acceptedTarget !== undefined)
350
+ metaObj.acceptedTarget = proposal.acceptedTarget;
62
351
  if (proposal.eligibilitySource !== undefined)
63
352
  metaObj.eligibilitySource = proposal.eligibilitySource;
353
+ validatePresentMetadata(metaObj);
64
354
  return {
65
355
  id: proposal.id,
66
356
  stash_dir: stashDir,
67
- ref: proposal.ref,
357
+ ref: currentProposalRef(proposal.ref, true),
68
358
  status: proposal.status,
69
359
  source: proposal.source,
70
360
  created_at: proposal.createdAt,
@@ -123,38 +413,12 @@ export function listStateProposals(db, options = {}) {
123
413
  content, frontmatter_json, metadata_json
124
414
  FROM proposals ${where} ORDER BY created_at ASC, rowid ASC`)
125
415
  .all(...params);
126
- return rows.map(proposalRowToProposal);
127
- }
128
- /**
129
- * Read every proposal's `gateDecision` record across all stashes (#612).
130
- *
131
- * Calibration reads the auto-accept gate's per-proposal decisions regardless of
132
- * the proposal's current lifecycle status — a proposal that was auto-accepted
133
- * is now `accepted`, an auto-rejected one stays `pending`, so filtering by
134
- * status would drop half the join. Rows without a `gateDecision` (created
135
- * before #577, or never gated) are skipped. The result is ordered by
136
- * `decidedAt ASC` for deterministic downstream aggregation, falling back to
137
- * `created_at` ordering from the SQL layer for rows with equal/missing
138
- * timestamps.
139
- */
140
- export function listProposalGateDecisions(db) {
141
- const rows = db.prepare("SELECT metadata_json FROM proposals ORDER BY created_at ASC, rowid ASC").all();
142
- const decisions = [];
143
- for (const row of rows) {
144
- let meta;
145
- try {
146
- meta = JSON.parse(row.metadata_json);
147
- }
148
- catch {
149
- continue;
150
- }
151
- const decision = meta.gateDecision;
152
- if (decision && typeof decision === "object" && typeof decision.outcome === "string") {
153
- decisions.push(decision);
154
- }
155
- }
156
- decisions.sort((a, b) => new Date(a.decidedAt).getTime() - new Date(b.decidedAt).getTime());
157
- return decisions;
416
+ // Archived rows (accepted/rejected/reverted) decode leniently so a
417
+ // terminal-status row that was rejected via the lenient path (or predates
418
+ // a required field) remains listable — a strict throw here would defeat
419
+ // the point of tolerating it at reject/archive time. Pending rows keep the
420
+ // strict decoder; nothing about the live queue changes here.
421
+ return rows.map((row) => (row.status === "pending" ? proposalRowToProposal(row) : proposalRowToProposalLenient(row)));
158
422
  }
159
423
  /**
160
424
  * Look up a single proposal by id, optionally scoped to one stash root.
@@ -167,6 +431,18 @@ export function getStateProposal(db, id, stashDir) {
167
431
  const row = (stashDir ? db.prepare(sql).get(id, stashDir) : db.prepare(sql).get(id));
168
432
  return row ? proposalRowToProposal(row) : undefined;
169
433
  }
434
+ /**
435
+ * Lenient counterpart to {@link getStateProposal} — used ONLY by the
436
+ * terminal-status (reject/archive) read paths in repository.ts that must
437
+ * tolerate a malformed row (see {@link proposalRowToProposalLenient}).
438
+ */
439
+ export function getStateProposalLenient(db, id, stashDir) {
440
+ const sql = `SELECT id, stash_dir, ref, status, source, created_at, updated_at,
441
+ content, frontmatter_json, metadata_json
442
+ FROM proposals WHERE id = ?${stashDir ? " AND stash_dir = ?" : ""}`;
443
+ const row = (stashDir ? db.prepare(sql).get(id, stashDir) : db.prepare(sql).get(id));
444
+ return row ? proposalRowToProposalLenient(row) : undefined;
445
+ }
170
446
  /**
171
447
  * Find PENDING proposal ids in one stash whose id starts with `idPrefix`.
172
448
  * Backs the UUID-prefix form of `akm proposal show/accept/... <prefix>` —
@@ -184,37 +460,3 @@ export function listStateProposalIdsByPrefix(db, stashDir, idPrefix) {
184
460
  .all(stashDir, `${escaped}%`);
185
461
  return rows.map((r) => r.id);
186
462
  }
187
- /**
188
- * Whether the legacy filesystem proposal import has already run for `stashDir`.
189
- * See migration 005 (`proposal_fs_imports`).
190
- */
191
- export function hasImportedFsProposals(db, stashDir) {
192
- // Drivers disagree on the no-row sentinel (bun:sqlite → null,
193
- // better-sqlite3 → undefined) — Boolean() covers both.
194
- return Boolean(db.prepare("SELECT 1 FROM proposal_fs_imports WHERE stash_dir = ?").get(stashDir));
195
- }
196
- /**
197
- * Record that the legacy filesystem proposal import completed for `stashDir`
198
- * so subsequent invocations skip the directory walk. INSERT OR REPLACE keeps
199
- * the call idempotent.
200
- */
201
- export function recordFsProposalsImport(db, stashDir, importedCount) {
202
- db.prepare("INSERT OR REPLACE INTO proposal_fs_imports (stash_dir, imported_at, imported_count) VALUES (?, ?, ?)").run(stashDir, new Date().toISOString(), importedCount);
203
- }
204
- /**
205
- * Insert a proposal row ONLY when the id is not already present (used by the
206
- * legacy filesystem import so re-runs never clobber rows that have since been
207
- * mutated through the canonical store). Returns true when a row was inserted.
208
- */
209
- export function insertProposalIfAbsent(db, proposal, stashDir) {
210
- const v = proposalToRowValues(proposal, stashDir);
211
- const result = db
212
- .prepare(`
213
- INSERT OR IGNORE INTO proposals
214
- (id, stash_dir, ref, status, source, created_at, updated_at, content, frontmatter_json, metadata_json)
215
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
216
- `)
217
- .run(v.id, v.stash_dir, v.ref, v.status, v.source, v.created_at, v.updated_at, v.content, v.frontmatter_json, v.metadata_json);
218
- const changes = result.changes ?? 0;
219
- return Number(changes) > 0;
220
- }
@@ -2,7 +2,7 @@
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
4
  import { rethrowIfTestIsolationError } from "../../core/errors.js";
5
- import { closeDatabase, openIndexDatabase } from "../../indexer/db/db.js";
5
+ import { closeDatabase, openIndexDatabase } from "./index-connection.js";
6
6
  import { getRegistryIndexCache, upsertRegistryIndexCache } from "./registry-index-cache-repository.js";
7
7
  /**
8
8
  * RAII-style lifecycle helper for the registry cache DB. Opens the DB (treating