akm-cli 0.9.0-rc.8 → 0.9.0

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 (450) hide show
  1. package/CHANGELOG.md +1063 -44
  2. package/README.md +51 -25
  3. package/SECURITY.md +14 -1
  4. package/STABILITY.md +497 -0
  5. package/dist/akm +148 -35
  6. package/dist/{akm-migrate-storage → akm-migrate} +6 -9
  7. package/dist/assets/hints/cli-hints-full.md +223 -95
  8. package/dist/assets/hints/cli-hints-short.md +85 -22
  9. package/dist/assets/improve-strategies/default.json +1 -1
  10. package/dist/assets/improve-strategies/reflect-distill.json +1 -1
  11. package/dist/assets/prompts/memory-infer-user.md +2 -3
  12. package/dist/assets/stash-skeleton/README.md +6 -5
  13. package/dist/assets/stash-skeleton/facts/conventions/assets/agent.md +2 -0
  14. package/dist/assets/stash-skeleton/facts/conventions/assets/command.md +2 -0
  15. package/dist/assets/stash-skeleton/facts/conventions/assets/fact.md +2 -0
  16. package/dist/assets/stash-skeleton/facts/conventions/assets/knowledge.md +2 -0
  17. package/dist/assets/stash-skeleton/facts/conventions/assets/lesson.md +2 -0
  18. package/dist/assets/stash-skeleton/facts/conventions/assets/memory.md +2 -0
  19. package/dist/assets/stash-skeleton/facts/conventions/assets/script.md +2 -0
  20. package/dist/assets/stash-skeleton/facts/conventions/assets/skill.md +2 -0
  21. package/dist/assets/stash-skeleton/facts/conventions/assets/workflow.md +2 -0
  22. package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +2 -0
  23. package/dist/assets/stash-skeleton/facts/conventions/domains.md +2 -0
  24. package/dist/assets/stash-skeleton/facts/conventions/organization.md +20 -9
  25. package/dist/assets/tasks/core/extract.yml +1 -1
  26. package/dist/assets/tasks/core/version-check.yml +1 -1
  27. package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +5 -0
  28. package/dist/assets/tasks/improve/akm-improve-catchup.yml +8 -0
  29. package/dist/assets/tasks/improve/akm-improve-consolidate.yml +5 -0
  30. package/dist/assets/tasks/improve/akm-improve-frequent.yml +5 -0
  31. package/dist/assets/tasks/improve/akm-improve-nightly.yml +5 -0
  32. package/dist/assets/templates/html/health.html +1 -3
  33. package/dist/assets/workflows/workflow-template.md +32 -15
  34. package/dist/cli/invocation.js +40 -15
  35. package/dist/cli/parse-args.js +0 -22
  36. package/dist/cli/retired-commands.js +121 -0
  37. package/dist/cli/shared.js +154 -22
  38. package/dist/cli/unknown-flags.js +236 -0
  39. package/dist/cli-node.mjs +2 -1
  40. package/dist/cli.js +696 -258
  41. package/dist/commands/agent/agent-dispatch.js +14 -3
  42. package/dist/commands/agent/contribute-cli.js +73 -88
  43. package/dist/commands/completions.js +79 -22
  44. package/dist/commands/config-cli.js +17 -150
  45. package/dist/commands/env/env-cli.js +59 -143
  46. package/dist/commands/env/env.js +12 -163
  47. package/dist/commands/env/marker-path.js +6 -0
  48. package/dist/commands/env/secret-cli.js +36 -66
  49. package/dist/commands/env/secret.js +24 -57
  50. package/dist/commands/feedback-cli.js +141 -87
  51. package/dist/commands/health/accept-rate.js +58 -0
  52. package/dist/commands/health/advisories.js +3 -4
  53. package/dist/commands/health/checks.js +85 -23
  54. package/dist/commands/health/html-report.js +7 -10
  55. package/dist/commands/health/improve-metrics.js +25 -83
  56. package/dist/commands/health/md-report.js +5 -9
  57. package/dist/commands/health/metrics.js +62 -20
  58. package/dist/commands/health/renderers.js +47 -0
  59. package/dist/commands/health/report-view-model.js +4 -5
  60. package/dist/commands/health/stash-exposure.js +1 -1
  61. package/dist/commands/health/surfaces.js +3 -48
  62. package/dist/commands/health/task-runs.js +3 -67
  63. package/dist/commands/health/types-improve.js +7 -0
  64. package/dist/commands/health.js +99 -28
  65. package/dist/commands/improve/anti-collapse.js +2 -2
  66. package/dist/commands/improve/autonomy-gate.js +68 -0
  67. package/dist/commands/improve/collapse-detector.js +41 -40
  68. package/dist/commands/improve/consolidate/eligibility.js +1 -23
  69. package/dist/commands/improve/consolidate/merge.js +4 -0
  70. package/dist/commands/improve/consolidate.js +140 -1000
  71. package/dist/commands/improve/distill/promote-memory.js +12 -12
  72. package/dist/commands/improve/distill/quality-gate.js +6 -6
  73. package/dist/commands/improve/distill.js +58 -69
  74. package/dist/commands/improve/eligibility.js +105 -57
  75. package/dist/commands/improve/extract-cli.js +14 -133
  76. package/dist/commands/improve/improve-cli.js +98 -114
  77. package/dist/commands/improve/improve-result-file.js +1 -28
  78. package/dist/commands/improve/improve-strategies.js +8 -5
  79. package/dist/commands/improve/improve.js +128 -91
  80. package/dist/commands/improve/loop-stages.js +182 -20
  81. package/dist/commands/improve/memory/derived-ref.js +45 -43
  82. package/dist/commands/improve/memory/memory-belief.js +1 -1
  83. package/dist/commands/improve/memory/memory-contradiction-detect.js +4 -12
  84. package/dist/commands/improve/memory/memory-improve.js +6 -5
  85. package/dist/commands/improve/outcome-loop.js +22 -65
  86. package/dist/commands/improve/preparation.js +114 -123
  87. package/dist/commands/improve/proactive-maintenance.js +2 -5
  88. package/dist/commands/improve/reflect.js +56 -160
  89. package/dist/commands/improve/salience.js +11 -122
  90. package/dist/commands/improve/source-identity.js +10 -38
  91. package/dist/commands/lint/base-linter.js +20 -124
  92. package/dist/commands/lint/env-key-rules.js +31 -47
  93. package/dist/commands/lint/index.js +249 -43
  94. package/dist/commands/{events.js → log.js} +33 -38
  95. package/dist/commands/migrate-cli.js +92 -12
  96. package/dist/commands/migration-tool.js +46 -0
  97. package/dist/commands/observability-cli.js +70 -209
  98. package/dist/commands/proposal/drain.js +101 -29
  99. package/dist/commands/proposal/proposal-cli.js +76 -48
  100. package/dist/commands/proposal/proposal.js +54 -18
  101. package/dist/commands/proposal/propose-cli.js +88 -0
  102. package/dist/commands/proposal/propose.js +23 -15
  103. package/dist/commands/proposal/repository.js +701 -278
  104. package/dist/commands/proposal/validators/proposal-quality-validators.js +2 -8
  105. package/dist/commands/proposal/validators/proposal-validators.js +55 -7
  106. package/dist/commands/proposal/validators/proposals.js +4 -7
  107. package/dist/commands/read/curate.js +34 -53
  108. package/dist/commands/read/knowledge.js +150 -95
  109. package/dist/commands/read/registry-search.js +2 -2
  110. package/dist/commands/read/remember-cli.js +42 -15
  111. package/dist/commands/read/search-cli.js +180 -78
  112. package/dist/commands/read/search.js +58 -43
  113. package/dist/commands/read/show.js +197 -141
  114. package/dist/commands/registry-cli.js +12 -51
  115. package/dist/commands/remember.js +14 -57
  116. package/dist/commands/sources/add-cli.js +100 -31
  117. package/dist/commands/sources/bundle-cli.js +166 -0
  118. package/dist/commands/sources/bundle-config-ops.js +7 -2
  119. package/dist/commands/sources/info.js +18 -5
  120. package/dist/commands/sources/init.js +12 -12
  121. package/dist/commands/sources/installed-stashes.js +382 -98
  122. package/dist/commands/sources/schema-repair.js +3 -2
  123. package/dist/commands/sources/self-update.js +131 -38
  124. package/dist/commands/sources/source-add.js +72 -17
  125. package/dist/commands/sources/source-clone.js +129 -45
  126. package/dist/commands/sources/source-manage.js +43 -23
  127. package/dist/commands/sources/sources-cli.js +57 -208
  128. package/dist/commands/sources/stash-cli.js +46 -53
  129. package/dist/commands/tasks/tasks-cli.js +91 -97
  130. package/dist/commands/tasks/tasks.js +276 -421
  131. package/dist/commands/workflow-cli.js +175 -450
  132. package/dist/core/adapter/adapters/akm-adapter.js +47 -28
  133. package/dist/core/adapter/adapters/akm-lint.js +42 -27
  134. package/dist/core/adapter/adapters/akm-metadata.js +15 -44
  135. package/dist/core/adapter/adapters/akm-task-adapter.js +15 -13
  136. package/dist/core/adapter/adapters/akm-workflow-adapter.js +55 -71
  137. package/dist/core/adapter/adapters/dotenv-adapter.js +1 -1
  138. package/dist/core/adapter/adapters/generic-files-adapter.js +2 -0
  139. package/dist/core/adapter/adapters/index.js +6 -6
  140. package/dist/core/adapter/adapters/llm-wiki-adapter.js +14 -8
  141. package/dist/core/adapter/adapters/okf-adapter.js +187 -19
  142. package/dist/core/adapter/adapters/shared.js +3 -19
  143. package/dist/core/adapter/adapters/tool-dir-shared.js +8 -3
  144. package/dist/core/adapter/adapters/website-snapshot-adapter.js +1 -0
  145. package/dist/core/adapter/detect-adapter.js +17 -0
  146. package/dist/core/adapter/recognize-match.js +6 -4
  147. package/dist/core/adapter/validate-context.js +214 -0
  148. package/dist/core/asset/akm-markdown.js +63 -0
  149. package/dist/core/asset/asset-placement.js +20 -6
  150. package/dist/core/asset/asset-ref.js +11 -9
  151. package/dist/core/asset/frontmatter-lint.js +30 -0
  152. package/dist/core/asset/frontmatter.js +37 -9
  153. package/dist/core/asset/markdown.js +40 -51
  154. package/dist/core/asset/resolve-ref.js +89 -18
  155. package/dist/core/asset/stash-meta.js +1 -1
  156. package/dist/core/bundle-id.js +51 -0
  157. package/dist/core/common.js +152 -38
  158. package/dist/core/config/config-io.js +12 -1
  159. package/dist/core/config/config-schema.js +35 -8
  160. package/dist/core/config/config-sources.js +55 -11
  161. package/dist/core/config/config-walker.js +25 -9
  162. package/dist/core/config/config.js +9 -48
  163. package/dist/core/config/experimental.js +21 -0
  164. package/dist/core/config/schema/embedding.js +5 -1
  165. package/dist/core/config/schema/experimental.js +30 -0
  166. package/dist/core/config/schema/improve-processes.js +0 -6
  167. package/dist/core/config/schema/improve.js +21 -3
  168. package/dist/core/config/schema/index-config.js +8 -15
  169. package/dist/core/config/schema/output.js +4 -1
  170. package/dist/core/config/schema/setup.js +9 -18
  171. package/dist/core/config/schema/sources-bundles.js +49 -33
  172. package/dist/core/config/schema/workflow.js +3 -3
  173. package/dist/core/env-secret-ref.js +76 -46
  174. package/dist/core/errors.js +18 -12
  175. package/dist/core/events.js +46 -128
  176. package/dist/core/file-change.js +6 -5
  177. package/dist/core/fs-txn.js +83 -7
  178. package/dist/core/git-message.js +2 -2
  179. package/dist/core/improve-result.js +1 -100
  180. package/dist/core/lesson-lint.js +1 -17
  181. package/dist/core/logs-db.js +2 -1
  182. package/dist/core/migration-operation.js +16 -0
  183. package/dist/core/mutation-target.js +78 -0
  184. package/dist/core/parse.js +4 -1
  185. package/dist/core/paths.js +17 -20
  186. package/dist/core/recognition-util.js +12 -14
  187. package/dist/core/redaction.js +34 -0
  188. package/dist/core/standards/resolve-standards-context.js +2 -14
  189. package/dist/core/standards/resolve-stash-standards.js +2 -2
  190. package/dist/core/standards/resolve-type-conventions.js +2 -2
  191. package/dist/core/state/migrations.js +41 -18
  192. package/dist/core/state-db.js +5 -14
  193. package/dist/core/structured.js +1 -1
  194. package/dist/core/subprocess.js +6 -4
  195. package/dist/core/text-truncation.js +9 -5
  196. package/dist/core/type-presentation.js +3 -3
  197. package/dist/core/warn.js +0 -3
  198. package/dist/core/write-source.js +771 -95
  199. package/dist/indexer/bundle-identity-guard.js +3 -2
  200. package/dist/indexer/db/graph-db.js +0 -24
  201. package/dist/indexer/ensure-index.js +1 -0
  202. package/dist/indexer/graph/graph-boost.js +9 -34
  203. package/dist/indexer/graph/graph-extraction.js +8 -5
  204. package/dist/indexer/index-writer-lock.js +53 -17
  205. package/dist/indexer/index-written-assets.js +16 -22
  206. package/dist/indexer/indexer.js +497 -239
  207. package/dist/indexer/installations.js +14 -96
  208. package/dist/indexer/passes/dir-staleness.js +16 -9
  209. package/dist/indexer/passes/memory-inference.js +11 -9
  210. package/dist/indexer/passes/metadata.js +113 -47
  211. package/dist/indexer/scan/doc-to-entry.js +38 -1
  212. package/dist/indexer/scan/drain-dir.js +13 -23
  213. package/dist/indexer/search/db-search.js +99 -54
  214. package/dist/indexer/search/fts-query.js +47 -24
  215. package/dist/indexer/search/ranking-contributors.js +42 -20
  216. package/dist/indexer/search/ranking.js +18 -99
  217. package/dist/indexer/search/search-fields.js +7 -2
  218. package/dist/indexer/search/search-source.js +82 -93
  219. package/dist/indexer/usage/usage-events.js +0 -89
  220. package/dist/indexer/walk/file-context.js +2 -1
  221. package/dist/indexer/walk/matchers.js +30 -43
  222. package/dist/indexer/walk/path-resolver.js +7 -2
  223. package/dist/indexer/walk/walker.js +38 -12
  224. package/dist/integrations/agent/builders.js +0 -6
  225. package/dist/integrations/agent/config.js +2 -2
  226. package/dist/integrations/agent/detect.js +49 -19
  227. package/dist/integrations/agent/engine-fallback.js +76 -0
  228. package/dist/integrations/agent/profiles.js +14 -0
  229. package/dist/integrations/agent/prompts.js +12 -8
  230. package/dist/integrations/agent/runner-dispatch.js +4 -2
  231. package/dist/integrations/agent/runner.js +0 -1
  232. package/dist/integrations/agent/spawn.js +5 -6
  233. package/dist/integrations/github.js +1 -1
  234. package/dist/integrations/harnesses/aider/agent-builder.js +6 -4
  235. package/dist/integrations/harnesses/amazonq/agent-builder.js +7 -4
  236. package/dist/integrations/harnesses/claude/session-log.js +0 -10
  237. package/dist/integrations/harnesses/codex/agent-builder.js +5 -2
  238. package/dist/integrations/harnesses/copilot/agent-builder.js +5 -3
  239. package/dist/integrations/harnesses/gemini/agent-builder.js +5 -3
  240. package/dist/integrations/harnesses/index.js +3 -7
  241. package/dist/integrations/harnesses/opencode/agent-builder.js +21 -2
  242. package/dist/integrations/harnesses/opencode/session-log.js +0 -15
  243. package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +13 -4
  244. package/dist/integrations/harnesses/openhands/agent-builder.js +9 -6
  245. package/dist/integrations/harnesses/pi/agent-builder.js +6 -4
  246. package/dist/integrations/lockfile.js +101 -6
  247. package/dist/integrations/session-logs/index.js +3 -28
  248. package/dist/llm/client.js +136 -100
  249. package/dist/llm/embedders/remote.js +13 -5
  250. package/dist/llm/feature-gate.js +4 -12
  251. package/dist/llm/graph-extract.js +5 -11
  252. package/dist/llm/memory-infer.js +144 -1
  253. package/dist/llm/metadata-enhance.js +5 -7
  254. package/dist/llm/structured-call.js +1 -1
  255. package/dist/llm/usage-persist.js +26 -5
  256. package/dist/llm/usage-telemetry.js +25 -2
  257. package/dist/output/cli-hints.js +1 -2
  258. package/dist/output/context.js +22 -7
  259. package/dist/output/format-exempt.js +80 -0
  260. package/dist/output/generic-render.js +259 -0
  261. package/dist/output/render-registry.js +57 -0
  262. package/dist/output/renderers.js +14 -36
  263. package/dist/output/shapes/curate.js +10 -1
  264. package/dist/output/shapes/events.js +12 -7
  265. package/dist/output/shapes/helpers.js +56 -83
  266. package/dist/output/shapes/migrate.js +8 -0
  267. package/dist/output/shapes/passthrough.js +7 -41
  268. package/dist/output/shapes/proposal/producer.js +15 -7
  269. package/dist/output/shapes.js +2 -9
  270. package/dist/output/text/{init.js → bundle-create.js} +3 -1
  271. package/dist/output/text/bundle-show.js +7 -0
  272. package/dist/output/text/command-format.js +164 -96
  273. package/dist/output/text/env.js +1 -3
  274. package/dist/output/text/events.js +8 -7
  275. package/dist/output/text/health-format.js +103 -0
  276. package/dist/output/text/health.js +7 -0
  277. package/dist/output/text/helpers.js +10 -8
  278. package/dist/output/text/lint-format.js +43 -0
  279. package/dist/output/text/{save.js → lint.js} +2 -2
  280. package/dist/output/text/migrate.js +88 -0
  281. package/dist/output/text/proposal/producer.js +4 -2
  282. package/dist/output/text/proposal-format.js +44 -72
  283. package/dist/output/text/registry-commands.js +1 -2
  284. package/dist/output/text/show-directives.js +15 -7
  285. package/dist/output/text/status-list.js +32 -0
  286. package/dist/output/text/sync.js +5 -0
  287. package/dist/output/text/workflow-format.js +24 -203
  288. package/dist/output/text/workflow.js +1 -7
  289. package/dist/output/text.js +16 -17
  290. package/dist/registry/factory.js +4 -6
  291. package/dist/registry/origin-resolve.js +16 -27
  292. package/dist/registry/providers/skills-sh.js +3 -3
  293. package/dist/registry/providers/static-index.js +13 -23
  294. package/dist/registry/resolve.js +42 -7
  295. package/dist/registry/semver.js +34 -84
  296. package/dist/runtime.js +2 -23
  297. package/dist/scripts/akm-migrate-node.js +60290 -0
  298. package/dist/scripts/akm-migrate.js +59628 -0
  299. package/dist/setup/detect.js +42 -15
  300. package/dist/setup/registry-stash-loader.js +2 -2
  301. package/dist/setup/setup.js +236 -136
  302. package/dist/setup/steps/connection.js +7 -9
  303. package/dist/setup/steps/platforms.js +9 -9
  304. package/dist/setup/steps/semantic.js +15 -3
  305. package/dist/setup/steps/sources.js +12 -13
  306. package/dist/setup/steps/stashdir.js +2 -3
  307. package/dist/setup/steps/tasks.js +237 -120
  308. package/dist/sources/freshness.js +1 -1
  309. package/dist/sources/provider-factory.js +11 -17
  310. package/dist/sources/providers/filesystem.js +2 -3
  311. package/dist/sources/providers/git-install.js +278 -34
  312. package/dist/sources/providers/git-provider.js +25 -23
  313. package/dist/sources/providers/git-stash.js +395 -106
  314. package/dist/sources/providers/git.js +2 -2
  315. package/dist/sources/providers/npm.js +16 -19
  316. package/dist/sources/providers/provider-utils.js +7 -4
  317. package/dist/sources/providers/sync-from-ref.js +3 -9
  318. package/dist/sources/providers/website.js +6 -1
  319. package/dist/sources/resolve.js +6 -5
  320. package/dist/sources/snapshot-fetchers/bluesky.js +146 -0
  321. package/dist/sources/snapshot-fetchers/content-extract.js +566 -0
  322. package/dist/sources/snapshot-fetchers/fetcher-util.js +41 -0
  323. package/dist/sources/snapshot-fetchers/github.js +100 -0
  324. package/dist/sources/snapshot-fetchers/host-guard.js +291 -0
  325. package/dist/sources/snapshot-fetchers/registry.js +17 -1
  326. package/dist/sources/snapshot-fetchers/robots.js +348 -0
  327. package/dist/sources/snapshot-fetchers/rss.js +282 -0
  328. package/dist/sources/snapshot-fetchers/secret-seam.js +42 -0
  329. package/dist/sources/snapshot-fetchers/website-ingest.js +566 -268
  330. package/dist/sources/snapshot-fetchers/x.js +910 -0
  331. package/dist/storage/database.js +7 -0
  332. package/dist/storage/engines/sqlite-migrations.js +23 -111
  333. package/dist/storage/managed-db.js +2 -2
  334. package/dist/storage/repositories/canaries-repository.js +1 -1
  335. package/dist/storage/repositories/events-repository.js +27 -11
  336. package/dist/storage/repositories/improve-runs-repository.js +6 -12
  337. package/dist/storage/repositories/index-connection.js +17 -6
  338. package/dist/storage/repositories/index-entries-repository.js +151 -240
  339. package/dist/storage/repositories/index-entry-mapper.js +15 -11
  340. package/dist/storage/repositories/index-fts-repository.js +5 -2
  341. package/dist/storage/repositories/index-llm-cache-repository.js +0 -1
  342. package/dist/storage/repositories/index-meta-repository.js +2 -3
  343. package/dist/storage/repositories/index-schema.js +10 -25
  344. package/dist/storage/repositories/index-utility-repository.js +15 -28
  345. package/dist/storage/repositories/index-vec-repository.js +6 -1
  346. package/dist/storage/repositories/outcome-repository.js +119 -0
  347. package/dist/storage/repositories/proposals-repository.js +296 -59
  348. package/dist/storage/repositories/registry-cache.js +19 -0
  349. package/dist/storage/repositories/salience-repository.js +172 -0
  350. package/dist/storage/repositories/task-history-repository.js +15 -13
  351. package/dist/storage/repositories/workflow-runs-repository.js +52 -40
  352. package/dist/tasks/backends/cron.js +105 -15
  353. package/dist/tasks/backends/index.js +1 -1
  354. package/dist/tasks/backends/launchd.js +85 -38
  355. package/dist/tasks/backends/schtasks.js +135 -15
  356. package/dist/tasks/embedded.js +56 -40
  357. package/dist/tasks/parser.js +7 -157
  358. package/dist/tasks/resolve-akm-bin.js +137 -59
  359. package/dist/tasks/runner.js +79 -42
  360. package/dist/tasks/scheduler-invocation.js +220 -10
  361. package/dist/tasks/schema.js +24 -1
  362. package/dist/tasks/task-id.js +1 -3
  363. package/dist/tasks/validator.js +20 -6
  364. package/dist/workflows/authoring/authoring.js +94 -143
  365. package/dist/workflows/authoring/scope-key.js +1 -1
  366. package/dist/workflows/exec/frozen-judge.js +28 -2
  367. package/dist/workflows/exec/native-executor.js +77 -57
  368. package/dist/workflows/exec/param-secrets.js +9 -9
  369. package/dist/workflows/exec/run-workflow.js +133 -79
  370. package/dist/workflows/exec/step-work.js +219 -346
  371. package/dist/{migrate-storage-node.mjs → workflows/exec/unit-dispatch.js} +1 -5
  372. package/dist/workflows/ir/compile.js +141 -270
  373. package/dist/workflows/ir/freeze.js +40 -30
  374. package/dist/workflows/ir/params.js +135 -11
  375. package/dist/workflows/ir/plan-hash.js +1 -1
  376. package/dist/workflows/ir/schema.js +25 -26
  377. package/dist/workflows/parser.js +872 -307
  378. package/dist/workflows/program/expressions.js +20 -208
  379. package/dist/workflows/program/schema.js +7 -10
  380. package/dist/workflows/renderer.js +95 -68
  381. package/dist/workflows/resource-limits.js +2 -0
  382. package/dist/workflows/runtime/checkin.js +3 -3
  383. package/dist/workflows/runtime/plan-classifier.js +16 -75
  384. package/dist/workflows/runtime/runs.js +186 -127
  385. package/dist/workflows/runtime/unit-checkin.js +1 -1
  386. package/dist/workflows/runtime/unit-phases.js +2 -2
  387. package/dist/workflows/runtime/workflow-asset-loader.js +232 -83
  388. package/dist/workflows/schema.js +1 -11
  389. package/dist/workflows/validate-summary.js +30 -36
  390. package/dist/workflows/validator.js +21 -62
  391. package/docs/README.md +68 -0
  392. package/docs/migration/README.md +8 -0
  393. package/docs/migration/release-notes/0.7.0.md +11 -11
  394. package/docs/migration/release-notes/0.9.0.md +208 -27
  395. package/docs/migration/v0.7-to-v0.8.md +46 -47
  396. package/docs/migration/v0.8-to-v0.9.md +564 -208
  397. package/docs/migration/v0.9.0-troubleshooting.md +561 -0
  398. package/docs/reference/README.md +12 -0
  399. package/docs/reference/cli.md +2253 -0
  400. package/docs/reference/configuration.md +358 -0
  401. package/docs/reference/data-and-telemetry.md +105 -42
  402. package/docs/reference/workflows.md +647 -0
  403. package/package.json +22 -11
  404. package/schemas/akm-asset-envelope.json +93 -0
  405. package/schemas/akm-config.json +81 -128
  406. package/schemas/akm-workflow.json +74 -73
  407. package/dist/assets/tasks/core/backup.yml +0 -5
  408. package/dist/assets/tasks/graph-refresh-weekly.yml +0 -10
  409. package/dist/cli/config-migrate.js +0 -1806
  410. package/dist/cli/config-validate.js +0 -41
  411. package/dist/commands/backup-cli.js +0 -56
  412. package/dist/commands/bundle/bundle-cli.js +0 -68
  413. package/dist/commands/bundle/bundle.js +0 -219
  414. package/dist/commands/graph/graph-cli.js +0 -124
  415. package/dist/commands/graph/graph.js +0 -489
  416. package/dist/commands/improve/extract-watch.js +0 -140
  417. package/dist/commands/mv-cli.js +0 -1221
  418. package/dist/commands/sources/history.js +0 -201
  419. package/dist/commands/tasks/default-tasks.js +0 -186
  420. package/dist/core/migration-backup.js +0 -1234
  421. package/dist/indexer/usage/unmigrated-vaults-guard.js +0 -95
  422. package/dist/llm/memory-infer-impl.js +0 -138
  423. package/dist/migrate/legacy/config-source-migration.js +0 -223
  424. package/dist/migrate/legacy/content-migration.js +0 -305
  425. package/dist/migrate/legacy/legacy-layout.js +0 -779
  426. package/dist/migrate/legacy/legacy-paths.js +0 -25
  427. package/dist/migrate/legacy/legacy-stash-json.js +0 -72
  428. package/dist/migrate/legacy/proposal-fs-import.js +0 -168
  429. package/dist/migrate/legacy/task-target-ref-migration.js +0 -272
  430. package/dist/migrate/legacy/three-db-cutover.js +0 -841
  431. package/dist/migrate/legacy/workflow-migrations-bodies.js +0 -52
  432. package/dist/migrate/legacy/workflow-migrations-frozen.js +0 -21
  433. package/dist/migrate/legacy-ref-grammar.js +0 -214
  434. package/dist/output/shapes/distill.js +0 -14
  435. package/dist/output/shapes/history.js +0 -11
  436. package/dist/output/text/distill.js +0 -6
  437. package/dist/output/text/enable-disable.js +0 -8
  438. package/dist/output/text/history.js +0 -6
  439. package/dist/registry/build-index.js +0 -382
  440. package/dist/schemas/akm-config.json +0 -4704
  441. package/dist/schemas/akm-task.json +0 -87
  442. package/dist/schemas/akm-workflow.json +0 -372
  443. package/dist/scripts/migrate-storage.js +0 -3816
  444. package/dist/workflows/authoring/workflow-program-template.yaml +0 -31
  445. package/dist/workflows/cli.js +0 -53
  446. package/dist/workflows/exec/brief.js +0 -481
  447. package/dist/workflows/exec/report.js +0 -1460
  448. package/dist/workflows/exec/watch.js +0 -116
  449. package/dist/workflows/program/parser.js +0 -813
  450. package/dist/workflows/program/project.js +0 -104
