@intentius/chant 0.124.45 → 0.124.48

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 (772) 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/capabilities/aws.paths +148 -0
  47. package/dist/capabilities/base-mappings.json +122 -0
  48. package/dist/capabilities/catalog.d.ts +89 -0
  49. package/dist/capabilities/catalog.d.ts.map +1 -0
  50. package/dist/capabilities/catalog.js +204 -0
  51. package/dist/capabilities/language.d.ts +103 -0
  52. package/dist/capabilities/language.d.ts.map +1 -0
  53. package/dist/capabilities/language.js +335 -0
  54. package/dist/capabilities/matcher.d.ts +65 -0
  55. package/dist/capabilities/matcher.d.ts.map +1 -0
  56. package/dist/capabilities/matcher.js +299 -0
  57. package/dist/capabilities/view.d.ts +207 -0
  58. package/dist/capabilities/view.d.ts.map +1 -0
  59. package/dist/capabilities/view.js +484 -0
  60. package/dist/cli/commands/carve.d.ts +3 -0
  61. package/dist/cli/commands/carve.d.ts.map +1 -1
  62. package/dist/cli/commands/carve.js +36 -7
  63. package/dist/cli/commands/import-report.d.ts +26 -0
  64. package/dist/cli/commands/import-report.d.ts.map +1 -0
  65. package/dist/cli/commands/import-report.js +65 -0
  66. package/dist/cli/commands/import.d.ts +11 -1
  67. package/dist/cli/commands/import.d.ts.map +1 -1
  68. package/dist/cli/commands/import.js +22 -3
  69. package/dist/cli/commands/lint.d.ts.map +1 -1
  70. package/dist/cli/commands/lint.js +1 -0
  71. package/dist/cli/commands/migrate.d.ts +13 -1
  72. package/dist/cli/commands/migrate.d.ts.map +1 -1
  73. package/dist/cli/commands/migrate.js +134 -10
  74. package/dist/cli/handlers/approve.d.ts.map +1 -1
  75. package/dist/cli/handlers/approve.js +21 -2
  76. package/dist/cli/handlers/build.d.ts.map +1 -1
  77. package/dist/cli/handlers/build.js +6 -1
  78. package/dist/cli/handlers/declared-graph.d.ts +44 -0
  79. package/dist/cli/handlers/declared-graph.d.ts.map +1 -0
  80. package/dist/cli/handlers/declared-graph.js +87 -0
  81. package/dist/cli/handlers/graph.d.ts +25 -0
  82. package/dist/cli/handlers/graph.d.ts.map +1 -1
  83. package/dist/cli/handlers/graph.js +93 -87
  84. package/dist/cli/handlers/ledger.d.ts +3 -0
  85. package/dist/cli/handlers/ledger.d.ts.map +1 -0
  86. package/dist/cli/handlers/ledger.js +55 -0
  87. package/dist/cli/handlers/migrate.d.ts.map +1 -1
  88. package/dist/cli/handlers/migrate.js +18 -11
  89. package/dist/cli/handlers/misc.d.ts.map +1 -1
  90. package/dist/cli/handlers/misc.js +12 -1
  91. package/dist/cli/handlers/pr-env.d.ts.map +1 -1
  92. package/dist/cli/handlers/pr-env.js +4 -3
  93. package/dist/cli/handlers/pr.d.ts +15 -1
  94. package/dist/cli/handlers/pr.d.ts.map +1 -1
  95. package/dist/cli/handlers/pr.js +143 -39
  96. package/dist/cli/handlers/query.d.ts +7 -2
  97. package/dist/cli/handlers/query.d.ts.map +1 -1
  98. package/dist/cli/handlers/query.js +16 -4
  99. package/dist/cli/handlers/release.d.ts.map +1 -1
  100. package/dist/cli/handlers/release.js +6 -3
  101. package/dist/cli/handlers/search-count.d.ts +89 -0
  102. package/dist/cli/handlers/search-count.d.ts.map +1 -0
  103. package/dist/cli/handlers/search-count.js +132 -0
  104. package/dist/cli/handlers/search.d.ts +356 -6
  105. package/dist/cli/handlers/search.d.ts.map +1 -1
  106. package/dist/cli/handlers/search.js +1039 -155
  107. package/dist/cli/main.d.ts.map +1 -1
  108. package/dist/cli/main.js +88 -17
  109. package/dist/cli/mcp/server.d.ts.map +1 -1
  110. package/dist/cli/mcp/server.js +3 -0
  111. package/dist/cli/mcp/tools/capabilities.d.ts +7 -0
  112. package/dist/cli/mcp/tools/capabilities.d.ts.map +1 -0
  113. package/dist/cli/mcp/tools/capabilities.js +27 -0
  114. package/dist/cli/mcp/workspace-tools.d.ts +3 -1
  115. package/dist/cli/mcp/workspace-tools.d.ts.map +1 -1
  116. package/dist/cli/mcp/workspace-tools.js +47 -2
  117. package/dist/cli/parse-args.d.ts.map +1 -1
  118. package/dist/cli/parse-args.js +100 -19
  119. package/dist/cli/registry.d.ts +36 -4
  120. package/dist/cli/registry.d.ts.map +1 -1
  121. package/dist/components/builders.d.ts +5 -1
  122. package/dist/components/builders.d.ts.map +1 -1
  123. package/dist/components/builders.js +5 -0
  124. package/dist/components/capability-plugin-loader.d.ts.map +1 -1
  125. package/dist/components/capability-plugin-loader.js +16 -1
  126. package/dist/components/capability-plugin.d.ts +14 -0
  127. package/dist/components/capability-plugin.d.ts.map +1 -1
  128. package/dist/components/pr-env-ports.d.ts +29 -0
  129. package/dist/components/pr-env-ports.d.ts.map +1 -0
  130. package/dist/components/pr-env-ports.js +77 -0
  131. package/dist/components/pr-env-run.d.ts +5 -21
  132. package/dist/components/pr-env-run.d.ts.map +1 -1
  133. package/dist/components/pr-env-run.js +6 -70
  134. package/dist/components/pr-environment.d.ts +2 -1
  135. package/dist/components/pr-environment.d.ts.map +1 -1
  136. package/dist/components/pr-environment.js +1 -1
  137. package/dist/components/pr-hooks.d.ts +21 -1
  138. package/dist/components/pr-hooks.d.ts.map +1 -1
  139. package/dist/components/pr-hooks.js +72 -4
  140. package/dist/components/pr-pipeline.d.ts +45 -10
  141. package/dist/components/pr-pipeline.d.ts.map +1 -1
  142. package/dist/components/pr-pipeline.js +47 -14
  143. package/dist/components/pr-policy.d.ts +36 -0
  144. package/dist/components/pr-policy.d.ts.map +1 -1
  145. package/dist/components/pr-policy.js +36 -0
  146. package/dist/components/starter-plugin.d.ts +1 -0
  147. package/dist/components/starter-plugin.d.ts.map +1 -1
  148. package/dist/components/starter-plugin.js +5 -1
  149. package/dist/components/verbs/index.d.ts +2 -0
  150. package/dist/components/verbs/index.d.ts.map +1 -1
  151. package/dist/components/verbs/index.js +2 -0
  152. package/dist/components/verbs/publish-artifact.d.ts +65 -0
  153. package/dist/components/verbs/publish-artifact.d.ts.map +1 -0
  154. package/dist/components/verbs/publish-artifact.js +74 -0
  155. package/dist/components/verbs/publish-image.d.ts +129 -0
  156. package/dist/components/verbs/publish-image.d.ts.map +1 -0
  157. package/dist/components/verbs/publish-image.js +145 -0
  158. package/dist/config-environments.d.ts +112 -0
  159. package/dist/config-environments.d.ts.map +1 -0
  160. package/dist/config-environments.js +114 -0
  161. package/dist/config.d.ts +32 -84
  162. package/dist/config.d.ts.map +1 -1
  163. package/dist/config.js +13 -96
  164. package/dist/gate-decision.d.ts +11 -2
  165. package/dist/gate-decision.d.ts.map +1 -1
  166. package/dist/gate-decision.js +15 -3
  167. package/dist/graph-detail.d.ts.map +1 -1
  168. package/dist/graph-detail.js +15 -3
  169. package/dist/graph-effective.d.ts +33 -2
  170. package/dist/graph-effective.d.ts.map +1 -1
  171. package/dist/graph-effective.js +215 -68
  172. package/dist/graph-ir.d.ts +48 -0
  173. package/dist/graph-ir.d.ts.map +1 -1
  174. package/dist/graph-ir.js +130 -0
  175. package/dist/graph-sub-template.d.ts +11 -0
  176. package/dist/graph-sub-template.d.ts.map +1 -0
  177. package/dist/graph-sub-template.js +19 -0
  178. package/dist/graph-walk.d.ts +66 -0
  179. package/dist/graph-walk.d.ts.map +1 -0
  180. package/dist/graph-walk.js +70 -0
  181. package/dist/import/parser.d.ts +19 -0
  182. package/dist/import/parser.d.ts.map +1 -1
  183. package/dist/lexicon.d.ts +80 -6
  184. package/dist/lexicon.d.ts.map +1 -1
  185. package/dist/lifecycle/gate-ledger.d.ts +11 -0
  186. package/dist/lifecycle/gate-ledger.d.ts.map +1 -1
  187. package/dist/lifecycle/git.d.ts +2 -5
  188. package/dist/lifecycle/git.d.ts.map +1 -1
  189. package/dist/lifecycle/ledger-read.d.ts +65 -0
  190. package/dist/lifecycle/ledger-read.d.ts.map +1 -0
  191. package/dist/lifecycle/ledger-read.js +160 -0
  192. package/dist/lifecycle/observe.d.ts +28 -0
  193. package/dist/lifecycle/observe.d.ts.map +1 -1
  194. package/dist/lifecycle/observe.js +23 -1
  195. package/dist/lifecycle/release-workstation.d.ts +7 -0
  196. package/dist/lifecycle/release-workstation.d.ts.map +1 -1
  197. package/dist/lifecycle/release-workstation.js +25 -0
  198. package/dist/lifecycle/run-ledger.d.ts +4 -3
  199. package/dist/lifecycle/run-ledger.d.ts.map +1 -1
  200. package/dist/lifecycle/run-ledger.js +1 -0
  201. package/dist/lint/discover.js +3 -1
  202. package/dist/lint/post-synth.d.ts +127 -1
  203. package/dist/lint/post-synth.d.ts.map +1 -1
  204. package/dist/lint/post-synth.js +84 -2
  205. package/dist/lint/rule.d.ts +6 -0
  206. package/dist/lint/rule.d.ts.map +1 -1
  207. package/dist/lint/rules/op/index.d.ts +1 -0
  208. package/dist/lint/rules/op/index.d.ts.map +1 -1
  209. package/dist/lint/rules/op/index.js +2 -0
  210. package/dist/lint/rules/op/ops019-workspace-op-target.d.ts +32 -0
  211. package/dist/lint/rules/op/ops019-workspace-op-target.d.ts.map +1 -0
  212. package/dist/lint/rules/op/ops019-workspace-op-target.js +63 -0
  213. package/dist/live-endpoint.d.ts +1 -1
  214. package/dist/live-endpoint.d.ts.map +1 -1
  215. package/dist/live-endpoint.js +1 -1
  216. package/dist/observation.d.ts +48 -1
  217. package/dist/observation.d.ts.map +1 -1
  218. package/dist/observation.js +21 -5
  219. package/dist/op/activities/activity-contracts.d.ts +9 -6
  220. package/dist/op/activities/activity-contracts.d.ts.map +1 -1
  221. package/dist/op/activities/activity-contracts.js +5 -2
  222. package/dist/op/activities/index.d.ts +2 -2
  223. package/dist/op/activities/index.d.ts.map +1 -1
  224. package/dist/op/activities/index.js +1 -1
  225. package/dist/op/activities/review-agent.d.ts +90 -4
  226. package/dist/op/activities/review-agent.d.ts.map +1 -1
  227. package/dist/op/activities/review-agent.js +217 -19
  228. package/dist/op/activities/work-evidence.d.ts +8 -1
  229. package/dist/op/activities/work-evidence.d.ts.map +1 -1
  230. package/dist/op/activities/work-evidence.js +1 -0
  231. package/dist/op/builders.d.ts +9 -5
  232. package/dist/op/builders.d.ts.map +1 -1
  233. package/dist/op/builders.js +9 -5
  234. package/dist/op/composites/apply-op.d.ts +29 -2
  235. package/dist/op/composites/apply-op.d.ts.map +1 -1
  236. package/dist/op/composites/apply-op.js +20 -1
  237. package/dist/op/gate-approval.d.ts +11 -5
  238. package/dist/op/gate-approval.d.ts.map +1 -1
  239. package/dist/op/gate-approval.js +11 -6
  240. package/dist/op/gate-quorum.d.ts +100 -3
  241. package/dist/op/gate-quorum.d.ts.map +1 -1
  242. package/dist/op/gate-quorum.js +108 -6
  243. package/dist/op/gate-review.d.ts +9 -0
  244. package/dist/op/gate-review.d.ts.map +1 -1
  245. package/dist/op/gate-review.js +13 -0
  246. package/dist/op/gate.d.ts +44 -3
  247. package/dist/op/gate.d.ts.map +1 -1
  248. package/dist/op/gate.js +25 -4
  249. package/dist/op/index.d.ts +3 -3
  250. package/dist/op/index.d.ts.map +1 -1
  251. package/dist/op/index.js +1 -1
  252. package/dist/op/local-executor.d.ts +38 -3
  253. package/dist/op/local-executor.d.ts.map +1 -1
  254. package/dist/op/local-executor.js +48 -6
  255. package/dist/op/op-waves-run.d.ts +26 -1
  256. package/dist/op/op-waves-run.d.ts.map +1 -1
  257. package/dist/op/op-waves-run.js +259 -13
  258. package/dist/op/op-waves.d.ts +72 -5
  259. package/dist/op/op-waves.d.ts.map +1 -1
  260. package/dist/op/op-waves.js +110 -15
  261. package/dist/op/runtime.d.ts +11 -0
  262. package/dist/op/runtime.d.ts.map +1 -1
  263. package/dist/op/schedule-overdue.d.ts +16 -0
  264. package/dist/op/schedule-overdue.d.ts.map +1 -1
  265. package/dist/op/schedule-overdue.js +36 -0
  266. package/dist/op/stage-hooks.d.ts +9 -2
  267. package/dist/op/stage-hooks.d.ts.map +1 -1
  268. package/dist/op/stage-hooks.js +7 -5
  269. package/dist/op/workspace-run-env.d.ts +22 -0
  270. package/dist/op/workspace-run-env.d.ts.map +1 -0
  271. package/dist/op/workspace-run-env.js +21 -0
  272. package/dist/pr-forge.d.ts +24 -0
  273. package/dist/pr-forge.d.ts.map +1 -1
  274. package/dist/pr-forge.js +47 -0
  275. package/dist/pr-post.d.ts +42 -0
  276. package/dist/pr-post.d.ts.map +1 -1
  277. package/dist/pr-post.js +67 -1
  278. package/dist/read-filter.d.ts +65 -0
  279. package/dist/read-filter.d.ts.map +1 -0
  280. package/dist/read-filter.js +179 -0
  281. package/dist/run-event.d.ts +1 -1
  282. package/dist/run-event.d.ts.map +1 -1
  283. package/dist/terraform/carve.d.ts +24 -3
  284. package/dist/terraform/carve.d.ts.map +1 -1
  285. package/dist/terraform/carve.js +32 -14
  286. package/dist/terraform/cuts.d.ts +97 -0
  287. package/dist/terraform/cuts.d.ts.map +1 -0
  288. package/dist/terraform/cuts.js +138 -0
  289. package/dist/terraform/folds.d.ts +26 -0
  290. package/dist/terraform/folds.d.ts.map +1 -0
  291. package/dist/terraform/folds.js +38 -0
  292. package/dist/terraform/graph.d.ts.map +1 -1
  293. package/dist/terraform/graph.js +10 -0
  294. package/dist/terraform/reach.d.ts +140 -0
  295. package/dist/terraform/reach.d.ts.map +1 -0
  296. package/dist/terraform/reach.js +170 -0
  297. package/dist/terraform/score.d.ts +14 -0
  298. package/dist/terraform/score.d.ts.map +1 -1
  299. package/dist/terraform/score.js +14 -31
  300. package/dist/terraform/state.d.ts.map +1 -1
  301. package/dist/terraform/state.js +4 -2
  302. package/dist/terraform/types.d.ts +8 -0
  303. package/dist/terraform/types.d.ts.map +1 -1
  304. package/dist/wave-blocked.d.ts +10 -1
  305. package/dist/wave-blocked.d.ts.map +1 -1
  306. package/dist/wave-blocked.js +31 -3
  307. package/dist/wave-runtime.mjs +266 -256
  308. package/dist/workspace/capabilities-contract.d.ts +66 -0
  309. package/dist/workspace/capabilities-contract.d.ts.map +1 -0
  310. package/dist/workspace/capabilities-contract.js +107 -0
  311. package/dist/workspace/capabilities.schema.json +229 -0
  312. package/dist/workspace/check.schema.json +11 -2
  313. package/dist/workspace/checks/ci-branch.d.ts +44 -0
  314. package/dist/workspace/checks/ci-branch.d.ts.map +1 -0
  315. package/dist/workspace/checks/ci-branch.js +133 -0
  316. package/dist/workspace/checks/links.d.ts +3 -0
  317. package/dist/workspace/checks/links.d.ts.map +1 -1
  318. package/dist/workspace/checks/links.js +12 -1
  319. package/dist/workspace/checks/org.d.ts +48 -0
  320. package/dist/workspace/checks/org.d.ts.map +1 -0
  321. package/dist/workspace/checks/org.js +156 -0
  322. package/dist/workspace/checks.d.ts +11 -1
  323. package/dist/workspace/checks.d.ts.map +1 -1
  324. package/dist/workspace/checks.js +59 -7
  325. package/dist/workspace/ci-branches.d.ts +16 -0
  326. package/dist/workspace/ci-branches.d.ts.map +1 -1
  327. package/dist/workspace/ci-branches.js +27 -0
  328. package/dist/workspace/ci-green-cli.js +7 -7
  329. package/dist/workspace/ci-green-workflow.d.ts +1 -1
  330. package/dist/workspace/ci-green-workflow.d.ts.map +1 -1
  331. package/dist/workspace/ci-green-workflow.js +13 -8
  332. package/dist/workspace/ci-green.d.ts +14 -0
  333. package/dist/workspace/ci-green.d.ts.map +1 -1
  334. package/dist/workspace/ci-green.js +44 -11
  335. package/dist/workspace/ci-run.d.ts +9 -1
  336. package/dist/workspace/ci-run.d.ts.map +1 -1
  337. package/dist/workspace/ci-run.js +67 -6
  338. package/dist/workspace/ci-serve.d.ts +9 -0
  339. package/dist/workspace/ci-serve.d.ts.map +1 -1
  340. package/dist/workspace/ci-serve.js +114 -76
  341. package/dist/workspace/compose-graph.d.ts +23 -0
  342. package/dist/workspace/compose-graph.d.ts.map +1 -1
  343. package/dist/workspace/compose-graph.js +3 -1
  344. package/dist/workspace/composites.d.ts +4 -1
  345. package/dist/workspace/composites.d.ts.map +1 -1
  346. package/dist/workspace/composites.js +5 -2
  347. package/dist/workspace/composites.schema.json +22 -0
  348. package/dist/workspace/conformance/__writer_fixture__/work/work.schema.json +105 -1
  349. package/dist/workspace/conformance/index.d.ts +1 -1
  350. package/dist/workspace/conformance/index.d.ts.map +1 -1
  351. package/dist/workspace/conformance/index.js +39 -2
  352. package/dist/workspace/cross-root-lint.d.ts +56 -0
  353. package/dist/workspace/cross-root-lint.d.ts.map +1 -0
  354. package/dist/workspace/cross-root-lint.js +111 -0
  355. package/dist/workspace/dbt-models-reader.d.ts +44 -0
  356. package/dist/workspace/dbt-models-reader.d.ts.map +1 -0
  357. package/dist/workspace/dbt-models-reader.js +356 -0
  358. package/dist/workspace/dbt-project-common.d.ts +40 -0
  359. package/dist/workspace/dbt-project-common.d.ts.map +1 -0
  360. package/dist/workspace/dbt-project-common.js +106 -0
  361. package/dist/workspace/dbt-project-reader.d.ts +4 -3
  362. package/dist/workspace/dbt-project-reader.d.ts.map +1 -1
  363. package/dist/workspace/dbt-project-reader.js +14 -108
  364. package/dist/workspace/decision-rank.d.ts +26 -0
  365. package/dist/workspace/decision-rank.d.ts.map +1 -0
  366. package/dist/workspace/decision-rank.js +16 -0
  367. package/dist/workspace/declaration.d.ts +43 -2
  368. package/dist/workspace/declaration.d.ts.map +1 -1
  369. package/dist/workspace/declaration.js +45 -11
  370. package/dist/workspace/declaration.schema.json +133 -24
  371. package/dist/workspace/environments.d.ts +26 -2
  372. package/dist/workspace/environments.d.ts.map +1 -1
  373. package/dist/workspace/environments.js +26 -2
  374. package/dist/workspace/flyway-dir.d.ts +39 -0
  375. package/dist/workspace/flyway-dir.d.ts.map +1 -0
  376. package/dist/workspace/flyway-dir.js +104 -0
  377. package/dist/workspace/flyway-layout.d.ts +96 -0
  378. package/dist/workspace/flyway-layout.d.ts.map +1 -0
  379. package/dist/workspace/flyway-layout.js +308 -0
  380. package/dist/workspace/graph-cache.d.ts +8 -0
  381. package/dist/workspace/graph-cache.d.ts.map +1 -1
  382. package/dist/workspace/graph-cache.js +27 -3
  383. package/dist/workspace/graph-cli.d.ts +39 -2
  384. package/dist/workspace/graph-cli.d.ts.map +1 -1
  385. package/dist/workspace/graph-cli.js +92 -32
  386. package/dist/workspace/graph.schema.json +182 -0
  387. package/dist/workspace/intent.d.ts +2 -3
  388. package/dist/workspace/intent.d.ts.map +1 -1
  389. package/dist/workspace/intent.js +5 -9
  390. package/dist/workspace/kind-link-readers.d.ts +59 -2
  391. package/dist/workspace/kind-link-readers.d.ts.map +1 -1
  392. package/dist/workspace/kind-link-readers.js +17 -1
  393. package/dist/workspace/kind-readers.d.ts +3 -0
  394. package/dist/workspace/kind-readers.d.ts.map +1 -1
  395. package/dist/workspace/kind-readers.js +7 -1
  396. package/dist/workspace/kinds.d.ts +66 -2
  397. package/dist/workspace/kinds.d.ts.map +1 -1
  398. package/dist/workspace/kinds.js +98 -4
  399. package/dist/workspace/ledger.schema.json +158 -0
  400. package/dist/workspace/lexicon-outputs.d.ts +20 -1
  401. package/dist/workspace/lexicon-outputs.d.ts.map +1 -1
  402. package/dist/workspace/lexicon-outputs.js +102 -10
  403. package/dist/workspace/lineage-check.d.ts +3 -0
  404. package/dist/workspace/lineage-check.d.ts.map +1 -1
  405. package/dist/workspace/lineage-check.js +23 -4
  406. package/dist/workspace/links.d.ts +8 -1
  407. package/dist/workspace/links.d.ts.map +1 -1
  408. package/dist/workspace/links.js +25 -1
  409. package/dist/workspace/ls.d.ts +8 -0
  410. package/dist/workspace/ls.d.ts.map +1 -1
  411. package/dist/workspace/ls.js +7 -1
  412. package/dist/workspace/ls.schema.json +7 -0
  413. package/dist/workspace/member-commands.d.ts +10 -1
  414. package/dist/workspace/member-commands.d.ts.map +1 -1
  415. package/dist/workspace/member-commands.js +71 -6
  416. package/dist/workspace/migrate-links.d.ts +45 -0
  417. package/dist/workspace/migrate-links.d.ts.map +1 -0
  418. package/dist/workspace/migrate-links.js +100 -0
  419. package/dist/workspace/migration-dirs.d.ts +74 -0
  420. package/dist/workspace/migration-dirs.d.ts.map +1 -0
  421. package/dist/workspace/migration-dirs.js +254 -0
  422. package/dist/workspace/nested-graph.d.ts +2 -0
  423. package/dist/workspace/nested-graph.d.ts.map +1 -1
  424. package/dist/workspace/nested-graph.js +32 -1
  425. package/dist/workspace/reason-codes.d.ts +18 -0
  426. package/dist/workspace/reason-codes.d.ts.map +1 -1
  427. package/dist/workspace/reason-codes.js +23 -0
  428. package/dist/workspace/records-cli.d.ts +11 -0
  429. package/dist/workspace/records-cli.d.ts.map +1 -1
  430. package/dist/workspace/records-cli.js +57 -5
  431. package/dist/workspace/records.schema.json +5 -0
  432. package/dist/workspace/release-candidates.d.ts +2 -0
  433. package/dist/workspace/release-candidates.d.ts.map +1 -1
  434. package/dist/workspace/release-candidates.js +5 -2
  435. package/dist/workspace/release-train.d.ts +53 -0
  436. package/dist/workspace/release-train.d.ts.map +1 -0
  437. package/dist/workspace/release-train.js +134 -0
  438. package/dist/workspace/release-workflow.d.ts.map +1 -1
  439. package/dist/workspace/release-workflow.js +4 -3
  440. package/dist/workspace/repo-ref.d.ts +45 -0
  441. package/dist/workspace/repo-ref.d.ts.map +1 -0
  442. package/dist/workspace/repo-ref.js +114 -0
  443. package/dist/workspace/run-event.schema.json +2 -2
  444. package/dist/workspace/runs-cli.d.ts +9 -0
  445. package/dist/workspace/runs-cli.d.ts.map +1 -1
  446. package/dist/workspace/runs-cli.js +48 -3
  447. package/dist/workspace/runs.schema.json +7 -0
  448. package/dist/workspace/search-cli.d.ts +204 -0
  449. package/dist/workspace/search-cli.d.ts.map +1 -0
  450. package/dist/workspace/search-cli.js +466 -0
  451. package/dist/workspace/search-contract.d.ts +56 -0
  452. package/dist/workspace/search-contract.d.ts.map +1 -0
  453. package/dist/workspace/search-contract.js +70 -0
  454. package/dist/workspace/search.schema.json +822 -0
  455. package/dist/workspace/status-decisions.d.ts +37 -0
  456. package/dist/workspace/status-decisions.d.ts.map +1 -0
  457. package/dist/workspace/status-decisions.js +147 -0
  458. package/dist/workspace/status-gates.d.ts +9 -0
  459. package/dist/workspace/status-gates.d.ts.map +1 -1
  460. package/dist/workspace/status.d.ts +4 -0
  461. package/dist/workspace/status.d.ts.map +1 -1
  462. package/dist/workspace/status.js +14 -2
  463. package/dist/workspace/status.schema.json +6 -0
  464. package/dist/workspace/work-cli.d.ts.map +1 -1
  465. package/dist/workspace/work-cli.js +5 -3
  466. package/dist/workspace/work-evidence-ops.d.ts +83 -0
  467. package/dist/workspace/work-evidence-ops.d.ts.map +1 -0
  468. package/dist/workspace/work-evidence-ops.js +169 -0
  469. package/dist/workspace/work-evidence.d.ts +12 -2
  470. package/dist/workspace/work-evidence.d.ts.map +1 -1
  471. package/dist/workspace/work-evidence.js +21 -3
  472. package/dist/workspace/work-evidence.schema.json +49 -2
  473. package/dist/workspace/workspace-gates.d.ts +110 -0
  474. package/dist/workspace/workspace-gates.d.ts.map +1 -0
  475. package/dist/workspace/workspace-gates.js +140 -0
  476. package/dist/workspace/workspace-kinds.schema.json +58 -3
  477. package/dist/workspace/workspace-ledger.d.ts +76 -0
  478. package/dist/workspace/workspace-ledger.d.ts.map +1 -0
  479. package/dist/workspace/workspace-ledger.js +91 -0
  480. package/dist/workspace/workspace-run.d.ts +112 -0
  481. package/dist/workspace/workspace-run.d.ts.map +1 -0
  482. package/dist/workspace/workspace-run.js +432 -0
  483. package/package.json +1 -1
  484. package/src/__golden__/wave-loop/op-by-apply-after-fails.json +10 -0
  485. package/src/__golden__/wave-loop/op-by-apply-hold.json +10 -0
  486. package/src/__golden__/wave-loop/op-by-apply-ignored.json +10 -0
  487. package/src/__golden__/wave-loop/op-by-apply-pass.json +10 -0
  488. package/src/__golden__/wave-loop/op-by-apply-skip.json +10 -0
  489. package/src/__golden__/wave-loop/op-cost-member-clash.json +6 -0
  490. package/src/__golden__/wave-loop/op-cost-member.json +13 -0
  491. package/src/__golden__/wave-loop/op-denied-source.json +16 -0
  492. package/src/__golden__/wave-loop/op-denied.json +16 -0
  493. package/src/__golden__/wave-loop/op-discover-rest-short.json +6 -0
  494. package/src/__golden__/wave-loop/op-discover-rest-stops.json +13 -0
  495. package/src/__golden__/wave-loop/op-discover-rest.json +26 -0
  496. package/src/__golden__/wave-loop/op-discover-wide.json +26 -0
  497. package/src/__golden__/wave-loop/op-held-on-again.json +16 -0
  498. package/src/__golden__/wave-loop/op-held-on-before-apply.json +16 -0
  499. package/src/__golden__/wave-loop/op-held-on.json +16 -0
  500. package/src/__golden__/wave-loop/op-hooks-apply-fails.json +13 -0
  501. package/src/__golden__/wave-loop/op-hooks-fail-after-apply.json +13 -0
  502. package/src/__golden__/wave-loop/op-hooks-fail-before-apply.json +13 -0
  503. package/src/__golden__/wave-loop/op-hooks-fail-before-plan.json +13 -0
  504. package/src/__golden__/wave-loop/op-hooks-held.json +13 -0
  505. package/src/__golden__/wave-loop/op-hooks-hold-before-apply.json +13 -0
  506. package/src/__golden__/wave-loop/op-hooks-pass.json +13 -0
  507. package/src/__golden__/wave-loop/op-hooks-refused-at-base.json +13 -0
  508. package/src/__golden__/wave-loop/op-hooks-share.json +33 -0
  509. package/src/__golden__/wave-loop/op-outcome-held.json +10 -0
  510. package/src/__golden__/wave-loop/op-outcome-replan-approved.json +10 -0
  511. package/src/__golden__/wave-loop/op-outcome-replan-forever.json +10 -0
  512. package/src/__golden__/wave-loop/op-outcome-replan.json +10 -0
  513. package/src/__golden__/wave-loop/op-outcome-stood-down.json +10 -0
  514. package/src/__golden__/wave-loop/op-outcome-unreadable.json +10 -0
  515. package/src/__golden__/wave-loop/op-overridden.json +16 -0
  516. package/src/__golden__/wave-loop/op-per-run.json +20 -0
  517. package/src/__golden__/wave-loop/op-point.json +13 -0
  518. package/src/__golden__/wave-loop/op-pr-review.json +10 -0
  519. package/src/__golden__/wave-loop/op-sealed.json +10 -0
  520. package/src/__golden__/wave-loop/op-spend-change-only.json +10 -0
  521. package/src/__golden__/wave-loop/op-spend.json +10 -0
  522. package/src/__golden__/wave-loop/op-wave-commands.json +55 -0
  523. package/src/__golden__/wave-loop/op-wide-refused.json +26 -0
  524. package/src/__golden__/wave-loop/op-wide-waiting.json +29 -0
  525. package/src/__golden__/wave-loop/op-wide.json +39 -0
  526. package/src/__snapshots__/okf.test.ts.snap +10 -0
  527. package/src/action-pins.test.ts +78 -0
  528. package/src/action-pins.ts +92 -0
  529. package/src/capabilities/aws.paths +148 -0
  530. package/src/capabilities/base-mappings.json +122 -0
  531. package/src/capabilities/catalog.ts +230 -0
  532. package/src/capabilities/language.test.ts +191 -0
  533. package/src/capabilities/language.ts +373 -0
  534. package/src/capabilities/matcher.ts +315 -0
  535. package/src/capabilities/view-compose.test.ts +76 -0
  536. package/src/capabilities/view.ts +631 -0
  537. package/src/cli/commands/carve-score-once.test.ts +99 -0
  538. package/src/cli/commands/carve.ts +37 -6
  539. package/src/cli/commands/check-lexicon.test.ts +2 -2
  540. package/src/cli/commands/import-report.ts +71 -0
  541. package/src/cli/commands/import.ts +33 -3
  542. package/src/cli/commands/lint.ts +1 -0
  543. package/src/cli/commands/migrate-dialect.test.ts +145 -0
  544. package/src/cli/commands/migrate.ts +132 -11
  545. package/src/cli/handlers/__snapshots__/build-member.test.ts.snap +4 -4
  546. package/src/cli/handlers/approve.ts +23 -2
  547. package/src/cli/handlers/build.ts +7 -1
  548. package/src/cli/handlers/declared-graph.ts +99 -0
  549. package/src/cli/handlers/graph.test.ts +94 -3
  550. package/src/cli/handlers/graph.ts +123 -96
  551. package/src/cli/handlers/ledger.ts +54 -0
  552. package/src/cli/handlers/migrate.ts +21 -12
  553. package/src/cli/handlers/misc.ts +10 -1
  554. package/src/cli/handlers/pr-env.ts +3 -4
  555. package/src/cli/handlers/pr.ts +138 -36
  556. package/src/cli/handlers/query.ts +16 -4
  557. package/src/cli/handlers/release.ts +6 -3
  558. package/src/cli/handlers/search-build-roots.test.ts +144 -0
  559. package/src/cli/handlers/search-count.test.ts +191 -0
  560. package/src/cli/handlers/search-count.ts +165 -0
  561. package/src/cli/handlers/search-json.test.ts +333 -0
  562. package/src/cli/handlers/search-live.test.ts +387 -0
  563. package/src/cli/handlers/search-paths.test.ts +235 -0
  564. package/src/cli/handlers/search.ts +1291 -166
  565. package/src/cli/main.test.ts +43 -3
  566. package/src/cli/main.ts +88 -17
  567. package/src/cli/mcp/server.test.ts +3 -3
  568. package/src/cli/mcp/server.ts +3 -0
  569. package/src/cli/mcp/tools/capabilities.ts +32 -0
  570. package/src/cli/mcp/workspace-tools.e2e.test.ts +21 -1
  571. package/src/cli/mcp/workspace-tools.ts +47 -2
  572. package/src/cli/parse-args.ts +79 -15
  573. package/src/cli/registry.ts +36 -4
  574. package/src/components/builders.ts +8 -0
  575. package/src/components/capability-plugin-loader.ts +13 -1
  576. package/src/components/capability-plugin.ts +16 -0
  577. package/src/components/pr-env-ports.ts +89 -0
  578. package/src/components/pr-env-run-bundle.test.ts +54 -0
  579. package/src/components/pr-env-run.ts +5 -76
  580. package/src/components/pr-environment.ts +2 -1
  581. package/src/components/pr-hooks.test.ts +73 -5
  582. package/src/components/pr-hooks.ts +95 -5
  583. package/src/components/pr-pipeline.ts +64 -16
  584. package/src/components/pr-policy.test.ts +64 -1
  585. package/src/components/pr-policy.ts +53 -0
  586. package/src/components/registry.test.ts +1 -1
  587. package/src/components/starter-plugin.ts +6 -0
  588. package/src/components/verbs/index.ts +2 -0
  589. package/src/components/verbs/publish-artifact.test.ts +60 -0
  590. package/src/components/verbs/publish-artifact.ts +122 -0
  591. package/src/components/verbs/publish-image.test.ts +101 -0
  592. package/src/components/verbs/publish-image.ts +265 -0
  593. package/src/config-environments.ts +160 -0
  594. package/src/config.ts +44 -124
  595. package/src/gate-decision-bundle.test.ts +1 -0
  596. package/src/gate-decision-identity.test.ts +9 -0
  597. package/src/gate-decision.ts +26 -3
  598. package/src/graph-detail.ts +15 -3
  599. package/src/graph-effective.ts +226 -75
  600. package/src/graph-ir.test.ts +163 -0
  601. package/src/graph-ir.ts +174 -0
  602. package/src/graph-sub-template.ts +22 -0
  603. package/src/graph-walk.test.ts +44 -0
  604. package/src/graph-walk.ts +102 -0
  605. package/src/import/parser.ts +20 -0
  606. package/src/lexicon.ts +84 -6
  607. package/src/lifecycle/gate-ledger.ts +8 -0
  608. package/src/lifecycle/git.ts +2 -2
  609. package/src/lifecycle/ledger-read.test.ts +107 -0
  610. package/src/lifecycle/ledger-read.ts +195 -0
  611. package/src/lifecycle/observe.test.ts +27 -1
  612. package/src/lifecycle/observe.ts +43 -1
  613. package/src/lifecycle/release-workstation.ts +24 -0
  614. package/src/lifecycle/run-ledger.ts +5 -2
  615. package/src/lint/cross-root.test.ts +122 -0
  616. package/src/lint/discover.ts +3 -1
  617. package/src/lint/post-synth.ts +212 -2
  618. package/src/lint/rule.ts +6 -0
  619. package/src/lint/rules/op/index.ts +2 -0
  620. package/src/lint/rules/op/ops019-workspace-op-target.ts +89 -0
  621. package/src/live-endpoint.ts +1 -1
  622. package/src/observation.test.ts +25 -0
  623. package/src/observation.ts +69 -5
  624. package/src/op/activities/activity-contracts.ts +5 -2
  625. package/src/op/activities/index.ts +2 -2
  626. package/src/op/activities/review-agent.test.ts +221 -4
  627. package/src/op/activities/review-agent.ts +265 -22
  628. package/src/op/activities/work-evidence.ts +9 -1
  629. package/src/op/builders.ts +9 -5
  630. package/src/op/composites/apply-op.test.ts +108 -0
  631. package/src/op/composites/apply-op.ts +37 -2
  632. package/src/op/gate-approval.test.ts +6 -1
  633. package/src/op/gate-approval.ts +12 -6
  634. package/src/op/gate-quorum-at-base.test.ts +211 -0
  635. package/src/op/gate-quorum.ts +156 -8
  636. package/src/op/gate-review.ts +14 -0
  637. package/src/op/gate.ts +67 -8
  638. package/src/op/index.ts +3 -2
  639. package/src/op/local-executor.ts +69 -9
  640. package/src/op/op-waves-depends-on.test.ts +81 -0
  641. package/src/op/op-waves-hook-targets.test.ts +4 -2
  642. package/src/op/op-waves-quorum-product.test.ts +158 -0
  643. package/src/op/op-waves-run.ts +288 -14
  644. package/src/op/op-waves.ts +143 -14
  645. package/src/op/runtime.ts +8 -0
  646. package/src/op/schedule-overdue.ts +33 -0
  647. package/src/op/stage-hooks.ts +13 -5
  648. package/src/op/workspace-run-env.ts +29 -0
  649. package/src/pr-forge-bundle.test.ts +2 -2
  650. package/src/pr-forge.test.ts +47 -0
  651. package/src/pr-forge.ts +68 -0
  652. package/src/pr-post-open.e2e.test.ts +36 -0
  653. package/src/pr-post.test.ts +102 -3
  654. package/src/pr-post.ts +89 -1
  655. package/src/read-filter.test.ts +54 -0
  656. package/src/read-filter.ts +193 -0
  657. package/src/run-event.ts +1 -1
  658. package/src/stage-hooks-bundle.test.ts +1 -0
  659. package/src/terraform/carve.ts +52 -15
  660. package/src/terraform/cuts.test.ts +173 -0
  661. package/src/terraform/cuts.ts +188 -0
  662. package/src/terraform/folds.ts +44 -0
  663. package/src/terraform/graph.ts +9 -0
  664. package/src/terraform/radius.test.ts +90 -0
  665. package/src/terraform/reach.test.ts +146 -0
  666. package/src/terraform/reach.ts +247 -0
  667. package/src/terraform/score.ts +27 -29
  668. package/src/terraform/state.ts +3 -1
  669. package/src/terraform/types.ts +8 -0
  670. package/src/wave-blocked.ts +28 -3
  671. package/src/wave-loop-golden.test.ts +4 -3
  672. package/src/workspace/behold-kinds.test.ts +1 -1
  673. package/src/workspace/capabilities-contract.test.ts +88 -0
  674. package/src/workspace/capabilities-contract.ts +132 -0
  675. package/src/workspace/capabilities.schema.json +229 -0
  676. package/src/workspace/check-contract.test.ts +7 -6
  677. package/src/workspace/check.schema.json +11 -2
  678. package/src/workspace/checks/ci-branch.test.ts +128 -0
  679. package/src/workspace/checks/ci-branch.ts +141 -0
  680. package/src/workspace/checks/links.ts +12 -1
  681. package/src/workspace/checks/org.ts +169 -0
  682. package/src/workspace/checks.ts +64 -7
  683. package/src/workspace/ci-branches.ts +31 -0
  684. package/src/workspace/ci-green-branches.test.ts +153 -0
  685. package/src/workspace/ci-green-cli.ts +7 -7
  686. package/src/workspace/ci-green-workflow.test.ts +4 -3
  687. package/src/workspace/ci-green-workflow.ts +13 -9
  688. package/src/workspace/ci-green.ts +49 -12
  689. package/src/workspace/ci-run.test.ts +72 -1
  690. package/src/workspace/ci-run.ts +68 -8
  691. package/src/workspace/ci-serve.test.ts +95 -0
  692. package/src/workspace/ci-serve.ts +106 -65
  693. package/src/workspace/component-environments.test.ts +25 -2
  694. package/src/workspace/compose-graph.ts +19 -3
  695. package/src/workspace/composites.schema.json +22 -0
  696. package/src/workspace/composites.test.ts +39 -8
  697. package/src/workspace/composites.ts +6 -2
  698. package/src/workspace/conformance/__writer_fixture__/work/work.schema.json +105 -1
  699. package/src/workspace/conformance/conformance.e2e.test.ts +14 -1
  700. package/src/workspace/conformance/index.ts +31 -2
  701. package/src/workspace/cross-root-lint.test.ts +90 -0
  702. package/src/workspace/cross-root-lint.ts +126 -0
  703. package/src/workspace/dbt-kind.test.ts +3 -2
  704. package/src/workspace/dbt-models-reader.ts +362 -0
  705. package/src/workspace/dbt-models.test.ts +248 -0
  706. package/src/workspace/dbt-project-common.ts +113 -0
  707. package/src/workspace/dbt-project-reader.ts +29 -112
  708. package/src/workspace/decision-rank.ts +40 -0
  709. package/src/workspace/declaration.schema.json +133 -24
  710. package/src/workspace/declaration.ts +84 -15
  711. package/src/workspace/environments.ts +40 -4
  712. package/src/workspace/flyway-dir.ts +113 -0
  713. package/src/workspace/flyway-layout.ts +337 -0
  714. package/src/workspace/graph-cache.ts +27 -3
  715. package/src/workspace/graph-cli.ts +119 -32
  716. package/src/workspace/graph-contract.test.ts +4 -2
  717. package/src/workspace/graph.schema.json +182 -0
  718. package/src/workspace/identity.test.ts +14 -2
  719. package/src/workspace/intent.ts +6 -14
  720. package/src/workspace/kind-link-readers.ts +68 -3
  721. package/src/workspace/kind-readers.e2e.test.ts +28 -0
  722. package/src/workspace/kind-readers.test.ts +1 -1
  723. package/src/workspace/kind-readers.ts +7 -1
  724. package/src/workspace/kinds.test.ts +12 -7
  725. package/src/workspace/kinds.ts +132 -7
  726. package/src/workspace/ledger.schema.json +158 -0
  727. package/src/workspace/lexicon-outputs.ts +132 -13
  728. package/src/workspace/lineage-check.ts +30 -7
  729. package/src/workspace/links.ts +24 -1
  730. package/src/workspace/ls-contract.test.ts +1 -1
  731. package/src/workspace/ls.schema.json +7 -0
  732. package/src/workspace/ls.ts +10 -1
  733. package/src/workspace/member-commands.ts +82 -3
  734. package/src/workspace/member-file-schema.test.ts +124 -0
  735. package/src/workspace/migrate-links.test.ts +99 -0
  736. package/src/workspace/migrate-links.ts +108 -0
  737. package/src/workspace/migration-dirs.test.ts +272 -0
  738. package/src/workspace/migration-dirs.ts +267 -0
  739. package/src/workspace/nested-graph.ts +32 -1
  740. package/src/workspace/org-scope.test.ts +238 -0
  741. package/src/workspace/reason-codes.test.ts +13 -1
  742. package/src/workspace/reason-codes.ts +23 -0
  743. package/src/workspace/records-cli.ts +58 -5
  744. package/src/workspace/records.schema.json +5 -0
  745. package/src/workspace/release-candidates.ts +7 -2
  746. package/src/workspace/release-train.ts +157 -0
  747. package/src/workspace/release-workflow.ts +4 -3
  748. package/src/workspace/repo-ref.ts +113 -0
  749. package/src/workspace/run-event.schema.json +2 -2
  750. package/src/workspace/runs-cli.ts +48 -4
  751. package/src/workspace/runs.schema.json +7 -0
  752. package/src/workspace/search-cli.e2e.test.ts +305 -0
  753. package/src/workspace/search-cli.ts +591 -0
  754. package/src/workspace/search-contract.ts +95 -0
  755. package/src/workspace/search.schema.json +822 -0
  756. package/src/workspace/status-contract.test.ts +46 -1
  757. package/src/workspace/status-decisions.test.ts +100 -0
  758. package/src/workspace/status-decisions.ts +151 -0
  759. package/src/workspace/status-gates.ts +9 -0
  760. package/src/workspace/status.schema.json +6 -0
  761. package/src/workspace/status.ts +17 -3
  762. package/src/workspace/where-filters.test.ts +39 -0
  763. package/src/workspace/work-cli.ts +5 -3
  764. package/src/workspace/work-evidence-ops.test.ts +176 -0
  765. package/src/workspace/work-evidence-ops.ts +189 -0
  766. package/src/workspace/work-evidence.schema.json +49 -2
  767. package/src/workspace/work-evidence.ts +22 -3
  768. package/src/workspace/workspace-gates.ts +200 -0
  769. package/src/workspace/workspace-kinds.schema.json +58 -3
  770. package/src/workspace/workspace-ledger.ts +130 -0
  771. package/src/workspace/workspace-run.test.ts +322 -0
  772. package/src/workspace/workspace-run.ts +461 -0
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Org scope (#3168): members of kind `repo`, which name another repository's
3
+ * workspace by URL and pinned revision, and the org-level workspace that
4
+ * holds only such members.
5
+ *
6
+ * | Id | Check |
7
+ * |---|---|
8
+ * | WSP013 | an org workspace holds only repo members |
9
+ * | WSP014 | every repository the forge lists is declared (with `--forge-repos`) |
10
+ * | WSP015 | every declared repository is one the forge lists (with `--forge-repos`) |
11
+ * | WSP016 | no repo member's URL carries a password or token |
12
+ *
13
+ * The forge's list is input, never fetched here: a warden enumerates the
14
+ * org's repositories from its own API and hands the list to
15
+ * `chant workspace check --forge-repos <file>`, so the check stays offline.
16
+ */
17
+ import type { WorkspaceCheck } from "../checks.js";
18
+ /** One repository the forge lists. */
19
+ export interface ForgeRepo {
20
+ url: string;
21
+ /** An archived repository need not be declared, and declaring one is not a drop. */
22
+ archived: boolean;
23
+ }
24
+ /** The forge's repository list for `--forge-repos` (#3168), as a warden writes it. */
25
+ export interface ForgeRepoList {
26
+ /** The file it was read from, for messages. */
27
+ source: string;
28
+ repos: ForgeRepo[];
29
+ }
30
+ /**
31
+ * Parse a forge repository list. Three shapes are read: `{ "repos": [...] }`
32
+ * (a warden may add `forge` and `org` beside it), a bare array, and, for each
33
+ * repository, a URL string or `{ "url", "archived"? }`. Throws an Error that
34
+ * says what is wrong.
35
+ */
36
+ export declare function parseForgeRepos(text: string, source: string): ForgeRepoList;
37
+ /**
38
+ * A repository URL reduced to what names the repository, so the forge's
39
+ * https URL and a declaration's ssh or scp-style URL compare equal:
40
+ * `host/owner/repo`, lowercased, with no scheme, user, port, `.git` or
41
+ * trailing slash. A local path or file URL becomes its absolute path,
42
+ * resolved from `base`.
43
+ */
44
+ export declare function repoKey(url: string, base?: string): string;
45
+ /** Whether a URL carries a password or token, which a declaration must never hold. */
46
+ export declare function urlCredential(url: string): boolean;
47
+ export declare const ORG_CHECKS: readonly WorkspaceCheck[];
48
+ //# sourceMappingURL=org.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"org.d.ts","sourceRoot":"","sources":["../../../src/workspace/checks/org.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAuB,MAAM,WAAW,CAAC;AAErE,sCAAsC;AACtC,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,oFAAoF;IACpF,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,sFAAsF;AACtF,MAAM,WAAW,aAAa;IAC5B,+CAA+C;IAC/C,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,SAAS,EAAE,CAAC;CACpB;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,aAAa,CAiB3E;AAED;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,GAAE,MAAsB,GAAG,MAAM,CAmBzE;AAMD,sFAAsF;AACtF,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CASlD;AAQD,eAAO,MAAM,UAAU,EAAE,SAAS,cAAc,EA0D/C,CAAC"}
@@ -0,0 +1,156 @@
1
+ /**
2
+ * Org scope (#3168): members of kind `repo`, which name another repository's
3
+ * workspace by URL and pinned revision, and the org-level workspace that
4
+ * holds only such members.
5
+ *
6
+ * | Id | Check |
7
+ * |---|---|
8
+ * | WSP013 | an org workspace holds only repo members |
9
+ * | WSP014 | every repository the forge lists is declared (with `--forge-repos`) |
10
+ * | WSP015 | every declared repository is one the forge lists (with `--forge-repos`) |
11
+ * | WSP016 | no repo member's URL carries a password or token |
12
+ *
13
+ * The forge's list is input, never fetched here: a warden enumerates the
14
+ * org's repositories from its own API and hands the list to
15
+ * `chant workspace check --forge-repos <file>`, so the check stays offline.
16
+ */
17
+ import { isAbsolute, resolve } from "node:path";
18
+ import { REPO_KIND } from "../kinds.js";
19
+ /**
20
+ * Parse a forge repository list. Three shapes are read: `{ "repos": [...] }`
21
+ * (a warden may add `forge` and `org` beside it), a bare array, and, for each
22
+ * repository, a URL string or `{ "url", "archived"? }`. Throws an Error that
23
+ * says what is wrong.
24
+ */
25
+ export function parseForgeRepos(text, source) {
26
+ let raw;
27
+ try {
28
+ raw = JSON.parse(text);
29
+ }
30
+ catch (err) {
31
+ throw new Error(`${source} is not JSON (${err.message})`);
32
+ }
33
+ const list = Array.isArray(raw) ? raw : raw !== null && typeof raw === "object" && Array.isArray(raw.repos) ? raw.repos : undefined;
34
+ if (!list)
35
+ throw new Error(`${source} is neither an array of repositories nor an object with a repos array`);
36
+ const repos = list.map((r, i) => {
37
+ if (typeof r === "string" && r.length > 0)
38
+ return { url: r, archived: false };
39
+ if (r !== null && typeof r === "object" && typeof r.url === "string") {
40
+ return { url: r.url, archived: r.archived === true };
41
+ }
42
+ throw new Error(`${source}: repos[${i}] is neither a URL nor an object with a url`);
43
+ });
44
+ return { source, repos };
45
+ }
46
+ /**
47
+ * A repository URL reduced to what names the repository, so the forge's
48
+ * https URL and a declaration's ssh or scp-style URL compare equal:
49
+ * `host/owner/repo`, lowercased, with no scheme, user, port, `.git` or
50
+ * trailing slash. A local path or file URL becomes its absolute path,
51
+ * resolved from `base`.
52
+ */
53
+ export function repoKey(url, base = process.cwd()) {
54
+ const trimmed = url.trim();
55
+ const scp = /^(?:[^@/\s]+@)?([^:/\s]+):(?!\/\/)(.+)$/.exec(trimmed);
56
+ let hostPath;
57
+ if (/^[a-z][a-z0-9+.-]*:\/\//i.test(trimmed)) {
58
+ let u;
59
+ try {
60
+ u = new URL(trimmed);
61
+ }
62
+ catch {
63
+ return trimmed.toLowerCase();
64
+ }
65
+ if (u.protocol === "file:")
66
+ return stripGit(decodeURIComponent(u.pathname));
67
+ hostPath = `${u.hostname}${u.pathname}`;
68
+ }
69
+ else if (scp && !isAbsolute(trimmed) && !/^[a-z]:[\\/]/i.test(trimmed)) {
70
+ hostPath = `${scp[1]}/${scp[2]}`;
71
+ }
72
+ else {
73
+ return stripGit(resolve(base, trimmed));
74
+ }
75
+ return stripGit(hostPath.replace(/\/+/g, "/")).toLowerCase();
76
+ }
77
+ function stripGit(path) {
78
+ return path.replace(/\/+$/, "").replace(/\.git$/, "");
79
+ }
80
+ /** Whether a URL carries a password or token, which a declaration must never hold. */
81
+ export function urlCredential(url) {
82
+ if (!/^[a-z][a-z0-9+.-]*:\/\//i.test(url))
83
+ return false;
84
+ try {
85
+ const u = new URL(url);
86
+ // ssh://git@host is a user name, not a secret; a password, or any user on http(s), is one.
87
+ return u.password !== "" || (u.username !== "" && /^https?:$/.test(u.protocol));
88
+ }
89
+ catch {
90
+ return false;
91
+ }
92
+ }
93
+ const repoMembers = (ctx) => ctx.declaration.members.filter((m) => m.kind === REPO_KIND && m.repo !== null);
94
+ function finding(check, message, pointer, entity) {
95
+ return { checkId: check.id, severity: check.severity, message, pointer, ...(entity !== undefined ? { entity } : {}) };
96
+ }
97
+ export const ORG_CHECKS = [
98
+ {
99
+ id: "WSP013",
100
+ name: "org-member-local",
101
+ description: "An org workspace (scope org) holds only members of kind repo, each a reference to another repository's workspace (#3168).",
102
+ severity: "error",
103
+ configurable: false,
104
+ check(ctx) {
105
+ if (ctx.declaration.scope !== "org")
106
+ return [];
107
+ return ctx.declaration.entries
108
+ .filter((e) => e.kind !== REPO_KIND)
109
+ .map((e) => finding(this, `${e.type === "group" ? "example group" : "member"} ${e.name} is kind ${e.kind}, and an org workspace holds only repo members; move it into a repository's own workspace and reference that`, `${e.pointer}/kind`, e.name));
110
+ },
111
+ },
112
+ {
113
+ id: "WSP014",
114
+ name: "org-repo-undeclared",
115
+ description: "With --forge-repos, every repository the forge lists, archived ones aside, is named by a repo member (#3168).",
116
+ severity: "error",
117
+ configurable: true,
118
+ check(ctx) {
119
+ const forge = ctx.facts?.forgeRepos;
120
+ if (!forge)
121
+ return [];
122
+ const declared = new Set(repoMembers(ctx).map((m) => repoKey(m.repo.url)));
123
+ return forge.repos
124
+ .filter((r) => !r.archived && !declared.has(repoKey(r.url)))
125
+ .map((r) => finding(this, `the forge lists ${r.url} (${forge.source}), and no repo member names it; add a member of kind repo with its url and pinned rev`, "/members"));
126
+ },
127
+ },
128
+ {
129
+ id: "WSP015",
130
+ name: "org-repo-dropped",
131
+ description: "With --forge-repos, every repository a repo member names is one the forge still lists (#3168).",
132
+ severity: "warning",
133
+ configurable: true,
134
+ check(ctx) {
135
+ const forge = ctx.facts?.forgeRepos;
136
+ if (!forge)
137
+ return [];
138
+ const listed = new Set(forge.repos.map((r) => repoKey(r.url)));
139
+ return repoMembers(ctx)
140
+ .filter((m) => !listed.has(repoKey(m.repo.url)))
141
+ .map((m) => finding(this, `member ${m.name} names ${m.repo.url}, which the forge no longer lists (${forge.source}); remove the member or say why it stays`, `${m.pointer}/repo/url`, m.name));
142
+ },
143
+ },
144
+ {
145
+ id: "WSP016",
146
+ name: "repo-url-credential",
147
+ description: "No repo member's URL carries a password or token: the declaration is committed, and git's own credential helpers supply access (#3168).",
148
+ severity: "error",
149
+ configurable: false,
150
+ check(ctx) {
151
+ return repoMembers(ctx)
152
+ .filter((m) => urlCredential(m.repo.url))
153
+ .map((m) => finding(this, `member ${m.name}'s repo url carries a credential; name the repository without one and let git's credential helper supply access`, `${m.pointer}/repo/url`, m.name));
154
+ },
155
+ },
156
+ ];
@@ -21,7 +21,8 @@
21
21
  *
22
22
  * | Ids | Checks |
23
23
  * |---|---|
24
- * | WSP001 to WSP011 | the declaration and member kinds (this file) |
24
+ * | WSP001 to WSP012 | the declaration and member kinds (this file), and a member's file against its kind's schema (#3672) |
25
+ * | WSP013 to WSP016 | org scope: repo members and the org workspace, checked against the forge's list with `--forge-repos` (#3168) |
25
26
  * | WSP071, WSP072 | member ledgers |
26
27
  * | WSP081 to WSP083 | recorded pipelines |
27
28
  * | WSP091 to WSP099 | member links (#2539, #2558), and those a kind's reader finds in a member's files (#3932) |
@@ -38,6 +39,7 @@
38
39
  * | WSP141, WSP142 | member links resolved against a live read, with `--live` (#2549) |
39
40
  * | WSP131 to WSP133 | diagram artifacts: source and render exist, a recorded source hash still matches (#2764) |
40
41
  * | WSP151 | what a member under `ci.workflow` still lacks (#4168 step 6) |
42
+ * | WSP152 | a member's generated pipeline targets the branch `ci.branches` routes it to (#4325) |
41
43
  * | WSP161 to WSP165 | the security groups the declaration opts into: what each still lacks (#4168 step 7) |
42
44
  */
43
45
  import type { LintDiagnostic, LintRule, Severity } from "../lint/rule.js";
@@ -53,9 +55,11 @@ import { type MemberLedgerFacts } from "./checks/ledgers.js";
53
55
  import { type MemberPipelineFacts } from "./checks/pipelines.js";
54
56
  import { type LiveLinkFacts } from "./checks/live.js";
55
57
  import { type RecordFacts } from "./checks/records.js";
58
+ import { type ForgeRepoList } from "./checks/org.js";
56
59
  import { type DeclaredKind } from "./declared-kinds.js";
57
60
  import { type ResolvedBoxIntent } from "./box-intent.js";
58
61
  import { type MemberLexiconOutputs } from "./lexicon-outputs.js";
62
+ import type { KindLinkRead } from "./kind-link-readers.js";
59
63
  /**
60
64
  * What the checks beyond the declaration read, gathered from the checkout
61
65
  * before any check runs. A field left out was not gathered, and the checks
@@ -78,6 +82,10 @@ export interface WorkspaceFacts {
78
82
  boxIntents?: readonly ResolvedBoxIntent[];
79
83
  /** The outputs linked members' lexicons report about their declarations, read by folding their source (#3931). */
80
84
  lexiconOutputs?: ReadonlyMap<string, MemberLexiconOutputs>;
85
+ /** The links members' lexicons read from their declarations, such as an otel clickhouse exporter's tables (#4397). */
86
+ lexiconLinks?: ReadonlyMap<string, KindLinkRead>;
87
+ /** The forge's repository list, from `--forge-repos` (#3168). */
88
+ forgeRepos?: ForgeRepoList;
81
89
  }
82
90
  /** What every declaration check reads. */
83
91
  export interface WorkspaceCheckContext {
@@ -195,6 +203,8 @@ export interface DeclarationCheckOptions {
195
203
  env: string;
196
204
  onStderr?: (text: string) => void;
197
205
  };
206
+ /** The forge's repository list, from `--forge-repos` (#3168), for WSP014 and WSP015. Read under `--at` too: it is input, not the tree. */
207
+ forgeRepos?: ForgeRepoList;
198
208
  }
199
209
  /**
200
210
  * Gather {@link WorkspaceFacts} for the declaration in `root`. Member
@@ -1 +1 @@
1
- {"version":3,"file":"checks.d.ts","sourceRoot":"","sources":["../../src/workspace/checks.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"checks.d.ts","sourceRoot":"","sources":["../../src/workspace/checks.ts"],"names":[],"mappings":"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"}
@@ -21,7 +21,8 @@
21
21
  *
22
22
  * | Ids | Checks |
23
23
  * |---|---|
24
- * | WSP001 to WSP011 | the declaration and member kinds (this file) |
24
+ * | WSP001 to WSP012 | the declaration and member kinds (this file), and a member's file against its kind's schema (#3672) |
25
+ * | WSP013 to WSP016 | org scope: repo members and the org workspace, checked against the forge's list with `--forge-repos` (#3168) |
25
26
  * | WSP071, WSP072 | member ledgers |
26
27
  * | WSP081 to WSP083 | recorded pipelines |
27
28
  * | WSP091 to WSP099 | member links (#2539, #2558), and those a kind's reader finds in a member's files (#3932) |
@@ -38,13 +39,14 @@
38
39
  * | WSP141, WSP142 | member links resolved against a live read, with `--live` (#2549) |
39
40
  * | WSP131 to WSP133 | diagram artifacts: source and render exist, a recorded source hash still matches (#2764) |
40
41
  * | WSP151 | what a member under `ci.workflow` still lacks (#4168 step 6) |
42
+ * | WSP152 | a member's generated pipeline targets the branch `ci.branches` routes it to (#4325) |
41
43
  * | WSP161 to WSP165 | the security groups the declaration opts into: what each still lacks (#4168 step 7) |
42
44
  */
43
45
  import { realpathSync } from "node:fs";
44
46
  import { relative, sep } from "node:path";
45
47
  import { readDeclaration, resolveGroups, WorkspaceReadError } from "./declaration.js";
46
48
  import { parseJsonText, pointerToken } from "./jsonc.js";
47
- import { loadKindRegistry, probeKind, resolveKind, resolveMemberFields } from "./kinds.js";
49
+ import { checkMemberFile, loadKindRegistry, probeKind, REPO_KIND, resolveKind, resolveMemberFields } from "./kinds.js";
48
50
  import { coreClassRegistry, loadClassRegistry, unknownScopeClasses } from "./principal-classes.js";
49
51
  import { gitTop, workingTree } from "./tree.js";
50
52
  import { LINK_CHECKS, linkTable } from "./checks/links.js";
@@ -57,9 +59,11 @@ import { BOX_CHECKS } from "./checks/boxes.js";
57
59
  import { DIAGRAM_CHECKS } from "./checks/diagrams.js";
58
60
  import { SECURITY_CHECKS } from "./checks/security.js";
59
61
  import { CI_WORKFLOW_CHECKS } from "./checks/ci-workflow.js";
62
+ import { CI_BRANCH_CHECKS } from "./checks/ci-branch.js";
63
+ import { ORG_CHECKS } from "./checks/org.js";
60
64
  import { loadDeclaredKinds } from "./declared-kinds.js";
61
65
  import { resolveBoxIntents } from "./box-intent.js";
62
- import { gatherLexiconOutputs } from "./lexicon-outputs.js";
66
+ import { gatherLexiconLinks, gatherLexiconOutputs } from "./lexicon-outputs.js";
63
67
  const HELP = "https://intentius.io/chant/cli/workspace-check/#declaration-checks";
64
68
  const memberDir = (dir) => (dir === "." ? "" : dir);
65
69
  function entryFinding(check, entry, field, message) {
@@ -71,9 +75,9 @@ function entryFinding(check, entry, field, message) {
71
75
  pointer: field ? `${entry.pointer}/${field}` : entry.pointer,
72
76
  };
73
77
  }
74
- /** The dir exists and the kind is known: the members every probe check reads. */
78
+ /** The dir exists and the kind is known: the members every probe check reads. A repo member has no directory here (#3168). */
75
79
  function readableMembers(ctx) {
76
- return ctx.declaration.members.filter((m) => ctx.tree.stat(memberDir(m.dir)) === "dir" && ctx.kinds.get(m.kind) !== undefined);
80
+ return ctx.declaration.members.filter((m) => m.kind !== REPO_KIND && ctx.tree.stat(memberDir(m.dir)) === "dir" && ctx.kinds.get(m.kind) !== undefined);
77
81
  }
78
82
  /** The first id of the read failure, used by {@link runDeclarationChecks} when the declaration can't be read. */
79
83
  export const UNREADABLE_CHECK_ID = "WSP001";
@@ -136,7 +140,7 @@ export const WORKSPACE_CHECKS = [
136
140
  configurable: true,
137
141
  check(ctx) {
138
142
  return ctx.declaration.members
139
- .filter((m) => ctx.tree.stat(memberDir(m.dir)) !== "dir")
143
+ .filter((m) => m.kind !== REPO_KIND && ctx.tree.stat(memberDir(m.dir)) !== "dir")
140
144
  .map((m) => entryFinding(this, m, "dir", `member ${m.name}'s directory ${m.dir} does not exist${ctx.tree.label}`));
141
145
  },
142
146
  },
@@ -258,6 +262,45 @@ export const WORKSPACE_CHECKS = [
258
262
  return out;
259
263
  },
260
264
  },
265
+ {
266
+ id: "WSP012",
267
+ name: "member-file-invalid",
268
+ description: "Every member of a kind that names a member file has that file, and it passes the kind's JSON Schema (#3672).",
269
+ severity: "error",
270
+ configurable: true,
271
+ check(ctx) {
272
+ const out = [];
273
+ for (const m of readableMembers(ctx)) {
274
+ const kind = ctx.kinds.get(m.kind);
275
+ const mf = kind.memberFile;
276
+ if (!mf)
277
+ continue;
278
+ const file = memberDir(m.dir) === "" ? mf.path : `${memberDir(m.dir)}/${mf.path}`;
279
+ if (!mf.validate) {
280
+ out.push(entryFinding(this, m, "kind", `member ${m.name}'s ${mf.path} can't be checked: kind ${m.kind}'s schema ${mf.schema} did not load (see WSP002)`));
281
+ continue;
282
+ }
283
+ if (ctx.tree.stat(file) !== "file") {
284
+ out.push(entryFinding(this, m, "dir", `member ${m.name} (${m.dir}) has no ${mf.path}, which kind ${m.kind} requires${ctx.tree.label}`));
285
+ continue;
286
+ }
287
+ let text;
288
+ try {
289
+ text = ctx.tree.read(file);
290
+ }
291
+ catch (err) {
292
+ out.push(entryFinding(this, m, "dir", `member ${m.name}'s ${mf.path} can't be read: ${err.message}`));
293
+ continue;
294
+ }
295
+ for (const p of checkMemberFile(mf, mf.path, text)) {
296
+ out.push({ ...entryFinding(this, m, null, `member ${m.name}'s ${mf.path} fails kind ${m.kind}'s schema ${mf.schema}: ${p.message}`), treeFile: file, line: 1, column: 1 });
297
+ }
298
+ }
299
+ return out;
300
+ },
301
+ },
302
+ // Org scope (#3168), WSP013 to WSP016.
303
+ ...ORG_CHECKS,
261
304
  // Member ledgers (#2538).
262
305
  ...LEDGER_CHECKS,
263
306
  // Recorded pipelines (#2542).
@@ -276,6 +319,8 @@ export const WORKSPACE_CHECKS = [
276
319
  ...LIVE_CHECKS,
277
320
  // What a member under ci.workflow still lacks (#4168 step 6), WSP151.
278
321
  ...CI_WORKFLOW_CHECKS,
322
+ // A member's pipeline targets the branch ci.branches routes it to (#4325), WSP152.
323
+ ...CI_BRANCH_CHECKS,
279
324
  // The security groups the declaration opts into (#4168 step 7), WSP161 to WSP165.
280
325
  ...SECURITY_CHECKS,
281
326
  ];
@@ -399,11 +444,18 @@ export async function runDeclarationChecks(root, display = (f) => f, options = {
399
444
  // A box's intent is read from the working tree's records, so not under --at (#2850).
400
445
  const boxIntents = declaredKinds && !options.tree ? await resolveBoxIntents(declaration, root, declaredKinds) : undefined;
401
446
  // A linked member's lexicons name its tables and columns as outputs (#3931); reading them folds its source, never runs it.
402
- const lexiconOutputs = options.gather === false ? undefined : await gatherLexiconOutputs(root, declaration, options.tree ? workingTree(root) : tree, groups, registry, { atRevision: options.tree !== undefined });
447
+ // A member's lexicons may also read other members' outputs from its declarations (#4397); their targets are read too.
448
+ const outputsTree = options.tree ? workingTree(root) : tree;
449
+ const lexiconLinks = options.gather === false ? undefined : await gatherLexiconLinks(root, declaration, outputsTree, groups, registry, { atRevision: options.tree !== undefined });
450
+ const lexiconOutputs = options.gather === false
451
+ ? undefined
452
+ : await gatherLexiconOutputs(root, declaration, outputsTree, groups, registry, { atRevision: options.tree !== undefined, ...(lexiconLinks ? { lexiconLinks } : {}) });
403
453
  const facts = {
404
454
  ...(lexiconOutputs && lexiconOutputs.size > 0 ? { lexiconOutputs } : {}),
455
+ ...(lexiconLinks && lexiconLinks.size > 0 ? { lexiconLinks } : {}),
405
456
  ...gathered,
406
457
  ...(options.records ? { records: options.records } : {}),
458
+ ...(options.forgeRepos ? { forgeRepos: options.forgeRepos } : {}),
407
459
  ...(declaredKinds ? { declaredKinds } : {}),
408
460
  ...(boxIntents ? { boxIntents } : {}),
409
461
  ...(options.live && !options.tree ? { live: await gatherLiveLinkFacts(root, declaration, registry, options.live.env, options.live.onStderr) } : {}),
@@ -27,6 +27,22 @@ export declare function routeConflicts(branches: MemberGlobs | undefined, member
27
27
  member: string;
28
28
  branches: string[];
29
29
  }>;
30
+ /**
31
+ * The branches `chant ci serve` polls (#4325), and the ones among them a job
32
+ * is told with `--branch`.
33
+ *
34
+ * - A routed member polls its route alone. A `named` branch that differs
35
+ * from the route is refused, as `chant build --pr-loop` refuses it.
36
+ * - An unrouted member polls `fallback`, which may not be a routed branch.
37
+ * - Where no member is in play (the workspace root), `fallback` and then each
38
+ * routed branch, so every branch a member applies from is watched.
39
+ *
40
+ * `fallback` is the branch `--branch` names, else the default branch.
41
+ */
42
+ export declare function servedBranches(branches: MemberGlobs | undefined, member: string | undefined, fallback: string, named: boolean): {
43
+ served: string[];
44
+ routed: string[];
45
+ };
30
46
  /**
31
47
  * Whether a push to `pushed` applies `member`, with a line that says why.
32
48
  * A routed member applies only from its branch. Any other member applies
@@ -1 +1 @@
1
- {"version":3,"file":"ci-branches.d.ts","sourceRoot":"","sources":["../../src/workspace/ci-branches.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAKH,iDAAiD;AACjD,MAAM,MAAM,WAAW,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC,CAAC;AAItE,0EAA0E;AAC1E,wBAAgB,YAAY,CAAC,GAAG,EAAE,WAAW,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAEnF;AAED,oFAAoF;AACpF,wBAAgB,YAAY,CAAC,QAAQ,EAAE,WAAW,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAE7F;AAED,oGAAoG;AACpG,wBAAgB,cAAc,CAAC,QAAQ,EAAE,WAAW,GAAG,SAAS,EAAE,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,KAAK,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAE3I;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,WAAW,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAWjI;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,WAAW,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAO/I;AAED,mIAAmI;AACnI,wBAAgB,mBAAmB,CAAC,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAe,GAAG,MAAM,GAAG,SAAS,CAE7G"}
1
+ {"version":3,"file":"ci-branches.d.ts","sourceRoot":"","sources":["../../src/workspace/ci-branches.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAKH,iDAAiD;AACjD,MAAM,MAAM,WAAW,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC,CAAC;AAItE,0EAA0E;AAC1E,wBAAgB,YAAY,CAAC,GAAG,EAAE,WAAW,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAEnF;AAED,oFAAoF;AACpF,wBAAgB,YAAY,CAAC,QAAQ,EAAE,WAAW,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAE7F;AAED,oGAAoG;AACpG,wBAAgB,cAAc,CAAC,QAAQ,EAAE,WAAW,GAAG,SAAS,EAAE,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,KAAK,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAE3I;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,WAAW,GAAG,SAAS,EACjC,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,OAAO,GACb;IAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAYxC;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,WAAW,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAWjI;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,WAAW,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAO/I;AAED,mIAAmI;AACnI,wBAAgB,mBAAmB,CAAC,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAe,GAAG,MAAM,GAAG,SAAS,CAE7G"}
@@ -31,6 +31,33 @@ export function routedBranch(branches, member) {
31
31
  export function routeConflicts(branches, members) {
32
32
  return members.map((member) => ({ member, branches: keysMatching(branches, member) })).filter((c) => c.branches.length > 1);
33
33
  }
34
+ /**
35
+ * The branches `chant ci serve` polls (#4325), and the ones among them a job
36
+ * is told with `--branch`.
37
+ *
38
+ * - A routed member polls its route alone. A `named` branch that differs
39
+ * from the route is refused, as `chant build --pr-loop` refuses it.
40
+ * - An unrouted member polls `fallback`, which may not be a routed branch.
41
+ * - Where no member is in play (the workspace root), `fallback` and then each
42
+ * routed branch, so every branch a member applies from is watched.
43
+ *
44
+ * `fallback` is the branch `--branch` names, else the default branch.
45
+ */
46
+ export function servedBranches(branches, member, fallback, named) {
47
+ const keys = Object.keys(branches ?? {});
48
+ if (member === undefined)
49
+ return { served: [fallback, ...keys.filter((k) => k !== fallback)], routed: keys };
50
+ const own = routedBranch(branches, member);
51
+ if (own !== null) {
52
+ if (named && fallback !== own)
53
+ throw new Error(`--branch ${fallback}: ci.branches routes member ${member} to ${own}, so ci serve polls ${own}`);
54
+ return { served: [own], routed: [own] };
55
+ }
56
+ if (keys.includes(fallback)) {
57
+ throw new Error(`--branch ${fallback}: ci.branches applies only the members its globs match from ${fallback}, and member ${member} is not one`);
58
+ }
59
+ return { served: [fallback], routed: [] };
60
+ }
34
61
  /**
35
62
  * Whether a push to `pushed` applies `member`, with a line that says why.
36
63
  * A routed member applies only from its branch. Any other member applies
@@ -30,10 +30,10 @@ import { findWorkspaceRoot } from "../project-root.js";
30
30
  import { ciList, ciTick, CiGreenError, formatList, formatTick, lastGreen, RUNNER_KEY_ENV } from "./ci-green.js";
31
31
  import { ciForgeFromEnv } from "./ci-green-forge.js";
32
32
  import { ACTIONS_NAME, buildTriggerEdits, CI_GREEN_WORKFLOW_FILE, ciGreenHeader, readWorkflowSources, renderCiGreenWorkflow, workflowsHolding, writeWorkflowFile } from "./ci-green-workflow.js";
33
- import { readDeclaration, readerVersion, WorkspaceReadError } from "./declaration.js";
33
+ import { greenBranches, readDeclaration, readerVersion, WorkspaceReadError } from "./declaration.js";
34
34
  import { recordGeneratedFiles, resolveMemberContext, shellArg } from "./member-pipeline.js";
35
35
  import { gitTop, workingTree } from "./tree.js";
36
- const USAGE = "chant ci last-green [--json] [--from <rev>] | ci list [--json] [--limit <n>] [--since <rev>] [--forge github] [--source checks|runs] | ci tick [--dry-run] [--forge github] [--source checks|runs] [--key <runner key.pem>] | " +
36
+ const USAGE = "chant ci last-green [--json] [--from <rev>] [--branch <branch>] | ci list [--json] [--branch <branch>] [--limit <n>] [--since <rev>] [--forge github] [--source checks|runs] | ci tick [--dry-run] [--forge github] [--source checks|runs] [--key <runner key.pem>] | " +
37
37
  "ci workflow [--workflow <name>]... [--output <file>] [--chant <command>] [--install <command>] [--token-secret <NAME> | --app-id-var <VAR> --app-key-secret <NAME>] [--runner-key-secret <NAME>]";
38
38
  export { RUNNER_KEY_ENV };
39
39
  /** `--source`, checked (#4044): `checks` or `runs`, or undefined to follow `ci.green.source`. */
@@ -51,7 +51,7 @@ function warnIgnored(ignored) {
51
51
  console.error(`warning: ignored ${t.tag} (${t.status}): ${t.reason}`);
52
52
  }
53
53
  export async function runCiLastGreen(ctx) {
54
- const doc = lastGreen({ cwd: process.cwd(), ...(ctx.args.migrateFrom !== undefined ? { from: ctx.args.migrateFrom } : {}) });
54
+ const doc = lastGreen({ cwd: process.cwd(), ...(ctx.args.branch !== undefined ? { branch: ctx.args.branch } : {}), ...(ctx.args.migrateFrom !== undefined ? { from: ctx.args.migrateFrom } : {}) });
55
55
  if (ctx.args.json) {
56
56
  console.log(JSON.stringify(doc, null, 2));
57
57
  return "error" in doc ? 1 : 0;
@@ -76,7 +76,7 @@ export async function runCiList(ctx) {
76
76
  // Only an explicit --forge reaches the network; without it the list reads local refs and tags.
77
77
  const forge = ctx.args.forge !== undefined ? ciForgeFromEnv(ctx.args.forge) : undefined;
78
78
  const source = sourceOf(ctx.args);
79
- const doc = await ciList({ cwd: process.cwd(), limit, since: ctx.args.since, forge, ...(source ? { source } : {}) });
79
+ const doc = await ciList({ cwd: process.cwd(), ...(ctx.args.branch !== undefined ? { branch: ctx.args.branch } : {}), limit, since: ctx.args.since, forge, ...(source ? { source } : {}) });
80
80
  if (ctx.args.json) {
81
81
  console.log(JSON.stringify(doc, null, 2));
82
82
  return "error" in doc ? 1 : 0;
@@ -192,14 +192,14 @@ export async function runCiWorkflow(ctx) {
192
192
  const written = writeWorkflowFile(target, ciGreenHeader(command, member ? "member" : "root") + yaml);
193
193
  if (member)
194
194
  recordGeneratedFiles(member.memberRoot, [{ path: fromRepo, command }]);
195
- console.log(`Wrote ${written}: ticks when ${workflows.join(", ")} complete${workflows.length === 1 ? "s" : ""} on ${green.branch}${compose ? " or a chant/compose/ branch" : ""}, and every 15 minutes.`);
195
+ console.log(`Wrote ${written}: ticks when ${workflows.join(", ")} complete${workflows.length === 1 ? "s" : ""} on ${greenBranches(green).join(", ")}${compose ? " or a chant/compose/ branch" : ""}, and every 15 minutes.`);
196
196
  for (const e of edits) {
197
197
  if (!e.changed)
198
198
  continue;
199
199
  const path = writeWorkflowFile(join(repoRoot, e.path), e.text);
200
200
  console.log(e.build === "newest"
201
- ? `Wrote ${path}'s triggers and concurrency: ${e.phases.join(", ")} build${e.phases.length === 1 ? "s" : ""} the newest commit on ${green.branch} when a run ends, and a ci/build/<sha> tag by hand.`
202
- : `Wrote ${path}'s triggers and concurrency: ${e.phases.join(", ")} build${e.phases.length === 1 ? "s" : ""} every commit on ${green.branch}, none cancelled, and a ci/build/<sha> tag by hand when the forge ran nothing.`);
201
+ ? `Wrote ${path}'s triggers and concurrency: ${e.phases.join(", ")} build${e.phases.length === 1 ? "s" : ""} the newest commit on ${greenBranches(green).join(", ")} when a run ends, and a ci/build/<sha> tag by hand.`
202
+ : `Wrote ${path}'s triggers and concurrency: ${e.phases.join(", ")} build${e.phases.length === 1 ? "s" : ""} every commit on ${greenBranches(green).join(", ")}, none cancelled, and a ci/build/<sha> tag by hand when the forge ran nothing.`);
203
203
  }
204
204
  return 0;
205
205
  }
@@ -44,7 +44,7 @@
44
44
  * the command runs in records it in its generated-file record, so `WSP081`
45
45
  * allows one declarer.
46
46
  */
47
- import type { CiBuild, CiGreen } from "./declaration.js";
47
+ import { type CiBuild, type CiGreen } from "./declaration.js";
48
48
  /** Where the workflow goes, relative to the repository root. */
49
49
  export declare const CI_GREEN_WORKFLOW_FILE = ".github/workflows/chant-ci-green.yml";
50
50
  export declare const CI_GREEN_WORKFLOW_NAME = "chant-ci-green";
@@ -1 +1 @@
1
- {"version":3,"file":"ci-green-workflow.d.ts","sourceRoot":"","sources":["../../src/workspace/ci-green-workflow.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ci-green-workflow.d.ts","sourceRoot":"","sources":["../../src/workspace/ci-green-workflow.ts"],"names":[],"mappings":"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"}
@@ -47,7 +47,9 @@
47
47
  import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from "node:fs";
48
48
  import { dirname, join, relative, resolve, sep } from "node:path";
49
49
  import { GENERATED_MARKER } from "../discovery/files.js";
50
+ import { ACTION_PINS, tagComments, usesRef } from "../action-pins.js";
50
51
  import { emitYAMLEntry, parseYAMLDocument } from "../yaml.js";
52
+ import { greenBranches } from "./declaration.js";
51
53
  import { matchesCheckRun } from "./ci-green.js";
52
54
  import { githubSecretOrJobToken } from "../ci-jobs.js";
53
55
  import { COMPOSE_BRANCH_PREFIX } from "../lifecycle/compose-refs.js";
@@ -165,7 +167,7 @@ export function renderCiGreenWorkflow(input) {
165
167
  ? [
166
168
  " - name: Mint a GitHub App token that may push tags to commits that change workflows",
167
169
  " id: app-token",
168
- " uses: actions/create-github-app-token@v2",
170
+ ` uses: ${usesRef(ACTION_PINS.createGithubAppToken2)}`,
169
171
  " with:",
170
172
  ` app-id: \${{ vars.${push.appIdVar} }}`,
171
173
  ` private-key: \${{ secrets.${push.appKeySecret} }}`,
@@ -184,7 +186,7 @@ export function renderCiGreenWorkflow(input) {
184
186
  " types:",
185
187
  " - completed",
186
188
  " branches:",
187
- ` - ${q(green.branch)}`,
189
+ ...greenBranches(green).map((b) => ` - ${q(b)}`),
188
190
  // #4169: a build the tick asked for runs at a ci/build/<sha> tag, and its completion ticks too.
189
191
  ...(newestPhases(green) ? [` - ${q("ci/build/**")}`] : []),
190
192
  // #4220: a composed commit's phases run on its chant/compose/<name> branch, and their completion ticks too.
@@ -210,12 +212,12 @@ export function renderCiGreenWorkflow(input) {
210
212
  " timeout-minutes: 15",
211
213
  " steps:",
212
214
  ...mint,
213
- " - uses: actions/checkout@v6",
215
+ ` - uses: ${usesRef(ACTION_PINS.checkout6)}`,
214
216
  " with:",
215
217
  ` ref: ${q(green.branch)}`,
216
218
  " fetch-depth: 0",
217
219
  ...token,
218
- " - uses: actions/setup-node@v6",
220
+ ` - uses: ${usesRef(ACTION_PINS.setupNode6)}`,
219
221
  " with:",
220
222
  " node-version: \"24\"",
221
223
  ...cache,
@@ -229,7 +231,7 @@ export function renderCiGreenWorkflow(input) {
229
231
  ...(input.runnerKeySecret ? [` CHANT_RUNNER_KEY: \${{ secrets.${input.runnerKeySecret} }}`] : []),
230
232
  ` run: ${tick}`,
231
233
  ];
232
- return lines.join("\n") + "\n";
234
+ return tagComments(lines.join("\n") + "\n");
233
235
  }
234
236
  /** Whether any phase sets `build` (#4169): then the tick may re-run jobs and start workflows. */
235
237
  export const declaresBuild = (green) => green.phases.some((p) => p.build !== undefined);
@@ -294,7 +296,7 @@ export function buildTriggerEdits(green, sources, options = {}) {
294
296
  delete on.schedule;
295
297
  const push = isObject(on.push) ? { ...on.push } : {};
296
298
  const branches = Array.isArray(push.branches) ? push.branches.filter((b) => typeof b === "string") : [];
297
- const withBranch = branches.includes(green.branch) ? branches : [...branches, green.branch];
299
+ const withBranch = [...branches, ...greenBranches(green).filter((b) => !branches.includes(b))];
298
300
  push.branches = compose && !withBranch.includes(COMPOSE_BRANCHES) ? [...withBranch, COMPOSE_BRANCHES] : withBranch;
299
301
  const { push: _push, workflow_dispatch: dispatch, ...rest } = on;
300
302
  text = writeTopLevel(text, "on", { push, workflow_dispatch: dispatch ?? {}, ...rest });
@@ -315,8 +317,11 @@ export function buildTriggerEdits(green, sources, options = {}) {
315
317
  if (next !== on)
316
318
  text = writeTopLevel(text, "on", next);
317
319
  // #4220: a compose branch's commits each get a verdict, so its runs are keyed by commit, as the trunk branch's are.
318
- const keyed = compose ? `(github.ref == '${main}' || startsWith(github.ref, 'refs/heads/${COMPOSE_BRANCH_PREFIX}'))` : `github.ref == '${main}'`;
319
- const unkeyed = compose ? `!${keyed}` : `github.ref != '${main}'`;
320
+ // #4325: each branch ci.green judges is keyed by commit.
321
+ const heads = greenBranches(green).map((b) => `github.ref == 'refs/heads/${b}'`);
322
+ const several = heads.length > 1;
323
+ const keyed = compose ? `(${[...heads, `startsWith(github.ref, 'refs/heads/${COMPOSE_BRANCH_PREFIX}')`].join(" || ")})` : several ? `(${heads.join(" || ")})` : `github.ref == '${main}'`;
324
+ const unkeyed = compose || several ? `!${keyed}` : `github.ref != '${main}'`;
320
325
  // Written as lines: the emitter would quote the expression, and GitHub reads it the same either way.
321
326
  text = writeTopLevel(text, "concurrency", [
322
327
  "concurrency:",