@intentius/chant 0.124.46 → 0.124.49

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 (726) hide show
  1. package/dist/__golden__/wave-loop/op-by-apply-after-fails.json +10 -0
  2. package/dist/__golden__/wave-loop/op-by-apply-hold.json +10 -0
  3. package/dist/__golden__/wave-loop/op-by-apply-ignored.json +10 -0
  4. package/dist/__golden__/wave-loop/op-by-apply-pass.json +10 -0
  5. package/dist/__golden__/wave-loop/op-by-apply-skip.json +10 -0
  6. package/dist/__golden__/wave-loop/op-cost-member-clash.json +6 -0
  7. package/dist/__golden__/wave-loop/op-cost-member.json +13 -0
  8. package/dist/__golden__/wave-loop/op-denied-source.json +16 -0
  9. package/dist/__golden__/wave-loop/op-denied.json +16 -0
  10. package/dist/__golden__/wave-loop/op-discover-rest-short.json +6 -0
  11. package/dist/__golden__/wave-loop/op-discover-rest-stops.json +13 -0
  12. package/dist/__golden__/wave-loop/op-discover-rest.json +26 -0
  13. package/dist/__golden__/wave-loop/op-discover-wide.json +26 -0
  14. package/dist/__golden__/wave-loop/op-held-on-again.json +16 -0
  15. package/dist/__golden__/wave-loop/op-held-on-before-apply.json +16 -0
  16. package/dist/__golden__/wave-loop/op-held-on.json +16 -0
  17. package/dist/__golden__/wave-loop/op-hooks-apply-fails.json +13 -0
  18. package/dist/__golden__/wave-loop/op-hooks-fail-after-apply.json +13 -0
  19. package/dist/__golden__/wave-loop/op-hooks-fail-before-apply.json +13 -0
  20. package/dist/__golden__/wave-loop/op-hooks-fail-before-plan.json +13 -0
  21. package/dist/__golden__/wave-loop/op-hooks-held.json +13 -0
  22. package/dist/__golden__/wave-loop/op-hooks-hold-before-apply.json +13 -0
  23. package/dist/__golden__/wave-loop/op-hooks-pass.json +13 -0
  24. package/dist/__golden__/wave-loop/op-hooks-refused-at-base.json +13 -0
  25. package/dist/__golden__/wave-loop/op-hooks-share.json +33 -0
  26. package/dist/__golden__/wave-loop/op-outcome-held.json +10 -0
  27. package/dist/__golden__/wave-loop/op-outcome-replan-approved.json +10 -0
  28. package/dist/__golden__/wave-loop/op-outcome-replan-forever.json +10 -0
  29. package/dist/__golden__/wave-loop/op-outcome-replan.json +10 -0
  30. package/dist/__golden__/wave-loop/op-outcome-stood-down.json +10 -0
  31. package/dist/__golden__/wave-loop/op-outcome-unreadable.json +10 -0
  32. package/dist/__golden__/wave-loop/op-overridden.json +16 -0
  33. package/dist/__golden__/wave-loop/op-per-run.json +20 -0
  34. package/dist/__golden__/wave-loop/op-point.json +13 -0
  35. package/dist/__golden__/wave-loop/op-pr-review.json +10 -0
  36. package/dist/__golden__/wave-loop/op-sealed.json +10 -0
  37. package/dist/__golden__/wave-loop/op-spend-change-only.json +10 -0
  38. package/dist/__golden__/wave-loop/op-spend.json +10 -0
  39. package/dist/__golden__/wave-loop/op-wave-commands.json +55 -0
  40. package/dist/__golden__/wave-loop/op-wide-refused.json +26 -0
  41. package/dist/__golden__/wave-loop/op-wide-waiting.json +29 -0
  42. package/dist/__golden__/wave-loop/op-wide.json +39 -0
  43. package/dist/action-pins.d.ts +61 -0
  44. package/dist/action-pins.d.ts.map +1 -0
  45. package/dist/action-pins.js +77 -0
  46. package/dist/cli/commands/carve.d.ts +3 -0
  47. package/dist/cli/commands/carve.d.ts.map +1 -1
  48. package/dist/cli/commands/carve.js +36 -7
  49. package/dist/cli/commands/import-report.d.ts +26 -0
  50. package/dist/cli/commands/import-report.d.ts.map +1 -0
  51. package/dist/cli/commands/import-report.js +65 -0
  52. package/dist/cli/commands/import.d.ts +11 -1
  53. package/dist/cli/commands/import.d.ts.map +1 -1
  54. package/dist/cli/commands/import.js +22 -3
  55. package/dist/cli/commands/migrate.d.ts +13 -1
  56. package/dist/cli/commands/migrate.d.ts.map +1 -1
  57. package/dist/cli/commands/migrate.js +134 -10
  58. package/dist/cli/handlers/approve.d.ts.map +1 -1
  59. package/dist/cli/handlers/approve.js +41 -14
  60. package/dist/cli/handlers/build.d.ts.map +1 -1
  61. package/dist/cli/handlers/build.js +6 -1
  62. package/dist/cli/handlers/graph-reader.d.ts +26 -0
  63. package/dist/cli/handlers/graph-reader.d.ts.map +1 -0
  64. package/dist/cli/handlers/graph-reader.js +41 -0
  65. package/dist/cli/handlers/graph.d.ts.map +1 -1
  66. package/dist/cli/handlers/graph.js +14 -0
  67. package/dist/cli/handlers/ledger.d.ts +3 -0
  68. package/dist/cli/handlers/ledger.d.ts.map +1 -0
  69. package/dist/cli/handlers/ledger.js +55 -0
  70. package/dist/cli/handlers/migrate.d.ts.map +1 -1
  71. package/dist/cli/handlers/migrate.js +18 -11
  72. package/dist/cli/handlers/misc.d.ts.map +1 -1
  73. package/dist/cli/handlers/misc.js +12 -1
  74. package/dist/cli/handlers/pr-env.js +2 -2
  75. package/dist/cli/handlers/pr.d.ts +15 -1
  76. package/dist/cli/handlers/pr.d.ts.map +1 -1
  77. package/dist/cli/handlers/pr.js +183 -40
  78. package/dist/cli/handlers/query.d.ts +7 -2
  79. package/dist/cli/handlers/query.d.ts.map +1 -1
  80. package/dist/cli/handlers/query.js +16 -4
  81. package/dist/cli/handlers/release.d.ts.map +1 -1
  82. package/dist/cli/handlers/release.js +6 -3
  83. package/dist/cli/handlers/search.d.ts +2 -4
  84. package/dist/cli/handlers/search.d.ts.map +1 -1
  85. package/dist/cli/handlers/search.js +13 -39
  86. package/dist/cli/main.d.ts.map +1 -1
  87. package/dist/cli/main.js +87 -14
  88. package/dist/cli/parse-args.d.ts.map +1 -1
  89. package/dist/cli/parse-args.js +47 -2
  90. package/dist/cli/registry.d.ts +22 -4
  91. package/dist/cli/registry.d.ts.map +1 -1
  92. package/dist/components/builders.d.ts +5 -1
  93. package/dist/components/builders.d.ts.map +1 -1
  94. package/dist/components/builders.js +5 -0
  95. package/dist/components/capability-plugin-loader.d.ts.map +1 -1
  96. package/dist/components/capability-plugin-loader.js +16 -1
  97. package/dist/components/capability-plugin.d.ts +14 -0
  98. package/dist/components/capability-plugin.d.ts.map +1 -1
  99. package/dist/components/pr-hooks.d.ts +21 -1
  100. package/dist/components/pr-hooks.d.ts.map +1 -1
  101. package/dist/components/pr-hooks.js +72 -4
  102. package/dist/components/pr-pipeline.d.ts +45 -10
  103. package/dist/components/pr-pipeline.d.ts.map +1 -1
  104. package/dist/components/pr-pipeline.js +47 -14
  105. package/dist/components/pr-policy.d.ts +36 -0
  106. package/dist/components/pr-policy.d.ts.map +1 -1
  107. package/dist/components/pr-policy.js +36 -0
  108. package/dist/components/pr-run.d.ts +3 -0
  109. package/dist/components/pr-run.d.ts.map +1 -1
  110. package/dist/components/pr-run.js +1 -0
  111. package/dist/components/starter-plugin.d.ts +1 -0
  112. package/dist/components/starter-plugin.d.ts.map +1 -1
  113. package/dist/components/starter-plugin.js +5 -1
  114. package/dist/components/verbs/index.d.ts +2 -0
  115. package/dist/components/verbs/index.d.ts.map +1 -1
  116. package/dist/components/verbs/index.js +2 -0
  117. package/dist/components/verbs/publish-artifact.d.ts +65 -0
  118. package/dist/components/verbs/publish-artifact.d.ts.map +1 -0
  119. package/dist/components/verbs/publish-artifact.js +74 -0
  120. package/dist/components/verbs/publish-image.d.ts +129 -0
  121. package/dist/components/verbs/publish-image.d.ts.map +1 -0
  122. package/dist/components/verbs/publish-image.js +145 -0
  123. package/dist/config-environments.d.ts +20 -0
  124. package/dist/config-environments.d.ts.map +1 -1
  125. package/dist/config-environments.js +12 -0
  126. package/dist/config.d.ts +25 -1
  127. package/dist/config.d.ts.map +1 -1
  128. package/dist/config.js +10 -2
  129. package/dist/gate-decision.d.ts +20 -2
  130. package/dist/gate-decision.d.ts.map +1 -1
  131. package/dist/gate-decision.js +30 -3
  132. package/dist/graph-ir.d.ts +25 -0
  133. package/dist/graph-ir.d.ts.map +1 -1
  134. package/dist/graph-walk.d.ts +66 -0
  135. package/dist/graph-walk.d.ts.map +1 -0
  136. package/dist/graph-walk.js +70 -0
  137. package/dist/import/parser.d.ts +19 -0
  138. package/dist/import/parser.d.ts.map +1 -1
  139. package/dist/lexicon.d.ts +94 -6
  140. package/dist/lexicon.d.ts.map +1 -1
  141. package/dist/lifecycle/gate-ledger.d.ts +11 -0
  142. package/dist/lifecycle/gate-ledger.d.ts.map +1 -1
  143. package/dist/lifecycle/git.d.ts +2 -5
  144. package/dist/lifecycle/git.d.ts.map +1 -1
  145. package/dist/lifecycle/ledger-read.d.ts +65 -0
  146. package/dist/lifecycle/ledger-read.d.ts.map +1 -0
  147. package/dist/lifecycle/ledger-read.js +160 -0
  148. package/dist/lifecycle/release-workstation.d.ts +7 -0
  149. package/dist/lifecycle/release-workstation.d.ts.map +1 -1
  150. package/dist/lifecycle/release-workstation.js +25 -0
  151. package/dist/lifecycle/run-ledger.d.ts +4 -3
  152. package/dist/lifecycle/run-ledger.d.ts.map +1 -1
  153. package/dist/lifecycle/run-ledger.js +1 -0
  154. package/dist/lint/discover.js +3 -1
  155. package/dist/lint/post-synth.d.ts +127 -1
  156. package/dist/lint/post-synth.d.ts.map +1 -1
  157. package/dist/lint/post-synth.js +84 -2
  158. package/dist/lint/rules/op/index.d.ts +1 -0
  159. package/dist/lint/rules/op/index.d.ts.map +1 -1
  160. package/dist/lint/rules/op/index.js +2 -0
  161. package/dist/lint/rules/op/ops019-workspace-op-target.d.ts +32 -0
  162. package/dist/lint/rules/op/ops019-workspace-op-target.d.ts.map +1 -0
  163. package/dist/lint/rules/op/ops019-workspace-op-target.js +63 -0
  164. package/dist/op/activities/activity-contracts.d.ts +9 -6
  165. package/dist/op/activities/activity-contracts.d.ts.map +1 -1
  166. package/dist/op/activities/activity-contracts.js +5 -2
  167. package/dist/op/activities/index.d.ts +2 -2
  168. package/dist/op/activities/index.d.ts.map +1 -1
  169. package/dist/op/activities/index.js +1 -1
  170. package/dist/op/activities/review-agent.d.ts +90 -4
  171. package/dist/op/activities/review-agent.d.ts.map +1 -1
  172. package/dist/op/activities/review-agent.js +217 -19
  173. package/dist/op/activities/work-evidence.d.ts +8 -1
  174. package/dist/op/activities/work-evidence.d.ts.map +1 -1
  175. package/dist/op/activities/work-evidence.js +1 -0
  176. package/dist/op/builders.d.ts +9 -5
  177. package/dist/op/builders.d.ts.map +1 -1
  178. package/dist/op/builders.js +9 -5
  179. package/dist/op/composites/apply-op.d.ts +29 -2
  180. package/dist/op/composites/apply-op.d.ts.map +1 -1
  181. package/dist/op/composites/apply-op.js +20 -1
  182. package/dist/op/gate-approval-base.d.ts +25 -0
  183. package/dist/op/gate-approval-base.d.ts.map +1 -0
  184. package/dist/op/gate-approval-base.js +71 -0
  185. package/dist/op/gate-approval.d.ts +18 -9
  186. package/dist/op/gate-approval.d.ts.map +1 -1
  187. package/dist/op/gate-approval.js +13 -31
  188. package/dist/op/gate-name.d.ts +13 -0
  189. package/dist/op/gate-name.d.ts.map +1 -1
  190. package/dist/op/gate-name.js +14 -1
  191. package/dist/op/gate-quorum.d.ts +100 -3
  192. package/dist/op/gate-quorum.d.ts.map +1 -1
  193. package/dist/op/gate-quorum.js +108 -6
  194. package/dist/op/gate-review.d.ts +9 -0
  195. package/dist/op/gate-review.d.ts.map +1 -1
  196. package/dist/op/gate-review.js +13 -0
  197. package/dist/op/gate.d.ts +47 -5
  198. package/dist/op/gate.d.ts.map +1 -1
  199. package/dist/op/gate.js +25 -4
  200. package/dist/op/index.d.ts +3 -3
  201. package/dist/op/index.d.ts.map +1 -1
  202. package/dist/op/index.js +1 -1
  203. package/dist/op/local-executor.d.ts +45 -3
  204. package/dist/op/local-executor.d.ts.map +1 -1
  205. package/dist/op/local-executor.js +68 -7
  206. package/dist/op/op-waves-run.d.ts +26 -1
  207. package/dist/op/op-waves-run.d.ts.map +1 -1
  208. package/dist/op/op-waves-run.js +259 -13
  209. package/dist/op/op-waves.d.ts +72 -5
  210. package/dist/op/op-waves.d.ts.map +1 -1
  211. package/dist/op/op-waves.js +110 -15
  212. package/dist/op/runtime.d.ts +11 -0
  213. package/dist/op/runtime.d.ts.map +1 -1
  214. package/dist/op/schedule-overdue.d.ts +16 -0
  215. package/dist/op/schedule-overdue.d.ts.map +1 -1
  216. package/dist/op/schedule-overdue.js +36 -0
  217. package/dist/op/stage-hooks.d.ts +9 -2
  218. package/dist/op/stage-hooks.d.ts.map +1 -1
  219. package/dist/op/stage-hooks.js +7 -5
  220. package/dist/op/workspace-run-env.d.ts +22 -0
  221. package/dist/op/workspace-run-env.d.ts.map +1 -0
  222. package/dist/op/workspace-run-env.js +21 -0
  223. package/dist/pr-forge.d.ts +24 -0
  224. package/dist/pr-forge.d.ts.map +1 -1
  225. package/dist/pr-forge.js +47 -0
  226. package/dist/pr-loop.d.ts +10 -0
  227. package/dist/pr-loop.d.ts.map +1 -1
  228. package/dist/pr-loop.js +4 -0
  229. package/dist/pr-migrations.d.ts +62 -0
  230. package/dist/pr-migrations.d.ts.map +1 -0
  231. package/dist/pr-migrations.js +50 -0
  232. package/dist/pr-post.d.ts +42 -0
  233. package/dist/pr-post.d.ts.map +1 -1
  234. package/dist/pr-post.js +68 -2
  235. package/dist/read-filter.d.ts +65 -0
  236. package/dist/read-filter.d.ts.map +1 -0
  237. package/dist/read-filter.js +179 -0
  238. package/dist/run-event.d.ts +1 -1
  239. package/dist/run-event.d.ts.map +1 -1
  240. package/dist/terraform/carve.d.ts +24 -3
  241. package/dist/terraform/carve.d.ts.map +1 -1
  242. package/dist/terraform/carve.js +32 -14
  243. package/dist/terraform/cuts.d.ts +97 -0
  244. package/dist/terraform/cuts.d.ts.map +1 -0
  245. package/dist/terraform/cuts.js +138 -0
  246. package/dist/terraform/folds.d.ts +26 -0
  247. package/dist/terraform/folds.d.ts.map +1 -0
  248. package/dist/terraform/folds.js +38 -0
  249. package/dist/terraform/graph.d.ts.map +1 -1
  250. package/dist/terraform/graph.js +10 -0
  251. package/dist/terraform/reach.d.ts +140 -0
  252. package/dist/terraform/reach.d.ts.map +1 -0
  253. package/dist/terraform/reach.js +170 -0
  254. package/dist/terraform/score.d.ts +14 -0
  255. package/dist/terraform/score.d.ts.map +1 -1
  256. package/dist/terraform/score.js +14 -31
  257. package/dist/terraform/state.d.ts.map +1 -1
  258. package/dist/terraform/state.js +4 -2
  259. package/dist/terraform/types.d.ts +8 -0
  260. package/dist/terraform/types.d.ts.map +1 -1
  261. package/dist/wave-blocked.d.ts +10 -1
  262. package/dist/wave-blocked.d.ts.map +1 -1
  263. package/dist/wave-blocked.js +31 -3
  264. package/dist/wave-runtime.mjs +264 -254
  265. package/dist/workspace/check.schema.json +13 -2
  266. package/dist/workspace/checks/ci-branch.d.ts +44 -0
  267. package/dist/workspace/checks/ci-branch.d.ts.map +1 -0
  268. package/dist/workspace/checks/ci-branch.js +133 -0
  269. package/dist/workspace/checks/gate-approval.d.ts +58 -0
  270. package/dist/workspace/checks/gate-approval.d.ts.map +1 -0
  271. package/dist/workspace/checks/gate-approval.js +103 -0
  272. package/dist/workspace/checks/links.d.ts +3 -0
  273. package/dist/workspace/checks/links.d.ts.map +1 -1
  274. package/dist/workspace/checks/links.js +12 -1
  275. package/dist/workspace/checks/org.d.ts +48 -0
  276. package/dist/workspace/checks/org.d.ts.map +1 -0
  277. package/dist/workspace/checks/org.js +156 -0
  278. package/dist/workspace/checks.d.ts +12 -1
  279. package/dist/workspace/checks.d.ts.map +1 -1
  280. package/dist/workspace/checks.js +63 -7
  281. package/dist/workspace/ci-branches.d.ts +16 -0
  282. package/dist/workspace/ci-branches.d.ts.map +1 -1
  283. package/dist/workspace/ci-branches.js +27 -0
  284. package/dist/workspace/ci-green-cli.js +7 -7
  285. package/dist/workspace/ci-green-workflow.d.ts +1 -1
  286. package/dist/workspace/ci-green-workflow.d.ts.map +1 -1
  287. package/dist/workspace/ci-green-workflow.js +13 -8
  288. package/dist/workspace/ci-green.d.ts +14 -0
  289. package/dist/workspace/ci-green.d.ts.map +1 -1
  290. package/dist/workspace/ci-green.js +44 -11
  291. package/dist/workspace/ci-run.d.ts +9 -1
  292. package/dist/workspace/ci-run.d.ts.map +1 -1
  293. package/dist/workspace/ci-run.js +67 -6
  294. package/dist/workspace/ci-serve.d.ts +9 -0
  295. package/dist/workspace/ci-serve.d.ts.map +1 -1
  296. package/dist/workspace/ci-serve.js +114 -76
  297. package/dist/workspace/compose-graph.d.ts +14 -0
  298. package/dist/workspace/compose-graph.d.ts.map +1 -1
  299. package/dist/workspace/composites.d.ts +4 -1
  300. package/dist/workspace/composites.d.ts.map +1 -1
  301. package/dist/workspace/composites.js +5 -2
  302. package/dist/workspace/composites.schema.json +22 -0
  303. package/dist/workspace/conformance/__writer_fixture__/work/work.schema.json +105 -1
  304. package/dist/workspace/cross-root-lint.d.ts +56 -0
  305. package/dist/workspace/cross-root-lint.d.ts.map +1 -0
  306. package/dist/workspace/cross-root-lint.js +111 -0
  307. package/dist/workspace/dbt-models-reader.d.ts +44 -0
  308. package/dist/workspace/dbt-models-reader.d.ts.map +1 -0
  309. package/dist/workspace/dbt-models-reader.js +356 -0
  310. package/dist/workspace/dbt-project-common.d.ts +40 -0
  311. package/dist/workspace/dbt-project-common.d.ts.map +1 -0
  312. package/dist/workspace/dbt-project-common.js +106 -0
  313. package/dist/workspace/dbt-project-reader.d.ts +4 -3
  314. package/dist/workspace/dbt-project-reader.d.ts.map +1 -1
  315. package/dist/workspace/dbt-project-reader.js +14 -108
  316. package/dist/workspace/decision-rank.d.ts +26 -0
  317. package/dist/workspace/decision-rank.d.ts.map +1 -0
  318. package/dist/workspace/decision-rank.js +16 -0
  319. package/dist/workspace/declaration.d.ts +50 -2
  320. package/dist/workspace/declaration.d.ts.map +1 -1
  321. package/dist/workspace/declaration.js +57 -11
  322. package/dist/workspace/declaration.schema.json +166 -24
  323. package/dist/workspace/environments.d.ts +26 -2
  324. package/dist/workspace/environments.d.ts.map +1 -1
  325. package/dist/workspace/environments.js +26 -2
  326. package/dist/workspace/exit-cli.d.ts +44 -0
  327. package/dist/workspace/exit-cli.d.ts.map +1 -0
  328. package/dist/workspace/exit-cli.js +198 -0
  329. package/dist/workspace/exit.d.ts +159 -0
  330. package/dist/workspace/exit.d.ts.map +1 -0
  331. package/dist/workspace/exit.js +480 -0
  332. package/dist/workspace/exit.schema.json +257 -0
  333. package/dist/workspace/flyway-dir.d.ts +39 -0
  334. package/dist/workspace/flyway-dir.d.ts.map +1 -0
  335. package/dist/workspace/flyway-dir.js +104 -0
  336. package/dist/workspace/flyway-layout.d.ts +96 -0
  337. package/dist/workspace/flyway-layout.d.ts.map +1 -0
  338. package/dist/workspace/flyway-layout.js +308 -0
  339. package/dist/workspace/graph-cache.d.ts +3 -1
  340. package/dist/workspace/graph-cache.d.ts.map +1 -1
  341. package/dist/workspace/graph-cache.js +12 -1
  342. package/dist/workspace/graph-cli.d.ts.map +1 -1
  343. package/dist/workspace/graph-cli.js +26 -8
  344. package/dist/workspace/graph.schema.json +34 -0
  345. package/dist/workspace/import-fetch.d.ts +38 -0
  346. package/dist/workspace/import-fetch.d.ts.map +1 -0
  347. package/dist/workspace/import-fetch.js +99 -0
  348. package/dist/workspace/import-init.d.ts +26 -0
  349. package/dist/workspace/import-init.d.ts.map +1 -0
  350. package/dist/workspace/import-init.js +130 -0
  351. package/dist/workspace/import-source.d.ts +147 -0
  352. package/dist/workspace/import-source.d.ts.map +1 -0
  353. package/dist/workspace/import-source.js +370 -0
  354. package/dist/workspace/init.d.ts +4 -0
  355. package/dist/workspace/init.d.ts.map +1 -1
  356. package/dist/workspace/init.js +70 -3
  357. package/dist/workspace/intent.d.ts +2 -3
  358. package/dist/workspace/intent.d.ts.map +1 -1
  359. package/dist/workspace/intent.js +5 -9
  360. package/dist/workspace/kind-link-readers.d.ts +59 -2
  361. package/dist/workspace/kind-link-readers.d.ts.map +1 -1
  362. package/dist/workspace/kind-link-readers.js +17 -1
  363. package/dist/workspace/kind-readers.d.ts +6 -0
  364. package/dist/workspace/kind-readers.d.ts.map +1 -1
  365. package/dist/workspace/kind-readers.js +18 -0
  366. package/dist/workspace/kinds.d.ts +90 -3
  367. package/dist/workspace/kinds.d.ts.map +1 -1
  368. package/dist/workspace/kinds.js +161 -7
  369. package/dist/workspace/ledger.schema.json +158 -0
  370. package/dist/workspace/lexicon-outputs.d.ts +20 -1
  371. package/dist/workspace/lexicon-outputs.d.ts.map +1 -1
  372. package/dist/workspace/lexicon-outputs.js +102 -10
  373. package/dist/workspace/lineage-check.d.ts +3 -0
  374. package/dist/workspace/lineage-check.d.ts.map +1 -1
  375. package/dist/workspace/lineage-check.js +23 -4
  376. package/dist/workspace/lineage-upgrade.d.ts.map +1 -1
  377. package/dist/workspace/lineage-upgrade.js +13 -4
  378. package/dist/workspace/links.d.ts +8 -1
  379. package/dist/workspace/links.d.ts.map +1 -1
  380. package/dist/workspace/links.js +25 -1
  381. package/dist/workspace/ls.d.ts +8 -0
  382. package/dist/workspace/ls.d.ts.map +1 -1
  383. package/dist/workspace/ls.js +7 -1
  384. package/dist/workspace/ls.schema.json +7 -0
  385. package/dist/workspace/member-commands.d.ts.map +1 -1
  386. package/dist/workspace/member-commands.js +54 -5
  387. package/dist/workspace/migrate-links.d.ts +45 -0
  388. package/dist/workspace/migrate-links.d.ts.map +1 -0
  389. package/dist/workspace/migrate-links.js +100 -0
  390. package/dist/workspace/migration-dirs.d.ts +74 -0
  391. package/dist/workspace/migration-dirs.d.ts.map +1 -0
  392. package/dist/workspace/migration-dirs.js +254 -0
  393. package/dist/workspace/new-migrations.d.ts +47 -0
  394. package/dist/workspace/new-migrations.d.ts.map +1 -0
  395. package/dist/workspace/new-migrations.js +91 -0
  396. package/dist/workspace/pr-report.schema.json +46 -0
  397. package/dist/workspace/promote.d.ts +96 -0
  398. package/dist/workspace/promote.d.ts.map +1 -0
  399. package/dist/workspace/promote.js +263 -0
  400. package/dist/workspace/reason-codes.d.ts +21 -0
  401. package/dist/workspace/reason-codes.d.ts.map +1 -1
  402. package/dist/workspace/reason-codes.js +25 -0
  403. package/dist/workspace/records-cli.d.ts +11 -0
  404. package/dist/workspace/records-cli.d.ts.map +1 -1
  405. package/dist/workspace/records-cli.js +57 -5
  406. package/dist/workspace/records.schema.json +5 -0
  407. package/dist/workspace/release-candidates.d.ts +2 -0
  408. package/dist/workspace/release-candidates.d.ts.map +1 -1
  409. package/dist/workspace/release-candidates.js +5 -2
  410. package/dist/workspace/release-train.d.ts +53 -0
  411. package/dist/workspace/release-train.d.ts.map +1 -0
  412. package/dist/workspace/release-train.js +134 -0
  413. package/dist/workspace/release-workflow.d.ts.map +1 -1
  414. package/dist/workspace/release-workflow.js +4 -3
  415. package/dist/workspace/repo-ref.d.ts +45 -0
  416. package/dist/workspace/repo-ref.d.ts.map +1 -0
  417. package/dist/workspace/repo-ref.js +114 -0
  418. package/dist/workspace/run-event.schema.json +2 -2
  419. package/dist/workspace/runs-cli.d.ts +9 -0
  420. package/dist/workspace/runs-cli.d.ts.map +1 -1
  421. package/dist/workspace/runs-cli.js +48 -3
  422. package/dist/workspace/runs.schema.json +7 -0
  423. package/dist/workspace/search-contract.d.ts +1 -1
  424. package/dist/workspace/search-contract.d.ts.map +1 -1
  425. package/dist/workspace/status-decisions.d.ts +37 -0
  426. package/dist/workspace/status-decisions.d.ts.map +1 -0
  427. package/dist/workspace/status-decisions.js +147 -0
  428. package/dist/workspace/status-gates.d.ts +9 -0
  429. package/dist/workspace/status-gates.d.ts.map +1 -1
  430. package/dist/workspace/status.d.ts +4 -0
  431. package/dist/workspace/status.d.ts.map +1 -1
  432. package/dist/workspace/status.js +14 -2
  433. package/dist/workspace/status.schema.json +6 -0
  434. package/dist/workspace/work-cli.d.ts.map +1 -1
  435. package/dist/workspace/work-cli.js +5 -3
  436. package/dist/workspace/work-evidence-ops.d.ts +83 -0
  437. package/dist/workspace/work-evidence-ops.d.ts.map +1 -0
  438. package/dist/workspace/work-evidence-ops.js +169 -0
  439. package/dist/workspace/work-evidence.d.ts +12 -2
  440. package/dist/workspace/work-evidence.d.ts.map +1 -1
  441. package/dist/workspace/work-evidence.js +21 -3
  442. package/dist/workspace/work-evidence.schema.json +49 -2
  443. package/dist/workspace/workspace-gates.d.ts +110 -0
  444. package/dist/workspace/workspace-gates.d.ts.map +1 -0
  445. package/dist/workspace/workspace-gates.js +140 -0
  446. package/dist/workspace/workspace-kinds.schema.json +108 -10
  447. package/dist/workspace/workspace-ledger.d.ts +76 -0
  448. package/dist/workspace/workspace-ledger.d.ts.map +1 -0
  449. package/dist/workspace/workspace-ledger.js +91 -0
  450. package/dist/workspace/workspace-run.d.ts +112 -0
  451. package/dist/workspace/workspace-run.d.ts.map +1 -0
  452. package/dist/workspace/workspace-run.js +432 -0
  453. package/package.json +1 -1
  454. package/src/__golden__/wave-loop/op-by-apply-after-fails.json +10 -0
  455. package/src/__golden__/wave-loop/op-by-apply-hold.json +10 -0
  456. package/src/__golden__/wave-loop/op-by-apply-ignored.json +10 -0
  457. package/src/__golden__/wave-loop/op-by-apply-pass.json +10 -0
  458. package/src/__golden__/wave-loop/op-by-apply-skip.json +10 -0
  459. package/src/__golden__/wave-loop/op-cost-member-clash.json +6 -0
  460. package/src/__golden__/wave-loop/op-cost-member.json +13 -0
  461. package/src/__golden__/wave-loop/op-denied-source.json +16 -0
  462. package/src/__golden__/wave-loop/op-denied.json +16 -0
  463. package/src/__golden__/wave-loop/op-discover-rest-short.json +6 -0
  464. package/src/__golden__/wave-loop/op-discover-rest-stops.json +13 -0
  465. package/src/__golden__/wave-loop/op-discover-rest.json +26 -0
  466. package/src/__golden__/wave-loop/op-discover-wide.json +26 -0
  467. package/src/__golden__/wave-loop/op-held-on-again.json +16 -0
  468. package/src/__golden__/wave-loop/op-held-on-before-apply.json +16 -0
  469. package/src/__golden__/wave-loop/op-held-on.json +16 -0
  470. package/src/__golden__/wave-loop/op-hooks-apply-fails.json +13 -0
  471. package/src/__golden__/wave-loop/op-hooks-fail-after-apply.json +13 -0
  472. package/src/__golden__/wave-loop/op-hooks-fail-before-apply.json +13 -0
  473. package/src/__golden__/wave-loop/op-hooks-fail-before-plan.json +13 -0
  474. package/src/__golden__/wave-loop/op-hooks-held.json +13 -0
  475. package/src/__golden__/wave-loop/op-hooks-hold-before-apply.json +13 -0
  476. package/src/__golden__/wave-loop/op-hooks-pass.json +13 -0
  477. package/src/__golden__/wave-loop/op-hooks-refused-at-base.json +13 -0
  478. package/src/__golden__/wave-loop/op-hooks-share.json +33 -0
  479. package/src/__golden__/wave-loop/op-outcome-held.json +10 -0
  480. package/src/__golden__/wave-loop/op-outcome-replan-approved.json +10 -0
  481. package/src/__golden__/wave-loop/op-outcome-replan-forever.json +10 -0
  482. package/src/__golden__/wave-loop/op-outcome-replan.json +10 -0
  483. package/src/__golden__/wave-loop/op-outcome-stood-down.json +10 -0
  484. package/src/__golden__/wave-loop/op-outcome-unreadable.json +10 -0
  485. package/src/__golden__/wave-loop/op-overridden.json +16 -0
  486. package/src/__golden__/wave-loop/op-per-run.json +20 -0
  487. package/src/__golden__/wave-loop/op-point.json +13 -0
  488. package/src/__golden__/wave-loop/op-pr-review.json +10 -0
  489. package/src/__golden__/wave-loop/op-sealed.json +10 -0
  490. package/src/__golden__/wave-loop/op-spend-change-only.json +10 -0
  491. package/src/__golden__/wave-loop/op-spend.json +10 -0
  492. package/src/__golden__/wave-loop/op-wave-commands.json +55 -0
  493. package/src/__golden__/wave-loop/op-wide-refused.json +26 -0
  494. package/src/__golden__/wave-loop/op-wide-waiting.json +29 -0
  495. package/src/__golden__/wave-loop/op-wide.json +39 -0
  496. package/src/action-pins.test.ts +78 -0
  497. package/src/action-pins.ts +92 -0
  498. package/src/cli/commands/carve-score-once.test.ts +99 -0
  499. package/src/cli/commands/carve.ts +37 -6
  500. package/src/cli/commands/check-lexicon.test.ts +2 -2
  501. package/src/cli/commands/import-report.ts +71 -0
  502. package/src/cli/commands/import.ts +33 -3
  503. package/src/cli/commands/migrate-dialect.test.ts +145 -0
  504. package/src/cli/commands/migrate.ts +132 -11
  505. package/src/cli/handlers/__snapshots__/build-member.test.ts.snap +4 -4
  506. package/src/cli/handlers/approve.ts +33 -4
  507. package/src/cli/handlers/build.ts +7 -1
  508. package/src/cli/handlers/graph-reader.test.ts +31 -0
  509. package/src/cli/handlers/graph-reader.ts +51 -0
  510. package/src/cli/handlers/graph.ts +14 -0
  511. package/src/cli/handlers/ledger.ts +54 -0
  512. package/src/cli/handlers/migrate.ts +21 -12
  513. package/src/cli/handlers/misc.ts +10 -1
  514. package/src/cli/handlers/pr-env.ts +2 -2
  515. package/src/cli/handlers/pr.ts +176 -37
  516. package/src/cli/handlers/query.ts +16 -4
  517. package/src/cli/handlers/release.ts +6 -3
  518. package/src/cli/handlers/search.ts +13 -34
  519. package/src/cli/main.test.ts +17 -0
  520. package/src/cli/main.ts +87 -14
  521. package/src/cli/parse-args.ts +35 -2
  522. package/src/cli/registry.ts +22 -4
  523. package/src/components/builders.ts +8 -0
  524. package/src/components/capability-plugin-loader.ts +13 -1
  525. package/src/components/capability-plugin.ts +16 -0
  526. package/src/components/pr-env-run-bundle.test.ts +1 -0
  527. package/src/components/pr-hooks.test.ts +73 -5
  528. package/src/components/pr-hooks.ts +95 -5
  529. package/src/components/pr-pipeline.ts +64 -16
  530. package/src/components/pr-policy.test.ts +64 -1
  531. package/src/components/pr-policy.ts +53 -0
  532. package/src/components/pr-run.ts +4 -0
  533. package/src/components/registry.test.ts +1 -1
  534. package/src/components/starter-plugin.ts +6 -0
  535. package/src/components/verbs/index.ts +2 -0
  536. package/src/components/verbs/publish-artifact.test.ts +60 -0
  537. package/src/components/verbs/publish-artifact.ts +122 -0
  538. package/src/components/verbs/publish-image.test.ts +101 -0
  539. package/src/components/verbs/publish-image.ts +265 -0
  540. package/src/config-environments.ts +28 -1
  541. package/src/config.ts +24 -1
  542. package/src/gate-decision-bundle.test.ts +5 -2
  543. package/src/gate-decision-identity.test.ts +20 -0
  544. package/src/gate-decision.ts +46 -3
  545. package/src/graph-ir.ts +27 -0
  546. package/src/graph-walk.test.ts +44 -0
  547. package/src/graph-walk.ts +102 -0
  548. package/src/import/parser.ts +20 -0
  549. package/src/lexicon.ts +98 -6
  550. package/src/lifecycle/gate-ledger.ts +8 -0
  551. package/src/lifecycle/git.ts +2 -2
  552. package/src/lifecycle/ledger-read.test.ts +107 -0
  553. package/src/lifecycle/ledger-read.ts +195 -0
  554. package/src/lifecycle/release-workstation.ts +24 -0
  555. package/src/lifecycle/run-ledger.ts +5 -2
  556. package/src/lint/cross-root.test.ts +122 -0
  557. package/src/lint/discover.ts +3 -1
  558. package/src/lint/post-synth.ts +212 -2
  559. package/src/lint/rules/op/index.ts +2 -0
  560. package/src/lint/rules/op/ops019-workspace-op-target.ts +89 -0
  561. package/src/op/activities/activity-contracts.ts +5 -2
  562. package/src/op/activities/index.ts +2 -2
  563. package/src/op/activities/review-agent.test.ts +221 -4
  564. package/src/op/activities/review-agent.ts +265 -22
  565. package/src/op/activities/work-evidence.ts +9 -1
  566. package/src/op/builders.ts +9 -5
  567. package/src/op/composites/apply-op.test.ts +108 -0
  568. package/src/op/composites/apply-op.ts +37 -2
  569. package/src/op/gate-approval-at-base.test.ts +97 -0
  570. package/src/op/gate-approval-base.ts +72 -0
  571. package/src/op/gate-approval.test.ts +6 -1
  572. package/src/op/gate-approval.ts +22 -27
  573. package/src/op/gate-name.ts +16 -1
  574. package/src/op/gate-quorum-at-base.test.ts +211 -0
  575. package/src/op/gate-quorum.ts +156 -8
  576. package/src/op/gate-review.ts +14 -0
  577. package/src/op/gate.ts +69 -9
  578. package/src/op/index.ts +3 -2
  579. package/src/op/local-executor.ts +91 -11
  580. package/src/op/op-waves-depends-on.test.ts +81 -0
  581. package/src/op/op-waves-hook-targets.test.ts +4 -2
  582. package/src/op/op-waves-quorum-product.test.ts +158 -0
  583. package/src/op/op-waves-run.ts +288 -14
  584. package/src/op/op-waves.ts +143 -14
  585. package/src/op/runtime.ts +8 -0
  586. package/src/op/schedule-overdue.ts +33 -0
  587. package/src/op/stage-hooks.ts +13 -5
  588. package/src/op/workspace-run-env.ts +29 -0
  589. package/src/pr-forge-bundle.test.ts +2 -2
  590. package/src/pr-forge.test.ts +47 -0
  591. package/src/pr-forge.ts +68 -0
  592. package/src/pr-loop-bundle.test.ts +3 -2
  593. package/src/pr-loop.test.ts +52 -0
  594. package/src/pr-loop.ts +12 -0
  595. package/src/pr-migrations.ts +97 -0
  596. package/src/pr-post-open.e2e.test.ts +36 -0
  597. package/src/pr-post.test.ts +102 -3
  598. package/src/pr-post.ts +90 -2
  599. package/src/read-filter.test.ts +54 -0
  600. package/src/read-filter.ts +193 -0
  601. package/src/run-event.ts +1 -1
  602. package/src/stage-hooks-bundle.test.ts +1 -0
  603. package/src/terraform/carve.ts +52 -15
  604. package/src/terraform/cuts.test.ts +173 -0
  605. package/src/terraform/cuts.ts +188 -0
  606. package/src/terraform/folds.ts +44 -0
  607. package/src/terraform/graph.ts +9 -0
  608. package/src/terraform/radius.test.ts +90 -0
  609. package/src/terraform/reach.test.ts +146 -0
  610. package/src/terraform/reach.ts +247 -0
  611. package/src/terraform/score.ts +27 -29
  612. package/src/terraform/state.ts +3 -1
  613. package/src/terraform/types.ts +8 -0
  614. package/src/wave-blocked.ts +28 -3
  615. package/src/wave-loop-golden.test.ts +4 -3
  616. package/src/workspace/__fixtures__/import/spacelift.json +9 -0
  617. package/src/workspace/__fixtures__/import/tfc.json +13 -0
  618. package/src/workspace/behold-kinds.test.ts +2 -1
  619. package/src/workspace/check-contract.test.ts +8 -6
  620. package/src/workspace/check.schema.json +13 -2
  621. package/src/workspace/checks/ci-branch.test.ts +128 -0
  622. package/src/workspace/checks/ci-branch.ts +141 -0
  623. package/src/workspace/checks/gate-approval.test.ts +77 -0
  624. package/src/workspace/checks/gate-approval.ts +121 -0
  625. package/src/workspace/checks/links.ts +12 -1
  626. package/src/workspace/checks/org.ts +169 -0
  627. package/src/workspace/checks.ts +68 -7
  628. package/src/workspace/ci-branches.ts +31 -0
  629. package/src/workspace/ci-green-branches.test.ts +153 -0
  630. package/src/workspace/ci-green-cli.ts +7 -7
  631. package/src/workspace/ci-green-workflow.test.ts +4 -3
  632. package/src/workspace/ci-green-workflow.ts +13 -9
  633. package/src/workspace/ci-green.ts +49 -12
  634. package/src/workspace/ci-run.test.ts +72 -1
  635. package/src/workspace/ci-run.ts +68 -8
  636. package/src/workspace/ci-serve.test.ts +95 -0
  637. package/src/workspace/ci-serve.ts +106 -65
  638. package/src/workspace/component-environments.test.ts +25 -2
  639. package/src/workspace/compose-graph.ts +9 -2
  640. package/src/workspace/composites.schema.json +22 -0
  641. package/src/workspace/composites.test.ts +39 -8
  642. package/src/workspace/composites.ts +6 -2
  643. package/src/workspace/conformance/__writer_fixture__/work/work.schema.json +105 -1
  644. package/src/workspace/cross-root-lint.test.ts +90 -0
  645. package/src/workspace/cross-root-lint.ts +126 -0
  646. package/src/workspace/dbt-kind.test.ts +3 -2
  647. package/src/workspace/dbt-models-reader.ts +362 -0
  648. package/src/workspace/dbt-models.test.ts +248 -0
  649. package/src/workspace/dbt-project-common.ts +113 -0
  650. package/src/workspace/dbt-project-reader.ts +29 -112
  651. package/src/workspace/decision-rank.ts +40 -0
  652. package/src/workspace/declaration.schema.json +166 -24
  653. package/src/workspace/declaration.ts +101 -15
  654. package/src/workspace/environments.ts +40 -4
  655. package/src/workspace/exit-cli.ts +219 -0
  656. package/src/workspace/exit.schema.json +257 -0
  657. package/src/workspace/exit.test.ts +185 -0
  658. package/src/workspace/exit.ts +560 -0
  659. package/src/workspace/flyway-dir.ts +113 -0
  660. package/src/workspace/flyway-layout.ts +337 -0
  661. package/src/workspace/graph-cache.ts +12 -2
  662. package/src/workspace/graph-cli.ts +25 -10
  663. package/src/workspace/graph-contract.test.ts +4 -2
  664. package/src/workspace/graph.schema.json +34 -0
  665. package/src/workspace/identity.test.ts +29 -2
  666. package/src/workspace/import-fetch.ts +151 -0
  667. package/src/workspace/import-init.ts +147 -0
  668. package/src/workspace/import-source.test.ts +183 -0
  669. package/src/workspace/import-source.ts +462 -0
  670. package/src/workspace/init.test.ts +55 -1
  671. package/src/workspace/init.ts +66 -4
  672. package/src/workspace/intent.ts +6 -14
  673. package/src/workspace/kind-link-readers.ts +68 -3
  674. package/src/workspace/kind-readers.test.ts +36 -0
  675. package/src/workspace/kind-readers.ts +18 -1
  676. package/src/workspace/kinds.test.ts +35 -7
  677. package/src/workspace/kinds.ts +212 -11
  678. package/src/workspace/ledger.schema.json +158 -0
  679. package/src/workspace/lexicon-outputs.ts +132 -13
  680. package/src/workspace/lineage-check.ts +30 -7
  681. package/src/workspace/lineage-upgrade.test.ts +20 -0
  682. package/src/workspace/lineage-upgrade.ts +16 -7
  683. package/src/workspace/links.ts +24 -1
  684. package/src/workspace/ls-contract.test.ts +1 -1
  685. package/src/workspace/ls.schema.json +7 -0
  686. package/src/workspace/ls.ts +10 -1
  687. package/src/workspace/member-commands.ts +60 -2
  688. package/src/workspace/member-file-schema.test.ts +124 -0
  689. package/src/workspace/migrate-links.test.ts +99 -0
  690. package/src/workspace/migrate-links.ts +108 -0
  691. package/src/workspace/migration-dirs.test.ts +272 -0
  692. package/src/workspace/migration-dirs.ts +267 -0
  693. package/src/workspace/new-migrations.test.ts +98 -0
  694. package/src/workspace/new-migrations.ts +109 -0
  695. package/src/workspace/org-scope.test.ts +238 -0
  696. package/src/workspace/pr-report.schema.json +46 -0
  697. package/src/workspace/promote.test.ts +114 -0
  698. package/src/workspace/promote.ts +302 -0
  699. package/src/workspace/reason-codes.test.ts +10 -1
  700. package/src/workspace/reason-codes.ts +25 -0
  701. package/src/workspace/records-cli.ts +58 -5
  702. package/src/workspace/records.schema.json +5 -0
  703. package/src/workspace/release-candidates.ts +7 -2
  704. package/src/workspace/release-train.ts +157 -0
  705. package/src/workspace/release-workflow.ts +4 -3
  706. package/src/workspace/repo-ref.ts +113 -0
  707. package/src/workspace/run-event.schema.json +2 -2
  708. package/src/workspace/runs-cli.ts +48 -4
  709. package/src/workspace/runs.schema.json +7 -0
  710. package/src/workspace/status-contract.test.ts +46 -1
  711. package/src/workspace/status-decisions.test.ts +100 -0
  712. package/src/workspace/status-decisions.ts +151 -0
  713. package/src/workspace/status-gates.ts +9 -0
  714. package/src/workspace/status.schema.json +6 -0
  715. package/src/workspace/status.ts +17 -3
  716. package/src/workspace/where-filters.test.ts +39 -0
  717. package/src/workspace/work-cli.ts +5 -3
  718. package/src/workspace/work-evidence-ops.test.ts +176 -0
  719. package/src/workspace/work-evidence-ops.ts +189 -0
  720. package/src/workspace/work-evidence.schema.json +49 -2
  721. package/src/workspace/work-evidence.ts +22 -3
  722. package/src/workspace/workspace-gates.ts +200 -0
  723. package/src/workspace/workspace-kinds.schema.json +108 -10
  724. package/src/workspace/workspace-ledger.ts +130 -0
  725. package/src/workspace/workspace-run.test.ts +322 -0
  726. package/src/workspace/workspace-run.ts +461 -0