@@ -1,56 +1,28 @@
1
1
  // This Source Code Form is subject to the terms of the Mozilla Public
2
2
  // License, v. 2.0. If a copy of the MPL was not distributed with this
3
3
  // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
- import path from "node:path";
5
- import { primaryBundlePath } from "../../core/config/config.js";
6
- // ── Durable improve-state keys (Chunk-8 WI-8.5c — collapsed to the item_ref) ──
4
+ // ── Durable improve-state keys ───────────────────────────────────────────────
7
5
  //
8
- // Every improve ref is now the new grammar (a SHORT conceptId), and the durable
6
+ // Every improve ref uses the current grammar (a short conceptId), and the durable
9
7
  // state key is the resolved index entry's `item_ref` when the planner supplied
10
8
  // one, else the conceptId `ref` itself (`preparation.ts`
11
- // `salienceWriteKey`/`outcomeWriteKey` = `itemRef ?? ref`). The pre-flip
12
- // source-qualified / legacy-bare dual-key machinery (and its dependency on the
13
- // retired dual-grammar stored-ref parser) is gone.
9
+ // `salienceWriteKey`/`outcomeWriteKey` = `itemRef ?? ref`).
14
10
  /**
15
11
  * The durable improve-state key for a ref with no resolved `item_ref` — the
16
- * conceptId `ref` itself. (`sourceName` is retained for call-site compatibility;
17
- * the pre-flip source-qualification it drove is gone.)
12
+ * conceptId `ref` itself.
18
13
  */