@@ -174,9 +174,12 @@ export async function runReleaseCut(ctx: CommandContext): Promise<number> {
174
174
  const { scopeSource } = await import("../../workspace/write-scope");
175
175
  const { releaseRuleFrom } = await import("../../workspace/identity");
176
176
  const source = scopeSource(cwd);
177
- trunk = ws.resolveTrunk(top, source.declaration?.ci?.green?.branch ?? null);
177
+ const greenDecl = source.declaration?.ci?.green ?? null;
178
+ const primary = ws.resolveTrunk(top, greenDecl?.branch ?? null);
179
+ trunk = primary;
178
180
  try {
179
- ws.checkOnTrunk(top, commit, trunk);
181
+ // #4325: a commit of a branch ci.green also judges (one ci.branches routes members to) is cut like trunk's.
182
+ trunk = ws.checkOnGreenBranches(top, commit, primary, (greenDecl?.branches ?? []).slice(1));
180
183
  } catch (err) {
181
184
  // #4168 4.3: a commit of a pushed compose branch is cut too, and the cut records what it carries.
182
185
  if (!(err instanceof ws.WorkstationCheckError) || err.code !== "release-commit-not-on-trunk") throw err;
@@ -552,7 +555,7 @@ export async function runReleaseVerify(ctx: CommandContext): Promise<number> {
552
555
  */
553
556
  export async function runReleaseCandidates(ctx: CommandContext): Promise<number> {
554
557
  const { releaseCandidatesDocument } = await import("../../workspace/release-candidates");
555
- const doc = await releaseCandidatesDocument({ cwd: resolve("."), ...(ctx.args.env ? { env: ctx.args.env } : {}) });
558
+ const doc = await releaseCandidatesDocument({ cwd: resolve("."), ...(ctx.args.env ? { env: ctx.args.env } : {}), ...(ctx.args.branch ? { branch: ctx.args.branch } : {}) });
556
559
  if (ctx.args.json) {
557
560
  console.log(JSON.stringify(doc, null, 2));
558
561
  return "error" in doc ? 1 : 0;
@@ -22,6 +22,7 @@ import { collectBuildRootContributors, loadPlugins, resolveProjectLexicons } fro
22
22
  import { declaredBuildRootContributors, mergeDeclaredBuildRoots, withLexiconEdges } from "./declared-graph";
23
23
  import { parseCountBy, countGroups, countsJson, formatCounts, groupMembers, hasManyTerraformRoots, type CountBy } from "./search-count";
24
24
  import { formatError, formatWarning } from "../format";
25
+ import { adjacencyOf, walkBreadthFirst } from "../../graph-walk";
25
26
  import type { CommandContext } from "../registry";
26
27
  import { SEARCH_CONTRACT_VERSION, SEARCH_OUTPUT_SCHEMA_ID, type SearchErrorCode, type SearchFailure, type SearchHead } from "../../workspace/search-contract";
27
28
 
@@ -1870,13 +1871,7 @@ const adjacency = new WeakMap<GraphIR, { out: Map<string, IREdge[]>; in: Map<str
1870
1871
  function edgeIndex(ir: GraphIR): { out: Map<string, IREdge[]>; in: Map<string, IREdge[]> } {
1871
1872
  let idx = adjacency.get(ir);
1872
1873
  if (!idx) {
1873
- idx = { out: new Map(), in: new Map() };
1874
- for (const e of ir.edges ?? []) {
1875
- if (!idx.out.has(e.from)) idx.out.set(e.from, []);
1876
- idx.out.get(e.from)!.push(e);
1877
- if (!idx.in.has(e.to)) idx.in.set(e.to, []);
1878
- idx.in.get(e.to)!.push(e);
1879
- }
1874
+ idx = adjacencyOf(ir.edges ?? []);
1880
1875
  adjacency.set(ir, idx);
1881
1876
  }
1882
1877
  return idx;
@@ -1894,17 +1889,14 @@ function sameName(a: string | undefined, b: string): boolean {
1894
1889
  * the target leaf (any node when the term has none) at a depth inside the
1895
1890
  * term's range. A plain `->`/`<-` is the range 1..1.
1896
1891
  *
1897
- * Termination on a cycle: a state is (node, depth capped at the range's
1898
- * minimum). Past the minimum, arriving at a node again by a longer walk can
1899
- * reach nothing the first arrival could not, so it is not queued twice. The
1900
- * state space is finite and the walk always ends.
1892
+ * The walk is `walkBreadthFirst` (graph-walk.ts), shared with carve's
1893
+ * reachability (#2325); it is what terminates on a cycle.
1901
1894
  */
1902
1895
  function findPath(n: IRNode, t: Term, ir: GraphIR, byId: Map<string, IRNode>): PathHop[] | null {
1903
1896
  if (t.kind !== "edge") return null;
1904
1897
  const { min, max } = t.depth ?? { min: 1, max: 1 };
1905
1898
  const idx = edgeIndex(ir);
1906
1899
  const out = t.dir === "out";
1907
- type State = { id: string; depth: number; hops: PathHop[] };
1908
1900
  // A capability edge (#4375) stands for the hops that proved it.
1909
1901
  const steps = (id: string): { far: string; hops: PathHop[] }[] => {
1910
1902
  if (t.capability !== undefined) return capabilitySteps(id, t.capability, out, ir);
@@ -1915,28 +1907,15 @@ function findPath(n: IRNode, t: Term, ir: GraphIR, byId: Map<string, IRNode>): P
1915
1907
  hops: [{ from: e.from, ...(e.viaAttr ? { fromAttr: e.viaAttr } : {}), to: e.to, ...(e.toAttr ? { toAttr: e.toAttr } : {}) }],
1916
1908
  })));
1917
1909
  };
1918
- const seen = new Set<string>([`${n.id}|0`]);
1919
- let frontier: State[] = [{ id: n.id, depth: 0, hops: [] }];
1920
- while (frontier.length > 0) {
1921
- const next: State[] = [];
1922
- for (const s of frontier) {
1923
- if (s.depth >= max) continue;
1924
- for (const step of steps(s.id)) {
1925
- const farId = step.far;
1926
- const far = byId.get(farId);
1927
- if (!far) continue;
1928
- const depth = s.depth + 1;
1929
- const hops = [...s.hops, ...step.hops];
1930
- if (depth >= min && (!t.sub || matchTerm(far, t.sub, ir, byId))) return hops;
1931
- const key = `${farId}|${Math.min(depth, min)}`;
1932
- if (seen.has(key)) continue;
1933
- seen.add(key);
1934
- next.push({ id: farId, depth, hops });
1935
- }
1936
- }
1937
- frontier = next;
1938
- }
1939
- return null;
1910
+ // A node the graph does not hold is no step at all, and the match is the
1911
+ // first arrival in range that satisfies the target leaf (#4359).
1912
+ const found = walkBreadthFirst<PathHop>(n.id, {
1913
+ min,
1914
+ max,
1915
+ steps: (id) => steps(id).filter((step) => byId.has(step.far)),
1916
+ arrive: ({ id }) => !t.sub || matchTerm(byId.get(id)!, t.sub, ir, byId),
1917
+ });
1918
+ return found ? found.hops : null;
1940
1919
  }
1941
1920
 
1942
1921
  function bareId(id: string): string {
@@ -852,6 +852,7 @@ describe("workspace init and ls (#2534)", () => {
852
852
  "workspace build",
853
853
  "workspace check",
854
854
  "workspace evidence",
855
+ "workspace exit",
855
856
  "workspace export",
856
857
  "workspace graph",
857
858
  "workspace hash-index",
@@ -868,11 +869,14 @@ describe("workspace init and ls (#2534)", () => {
868
869
  "workspace patch",
869
870
  "workspace pin",
870
871
  "workspace points",
872
+ "workspace promote",
871
873
  "workspace records",
874
+ "workspace run",
872
875
  "workspace runs",
873
876
  "workspace search",
874
877
  "workspace signers",
875
878
  "workspace status",
879
+ "workspace train",
876
880
  "workspace trust",
877
881
  "workspace upgrade",
878
882
  "workspace verify",
@@ -882,6 +886,19 @@ describe("workspace init and ls (#2534)", () => {
882
886
  ]);
883
887
  });
884
888
 
889
+ test("run and train take their targets and flags (#2554)", () => {
890
+ const run = parseArgs(["workspace", "run", "api/deploy", "web/deploy", "--gate", "release", "--env", "prod"]);
891
+ expect(run).toMatchObject({ command: "workspace", path: "run", positionals: ["run", "api/deploy", "web/deploy"], gate: "release", env: "prod" });
892
+ expect(resolveCommand(run, commandRegistry)?.def.name).toBe("workspace run");
893
+ expect(parseArgs(["workspace", "run", "--dependents-of", "network", "--op", "deploy"])).toMatchObject({ dependentsOf: "network", op: "deploy" });
894
+ expect(() => parseArgs(["workspace", "run", "--dependents-of"])).toThrow(/--dependents-of needs a member/);
895
+ const train = parseArgs(["workspace", "train", "prod", "--pin", "api=v2", "--pin", "web=v1"]);
896
+ expect(train).toMatchObject({ positionals: ["train", "prod"], pins: ["api=v2", "web=v1"] });
897
+ expect(resolveCommand(train, commandRegistry)?.def.name).toBe("workspace train");
898
+ expect(() => parseArgs(["workspace", "train", "prod", "--pin", "api"])).toThrow(/--pin needs a member and a release/);
899
+ expect(parseArgs(["workspace", "lint", "--cross-root", "--format", "json"])).toMatchObject({ path: "lint", crossRoot: true, format: "json" });
900
+ });
901
+
885
902
  test("adopt-lineage, hash-index, versions and upgrade --source take their flags (#2551)", () => {
886
903
  const adopt = parseArgs(["workspace", "adopt-lineage", "app", "--from", "acme/starter#svc", "--tags", "v*", "--index", "i.json", "--param", "name=x", "--dry-run"]);
887
904
  expect(adopt).toMatchObject({ command: "workspace", path: "adopt-lineage", extraPositional: "app", migrateFrom: "acme/starter#svc", tags: "v*", index: "i.json", param: ["name=x"], dryRun: true });
package/src/cli/main.ts CHANGED
@@ -183,7 +183,14 @@ Commands:
183
183
  the resources and snapshots each lexicon observed, Op
184
184
  runs, gates, deploys, releases and cuts, loaded into
185
185
  node:sqlite (schema v1, listed in chant_schema).
186
- --member <name> keeps members; --json prints rows
186
+ --member <name> keeps members; --json prints rows.
187
+ For a read contract, use chant ledger
188
+ ledger <table> [dir] One ledger's rows from chant/lifecycle as a read
189
+ contract (resources, snapshots, runs, gates, deploys,
190
+ releases, cuts; the columns chant query loads).
191
+ --where <field><op><value> (= != < <= > >= ~,
192
+ repeatable), --since <time|7d>, --at <rev> of
193
+ chant/lifecycle, --member <name>, --json
187
194
  generate Generate typed code from sources chant.config declares
188
195
  (k8s.crds, helm.charts) into src/generated/<lexicon>/
189
196
  (codegen.outDir); --check exits 1 when the committed
@@ -607,6 +614,16 @@ Workspace (level 1, #2524):
607
614
  write it only on confirmation (--yes writes without
608
615
  asking; --name <name> names the workspace; --verbose
609
616
  lists every file leaving the root project)
617
+ --from tfc|spacelift|backstage proposes from a
618
+ Terraform Cloud organization (--org, or --input <export>),
619
+ a Spacelift account (--endpoint, or --input <export>) or
620
+ the catalog-info.yaml files under dir, and shows what
621
+ it left out (#3178)
622
+ workspace promote <member> [--state <tfstate>] [--lexicon <name>] [--dry-run] [--output <patch>] [--json]
623
+ Move a member one rung up the kind ladder (terraform to
624
+ choudoufu runs live-check and the adoption report;
625
+ choudoufu or other to chant runs chant import), staged
626
+ in a worktree and gated on the patch digest like upgrade
610
627
  workspace ls [dir] List the declaration's members and example groups.
611
628
  A member that can't be read is listed with a reason
612
629
  code and still exits 0. --at <rev> reads a commit's
@@ -626,7 +643,7 @@ Workspace (level 1, #2524):
626
643
  restore, from the deploy records, releases and ci
627
644
  revoked tags. Eight weeks back by default. Read only;
628
645
  never fetches. --json prints the read-contract document
629
- workspace records [--kind <kind file>] [--current] [--uncommitted | --at <rev>] [--base <rev>] [--require attested] [--json]
646
+ workspace records [--kind <kind file>] [--current] [--uncommitted | --at <rev>] [--base <rev>] [--require attested] [--where <field><op><value>]... [--json]
630
647
  Without --kind, every record kind the declaration
631
648
  names. Read the records a record kind locates, validated
632
649
  against its schema, with reason codes for invalid
@@ -639,7 +656,9 @@ Workspace (level 1, #2524):
639
656
  asset-drift or asset-missing. In the working tree,
640
657
  each record says whether it is committed, modified
641
658
  or new against HEAD, with the branch and base;
642
- --uncommitted lists only the modified and new ones
659
+ --uncommitted lists only the modified and new ones;
660
+ --where keeps the records a typed filter matches
661
+ (id, path, state, valid, data.<key>, ...)
643
662
  workspace records [--kind <kind file>] --since <rev|session id> [--at <rev>] [--json]
644
663
  What changed in the records between <rev> and --at
645
664
  (default: the working tree): new and removed records,
@@ -709,14 +728,16 @@ Workspace (level 1, #2524):
709
728
  a url or a path pinned by hash) is appended to the
710
729
  item's pins through records amend. Prints the
711
730
  work-evidence document and never commits
712
- workspace runs [--unit <id>] [--decision <id>] [--by <principal>] [--since <rev>] [--follow-squash] [--json]
731
+ workspace runs [--unit <id>] [--decision <id>] [--by <principal>] [--since <rev>] [--where <field><op><value>]... [--follow-squash] [--json]
713
732
  The agent runs in the run ledger on chant/lifecycle, each
714
733
  with its model, tokens, cost and the commits it made,
715
734
  and totals per work item, decision and principal; a run
716
735
  that reports no cost is listed as unpriced, never zero.
717
736
  Read-only, never fetches; --follow-squash joins each
718
737
  squash merge to its pull request's runs, fetching a
719
- missing refs/pull/<n>/head from origin
738
+ missing refs/pull/<n>/head from origin; --where keeps
739
+ the runs a typed filter matches (state, model,
740
+ startedAt, cost.amount, ...) before the totals
720
741
  workspace runs start --from <file|->
721
742
  Record that an agent run started: who it worked for,
722
743
  its harness, model, work item and lease. Prints the run
@@ -850,6 +871,15 @@ Workspace (level 1, #2524):
850
871
  manual steps. Needs no workspace file
851
872
  workspace lineage resolve <path>
852
873
  Close a manual step once the file is merged by hand
874
+ workspace exit [<member>...] [--dry-run] [--drill] [--output <file>] [--json]
875
+ Leave chant: build each chant member once, commit the
876
+ native output (CloudFormation, ARM, Kubernetes YAML,
877
+ Compose, CI files), point its CI at the platform's own
878
+ CLI, drop the chant dependencies and set the member to
879
+ other. Staged in a worktree and gated on the patch
880
+ digest (chant approve workspace-exit <scope>). op.json
881
+ files stay. --drill runs it on a scratch copy and
882
+ checks each member, changing nothing.
853
883
  workspace upgrade [<scope>] [--to <ref|dir>] [--source <repo>[#<member>]] [--allow-code] [--dry-run] [--output <file>]
854
884
  Bring a lineage scope to a newer template version: fetch
855
885
  it, migrate and merge per file in a worktree, run build,
@@ -888,7 +918,7 @@ Workspace (level 1, #2524):
888
918
  workspace admit <return id> [--note <text>] [--dry-run] [--json]
889
919
  Admit the signers of a return in .chant/trust.json, so
890
920
  its signed work reads as attested once merged
891
- workspace check [--at <rev>] [--json] [--format stylish|json|sarif] [--generated] [--kind <kind file>] [--live --env <env>]
921
+ workspace check [--at <rev>] [--json] [--format stylish|json|sarif] [--generated] [--kind <kind file>] [--live --env <env>] [--forge-repos <file>]
892
922
  Fail on an unreadable lineage lock or an open manual
893
923
  step, and, in a declared workspace, on a WSP check of
894
924
  the declaration, member ledgers, pipelines or
@@ -900,7 +930,10 @@ Workspace (level 1, #2524):
900
930
  resolves each declared member link against the live
901
931
  graph of <env> (each chant member runs chant graph
902
932
  --live, which reaches the account) and reports
903
- WSP141 and WSP142
933
+ WSP141 and WSP142. --forge-repos reads a forge's
934
+ repository list from a file and reports repos an
935
+ org workspace lacks (WSP014) or names that the
936
+ forge no longer has (WSP015)
904
937
  workspace check --changes <base>..<head> [--work <id>] [--severity off|warn|fail] [--kind <kind file>...] [--json]
905
938
  Map each path the diff changes to the current records
906
939
  whose constrains cover it: change-uncovered when none
@@ -928,9 +961,12 @@ Workspace (level 1, #2524):
928
961
  its own chant, one process per toolchain. -o <dir>
929
962
  writes <dir>/<member>.json; --member narrows the run;
930
963
  --dry-run prints which chant runs which project
931
- workspace lint [dir] [--format stylish|json|sarif] [--member <name>]
964
+ workspace lint [dir] [--format stylish|json|sarif] [--member <name>] [--cross-root]
932
965
  Lint every chant member and example project with its
933
- own chant; sarif writes one run per member
966
+ own chant; sarif writes one run per member.
967
+ --cross-root adds the disagreement lint (LNK001 and
968
+ the lexicons' cross-root checks) over every member's
969
+ graph, where declared links and the graphs disagree
934
970
  workspace audit [dir] [--json] [--member <name>]
935
971
  Audit each chant member with its own .chant-audit.json;
936
972
  every finding carries a member field
@@ -967,6 +1003,29 @@ Workspace (level 1, #2524):
967
1003
  One decision's intent walk over every path: and member:
968
1004
  entry it constrains: the commits in its window, each
969
1005
  own, worked, within-other or unexplained, with counts
1006
+ workspace run <member>/<op>... [--env <env>] [--gate <name>] [--on <lexicon>] [--dry-run] [--json]
1007
+ Run Ops that span members (#2554): each target's chant
1008
+ run <op> in the member's directory, under its own
1009
+ chant, producers before the members that link to them.
1010
+ OPS019 checks every target against the composed graph
1011
+ first. Member run records cite the workspace run,
1012
+ whose record goes under _members/_workspace/<env>/.
1013
+ Exits 3 when a step stops at a gate
1014
+ workspace run --dependents-of <member> --op <op> [--env <env>] [--gate <name>] [--dry-run] [--json]
1015
+ Run <op> in every member that links to <member>,
1016
+ directly or not, nearest first; members without the
1017
+ Op are listed as skipped
1018
+ workspace run approve <gate> [--plan <digest>] [--approver <principal>]
1019
+ Approve a workspace gate's pending fact. It stands in
1020
+ for a member gate only when it covers that member's
1021
+ plan and the member sets acceptWorkspaceGates at base
1022
+ workspace train <env> [--pin <member>=<label|digest>]... [--dry-run] [--json]
1023
+ Record a release train: one cut release of every
1024
+ chant member (the newest, unless --pin picks one),
1025
+ under _members/_workspace/<env>/trains.jsonl. Refuses
1026
+ when a member has no release
1027
+ workspace train list <env> [--json]
1028
+ The release trains recorded for <env>, oldest first
970
1029
 
971
1030
  Lifecycle (alias: lc):
972
1031
  lifecycle snapshot <env> Query API, save metadata to orphan branch
@@ -1040,7 +1099,9 @@ Component release ledger + status:
1040
1099
  from the report pr-plan --no-status wrote
1041
1100
  (--pr <n> --head <sha> --env <env> --forge
1042
1101
  <kind>), in a job that runs none of the
1043
- change's code (#4295)
1102
+ change's code (#4295); --open posts every
1103
+ open merge request's from a GitLab pipeline
1104
+ of the target branch (#4328)
1044
1105
  components pr-record On merge (#4168): plan the same members again,
1045
1106
  store the change set and write the merge record
1046
1107
  _merges/<commit>.json; applies and refuses
@@ -1198,12 +1259,16 @@ Options:
1198
1259
  JSON (lifecycle plan)
1199
1260
  OR '--report markdown': emit a reviewer-facing markdown
1200
1261
  render, holes and disruption included (lifecycle plan)
1201
- --from <name> Source lexicon for migrate (default: github)
1202
- --to <name> Target lexicon for migrate (default: gitlab)
1203
- --emit <fmt> Migration output format: yaml (default) or ts
1262
+ --from <name> Source for migrate: a lexicon, or lexicon/dialect such
1263
+ as sql/postgres (default: github)
1264
+ --to <name> Target for migrate, same form, such as sql/clickhouse
1265
+ (default: gitlab)
1266
+ --emit <fmt> Migration output format: yaml (default), ts, or sql;
1267
+ sql/clickhouse defaults to ts
1204
1268
  --strict Escalate needs-review/validation to errors (migrate);
1205
1269
  exit nonzero on an unresolved identity (lifecycle whoami)
1206
- --validate Run external validator (glci/glab) after migrate
1270
+ --validate Run external validator after migrate: glci/glab, or the
1271
+ ClickHouse emulator for sql/clickhouse
1207
1272
  --use-composites Rewrite to composite calls when patterns match (migrate)
1208
1273
  --components Target discovered Component declarations instead of
1209
1274
  lexicon resources (list, describe, graph, build, run)
@@ -1498,6 +1563,7 @@ export const commandRegistry: CommandDef[] = [
1498
1563
  { name: "search", handler: runSearch },
1499
1564
  // #4297 — SQL over the snapshots, runs, gates, deploys and releases on chant/lifecycle. Imported on first use.
1500
1565
  { name: "query", runsNoConfig: true, handler: async (ctx) => (await import("./handlers/query")).runQueryCommand(ctx) },
1566
+ { name: "ledger", runsNoConfig: true, handler: async (ctx) => (await import("./handlers/ledger")).runLedgerCommand(ctx) },
1501
1567
  // chant#2591 — `import --agents` and `audit` read chant.config statically
1502
1568
  // and never evaluate it (chant#2589 for audit, which audits code it must not run).
1503
1569
  { name: "import", handler: runImport, runsNoConfig: (args) => args.agents === true },
@@ -1608,6 +1674,9 @@ export const commandRegistry: CommandDef[] = [
1608
1674
  { name: "workspace metrics", runsNoConfig: true, handler: async (ctx) => (await import("../workspace/delivery-metrics")).runWorkspaceMetrics(ctx) },
1609
1675
  { name: "workspace status", runsNoConfig: true, handler: async (ctx) => (await import("../workspace/status")).runWorkspaceStatus(ctx) },
1610
1676
  { name: "workspace lineage", handler: async (ctx) => (await import("../workspace/lineage-cli")).runWorkspaceLineage(ctx) },
1677
+ { name: "workspace exit", handler: async (ctx) => (await import("../workspace/exit-cli")).runWorkspaceExit(ctx) },
1678
+ // #3178 — move a member one rung up the kind ladder, staged in a worktree and gated on the patch digest.
1679
+ { name: "workspace promote", handler: async (ctx) => (await import("../workspace/promote")).runWorkspacePromote(ctx) },
1611
1680
  { name: "workspace upgrade", handler: async (ctx) => (await import("../workspace/lineage-upgrade-cli")).runWorkspaceUpgrade(ctx) },
1612
1681
  // #2551 — adopt a lineage, the hash index it matches against, and the versions of a family of workspaces.
1613
1682
  { name: "workspace adopt-lineage", handler: async (ctx) => (await import("../workspace/lineage-adopt-cli")).runWorkspaceAdoptLineage(ctx) },
@@ -1629,6 +1698,10 @@ export const commandRegistry: CommandDef[] = [
1629
1698
  { name: "workspace audit", runsNoConfig: true, handler: async (ctx) => (await import("../workspace/member-commands")).runWorkspaceMembers(ctx, "audit") },
1630
1699
  { name: "workspace graph", handler: async (ctx) => (await import("../workspace/member-commands")).runWorkspaceMembers(ctx, "graph") },
1631
1700
  // #4374 — chant search in every member, under its own chant, composed with workspace graph's ids: the search document.
1701
+ // #2554 — Ops that span members, as <member>/<op> targets, each run under its member's own chant.
1702
+ { name: "workspace run", runsNoConfig: true, handler: async (ctx) => (await import("../workspace/workspace-run")).runWorkspaceRun(ctx) },
1703
+ // #2554 — a release train: one release of every chant member, pinned in the workspace ledger.
1704
+ { name: "workspace train", runsNoConfig: true, handler: async (ctx) => (await import("../workspace/release-train")).runWorkspaceTrain(ctx) },
1632
1705
  { name: "workspace search", runsNoConfig: true, handler: async (ctx) => (await import("../workspace/search-cli")).runWorkspaceSearch(ctx) },
1633
1706
  // Each unit decides for itself whether its config is loaded (runCommandInProcess).
1634
1707
  { name: "workspace member-run", runsNoConfig: true, handler: async (ctx) => (await import("../workspace/member-run")).runWorkspaceMemberRun(ctx, runCommandInProcess) },
@@ -47,6 +47,7 @@ const BOOLEAN_FLAGS = new Set([
47
47
  "--up",
48
48
  "--down",
49
49
  "--include-dependents",
50
+ "--cross-root",
50
51
  "--local",
51
52
  "--json",
52
53
  "--progress-json",
@@ -283,6 +284,9 @@ export function parseArgs(args: string[]): ParsedArgs {
283
284
  result.emit = args[++i];
284
285
  } else if (arg === "--dry-run") {
285
286
  result.dryRun = true;
287
+ } else if (arg === "--drill") {
288
+ // #3177 — `chant workspace exit --drill` runs the exit on a scratch copy.
289
+ result.drill = true;
286
290
  } else if (arg === "--yes") {
287
291
  result.yes = true;
288
292
  } else if (arg === "--push") {
@@ -380,6 +384,19 @@ export function parseArgs(args: string[]): ParsedArgs {
380
384
  result.head = args[++i];
381
385
  } else if (arg === "--include-dependents") {
382
386
  result.includeDependents = true;
387
+ } else if (arg === "--cross-root") {
388
+ // `chant workspace lint --cross-root` (#2549): the disagreement lint over every member's graph.
389
+ result.crossRoot = true;
390
+ } else if (arg === "--dependents-of") {
391
+ // `chant workspace run --dependents-of <member> --op <op>` (#2554).
392
+ const value = args[++i];
393
+ if (!value || value.startsWith("-")) throw new Error("--dependents-of needs a member name: --dependents-of <member>");
394
+ result.dependentsOf = value;
395
+ } else if (arg === "--pin") {
396
+ // `chant workspace train <env> --pin <member>=<label|digest>` (#2554), repeatable.
397
+ const value = args[++i];
398
+ if (!value || value.startsWith("-") || !value.includes("=")) throw new Error("--pin needs a member and a release: --pin <member>=<label|digest>");
399
+ (result.pins ??= []).push(value);
383
400
  } else if (arg === "--from-affected") {
384
401
  result.fromAffected = args[++i];
385
402
  } else if (arg === "--gate") {
@@ -908,6 +925,11 @@ export function parseArgs(args: string[]): ParsedArgs {
908
925
  const value = args[++i];
909
926
  if (!value || value.startsWith("-")) throw new Error(`${arg} needs a value: ${arg} <${arg.slice(2)}>`);
910
927
  result[arg.slice(2) as "holder" | "ttl" | "token" | "outcome"] = value;
928
+ } else if (arg === "--input" || arg === "--org" || arg === "--endpoint") {
929
+ // `chant workspace init --from tfc|spacelift` (#3178): an exported file instead of the API, the Terraform Cloud organization, the Spacelift GraphQL endpoint.
930
+ const value = args[++i];
931
+ if (!value || value.startsWith("-")) throw new Error(`${arg} needs a value: ${arg} <${arg === "--input" ? "file" : arg.slice(2)}>`);
932
+ result[arg.slice(2) as "input" | "org" | "endpoint"] = value;
911
933
  } else if (arg === "--signer") {
912
934
  // `chant workspace runs statement <id> --signer <principal>` (#3192): the runner principal that will sign.
913
935
  const value = args[++i];
@@ -932,8 +954,8 @@ export function parseArgs(args: string[]): ParsedArgs {
932
954
  } else if (arg === "--expire") {
933
955
  result.expire = true;
934
956
  } else if (arg === "--role") {
935
- // #2508 — a role the approver claims, which a gate's policy sees. A
936
- // quorum reads roles from .chant/trust.json at base instead (#4290).
957
+ // #2508 — a role the approver claims, recorded on the approval. A quorum
958
+ // (#4290) and a gate policy (#4324) read roles from .chant/trust.json at base.
937
959
  // Repeatable, and a comma list works too.
938
960
  const value = args[++i] ?? "";
939
961
  result.roles = [...(result.roles ?? []), ...value.split(",").map((r) => r.trim()).filter(Boolean)];
@@ -971,6 +993,12 @@ export function parseArgs(args: string[]): ParsedArgs {
971
993
  // #2537 — `chant build` and `chant lint` at a declared workspace root
972
994
  // run on the root project alone instead of refusing with WSP000.
973
995
  result.rootOnly = true;
996
+ } else if (arg === "--forge-repos") {
997
+ // #3168 — `chant workspace check --forge-repos <file>`: the forge's
998
+ // repository list, as a warden reads it, for an org workspace's checks.
999
+ const value = args[++i];
1000
+ if (!value || value.startsWith("-")) throw new Error("--forge-repos needs a file: --forge-repos <repos.json>");
1001
+ result.forgeRepos = value;
974
1002
  } else if (arg === "--generated") {
975
1003
  // #2641 — `chant workspace check --generated` runs each declared
976
1004
  // generator and compares its output with the file in the tree.
@@ -991,6 +1019,11 @@ export function parseArgs(args: string[]): ParsedArgs {
991
1019
  result.url = args[++i];
992
1020
  } else if (arg === "--op") {
993
1021
  result.op = args[++i];
1022
+ } else if (arg === "--where") {
1023
+ // #4363 — a typed filter on a contract read; repeatable, every clause has to hold.
1024
+ const value = args[++i];
1025
+ if (value === undefined || value.startsWith("--")) throw new Error("--where needs a clause: --where <field><op><value>");
1026
+ result.where = [...(result.where ?? []), value];
994
1027
  } else if (arg === "--since") {
995
1028
  result.since = args[++i];
996
1029
  } else if (arg === "--limit") {
@@ -83,7 +83,7 @@ export interface ParsedArgs {
83
83
  /** `chant run events <run> --follow` (#4042) — stream the run's events as they happen, until `run-settle`. */
84
84
  follow?: boolean;
85
85
  live: boolean;
86
- /** `chant migrate --from <name>` (default "github") */
86
+ /** `chant migrate --from <name>` (default "github"); `lexicon/dialect` for the sql lexicon */
87
87
  migrateFrom?: string;
88
88
  /** `chant import --kustomize <dir>` — render the kustomization, then import (#1548) */
89
89
  kustomize?: string;
@@ -103,9 +103,9 @@ export interface ParsedArgs {
103
103
  write?: boolean;
104
104
  /** `chant carve apply --write-source` — stamp the ownership marker into the emitted source */
105
105
  writeSource?: boolean;
106
- /** `chant migrate --to <name>` (default "gitlab") */
106
+ /** `chant migrate --to <name>` (default "gitlab"); `lexicon/dialect` for the sql lexicon */
107
107
  migrateTo?: string;
108
- /** `chant migrate --emit yaml|ts` */
108
+ /** `chant migrate --emit yaml|ts|sql` */
109
109
  emit?: string;
110
110
  /** Escalate needs-review diagnostics to errors (migrate command) */
111
111
  strict?: boolean;
@@ -165,6 +165,8 @@ export interface ParsedArgs {
165
165
  remove?: boolean;
166
166
  /** `chant lifecycle rollback --dry-run` — compute the rollback delta and print it; open no PR, push nothing, leave no branch. */
167
167
  dryRun?: boolean;
168
+ /** `chant workspace exit --drill` (#3177): run the exit on a scratch copy and check it, changing nothing. */
169
+ drill?: boolean;
168
170
  /** `chant lifecycle teardown <env> --yes` — execute the planned deletion
169
171
  * (#1222). Without it the command plans and stops. */
170
172
  yes?: boolean;
@@ -263,6 +265,12 @@ export interface ParsedArgs {
263
265
  head?: string;
264
266
  /** `chant lifecycle affected --include-dependents` — add downstream consumers */
265
267
  includeDependents?: boolean;
268
+ /** `chant workspace run --dependents-of <member> --op <op>` (#2554): run the Op in every member that links to this one, directly or not. */
269
+ dependentsOf?: string;
270
+ /** `chant workspace lint --cross-root` (#2549): also run the disagreement lint and the lexicons' cross-root checks over every member's graph. */
271
+ crossRoot?: boolean;
272
+ /** `chant workspace train <env> --pin <member>=<label|digest>` (#2554), repeatable: the release a train pins for that member instead of its newest. */
273
+ pins?: string[];
266
274
  /**
267
275
  * `chant components fan-out --from-affected <file>` (#2420) — read the
268
276
  * stack-level change signal from the JSON `chant lifecycle affected --json`
@@ -622,6 +630,12 @@ export interface ParsedArgs {
622
630
  claim?: string;
623
631
  /** `chant workspace evidence sign --environment <file>` (#2553): the runner environment, hashed into the evidence. */
624
632
  environment?: string;
633
+ /** `chant workspace init --from tfc|spacelift --input <file>` (#3178): an exported file read instead of the API. */
634
+ input?: string;
635
+ /** `chant workspace init --from tfc --org <name>` (#3178): the Terraform Cloud organization. */
636
+ org?: string;
637
+ /** `chant workspace init --from spacelift --endpoint <url>` (#3178): the account's GraphQL endpoint. */
638
+ endpoint?: string;
625
639
  /** `chant workspace runs statement <id> --signer <principal>` (#3192): the runner principal that will sign. */
626
640
  signer?: string;
627
641
  /** `chant workspace evidence verify --envelope <file>` (#2553). */
@@ -640,6 +654,8 @@ export interface ParsedArgs {
640
654
  * generators run member code.
641
655
  */
642
656
  generated?: boolean;
657
+ /** `chant workspace check --forge-repos <file>` (#3168): the forge's repository list, checked against an org workspace's repo members (WSP014, WSP015). */
658
+ forgeRepos?: string;
643
659
  /**
644
660
  * `chant workspace build|lint|audit|graph --member <name>` (#2537): run only
645
661
  * the named members or example groups. Repeatable, and a comma list works too.
@@ -788,7 +804,7 @@ export interface ParsedArgs {
788
804
  * on a model-authored channel.
789
805
  */
790
806
  allowSameOrigin?: boolean;
791
- /** `chant approve --role <name>` (#2508) — roles the approver claims, which a gate's policy sees. A quorum never counts them (#4290): its roles come from `.chant/trust.json` at base. Repeatable; a comma list also works. */
807
+ /** `chant approve --role <name>` (#2508) — roles the approver claims, recorded on the approval. Nothing trusts them: a quorum (#4290) and a gate policy (#4324) read roles from `.chant/trust.json` at base, for a sealed approval. Repeatable; a comma list also works. */
792
808
  roles?: string[];
793
809
  /** `chant approve --agent` (#2508) — record the approval as an agent's. An agent never counts toward a quorum; it passes a gate only through a policy permit in `enforce` mode. */
794
810
  agent?: boolean;
@@ -798,6 +814,8 @@ export interface ParsedArgs {
798
814
  op?: string;
799
815
  /** `chant operator log --since <iso>` (#2029) — only entries at or after this ISO-8601 instant. `chant workspace records --since <rev>` (#2673) — the revision to compare the records with. `chant workspace metrics --since <date>` (#4039) — the start of the window the metrics count. */
800
816
  since?: string;
817
+ /** `chant ledger`, `chant workspace records` and `chant workspace runs --where <field><op><value>` (#4363): typed filters, repeatable, all of which have to hold. */
818
+ where?: string[];
801
819
  /** `chant operator log --limit <n>` (#2029) — keep only the newest n entries (still printed oldest-first). */
802
820
  limit?: number;
803
821
  /** `chant approve <op> <gate> --url <url>` (#2028) — the address this resolution happened at (the PR/MR that carried the change), recorded typed on the gate-resolution fact so a reader is not sniffing `--note` for something link-shaped. Defaults to the PR/MR the surrounding CI job is for, when there is one. Must be an absolute http/https URL. */
@@ -19,6 +19,8 @@ import type {
19
19
  ZipPackageInput,
20
20
  JvmBuildInput,
21
21
  GenerateSbomInput,
22
+ PublishImageInput,
23
+ PublishArtifactInput,
22
24
  SignInput,
23
25
  AttestProvenanceInput,
24
26
  VerifyInput,
@@ -64,6 +66,12 @@ export const vulnGate = step<VulnGateInput>("vuln-gate");
64
66
  // The cloud-specific waits (`wait-for-stack`/`wait-steady-state`/`wait-job`)
65
67
  // ship as builders from the aws lexicon, alongside their capabilities.
66
68
  export const waitClusterHealthy = step<WaitClusterHealthyInput>("wait-cluster-healthy");
69
+ // ── publish (core owns the verb; each cloud lexicon contributes a registry login backend) ──
70
+ export const publishImage = step<PublishImageInput>("publish-image");
71
+ export const publishArtifact = step<PublishArtifactInput>("publish-artifact");
72
+ /** Alias for {@link publishArtifact}. */
73
+ export const publishAsset = publishArtifact;
74
+
67
75
  export const waitEndpoint = step<WaitEndpointInput>("wait-endpoint");
68
76
  export const healthGate = step<HealthGateInput>("health-gate");
69
77
 
@@ -26,6 +26,8 @@ import { lexiconModulePath, importLexiconPackage } from "../lexicon-module";
26
26
  import type { CapabilityPlugin } from "./capability-plugin";
27
27
  import { isCapabilityPlugin } from "./capability-plugin";
28
28
  import { starterCapabilityPlugin } from "./starter-plugin";
29
+ import { isRegistryBackendConsumer, type RegistryLoginBackend } from "./verbs/publish-image";
30
+ import { isStorageBackendConsumer, type ArtifactStorageBackend } from "./verbs/publish-artifact";
29
31
 
30
32
  /** Thrown when a dynamically-imported capability package does not satisfy `CapabilityPlugin` — the "malformed capability package" case #559 asks doctor/validation to detect. */
31
33
  export class MalformedCapabilityPluginError extends Error {
@@ -165,9 +167,19 @@ export function registerCapabilityPlugins(
165
167
  }
166
168
  }
167
169
 
170
+ const backends: RegistryLoginBackend[] = [];
171
+ for (const plugin of plugins) backends.push(...(plugin.registryBackends?.() ?? []));
172
+ const storage: ArtifactStorageBackend[] = [];
173
+ for (const plugin of plugins) storage.push(...(plugin.storageBackends?.() ?? []));
174
+
168
175
  for (const plugin of plugins) {
169
176
  for (const capability of plugin.capabilities()) {
170
- registry.register(capability);
177
+ // A capability that consumes registry login backends (`publish-image`)
178
+ // is re-bound to the backends of the plugins loaded for this registry.
179
+ let bound = capability;
180
+ if (isRegistryBackendConsumer(bound)) bound = bound.withRegistryBackends(backends) as typeof bound;
181
+ if (isStorageBackendConsumer(bound)) bound = bound.withStorageBackends(storage) as typeof bound;
182
+ registry.register(bound);
171
183
  }
172
184
  }
173
185
  return registry;
@@ -32,6 +32,8 @@ import { readFileSync } from "node:fs";
32
32
  import { dirname, join } from "node:path";
33
33
  import { fileURLToPath } from "node:url";
34
34
  import type { Capability } from "./capability";
35
+ import type { RegistryLoginBackend } from "./verbs/publish-image";
36
+ import type { ArtifactStorageBackend } from "./verbs/publish-artifact";
35
37
 
36
38
  /**
37
39
  * Manifest for a packaged capability plugin — the capability-side analogue
@@ -88,6 +90,20 @@ export interface CapabilityPlugin {
88
90
  /** Capability kinds grouped by family, informational — mirrors `STARTER_VERB_FAMILIES` (./registry.ts) shape for third-party plugins that want to publish the same grouping. */
89
91
  families?(): Record<string, readonly string[]>;
90
92
 
93
+ /**
94
+ * Registry login backends this plugin contributes to core's `publish-image`
95
+ * verb (aws: ECR, azure: ACR, gcp: Artifact Registry). Not capabilities, so
96
+ * several plugins may contribute without a duplicate-kind clash.
97
+ */
98
+ registryBackends?(): RegistryLoginBackend[];
99
+
100
+ /**
101
+ * Object-storage backends this plugin contributes to core's
102
+ * `publish-artifact` verb (aws: S3, azure: Blob, gcp: GCS). Like
103
+ * `registryBackends`, not capabilities, so several plugins may contribute.
104
+ */
105
+ storageBackends?(): ArtifactStorageBackend[];
106
+
91
107
  /** Optional initialization hook, called once after load (mirrors `LexiconPlugin.init`). */
92
108
  init?(): void | Promise<void>;
93
109
  }
@@ -47,6 +47,7 @@ describe("the pr-env-run bundle", () => {
47
47
  "packages/core/src/op/emulator-lifecycle.ts",
48
48
  "packages/core/src/plan-summary.ts",
49
49
  "packages/core/src/pr-loop.ts",
50
+ "packages/core/src/pr-migrations.ts",
50
51
  ]);
51
52
  expect(inputs.some((i) => /node_modules\/(ajv|js-yaml)\//.test(i) || i.endsWith("/op/gate.ts") || i.endsWith("/src/config.ts") || i.endsWith("/ts-loader.ts"))).toBe(false);
52
53
  expect(result.outputFiles.reduce((n, f) => n + f.contents.byteLength, 0)).toBeLessThan(40 * 1024);