19
- export function durableImproveRef(ref, _sourceName) {
14
+ export function durableImproveRef(ref) {
20
15
  return ref;
21
16
  }
22
- /** The conceptId for a stored key: strip a `bundle//` prefix if present. */
17
+ /** Return the conceptId portion of a durable improve-state key. */
23
18
  export function bareImproveRef(ref) {
24
19
  const boundary = ref.indexOf("//");
25
20
  return boundary >= 0 ? ref.slice(boundary + 2) : ref;
26
21
  }
27
22
  /**
28
- * The durable read key-set for improve state, collapsed onto the write key
29
- * (`preparation.ts` `salienceWriteKey`/`outcomeWriteKey` = `itemRef ?? ref`).
30
- * Because that write key is the `item_ref` for a provenance-bearing entry but
31
- * the bare conceptId `ref` for a provenance-absent one, an asset's durable rows
32
- * can carry EITHER spelling across runs — so the reader probes both, item_ref
33
- * first, deduped. The `sourceName`/`includeLegacyBare` parameters are retained
34
- * for call-site compatibility but no longer widen the set (the retired
35
- * source-qualified / legacy-bare arms).
23
+ * The single durable improve-state key used by both readers and writers.
24
+ * Indexed entries use item_ref; direct or provenance-free refs use conceptId.
36
25
  */
37
- export function improveStateReadRefs(ref, _sourceName, _includeLegacyBare = false, itemRef) {
38
- return itemRef !== undefined && itemRef !== ref ? [itemRef, ref] : [ref];
39
- }
40
- /**
41
- * Bare improve state predates source-qualified refs and belongs only to the
42
- * historical local stash. Named sources at any other root must never inherit it.
43
- */
44
- export function shouldReadLegacyBareImproveState(sourceName, sourcePath, config) {
45
- if (!sourceName || !sourcePath)
46
- return false;
47
- // 0.9.0 (spec §10.1 / Decision C): the historical local stash is the primary
48
- // bundle (`defaultBundle`). A named source at any other root must never
49
- // inherit the pre-source-qualified bare improve state. This defaultBundle-path
50
- // equivalence preserves the pre-cutover behavior for a migrated workspace,
51
- // whose `stashDir` became the defaultBundle's filesystem `path`.
52
- const primaryPath = primaryBundlePath(config);
53
- if (!primaryPath)
54
- return false;
55
- return path.resolve(sourcePath) === path.resolve(primaryPath);
26
+ export function improveStateReadRefs(ref, itemRef) {
27
+ return [itemRef ?? ref];
56
28
  }
@@ -10,7 +10,7 @@
10
10
  // `<type>:<slug>` -> on-disk-asset question and MUST agree on the set of
11
11
  // reachable refs for any given stash layout.
12
12
  //
13
- // The lock is enforced by `tests/contracts/ref-resolver-contract.test.ts`,
13
+ // The lock is enforced by `tests/integration/contracts/ref-resolver-contract.test.ts`,
14
14
  // which drives this implementation through a canonical fixture set. The
15
15
  // akm-plugins repo ships an equivalent test that drives its copy through the
16
16
  // SAME inputs and asserts identical outcomes. Any change to the resolver
@@ -19,50 +19,28 @@
19
19
  //
20
20
  // Cases the contract covers (see fixture in the contract test):
21
21
  // - existing memory / knowledge / agent / workflow / skill refs
22
- // - knowledge subdirectory layout (knowledge/<category>/<slug>.md)
22
+ // - namespaced knowledge paths (knowledge/<category>/<slug>.md)
23
23
  // - skill multi-file layout (skills/<slug>/SKILL.md)
24
- // - memory `.derived.md` sibling
25
24
  // - namespaced slugs containing `/`
26
25
  // - env (`env/.env`, `env/<name>.env`) and secret (`secrets/<name>`) refs
27
26
  // - non-existent refs
28
- // - script type (unresolvable by design — both must return false)
27
+ // - script paths with explicit extensions
29
28
  //
30
29
  // As of 0.9 the path mapping in `refToRelPath` is DERIVED FROM THE PLACEMENT
31
30
  // SPECS (`assetPathForName` in `src/core/asset/asset-placement.ts`) rather than
32
31
  // hand-encoded, so it can no longer drift from the placement layer. `env`/
33
- // `secret` refs are path-resolved. `script` stays unresolvable and `task`
34
- // keeps its legacy `.md` resolution (see refToRelPath for both).
32
+ // `secret`, `script`, and `task` refs are path-resolved.
35
33
  // ----------------------------------------------------------------------------
36
34
  import fs from "node:fs";
37
35
  import path from "node:path";
38
36
  import { assetPathForName, stashDirFor } from "../../core/asset/asset-placement.js";
39
37
  import { BUNDLE_REF_RE } from "../../core/asset/asset-ref.js";
38
+ import { spliceFrontmatterLine } from "../../core/asset/frontmatter.js";
39
+ import { checkUnquotedDescriptionColon } from "../../core/asset/frontmatter-lint.js";
40
40
  import { typeNameFromConceptId } from "../../core/asset/resolve-ref.js";
41
+ import { localDateStamp } from "../../core/common.js";
41
42
  import { findFenceRegions } from "./markdown-insertion.js";
42
43
  // ── Helpers ───────────────────────────────────────────────────────────────────
43
- function formatDate(d) {
44
- const y = d.getFullYear();
45
- const m = String(d.getMonth() + 1).padStart(2, "0");
46
- const day = String(d.getDate()).padStart(2, "0");
47
- return `${y}-${m}-${day}`;
48
- }
49
- function checkUnquotedColon(frontmatterText) {
50
- if (!frontmatterText)
51
- return null;
52
- for (const line of frontmatterText.split(/\r?\n/)) {
53
- const match = line.match(/^description:\s*(.*)/);
54
- if (!match)
55
- continue;
56
- const value = match[1].trim();
57
- if ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'"))) {
58
- return null;
59
- }
60
- if (value.includes(":")) {
61
- return `description value contains unquoted colon: ${value}`;
62
- }
63
- }
64
- return null;
65
- }
66
44
  function fixUnquotedColon(raw) {
67
45
  const lines = raw.split(/\r?\n/);
68
46
  if (lines[0]?.trim() !== "---")
@@ -88,15 +66,7 @@ function checkMissingUpdated(data, frontmatterText) {
88
66
  return frontmatterText !== null && !("updated" in data);
89
67
  }
90
68
  function fixMissingUpdated(raw, mtime) {
91
- const dateStr = formatDate(mtime);
92
- const lines = raw.split(/\r?\n/);
93
- if (lines[0]?.trim() !== "---")
94
- return raw;
95
- const closeIdx = lines.findIndex((l, i) => i > 0 && l.trim() === "---");
96
- if (closeIdx === -1)
97
- return raw;
98
- lines.splice(closeIdx, 0, `updated: ${dateStr}`);
99
- return lines.join("\n");
69
+ return spliceFrontmatterLine(raw, `updated: ${localDateStamp(mtime)}`) ?? raw;
100
70
  }
101
71
  // ── stale-path helpers ────────────────────────────────────────────────────────
102
72
  function checkStalePath(body) {
@@ -129,50 +99,17 @@ function stripFencedBlocks(body) {
129
99
  return lines.join("\n");
130
100
  }
131
101
  // ── missing-ref helpers ───────────────────────────────────────────────────────
132
- /**
133
- * Body-ref boundary grammar, shared with `akm mv`'s ref-rewrite pattern —
134
- * `src/commands/mv-cli.ts` imports these constants so the two grammars cannot
135
- * drift. Any character-class change here retargets both the lint missing-ref
136
- * scan and mv's inbound-xref rewriting.
137
- *
138
- * `REF_BOUNDARY_PREFIX_CLASS_SRC` is the character class a ref may start
139
- * after (a ref also matches at line start): whitespace, backtick, quote,
140
- * `(`, `[`, or `,` — the `[` admits markdown-link-style refs like
141
- * `see [memory:foo]`, which the legacy class silently skipped, and the `,`
142
- * admits the ref AFTER a bare comma in a no-space flow list like
143
- * `xrefs: [memory:a,memory:b]` (valid YAML). `,` is already a slug
144
- * TERMINATOR (excluded from `REF_SLUG_CHAR_CLASS_SRC`), so `a,b` splits
145
- * cleanly and adding it here cannot extend any existing match; false
146
- * positives are fenced by the type alternation — a comma only starts a match
147
- * when a literal `<type>:` follows it.
148
- *
149
- * `REF_SLUG_CHAR_CLASS_SRC` is the character class a ref's `<type>:<slug>`
150
- * token is made of; the first excluded character ends the ref.
151
- */
152
- export const REF_BOUNDARY_PREFIX_CLASS_SRC = "[\\s`\"'(,\\[]";
153
- export const REF_SLUG_CHAR_CLASS_SRC = "[^\\s\"'`)\\]>,\\n]";
154
102
  /**
155
103
  * Map from ref type to relative path pattern within stashRoot. Returns null to
156
104
  * skip (type is unresolvable by the slug walker).
157
105
  *
158
106
  * Path layout is owned by the placement layer: we resolve through
159
107
  * `assetPathForName(type, stashDirFor(type), name)` so the linter and the
160
- * rest of the CLI agree on where an asset lives. Two legacy carve-outs are
161
- * preserved to keep pre-0.9 behaviour byte-identical:
162
- * - `script`: returns null (scripts live in nested dirs with arbitrary
163
- * extensions — unresolvable by the slug-based walker, as the contract pins).
164
- * - `task`: M1 fix — tasks are stored as `<id>.yml` on disk, so resolve
165
- * `task:` refs against `tasks/<id>.yml` to match actual on-disk layout.
108
+ * rest of the CLI agree on where an asset lives.
166
109
  *
167
110
  * Exported for contract testing — see header CONTRACT block.
168
111
  */
169
112
  export function refToRelPath(refType, refName) {
170
- // script is intentionally unresolvable (contract-pinned).
171
- if (refType === "script")
172
- return null;
173
- // M1: tasks are stored as .yml on disk; resolve task: refs against tasks/<id>.yml.
174
- if (refType === "task")
175
- return path.join(stashDirFor("task") ?? "tasks", `${refName}.yml`);
176
113
  const typeDir = stashDirFor(refType);
177
114
  if (!typeDir)
178
115
  return null; // unknown type — skip
@@ -208,56 +145,16 @@ export function refExistsInAnyStash(relPath, refType, refName, stashRoots) {
208
145
  * (the contract pins `refToRelPath` + `refExistsInAnyStash`; this is the
209
146
  * shared internal both build on).
210
147
  */
211
- export function resolveRefPathInStash(relPath, refType, refName, root) {
148
+ export function resolveRefPathInStash(relPath, _refType, _refName, root) {
212
149
  const absPath = path.join(root, relPath);
213
150
  if (fs.existsSync(absPath))
214
151
  return absPath;
215
- // Multi-file skill layout: directory containing SKILL.md
216
- const bareDir = absPath.replace(/\.md$/, "");
217
- if (fs.existsSync(bareDir) && fs.existsSync(path.join(bareDir, "SKILL.md"))) {
218
- return path.join(bareDir, "SKILL.md");
219
- }
220
- // .derived.md variant for memory refs
221
- if (refType === "memory") {
222
- const derivedPath = path.join(root, "memories", `${refName}.derived.md`);
223
- if (fs.existsSync(derivedPath))
224
- return derivedPath;
225
- }
226
- // Knowledge-specific: search subdirectories like knowledge/projects/, knowledge/tools/, etc.
227
- if (refType === "knowledge") {
228
- try {
229
- const knowledgeDir = path.join(root, "knowledge");
230
- if (fs.existsSync(knowledgeDir) && fs.statSync(knowledgeDir).isDirectory()) {
231
- const entries = fs.readdirSync(knowledgeDir, { withFileTypes: true });
232
- for (const entry of entries) {
233
- if (!entry.isDirectory())
234
- continue;
235
- const subPath = path.join(knowledgeDir, entry.name, `${refName}.md`);
236
- if (fs.existsSync(subPath))
237
- return subPath;
238
- }
239
- }
240
- }
241
- catch {
242
- // Ignore errors reading directory
243
- }
244
- }
245
- // Fallback: the refName may already encode the full stash-relative path
246
- // (e.g. knowledge:skills/foo/references/bar where the file lives at
247
- // <stash>/skills/foo/references/bar.md, not <stash>/knowledge/skills/...).
248
- const directPath = path.join(root, `${refName}.md`);
249
- if (fs.existsSync(directPath))
250
- return directPath;
251
- const directDir = path.join(root, refName);
252
- if (fs.existsSync(directDir) && fs.existsSync(path.join(directDir, "SKILL.md"))) {
253
- return path.join(directDir, "SKILL.md");
254
- }
255
152
  return null;
256
153
  }
257
154
  /**
258
155
  * A `(refType, refName)` pair that is not a lint-checkable local asset ref —
259
- * shared skip-guard for BOTH recognition arms (legacy `type:name` and the 0.9.0
260
- * `bundle//conceptId` grammar). Filters the false-positive patterns:
156
+ * shared skip-guard for recognized `bundle//conceptId` refs. Filters the
157
+ * false-positive patterns:
261
158
  * - Shell variables: memory:$(cmd) or knowledge:${VAR} (guarded by callers on
262
159
  * the raw token, before it is split).
263
160
  * - Empty names or names that look like absolute paths / home dirs / URLs.
@@ -322,10 +219,10 @@ function scanBundleRefs(scanBody, allRoots) {
322
219
  */
323
220
  function classifyConceptRef(rawConceptId, allRoots) {
324
221
  const conceptId = rawConceptId.split("#", 1)[0];
325
- const legacy = typeNameFromConceptId(conceptId);
326
- if (legacy === undefined)
222
+ const parts = typeNameFromConceptId(conceptId);
223
+ if (parts === undefined)
327
224
  return null; // foreign type / not a local asset ref
328
- return localRefMissingRelPath(legacy.type, legacy.name, allRoots);
225
+ return localRefMissingRelPath(parts.type, parts.name, allRoots);
329
226
  }
330
227
  /**
331
228
  * Returns an array of {ref, resolvedRelPath} for every local AKM ref in the
@@ -401,9 +298,8 @@ function dedupeMissing(rows) {
401
298
  * would otherwise dangle them silently.
402
299
  *
403
300
  * `sources:` is deliberately excluded (non-wiki `sources:` was rejected as a
404
- * typed channel; wiki `sources:` is checked by lintWiki). `source_refs:` /
405
- * `evidenceSources:` are excluded too — they legitimately point at
406
- * merged-away or pruned assets (historical provenance).
301
+ * typed channel; wiki `sources:` is checked by lintWiki). `evidenceSources:` is
302
+ * excluded because it can point at merged-away or pruned assets.
407
303
  */
408
304
  const XREF_FRONTMATTER_KEYS = ["xrefs", "supersededBy", "contradictedBy"];
409
305
  /**
@@ -568,7 +464,7 @@ export function runBaseChecks(ctx) {
568
464
  const shouldRun = (issueType) => !lintSkip.includes(issueType);
569
465
  // ── 1. unquoted-colon ──────────────────────────────────────────────────
570
466
  if (shouldRun("unquoted-colon")) {
571
- const unquotedColonDetail = checkUnquotedColon(ctx.frontmatter);
467
+ const unquotedColonDetail = checkUnquotedDescriptionColon(ctx.frontmatter);
572
468
  if (unquotedColonDetail) {
573
469
  if (ctx.fix) {
574
470
  currentRaw = fixUnquotedColon(currentRaw);
@@ -605,7 +501,7 @@ export function runBaseChecks(ctx) {
605
501
  issues.push({
606
502
  file: ctx.relPath,
607
503
  issue: "missing-updated",
608
- detail: `stamped updated: ${formatDate(mtime)}`,
504
+ detail: `stamped updated: ${localDateStamp(mtime)}`,
609
505
  fixed: true,
610
506
  });
611
507
  }
@@ -632,7 +528,7 @@ export function runBaseChecks(ctx) {
632
528
  for (const candidate of [...staleInBody, ...staleInFrontmatter]) {
633
529
  // M4: Suggest portable replacement when path is under stashRoot.
634
530
  const portableHint = candidate.startsWith(ctx.stashRoot)
635
- ? ` (portable form: $AKM_STASH_DIR${candidate.slice(ctx.stashRoot.length)})`
531
+ ? ` (portable form: $AKM_BUNDLE_DIR${candidate.slice(ctx.stashRoot.length)})`
636
532
  : "";
637
533
  issues.push({
638
534
  file: ctx.relPath,
@@ -2,32 +2,32 @@
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
  /**
5
- * Vault security lint rules — flags known-dangerous environment variable names.
5
+ * Environment security lint rules — flags known-dangerous variable names.
6
6
  *
7
- * These env var names, when present as vault keys, indicate the vault can be
7
+ * These env var names, when present in an environment file, indicate the file can be
8
8
  * used to hijack process execution via loader injection, path override, or
9
9
  * shell/runtime startup hooks. The lint pass emits a warning-level finding;
10
- * it does NOT block vault load or `akm vault setKey`.
10
+ * it does NOT block local environment edits.
11
11
  *
12
12
  * Enforcement scope:
13
- * - `akm lint` reports findings as `dangerous-vault-key` (non-blocking warn).
14
- * - `akm add` BLOCKS install unless `--allow-insecure` is set (or, on TTY,
13
+ * - `akm lint` reports findings as `dangerous-env-key` (non-blocking warn).
14
+ * - `akm bundle add` BLOCKS install unless `--allow-insecure` is set (or, on TTY,
15
15
  * the user explicitly confirms at the prompt).
16
- * - `akm vault setKey` does NOT consult this list — by design, the operator
17
- * owns their own vault and may legitimately store any key locally. The
18
- * gate exists only for third-party stash installation.
16
+ * - Local env writes do NOT consult this list — by design, the operator may
17
+ * legitimately store any key locally. The gate exists only for third-party
18
+ * stash installation.
19
19
  *
20
20
  * False-positive tradeoff:
21
21
  * A handful of keys (EDITOR, VISUAL, PAGER) are included because they are
22
22
  * invoked by many interactive tools and are a documented RCE vector when
23
- * sourced from untrusted vaults. They will also flag on benign vaults
23
+ * sourced from untrusted environments. They will also flag on benign files
24
24
  * where the operator legitimately wants to set their editor — accept the
25
25
  * FP and bypass with `--allow-insecure` after review.
26
26
  */
27
27
  import fs from "node:fs";
28
28
  import { listKeys } from "../env/env.js";
29
29
  // ── Dangerous key set ─────────────────────────────────────────────────────────
30
- export const DANGEROUS_VAULT_KEYS = new Set([
30
+ export const DANGEROUS_ENV_KEYS = new Set([
31
31
  // Dynamic linker hijacking (Linux glibc ld.so)
32
32
  "LD_PRELOAD", // forces shared library injection
33
33
  "LD_LIBRARY_PATH", // overrides library search path
@@ -89,7 +89,7 @@ export const DANGEROUS_VAULT_KEYS = new Set([
89
89
  * prefixed with `BASH_FUNC_`. Listing every concrete name is impossible; we
90
90
  * test against this pattern set in addition to the literal `Set`.
91
91
  */
92
- export const DANGEROUS_VAULT_KEY_PATTERNS = [
92
+ export const DANGEROUS_ENV_KEY_PATTERNS = [
93
93
  {
94
94
  // CVE-2014-6271 (Shellshock) — bash imports exported functions named
95
95
  // `BASH_FUNC_<name>%%` and parses their bodies, enabling RCE.
@@ -103,13 +103,13 @@ export const DANGEROUS_VAULT_KEY_PATTERNS = [
103
103
  ];
104
104
  /**
105
105
  * Returns `true` if the given key name is dangerous — either by literal match
106
- * against `DANGEROUS_VAULT_KEYS` or by matching any entry in
107
- * `DANGEROUS_VAULT_KEY_PATTERNS`.
106
+ * against `DANGEROUS_ENV_KEYS` or by matching any entry in
107
+ * `DANGEROUS_ENV_KEY_PATTERNS`.
108
108
  */
109
- export function isDangerousVaultKey(key) {
110
- if (DANGEROUS_VAULT_KEYS.has(key))
109
+ export function isDangerousEnvKey(key) {
110
+ if (DANGEROUS_ENV_KEYS.has(key))
111
111
  return true;
112
- for (const { pattern } of DANGEROUS_VAULT_KEY_PATTERNS) {
112
+ for (const { pattern } of DANGEROUS_ENV_KEY_PATTERNS) {
113
113
  if (pattern.test(key))
114
114
  return true;
115
115
  }
@@ -117,27 +117,26 @@ export function isDangerousVaultKey(key) {
117
117
  }
118
118
  // ── Checker ───────────────────────────────────────────────────────────────────
119
119
  /**
120
- * Inspect a vault `.env` file and return a lint finding for every key whose
121
- * name appears in `DANGEROUS_VAULT_KEYS` or matches a pattern in
122
- * `DANGEROUS_VAULT_KEY_PATTERNS`.
120
+ * Inspect an `.env` file and return a lint finding for every key whose name
121
+ * appears in `DANGEROUS_ENV_KEYS` or matches `DANGEROUS_ENV_KEY_PATTERNS`.
123
122
  *
124
- * @param vaultPath Absolute path to the `.env` file.
123
+ * @param envPath Absolute path to the `.env` file.
125
124
  * @param relPath Stash-relative path used as the `file` field in findings
126
- * (e.g. `"vaults/prod.env"`).
127
- * @param vaultRef Human-readable vault ref (e.g. `"vault:prod"`) shown in
125
+ * (e.g. `"env/prod.env"`).
126
+ * @param envRef Human-readable env ref (e.g. `"env/prod"`) shown in
128
127
  * the finding message.
129
128
  */
130
129
  /** Suppression comment token checked case-insensitively on the preceding non-empty line. */
131
- const SUPPRESSION_COMMENT = "# akm-lint-ok: dangerous-vault-key";
130
+ const SUPPRESSION_COMMENT = "# akm-lint-ok: dangerous-env-key";
132
131
  /**
133
- * Returns the set of keys suppressed by an inline `# akm-lint-ok: dangerous-vault-key`
132
+ * Returns the set of keys suppressed by an inline `# akm-lint-ok: dangerous-env-key`
134
133
  * comment on the line immediately preceding the key assignment in the `.env` file.
135
134
  */
136
- function collectSuppressedKeys(vaultPath) {
135
+ function collectSuppressedKeys(envPath) {
137
136
  const suppressed = new Set();
138
137
  let raw;
139
138
  try {
140
- raw = fs.readFileSync(vaultPath, "utf8");
139
+ raw = fs.readFileSync(envPath, "utf8");
141
140
  }
142
141
  catch {
143
142
  return suppressed;
@@ -156,36 +155,21 @@ function collectSuppressedKeys(vaultPath) {
156
155
  }
157
156
  return suppressed;
158
157
  }
159
- export function checkVaultForDangerousKeys(vaultPath, relPath, vaultRef) {
160
- const { keys } = listKeys(vaultPath);
161
- const suppressed = collectSuppressedKeys(vaultPath);
158
+ export function checkEnvForDangerousKeys(envPath, relPath, envRef) {
159
+ const { keys } = listKeys(envPath);
160
+ const suppressed = collectSuppressedKeys(envPath);
162
161
  const issues = [];
163
162
  for (const key of keys) {
164
- if (!isDangerousVaultKey(key))
163
+ if (!isDangerousEnvKey(key))
165
164
  continue;
166
165
  if (suppressed.has(key))
167
166
  continue;
168
167
  issues.push({
169
168
  file: relPath,
170
- issue: "dangerous-vault-key",
171
- detail: `Env key \`${key}\` can be used to hijack process execution when injected via \`akm env run\`. Ref: ${vaultRef}. Review this file before running \`akm env run\` commands against untrusted stashes. (suppress with: ${SUPPRESSION_COMMENT} on previous line)`,
169
+ issue: "dangerous-env-key",
170
+ detail: `Env key \`${key}\` can be used to hijack process execution when injected via \`akm env run\`. Ref: ${envRef}. Review this file before running \`akm env run\` commands against untrusted stashes. (suppress with: ${SUPPRESSION_COMMENT} on previous line)`,
172
171
  fixed: false,
173
172
  });
174
173
  }
175
174
  return issues;
176
175
  }
177
- // ── Env-neutral aliases ───────────────────────────────────────────────────────
178
- //
179
- // These primitives guard *environment variable injection*, which is shared by
180
- // the `env` asset type, whole-file `secret` injection, and the `akm add`
181
- // supply-chain gate. The original `*Vault*` names are retained above for
182
- // backward compatibility (and stable lint output) through the 0.8.x
183
- // deprecation window; new call sites should prefer the env-neutral names.
184
- /** Env-neutral alias of {@link DANGEROUS_VAULT_KEYS}. */
185
- export const DANGEROUS_ENV_KEYS = DANGEROUS_VAULT_KEYS;
186
- /** Env-neutral alias of {@link DANGEROUS_VAULT_KEY_PATTERNS}. */
187
- export const DANGEROUS_ENV_KEY_PATTERNS = DANGEROUS_VAULT_KEY_PATTERNS;
188
- /** Env-neutral alias of {@link isDangerousVaultKey}. */
189
- export const isDangerousEnvKey = isDangerousVaultKey;
190
- /** Env-neutral alias of {@link checkVaultForDangerousKeys}. */
191
- export const checkEnvForDangerousKeys = checkVaultForDangerousKeys;