@intentius/chant 0.124.26 → 0.124.28

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 (459) hide show
  1. package/README.md +1 -1
  2. package/dist/__golden__/wave-loop/fan-out-gated.json +8 -0
  3. package/dist/__golden__/wave-loop/fan-out-no-members.json +4 -0
  4. package/dist/__golden__/wave-loop/fan-out-only.json +6 -0
  5. package/dist/__golden__/wave-loop/op-by-apply-hold.json +2 -0
  6. package/dist/__golden__/wave-loop/op-cost-member.json +3 -0
  7. package/dist/__golden__/wave-loop/op-held-on-before-apply.json +1 -0
  8. package/dist/__golden__/wave-loop/op-held-on.json +2 -0
  9. package/dist/__golden__/wave-loop/op-hooks-held.json +2 -0
  10. package/dist/__golden__/wave-loop/op-hooks-hold-before-apply.json +2 -0
  11. package/dist/__golden__/wave-loop/op-hooks-refused-at-base.json +3 -0
  12. package/dist/__golden__/wave-loop/op-hooks-share.json +3 -0
  13. package/dist/__golden__/wave-loop/op-per-run.json +7 -0
  14. package/dist/__golden__/wave-loop/op-pr-review.json +7 -0
  15. package/dist/__golden__/wave-loop/op-sealed.json +3 -0
  16. package/dist/__golden__/wave-loop/op-spend.json +3 -0
  17. package/dist/__golden__/wave-loop/op-wave-commands.json +7 -0
  18. package/dist/__golden__/wave-loop/op-wide-waiting.json +4 -0
  19. package/dist/change-set-graph.d.ts +56 -0
  20. package/dist/change-set-graph.d.ts.map +1 -0
  21. package/dist/change-set-graph.js +128 -0
  22. package/dist/change-set.d.ts +52 -3
  23. package/dist/change-set.d.ts.map +1 -1
  24. package/dist/change-set.js +35 -4
  25. package/dist/chant-version.d.ts +9 -0
  26. package/dist/chant-version.d.ts.map +1 -0
  27. package/dist/chant-version.js +16 -0
  28. package/dist/cli/commands/build.d.ts +8 -0
  29. package/dist/cli/commands/build.d.ts.map +1 -1
  30. package/dist/cli/commands/build.js +9 -8
  31. package/dist/cli/commands/check-lexicon-docs.d.ts.map +1 -1
  32. package/dist/cli/commands/check-lexicon-docs.js +30 -2
  33. package/dist/cli/commands/check-lexicon.d.ts.map +1 -1
  34. package/dist/cli/commands/check-lexicon.js +13 -2
  35. package/dist/cli/commands/init-lexicon/templates/docs.d.ts +4 -1
  36. package/dist/cli/commands/init-lexicon/templates/docs.d.ts.map +1 -1
  37. package/dist/cli/commands/init-lexicon/templates/docs.js +6 -6
  38. package/dist/cli/commands/init-lexicon.d.ts.map +1 -1
  39. package/dist/cli/commands/init-lexicon.js +17 -8
  40. package/dist/cli/handlers/approve.d.ts.map +1 -1
  41. package/dist/cli/handlers/approve.js +19 -4
  42. package/dist/cli/handlers/build.d.ts.map +1 -1
  43. package/dist/cli/handlers/build.js +28 -0
  44. package/dist/cli/handlers/change-set.d.ts +10 -0
  45. package/dist/cli/handlers/change-set.d.ts.map +1 -1
  46. package/dist/cli/handlers/change-set.js +51 -1
  47. package/dist/cli/handlers/fan-out.d.ts +1 -1
  48. package/dist/cli/handlers/fan-out.d.ts.map +1 -1
  49. package/dist/cli/handlers/fan-out.js +14 -3
  50. package/dist/cli/handlers/pr.d.ts +8 -2
  51. package/dist/cli/handlers/pr.d.ts.map +1 -1
  52. package/dist/cli/handlers/pr.js +148 -24
  53. package/dist/cli/handlers/promote.d.ts.map +1 -1
  54. package/dist/cli/handlers/promote.js +256 -21
  55. package/dist/cli/handlers/release.d.ts +34 -0
  56. package/dist/cli/handlers/release.d.ts.map +1 -0
  57. package/dist/cli/handlers/release.js +203 -0
  58. package/dist/cli/handlers/run.d.ts +28 -2
  59. package/dist/cli/handlers/run.d.ts.map +1 -1
  60. package/dist/cli/handlers/run.js +170 -13
  61. package/dist/cli/main.d.ts.map +1 -1
  62. package/dist/cli/main.js +88 -13
  63. package/dist/cli/mcp/workspace-tools.js +1 -1
  64. package/dist/cli/parse-args.d.ts.map +1 -1
  65. package/dist/cli/parse-args.js +49 -3
  66. package/dist/cli/registry.d.ts +29 -3
  67. package/dist/cli/registry.d.ts.map +1 -1
  68. package/dist/cli/run-events.d.ts +29 -0
  69. package/dist/cli/run-events.d.ts.map +1 -0
  70. package/dist/cli/run-events.js +47 -0
  71. package/dist/cli/version.d.ts +3 -5
  72. package/dist/cli/version.d.ts.map +1 -1
  73. package/dist/cli/version.js +3 -13
  74. package/dist/codegen/docs-in-site.d.ts +71 -0
  75. package/dist/codegen/docs-in-site.d.ts.map +1 -0
  76. package/dist/codegen/docs-in-site.js +177 -0
  77. package/dist/codegen/docs-types.d.ts +14 -1
  78. package/dist/codegen/docs-types.d.ts.map +1 -1
  79. package/dist/codegen/docs.d.ts +18 -1
  80. package/dist/codegen/docs.d.ts.map +1 -1
  81. package/dist/codegen/docs.js +40 -7
  82. package/dist/codegen/rehype-base-url.mjs +15 -9
  83. package/dist/components/auto-release.d.ts +4 -1
  84. package/dist/components/auto-release.d.ts.map +1 -1
  85. package/dist/components/auto-release.js +2 -0
  86. package/dist/components/cli-support.d.ts +6 -0
  87. package/dist/components/cli-support.d.ts.map +1 -1
  88. package/dist/components/cli-support.js +10 -9
  89. package/dist/components/driver.d.ts +42 -9
  90. package/dist/components/driver.d.ts.map +1 -1
  91. package/dist/components/driver.js +81 -54
  92. package/dist/components/fan-out-run.d.ts +7 -0
  93. package/dist/components/fan-out-run.d.ts.map +1 -1
  94. package/dist/components/fan-out-run.js +35 -26
  95. package/dist/components/pr-run.d.ts +11 -0
  96. package/dist/components/pr-run.d.ts.map +1 -1
  97. package/dist/components/pr-run.js +20 -1
  98. package/dist/components/promote-order.d.ts +38 -0
  99. package/dist/components/promote-order.d.ts.map +1 -0
  100. package/dist/components/promote-order.js +62 -0
  101. package/dist/components/promote.d.ts +15 -2
  102. package/dist/components/promote.d.ts.map +1 -1
  103. package/dist/components/promote.js +17 -0
  104. package/dist/components/release-compile.d.ts +133 -0
  105. package/dist/components/release-compile.d.ts.map +1 -0
  106. package/dist/components/release-compile.js +376 -0
  107. package/dist/components/release-gate.d.ts +125 -0
  108. package/dist/components/release-gate.d.ts.map +1 -0
  109. package/dist/components/release-gate.js +282 -0
  110. package/dist/components/release-promote.d.ts +96 -0
  111. package/dist/components/release-promote.d.ts.map +1 -0
  112. package/dist/components/release-promote.js +204 -0
  113. package/dist/components/run-progress.d.ts +7 -0
  114. package/dist/components/run-progress.d.ts.map +1 -1
  115. package/dist/components/wave-plan.d.ts +3 -1
  116. package/dist/components/wave-plan.d.ts.map +1 -1
  117. package/dist/components/wave-plan.js +1 -1
  118. package/dist/config.d.ts +7 -0
  119. package/dist/config.d.ts.map +1 -1
  120. package/dist/config.js +1 -0
  121. package/dist/index.d.ts +1 -0
  122. package/dist/index.d.ts.map +1 -1
  123. package/dist/index.js +2 -0
  124. package/dist/lifecycle/change-set-store.d.ts +67 -0
  125. package/dist/lifecycle/change-set-store.d.ts.map +1 -0
  126. package/dist/lifecycle/change-set-store.js +96 -0
  127. package/dist/lifecycle/commit-sha.d.ts +13 -0
  128. package/dist/lifecycle/commit-sha.d.ts.map +1 -0
  129. package/dist/lifecycle/commit-sha.js +21 -0
  130. package/dist/lifecycle/gate-change-set.d.ts +69 -0
  131. package/dist/lifecycle/gate-change-set.d.ts.map +1 -0
  132. package/dist/lifecycle/gate-change-set.js +106 -0
  133. package/dist/lifecycle/gate-ledger.d.ts +49 -1
  134. package/dist/lifecycle/gate-ledger.d.ts.map +1 -1
  135. package/dist/lifecycle/gate-ledger.js +18 -0
  136. package/dist/lifecycle/release-cut.d.ts +107 -0
  137. package/dist/lifecycle/release-cut.d.ts.map +1 -0
  138. package/dist/lifecycle/release-cut.js +273 -0
  139. package/dist/lifecycle/release-ledger.d.ts +54 -0
  140. package/dist/lifecycle/release-ledger.d.ts.map +1 -1
  141. package/dist/lifecycle/release-ledger.js +53 -20
  142. package/dist/lifecycle/release-store.d.ts +190 -0
  143. package/dist/lifecycle/release-store.d.ts.map +1 -0
  144. package/dist/lifecycle/release-store.js +318 -0
  145. package/dist/lifecycle/run-ledger.d.ts +4 -0
  146. package/dist/lifecycle/run-ledger.d.ts.map +1 -1
  147. package/dist/lifecycle/run-ledger.js +2 -0
  148. package/dist/op/activities/change-coverage.d.ts.map +1 -1
  149. package/dist/op/activities/change-coverage.js +4 -2
  150. package/dist/op/activities/source-release.d.ts.map +1 -1
  151. package/dist/op/activities/source-release.js +7 -3
  152. package/dist/op/activities/source-rollback.d.ts.map +1 -1
  153. package/dist/op/activities/source-rollback.js +7 -3
  154. package/dist/op/activity-registry.d.ts +6 -3
  155. package/dist/op/activity-registry.d.ts.map +1 -1
  156. package/dist/op/activity-registry.js +7 -5
  157. package/dist/op/discover.d.ts.map +1 -1
  158. package/dist/op/discover.js +14 -7
  159. package/dist/op/gate-name.d.ts +11 -2
  160. package/dist/op/gate-name.d.ts.map +1 -1
  161. package/dist/op/gate-name.js +12 -3
  162. package/dist/op/gate-run-locator.d.ts +22 -0
  163. package/dist/op/gate-run-locator.d.ts.map +1 -1
  164. package/dist/op/gate-run-locator.js +31 -0
  165. package/dist/op/gate.d.ts +27 -3
  166. package/dist/op/gate.d.ts.map +1 -1
  167. package/dist/op/gate.js +57 -3
  168. package/dist/op/local-executor.d.ts +36 -1
  169. package/dist/op/local-executor.d.ts.map +1 -1
  170. package/dist/op/local-executor.js +158 -52
  171. package/dist/op/op-waves-run.d.ts.map +1 -1
  172. package/dist/op/op-waves-run.js +4 -0
  173. package/dist/op/run-live.d.ts +2 -0
  174. package/dist/op/run-live.d.ts.map +1 -1
  175. package/dist/op/run-live.js +1 -1
  176. package/dist/op/runtime.d.ts +46 -0
  177. package/dist/op/runtime.d.ts.map +1 -1
  178. package/dist/op/runtimes/local.d.ts.map +1 -1
  179. package/dist/op/runtimes/local.js +12 -2
  180. package/dist/point-decision.d.ts +2 -0
  181. package/dist/point-decision.d.ts.map +1 -1
  182. package/dist/point-decision.js +9 -2
  183. package/dist/run-event-store.d.ts +77 -0
  184. package/dist/run-event-store.d.ts.map +1 -0
  185. package/dist/run-event-store.js +204 -0
  186. package/dist/run-event-stream.d.ts +132 -0
  187. package/dist/run-event-stream.d.ts.map +1 -0
  188. package/dist/run-event-stream.js +238 -0
  189. package/dist/run-event.d.ts +267 -0
  190. package/dist/run-event.d.ts.map +1 -0
  191. package/dist/run-event.js +207 -0
  192. package/dist/wave-runtime.mjs +225 -242
  193. package/dist/workspace/__fixtures__/run-event-check.d.ts +19 -0
  194. package/dist/workspace/__fixtures__/run-event-check.d.ts.map +1 -0
  195. package/dist/workspace/__fixtures__/run-event-check.js +59 -0
  196. package/dist/workspace/change-set-show.d.ts +56 -0
  197. package/dist/workspace/change-set-show.d.ts.map +1 -0
  198. package/dist/workspace/change-set-show.js +54 -0
  199. package/dist/workspace/change-set-show.schema.json +102 -0
  200. package/dist/workspace/change-set.schema.json +28 -1
  201. package/dist/workspace/changes-cli.d.ts.map +1 -1
  202. package/dist/workspace/changes-cli.js +10 -1
  203. package/dist/workspace/changes.d.ts +37 -0
  204. package/dist/workspace/changes.d.ts.map +1 -1
  205. package/dist/workspace/changes.js +49 -2
  206. package/dist/workspace/changes.schema.json +135 -0
  207. package/dist/workspace/ci-green-cli.d.ts +19 -4
  208. package/dist/workspace/ci-green-cli.d.ts.map +1 -1
  209. package/dist/workspace/ci-green-cli.js +75 -12
  210. package/dist/workspace/ci-green-forge.d.ts +20 -3
  211. package/dist/workspace/ci-green-forge.d.ts.map +1 -1
  212. package/dist/workspace/ci-green-forge.js +6 -4
  213. package/dist/workspace/ci-green-workflow.d.ts +11 -0
  214. package/dist/workspace/ci-green-workflow.d.ts.map +1 -1
  215. package/dist/workspace/ci-green-workflow.js +6 -0
  216. package/dist/workspace/ci-green.d.ts +273 -13
  217. package/dist/workspace/ci-green.d.ts.map +1 -1
  218. package/dist/workspace/ci-green.js +449 -38
  219. package/dist/workspace/ci-last-green.schema.json +32 -2
  220. package/dist/workspace/ci-list.schema.json +525 -0
  221. package/dist/workspace/commit-links.d.ts +85 -0
  222. package/dist/workspace/commit-links.d.ts.map +1 -0
  223. package/dist/workspace/commit-links.js +163 -0
  224. package/dist/workspace/declaration.d.ts +19 -0
  225. package/dist/workspace/declaration.d.ts.map +1 -1
  226. package/dist/workspace/declaration.js +1 -1
  227. package/dist/workspace/declaration.schema.json +12 -0
  228. package/dist/workspace/identity-gate-rule.d.ts +37 -0
  229. package/dist/workspace/identity-gate-rule.d.ts.map +1 -1
  230. package/dist/workspace/identity-gate-rule.js +72 -7
  231. package/dist/workspace/identity.d.ts +12 -0
  232. package/dist/workspace/identity.d.ts.map +1 -1
  233. package/dist/workspace/identity.js +13 -1
  234. package/dist/workspace/intent.d.ts +6 -1
  235. package/dist/workspace/intent.d.ts.map +1 -1
  236. package/dist/workspace/intent.js +51 -1
  237. package/dist/workspace/ls.d.ts +4 -0
  238. package/dist/workspace/ls.d.ts.map +1 -1
  239. package/dist/workspace/ls.js +2 -0
  240. package/dist/workspace/ls.schema.json +3 -1
  241. package/dist/workspace/member-pipeline.d.ts +6 -0
  242. package/dist/workspace/member-pipeline.d.ts.map +1 -1
  243. package/dist/workspace/member-pipeline.js +6 -0
  244. package/dist/workspace/promotion-order.d.ts +41 -0
  245. package/dist/workspace/promotion-order.d.ts.map +1 -0
  246. package/dist/workspace/promotion-order.js +95 -0
  247. package/dist/workspace/reason-codes.d.ts +2 -0
  248. package/dist/workspace/reason-codes.d.ts.map +1 -1
  249. package/dist/workspace/reason-codes.js +4 -1
  250. package/dist/workspace/releases.d.ts +72 -0
  251. package/dist/workspace/releases.d.ts.map +1 -0
  252. package/dist/workspace/releases.js +94 -0
  253. package/dist/workspace/releases.schema.json +391 -0
  254. package/dist/workspace/run-event.schema.json +288 -0
  255. package/dist/workspace/status-gates.d.ts +26 -1
  256. package/dist/workspace/status-gates.d.ts.map +1 -1
  257. package/dist/workspace/status-gates.js +31 -2
  258. package/dist/workspace/status-stewards.d.ts +4 -0
  259. package/dist/workspace/status-stewards.d.ts.map +1 -1
  260. package/dist/workspace/status-stewards.js +2 -0
  261. package/dist/workspace/status.d.ts +39 -0
  262. package/dist/workspace/status.d.ts.map +1 -1
  263. package/dist/workspace/status.js +48 -1
  264. package/dist/workspace/status.schema.json +70 -1
  265. package/dist/workspace/trust/ci-tag-statement.d.ts +102 -0
  266. package/dist/workspace/trust/ci-tag-statement.d.ts.map +1 -0
  267. package/dist/workspace/trust/ci-tag-statement.js +123 -0
  268. package/dist/workspace/trust/op-run-statement.d.ts +91 -0
  269. package/dist/workspace/trust/op-run-statement.d.ts.map +1 -0
  270. package/dist/workspace/trust/op-run-statement.js +143 -0
  271. package/dist/workspace/trust/rotation.d.ts +18 -2
  272. package/dist/workspace/trust/rotation.d.ts.map +1 -1
  273. package/dist/workspace/trust/rotation.js +65 -16
  274. package/dist/workspace/trust/seal.d.ts +11 -0
  275. package/dist/workspace/trust/seal.d.ts.map +1 -1
  276. package/dist/workspace/trust/seal.js +9 -0
  277. package/dist/workspace/trust/ssh-commit.d.ts.map +1 -1
  278. package/dist/workspace/trust/ssh-commit.js +10 -10
  279. package/package.json +1 -1
  280. package/src/__golden__/wave-loop/fan-out-gated.json +8 -0
  281. package/src/__golden__/wave-loop/fan-out-no-members.json +4 -0
  282. package/src/__golden__/wave-loop/fan-out-only.json +6 -0
  283. package/src/__golden__/wave-loop/op-by-apply-hold.json +2 -0
  284. package/src/__golden__/wave-loop/op-cost-member.json +3 -0
  285. package/src/__golden__/wave-loop/op-held-on-before-apply.json +1 -0
  286. package/src/__golden__/wave-loop/op-held-on.json +2 -0
  287. package/src/__golden__/wave-loop/op-hooks-held.json +2 -0
  288. package/src/__golden__/wave-loop/op-hooks-hold-before-apply.json +2 -0
  289. package/src/__golden__/wave-loop/op-hooks-refused-at-base.json +3 -0
  290. package/src/__golden__/wave-loop/op-hooks-share.json +3 -0
  291. package/src/__golden__/wave-loop/op-per-run.json +7 -0
  292. package/src/__golden__/wave-loop/op-pr-review.json +7 -0
  293. package/src/__golden__/wave-loop/op-sealed.json +3 -0
  294. package/src/__golden__/wave-loop/op-spend.json +3 -0
  295. package/src/__golden__/wave-loop/op-wave-commands.json +7 -0
  296. package/src/__golden__/wave-loop/op-wide-waiting.json +4 -0
  297. package/src/change-set-graph.test.ts +72 -0
  298. package/src/change-set-graph.ts +133 -0
  299. package/src/change-set.ts +76 -6
  300. package/src/chant-version.ts +16 -0
  301. package/src/cli/commands/build.ts +19 -8
  302. package/src/cli/commands/check-lexicon-docs.test.ts +51 -0
  303. package/src/cli/commands/check-lexicon-docs.ts +39 -2
  304. package/src/cli/commands/check-lexicon.ts +14 -2
  305. package/src/cli/commands/init-lexicon/templates/docs.ts +7 -6
  306. package/src/cli/commands/init-lexicon.test.ts +25 -0
  307. package/src/cli/commands/init-lexicon.ts +18 -8
  308. package/src/cli/compiled-cli.e2e.test.ts +31 -6
  309. package/src/cli/handlers/approve-release.test.ts +80 -0
  310. package/src/cli/handlers/approve.ts +18 -2
  311. package/src/cli/handlers/build.test.ts +52 -0
  312. package/src/cli/handlers/build.ts +29 -0
  313. package/src/cli/handlers/change-set.ts +49 -1
  314. package/src/cli/handlers/fan-out.test.ts +48 -0
  315. package/src/cli/handlers/fan-out.ts +15 -3
  316. package/src/cli/handlers/operator.test.ts +37 -0
  317. package/src/cli/handlers/pr.test.ts +194 -0
  318. package/src/cli/handlers/pr.ts +168 -34
  319. package/src/cli/handlers/promote.test.ts +389 -5
  320. package/src/cli/handlers/promote.ts +279 -20
  321. package/src/cli/handlers/release-implicit.e2e.test.ts +153 -0
  322. package/src/cli/handlers/release.e2e.test.ts +85 -0
  323. package/src/cli/handlers/release.ts +206 -0
  324. package/src/cli/handlers/run-auto-release.test.ts +71 -0
  325. package/src/cli/handlers/run-events-cmd.test.ts +92 -0
  326. package/src/cli/handlers/run.test.ts +30 -0
  327. package/src/cli/handlers/run.ts +176 -15
  328. package/src/cli/main.test.ts +7 -0
  329. package/src/cli/main.ts +88 -13
  330. package/src/cli/mcp/never-over-mcp.test.ts +2 -0
  331. package/src/cli/mcp/workspace-tools.ts +1 -1
  332. package/src/cli/parse-args.ts +37 -3
  333. package/src/cli/registry.ts +29 -3
  334. package/src/cli/run-events.ts +54 -0
  335. package/src/cli/version.ts +3 -13
  336. package/src/codegen/docs-in-site.test.ts +166 -0
  337. package/src/codegen/docs-in-site.ts +182 -0
  338. package/src/codegen/docs-site/AgentPrompt.astro +26 -1
  339. package/src/codegen/docs-types.ts +14 -1
  340. package/src/codegen/docs.ts +60 -7
  341. package/src/codegen/rehype-base-url.d.mts +3 -1
  342. package/src/codegen/rehype-base-url.mjs +15 -9
  343. package/src/codegen/rehype-base-url.test.ts +34 -0
  344. package/src/components/auto-release.test.ts +21 -0
  345. package/src/components/auto-release.ts +6 -1
  346. package/src/components/cli-support.test.ts +82 -0
  347. package/src/components/cli-support.ts +16 -9
  348. package/src/components/driver.ts +129 -56
  349. package/src/components/fan-out-run.ts +56 -35
  350. package/src/components/pr-run.ts +30 -1
  351. package/src/components/promote-order.test.ts +90 -0
  352. package/src/components/promote-order.ts +75 -0
  353. package/src/components/promote.test.ts +10 -1
  354. package/src/components/promote.ts +26 -1
  355. package/src/components/release-compile.test.ts +147 -0
  356. package/src/components/release-compile.ts +445 -0
  357. package/src/components/release-gate.test.ts +215 -0
  358. package/src/components/release-gate.ts +341 -0
  359. package/src/components/release-promote.test.ts +159 -0
  360. package/src/components/release-promote.ts +232 -0
  361. package/src/components/run-progress.ts +7 -0
  362. package/src/components/wave-plan.ts +1 -1
  363. package/src/config.ts +7 -1
  364. package/src/index.ts +2 -0
  365. package/src/lifecycle/change-set-store.test.ts +217 -0
  366. package/src/lifecycle/change-set-store.ts +112 -0
  367. package/src/lifecycle/commit-sha.ts +23 -0
  368. package/src/lifecycle/gate-change-set.e2e.test.ts +122 -0
  369. package/src/lifecycle/gate-change-set.ts +133 -0
  370. package/src/lifecycle/gate-ledger.test.ts +33 -0
  371. package/src/lifecycle/gate-ledger.ts +66 -1
  372. package/src/lifecycle/release-cut-signed.test.ts +180 -0
  373. package/src/lifecycle/release-cut.test.ts +411 -0
  374. package/src/lifecycle/release-cut.ts +367 -0
  375. package/src/lifecycle/release-ledger.test.ts +14 -0
  376. package/src/lifecycle/release-ledger.ts +85 -17
  377. package/src/lifecycle/release-store.ts +423 -0
  378. package/src/lifecycle/run-ledger.test.ts +10 -0
  379. package/src/lifecycle/run-ledger.ts +6 -0
  380. package/src/op/activities/change-coverage.ts +4 -1
  381. package/src/op/activities/source-release.ts +8 -3
  382. package/src/op/activities/source-rollback.ts +8 -4
  383. package/src/op/activity-registry.ts +7 -5
  384. package/src/op/commit-run-gate-deploy-join.test.ts +117 -0
  385. package/src/op/discover-root.test.ts +39 -0
  386. package/src/op/discover.ts +15 -8
  387. package/src/op/gate-name.ts +13 -3
  388. package/src/op/gate-release.test.ts +126 -0
  389. package/src/op/gate-run-locator.test.ts +110 -0
  390. package/src/op/gate-run-locator.ts +35 -0
  391. package/src/op/gate.ts +88 -6
  392. package/src/op/local-executor.ts +207 -52
  393. package/src/op/op-waves-run.ts +4 -0
  394. package/src/op/run-events.test.ts +166 -0
  395. package/src/op/run-live.ts +1 -1
  396. package/src/op/runtime.ts +39 -0
  397. package/src/op/runtimes/local.test.ts +16 -0
  398. package/src/op/runtimes/local.ts +13 -2
  399. package/src/point-decision.ts +12 -2
  400. package/src/run-event-store.test.ts +144 -0
  401. package/src/run-event-store.ts +213 -0
  402. package/src/run-event-stream.test.ts +175 -0
  403. package/src/run-event-stream.ts +306 -0
  404. package/src/run-event.test.ts +277 -0
  405. package/src/run-event.ts +451 -0
  406. package/src/wave-loop-golden.test.ts +9 -0
  407. package/src/workspace/__fixtures__/run-event-check.ts +58 -0
  408. package/src/workspace/ancestry-index.test.ts +93 -0
  409. package/src/workspace/change-set-show.schema.json +102 -0
  410. package/src/workspace/change-set-show.ts +72 -0
  411. package/src/workspace/change-set.schema.json +28 -1
  412. package/src/workspace/changes-cli.ts +10 -1
  413. package/src/workspace/changes.schema.json +135 -0
  414. package/src/workspace/changes.test.ts +1 -1
  415. package/src/workspace/changes.ts +84 -2
  416. package/src/workspace/ci-green-cli.ts +75 -13
  417. package/src/workspace/ci-green-forge.ts +24 -4
  418. package/src/workspace/ci-green-runs.test.ts +242 -0
  419. package/src/workspace/ci-green-signed.test.ts +302 -0
  420. package/src/workspace/ci-green-workflow.test.ts +16 -0
  421. package/src/workspace/ci-green-workflow.ts +12 -0
  422. package/src/workspace/ci-green.test.ts +131 -2
  423. package/src/workspace/ci-green.ts +624 -42
  424. package/src/workspace/ci-last-green.schema.json +32 -2
  425. package/src/workspace/ci-list.schema.json +525 -0
  426. package/src/workspace/commit-links.test.ts +279 -0
  427. package/src/workspace/commit-links.ts +183 -0
  428. package/src/workspace/declaration.schema.json +12 -0
  429. package/src/workspace/declaration.ts +22 -2
  430. package/src/workspace/identity-gate-rule.ts +91 -7
  431. package/src/workspace/identity.ts +14 -1
  432. package/src/workspace/intent.ts +48 -1
  433. package/src/workspace/ls.schema.json +3 -1
  434. package/src/workspace/ls.ts +6 -0
  435. package/src/workspace/member-pipeline.test.ts +17 -0
  436. package/src/workspace/member-pipeline.ts +9 -0
  437. package/src/workspace/promotion-order.ts +97 -0
  438. package/src/workspace/read-contract.e2e.test.ts +4 -1
  439. package/src/workspace/reason-codes.test.ts +2 -1
  440. package/src/workspace/reason-codes.ts +4 -1
  441. package/src/workspace/releases.schema.json +391 -0
  442. package/src/workspace/releases.test.ts +108 -0
  443. package/src/workspace/releases.ts +122 -0
  444. package/src/workspace/run-event.schema.json +288 -0
  445. package/src/workspace/status-contract.test.ts +52 -1
  446. package/src/workspace/status-gates.ts +56 -1
  447. package/src/workspace/status-stewards.ts +6 -0
  448. package/src/workspace/status.schema.json +70 -1
  449. package/src/workspace/status.ts +80 -1
  450. package/src/workspace/trust/ci-tag-statement.ts +151 -0
  451. package/src/workspace/trust/op-run-statement.ts +148 -0
  452. package/src/workspace/trust/rotation.ts +61 -14
  453. package/src/workspace/trust/seal.ts +10 -0
  454. package/src/workspace/trust/ssh-commit.ts +10 -9
  455. package/src/cli/commands/__fixtures__/init-lexicon-output/docs/astro.config.mjs +0 -14
  456. package/src/cli/commands/__fixtures__/init-lexicon-output/docs/package.json +0 -16
  457. package/src/cli/commands/__fixtures__/init-lexicon-output/docs/src/content/docs/index.mdx +0 -8
  458. package/src/cli/commands/__fixtures__/init-lexicon-output/docs/src/content.config.ts +0 -15
  459. package/src/cli/commands/__fixtures__/init-lexicon-output/docs/tsconfig.json +0 -10
@@ -210,6 +210,17 @@
210
210
  }
211
211
  ]
212
212
  },
213
+ "links": {
214
+ "description": "Whether each trunk commit of the range names the work item it belongs to (#4029): the first-parent commits of base..head, merges left out. A commit names one with a `Chant-Record: <kind>:<id>` trailer of a work kind the declaration names, or a `Chant-Lease` trailer a lease history on chant/lifecycle resolves to a work item. A window match does not count. Null when no work kind was read. The field is added within contract version 1, and is written by chant 0.124.28 and newer; a reader that finds none is reading an older chant. Its findings follow `severity`, like `findings`.",
215
+ "oneOf": [
216
+ {
217
+ "type": "null"
218
+ },
219
+ {
220
+ "$ref": "#/$defs/links"
221
+ }
222
+ ]
223
+ },
213
224
  "ok": {
214
225
  "type": "boolean",
215
226
  "description": "False when severity is fail and there is a finding, or when scope has a finding."
@@ -637,6 +648,130 @@
637
648
  "type": "string"
638
649
  }
639
650
  }
651
+ },
652
+ "links": {
653
+ "type": "object",
654
+ "required": [
655
+ "kinds",
656
+ "commits",
657
+ "findings"
658
+ ],
659
+ "properties": {
660
+ "kinds": {
661
+ "type": "array",
662
+ "items": {
663
+ "type": "string"
664
+ },
665
+ "description": "The work kinds read, by name. A Chant-Record links a commit only when its kind is one of these."
666
+ },
667
+ "commits": {
668
+ "type": "array",
669
+ "description": "Oldest first.",
670
+ "items": {
671
+ "$ref": "#/$defs/linkCommit"
672
+ }
673
+ },
674
+ "findings": {
675
+ "type": "array",
676
+ "items": {
677
+ "$ref": "#/$defs/linkFinding"
678
+ }
679
+ }
680
+ }
681
+ },
682
+ "linkCommit": {
683
+ "type": "object",
684
+ "required": [
685
+ "commit",
686
+ "subject",
687
+ "state",
688
+ "ids",
689
+ "problems"
690
+ ],
691
+ "properties": {
692
+ "commit": {
693
+ "type": "string",
694
+ "pattern": "^[0-9a-f]{40,64}$"
695
+ },
696
+ "subject": {
697
+ "type": "string"
698
+ },
699
+ "state": {
700
+ "enum": [
701
+ "linked",
702
+ "unlinked",
703
+ "wrong"
704
+ ],
705
+ "description": "linked: a trailer names a work record that exists, or a lease that resolves to one (a lease is taken as linked when this checkout has no chant/lifecycle branch to read). unlinked: no Chant-Record or Chant-Lease trailer names anything. wrong: trailers name a work item but none of them is one that exists."
706
+ },
707
+ "ids": {
708
+ "type": "array",
709
+ "items": {
710
+ "type": "string"
711
+ },
712
+ "description": "The work records the trailers name, as <kind>:<id>. Empty unless state is linked."
713
+ },
714
+ "problems": {
715
+ "type": "array",
716
+ "description": "The trailers that do not link the commit. Empty unless state is wrong.",
717
+ "items": {
718
+ "type": "object",
719
+ "required": [
720
+ "trailer",
721
+ "message"
722
+ ],
723
+ "properties": {
724
+ "trailer": {
725
+ "type": "string",
726
+ "description": "The trailer as written, such as Chant-Record: decision:ws-075."
727
+ },
728
+ "message": {
729
+ "type": "string"
730
+ }
731
+ }
732
+ }
733
+ }
734
+ }
735
+ },
736
+ "linkFinding": {
737
+ "type": "object",
738
+ "required": [
739
+ "id",
740
+ "code",
741
+ "commit",
742
+ "message",
743
+ "fix",
744
+ "severity"
745
+ ],
746
+ "properties": {
747
+ "id": {
748
+ "type": "string",
749
+ "description": "finding:<code>:<commit>."
750
+ },
751
+ "code": {
752
+ "enum": [
753
+ "commit-unlinked",
754
+ "commit-wrongly-linked"
755
+ ]
756
+ },
757
+ "commit": {
758
+ "type": "string",
759
+ "pattern": "^[0-9a-f]{40,64}$"
760
+ },
761
+ "message": {
762
+ "type": "string"
763
+ },
764
+ "fix": {
765
+ "type": "string",
766
+ "description": "What to change so the commit names its work item."
767
+ },
768
+ "severity": {
769
+ "enum": [
770
+ "warn",
771
+ "fail"
772
+ ]
773
+ }
774
+ }
640
775
  }
641
776
  }
642
777
  }
@@ -1,17 +1,32 @@
1
1
  /**
2
2
  * `chant ci` (#3573, ws-103): which commits passed CI.
3
3
  *
4
- * ci last-green [--json] the newest commit on the branch with a green tag and no revoked tag
5
- * ci tick [--dry-run] [--forge github] tag the commits that turned green, revoke the ones that turned red
4
+ * ci last-green [--json] [--from <rev>] the newest commit on the branch with a green tag and no revoked tag
5
+ * ci list [--json] [--limit <n>] [--since <rev>] [--forge github] [--source checks|runs]
6
+ * the branch's commits within the window, each with its state and phase results
7
+ * ci tick [--dry-run] [--forge github] [--source checks|runs] [--key <runner key.pem>]
8
+ * tag the commits that turned green, revoke the ones that turned red
6
9
  * ci workflow [--workflow <name>]... [--output <file>] [--chant <command>] [--install <command>]
7
- * [--token-secret <NAME> | --app-id-var <VAR> --app-key-secret <NAME>]
10
+ * [--token-secret <NAME> | --app-id-var <VAR> --app-key-secret <NAME>] [--runner-key-secret <NAME>]
8
11
  * write the root CI file that runs the tick
9
12
  *
10
- * `last-green --json` prints `ci-last-green.schema.json`. The tick and the
13
+ * The tick signs its tags with a runner key (#4031) from `--key <file>` or
14
+ * the PEM in `CHANT_RUNNER_KEY`, which the generated workflow sets from the
15
+ * secret `--runner-key-secret` names.
16
+ *
17
+ * `--source runs` (or `ci.green.source: "runs"`) reads phase results from
18
+ * chant's own signed Op runs on `chant/lifecycle` in place of the forge's
19
+ * check runs (#4044); a tick from runs needs no forge token.
20
+ *
21
+ * `last-green --json` prints `ci-last-green.schema.json` and `list --json` prints
22
+ * `ci-list.schema.json`. The tick and the
11
23
  * workflow print text.
12
24
  */
13
25
  import type { CommandContext } from "../cli/registry.js";
26
+ import { RUNNER_KEY_ENV } from "./ci-green.js";
27
+ export { RUNNER_KEY_ENV };
14
28
  export declare function runCiLastGreen(ctx: CommandContext): Promise<number>;
29
+ export declare function runCiList(ctx: CommandContext): Promise<number>;
15
30
  export declare function runCiTick(ctx: CommandContext): Promise<number>;
16
31
  export declare function runCiWorkflow(ctx: CommandContext): Promise<number>;
17
32
  //# sourceMappingURL=ci-green-cli.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ci-green-cli.d.ts","sourceRoot":"","sources":["../../src/workspace/ci-green-cli.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAWtD,wBAAsB,cAAc,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAgBzE;AAID,wBAAsB,SAAS,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAUpE;AAeD,wBAAsB,aAAa,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CA6CxE"}
1
+ {"version":3,"file":"ci-green-cli.d.ts","sourceRoot":"","sources":["../../src/workspace/ci-green-cli.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAKH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD,OAAO,EAAmE,cAAc,EAAE,MAAM,YAAY,CAAC;AAW7G,OAAO,EAAE,cAAc,EAAE,CAAC;AAe1B,wBAAsB,cAAc,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAiBzE;AAED,wBAAsB,SAAS,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAsBpE;AAID,wBAAsB,SAAS,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAapE;AAeD,wBAAsB,aAAa,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAkDxE"}
@@ -1,28 +1,56 @@
1
1
  /**
2
2
  * `chant ci` (#3573, ws-103): which commits passed CI.
3
3
  *
4
- * ci last-green [--json] the newest commit on the branch with a green tag and no revoked tag
5
- * ci tick [--dry-run] [--forge github] tag the commits that turned green, revoke the ones that turned red
4
+ * ci last-green [--json] [--from <rev>] the newest commit on the branch with a green tag and no revoked tag
5
+ * ci list [--json] [--limit <n>] [--since <rev>] [--forge github] [--source checks|runs]
6
+ * the branch's commits within the window, each with its state and phase results
7
+ * ci tick [--dry-run] [--forge github] [--source checks|runs] [--key <runner key.pem>]
8
+ * tag the commits that turned green, revoke the ones that turned red
6
9
  * ci workflow [--workflow <name>]... [--output <file>] [--chant <command>] [--install <command>]
7
- * [--token-secret <NAME> | --app-id-var <VAR> --app-key-secret <NAME>]
10
+ * [--token-secret <NAME> | --app-id-var <VAR> --app-key-secret <NAME>] [--runner-key-secret <NAME>]
8
11
  * write the root CI file that runs the tick
9
12
  *
10
- * `last-green --json` prints `ci-last-green.schema.json`. The tick and the
13
+ * The tick signs its tags with a runner key (#4031) from `--key <file>` or
14
+ * the PEM in `CHANT_RUNNER_KEY`, which the generated workflow sets from the
15
+ * secret `--runner-key-secret` names.
16
+ *
17
+ * `--source runs` (or `ci.green.source: "runs"`) reads phase results from
18
+ * chant's own signed Op runs on `chant/lifecycle` in place of the forge's
19
+ * check runs (#4044); a tick from runs needs no forge token.
20
+ *
21
+ * `last-green --json` prints `ci-last-green.schema.json` and `list --json` prints
22
+ * `ci-list.schema.json`. The tick and the
11
23
  * workflow print text.
12
24
  */
13
- import { existsSync, realpathSync } from "node:fs";
25
+ import { existsSync, readFileSync, realpathSync } from "node:fs";
14
26
  import { join, relative, resolve, sep } from "node:path";
15
27
  import { formatError } from "../cli/format.js";
16
28
  import { findWorkspaceRoot } from "../project-root.js";
17
- import { ciTick, CiGreenError, formatTick, lastGreen } from "./ci-green.js";
29
+ import { ciList, ciTick, CiGreenError, formatList, formatTick, lastGreen, RUNNER_KEY_ENV } from "./ci-green.js";
18
30
  import { ciForgeFromEnv } from "./ci-green-forge.js";
19
31
  import { ACTIONS_NAME, CI_GREEN_WORKFLOW_FILE, ciGreenHeader, readWorkflowSources, renderCiGreenWorkflow, workflowsHolding, writeWorkflowFile } from "./ci-green-workflow.js";
20
32
  import { readDeclaration, readerVersion, WorkspaceReadError } from "./declaration.js";
21
33
  import { recordGeneratedFiles, resolveMemberContext, shellArg } from "./member-pipeline.js";
22
34
  import { gitTop, workingTree } from "./tree.js";
23
- const USAGE = "chant ci last-green [--json] | ci tick [--dry-run] [--forge github] | ci workflow [--workflow <name>]... [--output <file>] [--chant <command>] [--install <command>] [--token-secret <NAME> | --app-id-var <VAR> --app-key-secret <NAME>]";
35
+ 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
+ "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>]";
37
+ export { RUNNER_KEY_ENV };
38
+ /** `--source`, checked (#4044): `checks` or `runs`, or undefined to follow `ci.green.source`. */
39
+ function sourceOf(args) {
40
+ const v = args.source;
41
+ if (v === undefined)
42
+ return undefined;
43
+ if (v !== "checks" && v !== "runs")
44
+ throw new Error(`--source takes checks (the forge's check runs) or runs (chant's own Op runs), not ${JSON.stringify(v)}`);
45
+ return v;
46
+ }
47
+ /** Each ignored tag as a warning line for stderr (#4031). */
48
+ function warnIgnored(ignored) {
49
+ for (const t of ignored)
50
+ console.error(`warning: ignored ${t.tag} (${t.status}): ${t.reason}`);
51
+ }
24
52
  export async function runCiLastGreen(ctx) {
25
- const doc = lastGreen({ cwd: process.cwd() });
53
+ const doc = lastGreen({ cwd: process.cwd(), ...(ctx.args.migrateFrom !== undefined ? { from: ctx.args.migrateFrom } : {}) });
26
54
  if (ctx.args.json) {
27
55
  console.log(JSON.stringify(doc, null, 2));
28
56
  return "error" in doc ? 1 : 0;
@@ -31,6 +59,7 @@ export async function runCiLastGreen(ctx) {
31
59
  console.error(formatError({ message: doc.error.message, hint: USAGE }));
32
60
  return 1;
33
61
  }
62
+ warnIgnored(doc.ignored);
34
63
  if (!doc.commit) {
35
64
  console.error(`No first-parent commit of ${doc.ref} has a ci/green tag without a ci/revoked one. Fetch the tags first: git fetch origin --tags`);
36
65
  return 1;
@@ -38,11 +67,39 @@ export async function runCiLastGreen(ctx) {
38
67
  console.log(doc.commit.sha);
39
68
  return 0;
40
69
  }
70
+ export async function runCiList(ctx) {
71
+ try {
72
+ const limit = ctx.args.limit;
73
+ if (limit !== undefined && (!Number.isInteger(limit) || limit < 1))
74
+ throw new Error("--limit takes a whole number of commits, 1 or more");
75
+ // Only an explicit --forge reaches the network; without it the list reads local refs and tags.
76
+ const forge = ctx.args.forge !== undefined ? ciForgeFromEnv(ctx.args.forge) : undefined;
77
+ const source = sourceOf(ctx.args);
78
+ const doc = await ciList({ cwd: process.cwd(), limit, since: ctx.args.since, forge, ...(source ? { source } : {}) });
79
+ if (ctx.args.json) {
80
+ console.log(JSON.stringify(doc, null, 2));
81
+ return "error" in doc ? 1 : 0;
82
+ }
83
+ if ("error" in doc) {
84
+ console.error(formatError({ message: doc.error.message, hint: USAGE }));
85
+ return 1;
86
+ }
87
+ console.log(formatList(doc));
88
+ return 0;
89
+ }
90
+ catch (err) {
91
+ console.error(formatError({ message: `chant ci list: ${describe(err)}`, hint: USAGE }));
92
+ return 1;
93
+ }
94
+ }
41
95
  const describe = (err) => (err instanceof WorkspaceReadError ? err.describe() : err instanceof Error ? err.message : String(err));
42
96
  export async function runCiTick(ctx) {
43
97
  try {
44
- const forge = ciForgeFromEnv(ctx.args.forge ?? "github");
45
- const result = await ciTick({ cwd: process.cwd(), forge, dryRun: ctx.args.dryRun === true });
98
+ const source = sourceOf(ctx.args);
99
+ // The forge is made only when the source is check runs, so a tick from chant runs needs no forge token.
100
+ const forge = () => ciForgeFromEnv(ctx.args.forge ?? "github");
101
+ const runnerKey = ctx.args.key !== undefined ? readFileSync(resolve(ctx.args.key), "utf-8") : process.env[RUNNER_KEY_ENV] || undefined;
102
+ const result = await ciTick({ cwd: process.cwd(), forge, dryRun: ctx.args.dryRun === true, ...(source ? { source } : {}), ...(runnerKey !== undefined ? { runnerKey } : {}) });
46
103
  console.log(formatTick(result, ctx.args.dryRun === true));
47
104
  return 0;
48
105
  }
@@ -54,7 +111,7 @@ export async function runCiTick(ctx) {
54
111
  /** The push token the flags ask for, or none for the Actions token. Throws on a half-given or clashing pair. */
55
112
  function pushToken(args) {
56
113
  const { ciTokenSecret: secret, ciAppIdVar: appIdVar, ciAppKeySecret: appKeySecret } = args;
57
- for (const [flag, name] of [["--token-secret", secret], ["--app-id-var", appIdVar], ["--app-key-secret", appKeySecret]]) {
114
+ for (const [flag, name] of [["--token-secret", secret], ["--app-id-var", appIdVar], ["--app-key-secret", appKeySecret], ["--runner-key-secret", args.ciRunnerKeySecret]]) {
58
115
  if (name !== undefined && !ACTIONS_NAME.test(name))
59
116
  throw new Error(`${flag} takes a secret or variable name, letters, digits and underscores, not ${JSON.stringify(name)}`);
60
117
  }
@@ -107,11 +164,17 @@ export async function runCiWorkflow(ctx) {
107
164
  parts.push("--token-secret", push.secret);
108
165
  if (push && "appIdVar" in push)
109
166
  parts.push("--app-id-var", push.appIdVar, "--app-key-secret", push.appKeySecret);
167
+ const runnerKeySecret = ctx.args.ciRunnerKeySecret;
168
+ if (runnerKeySecret)
169
+ parts.push("--runner-key-secret", runnerKeySecret);
170
+ if (green.signedSince && !runnerKeySecret) {
171
+ console.error(`warning: ci.green.signedSince is set, so the tick needs a runner key; pass --runner-key-secret <NAME> naming the repository secret that holds it, or every tick will fail`);
172
+ }
110
173
  const command = parts.map(shellArg).join(" ");
111
174
  const workspaceRoot = relative(repoRoot, root).split(sep).join("/") || ".";
112
175
  // The install runs in the workspace root, so its lockfile there keys setup-node's npm cache.
113
176
  const npmLock = ctx.args.ciInstall && existsSync(join(root, "package-lock.json")) ? (workspaceRoot === "." ? "package-lock.json" : `${workspaceRoot}/package-lock.json`) : undefined;
114
- const yaml = renderCiGreenWorkflow({ green, workflows, chantVersion: readerVersion(), workspaceRoot, chant: ctx.args.ciChant, install: ctx.args.ciInstall, npmLock, push });
177
+ const yaml = renderCiGreenWorkflow({ green, workflows, chantVersion: readerVersion(), workspaceRoot, chant: ctx.args.ciChant, install: ctx.args.ciInstall, npmLock, push, ...(runnerKeySecret ? { runnerKeySecret } : {}) });
115
178
  const written = writeWorkflowFile(target, ciGreenHeader(command, member ? "member" : "root") + yaml);
116
179
  if (member)
117
180
  recordGeneratedFiles(member.memberRoot, [{ path: fromRepo, command }]);
@@ -6,14 +6,17 @@
6
6
  * The tags themselves are git's, pushed to the remote like any other ref, so
7
7
  * the forge is asked for check runs and nothing else. GitHub is the one
8
8
  * forge implemented. Forgejo reports commit statuses rather than check runs,
9
- * and GitLab reports pipeline jobs; each can implement {@link CiForge} by
10
- * mapping those to {@link CheckRun}s, and until one does `--forge` refuses
11
- * them by name.
9
+ * and GitLab reports pipeline jobs, and neither gets a reader here (#4021): a
10
+ * project on either runs its pipelines as chant Ops and sets
11
+ * `ci.green.source` to `runs`, so the tick reads signed Op runs from the run
12
+ * ledger instead (#4044, `./ci-green.ts`). `--forge` refuses them by name and
13
+ * says so.
12
14
  *
13
15
  * The client takes a `fetch` like the pull-request loop's (`../pr-forge.ts`),
14
16
  * so the tests drive it with a recording fake and no network.
15
17
  */
16
18
  import { type ForgeFetch, type ForgeKind } from "../pr-forge.js";
19
+ import type { OpRunRecord } from "../op/runtime.js";
17
20
  /** One attempt of one check run on a commit. */
18
21
  export interface CheckRun {
19
22
  /** The forge's id. A later attempt of the same check has a larger one. */
@@ -25,6 +28,20 @@ export interface CheckRun {
25
28
  conclusion: string | null;
26
29
  completedAt: string | null;
27
30
  url: string | null;
31
+ /**
32
+ * Set when the "check run" is a chant Op run (#4044, `ci.green.source:
33
+ * "runs"`): the run's id and env, the runner whose statement it carries,
34
+ * and that statement. `name` is then the Op's name and `id` the run's end
35
+ * time in milliseconds, which orders a re-run after the run it replaced.
36
+ */
37
+ opRun?: OpRunRef;
38
+ }
39
+ /** The Op run a {@link CheckRun} stands for (#4044). */
40
+ export interface OpRunRef {
41
+ id: string;
42
+ env: string;
43
+ signer: string;
44
+ statement: NonNullable<OpRunRecord["statement"]>;
28
45
  }
29
46
  export interface CiForge {
30
47
  kind: ForgeKind;
@@ -1 +1 @@
1
- {"version":3,"file":"ci-green-forge.d.ts","sourceRoot":"","sources":["../../src/workspace/ci-green-forge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAwC,KAAK,UAAU,EAAE,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AAEpG,gDAAgD;AAChD,MAAM,WAAW,QAAQ;IACvB,0EAA0E;IAC1E,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,6GAA6G;IAC7G,MAAM,EAAE,MAAM,CAAC;IACf,8HAA8H;IAC9H,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;CACpB;AAED,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,SAAS,CAAC;IAChB,+CAA+C;IAC/C,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;CAC7C;AAED,MAAM,WAAW,oBAAoB;IACnC,sEAAsE;IACtE,OAAO,EAAE,MAAM,CAAC;IAChB,oBAAoB;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,UAAU,CAAC;CACpB;AAKD,+GAA+G;AAC/G,wBAAgB,aAAa,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAkCjE;AAED,0EAA0E;AAC1E,qBAAa,uBAAwB,SAAQ,KAAK;IAChD,YAAY,IAAI,EAAE,MAAM,EAGvB;CACF;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,GAAE,MAAiB,EAAE,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAe,EAAE,SAAS,CAAC,EAAE,UAAU,GAAG,OAAO,CAW9I"}
1
+ {"version":3,"file":"ci-green-forge.d.ts","sourceRoot":"","sources":["../../src/workspace/ci-green-forge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAwC,KAAK,UAAU,EAAE,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AACpG,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD,gDAAgD;AAChD,MAAM,WAAW,QAAQ;IACvB,0EAA0E;IAC1E,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,6GAA6G;IAC7G,MAAM,EAAE,MAAM,CAAC;IACf,8HAA8H;IAC9H,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,QAAQ,CAAC;CAClB;AAED,wDAAwD;AACxD,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,WAAW,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,CAAC;CAClD;AAED,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,SAAS,CAAC;IAChB,+CAA+C;IAC/C,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;CAC7C;AAED,MAAM,WAAW,oBAAoB;IACnC,sEAAsE;IACtE,OAAO,EAAE,MAAM,CAAC;IAChB,oBAAoB;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,UAAU,CAAC;CACpB;AAKD,+GAA+G;AAC/G,wBAAgB,aAAa,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAkCjE;AAED,0EAA0E;AAC1E,qBAAa,uBAAwB,SAAQ,KAAK;IAChD,YAAY,IAAI,EAAE,MAAM,EAKvB;CACF;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,GAAE,MAAiB,EAAE,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAe,EAAE,SAAS,CAAC,EAAE,UAAU,GAAG,OAAO,CAW9I"}
@@ -6,9 +6,11 @@
6
6
  * The tags themselves are git's, pushed to the remote like any other ref, so
7
7
  * the forge is asked for check runs and nothing else. GitHub is the one
8
8
  * forge implemented. Forgejo reports commit statuses rather than check runs,
9
- * and GitLab reports pipeline jobs; each can implement {@link CiForge} by
10
- * mapping those to {@link CheckRun}s, and until one does `--forge` refuses
11
- * them by name.
9
+ * and GitLab reports pipeline jobs, and neither gets a reader here (#4021): a
10
+ * project on either runs its pipelines as chant Ops and sets
11
+ * `ci.green.source` to `runs`, so the tick reads signed Op runs from the run
12
+ * ledger instead (#4044, `./ci-green.ts`). `--forge` refuses them by name and
13
+ * says so.
12
14
  *
13
15
  * The client takes a `fetch` like the pull-request loop's (`../pr-forge.ts`),
14
16
  * so the tests drive it with a recording fake and no network.
@@ -58,7 +60,7 @@ export function githubCiForge(opts) {
58
60
  /** Thrown for a forge `chant ci tick` has no check-run client for yet. */
59
61
  export class CiForgeUnsupportedError extends Error {
60
62
  constructor(kind) {
61
- super(`check runs are read from GitHub only so far, and --forge asked for ${kind}; see #3573`);
63
+ super(`check runs are read from GitHub only, and --forge asked for ${kind}. A ${kind} project runs its pipelines as chant Ops and sets ci.green.source to "runs" (or passes --source runs), so the tick reads signed Op runs from chant/lifecycle instead`);
62
64
  this.name = "CiForgeUnsupportedError";
63
65
  }
64
66
  }
@@ -34,6 +34,11 @@
34
34
  * tick's own `GITHUB_TOKEN`, which reads check runs, stays the Actions token:
35
35
  * a fine-grained personal access token can't call the Checks API.
36
36
  *
37
+ * `--runner-key-secret <NAME>` (#4031) hands the tick the runner key it
38
+ * signs its tags with, from `secrets.<NAME>` as `CHANT_RUNNER_KEY`. A
39
+ * declaration that sets `ci.green.signedSince` needs it: a tag outside that
40
+ * commit's strict first-parent ancestry without a statement is ignored.
41
+ *
37
42
  * Like a member's pipelines (./member-pipeline.ts), the file starts with the
38
43
  * generated-file header naming the command, and the member whose directory
39
44
  * the command runs in records it in its generated-file record, so `WSP081`
@@ -86,6 +91,12 @@ export interface WorkflowInput {
86
91
  workspaceRoot: string;
87
92
  /** How the tag push authenticates, when not with the Actions token. */
88
93
  push?: PushToken;
94
+ /**
95
+ * The repository secret holding the runner key the tick signs its tags
96
+ * with, as PEM (#4031). The tick step reads it from `CHANT_RUNNER_KEY`.
97
+ * The key's principal needs the `runner` role in `.chant/trust.json`.
98
+ */
99
+ runnerKeySecret?: string;
89
100
  }
90
101
  /**
91
102
  * A token the checkout persists for the tick's `git push`: a repository
@@ -1 +1 @@
1
- {"version":3,"file":"ci-green-workflow.d.ts","sourceRoot":"","sources":["../../src/workspace/ci-green-workflow.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAMH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAI7C,gEAAgE;AAChE,eAAO,MAAM,sBAAsB,yCAAyC,CAAC;AAC7E,eAAO,MAAM,sBAAsB,mBAAmB,CAAC;AAEvD,8CAA8C;AAC9C,MAAM,WAAW,cAAc;IAC7B,2EAA2E;IAC3E,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAKD,yHAAyH;AACzH,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,EAAE,CAYnD;AAYD,MAAM,WAAW,YAAY;IAC3B,0DAA0D;IAC1D,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,sDAAsD;IACtD,SAAS,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAChD,+CAA+C;IAC/C,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,oEAAoE;AACpE,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,cAAc,EAAE,GAAG,YAAY,CAyBjG;AAED,iEAAiE;AACjE,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,cAAc,EAAE,CASpF;AAID,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,OAAO,CAAC;IACf,sDAAsD;IACtD,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B,mEAAmE;IACnE,YAAY,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wFAAwF;IACxF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,8GAA8G;IAC9G,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mFAAmF;IACnF,aAAa,EAAE,MAAM,CAAC;IACtB,uEAAuE;IACvE,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB;AAED;;;;GAIG;AACH,MAAM,MAAM,SAAS,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAAC;AAExF,4GAA4G;AAC5G,eAAO,MAAM,YAAY,QAA6B,CAAC;AAEvD,mHAAmH;AACnH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CAqElE;AAED,yFAAyF;AACzF,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,GAAG,MAAM,GAAG,MAAM,CAE/E;AAED,kGAAkG;AAClG,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAItE"}
1
+ {"version":3,"file":"ci-green-workflow.d.ts","sourceRoot":"","sources":["../../src/workspace/ci-green-workflow.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAMH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAI7C,gEAAgE;AAChE,eAAO,MAAM,sBAAsB,yCAAyC,CAAC;AAC7E,eAAO,MAAM,sBAAsB,mBAAmB,CAAC;AAEvD,8CAA8C;AAC9C,MAAM,WAAW,cAAc;IAC7B,2EAA2E;IAC3E,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAKD,yHAAyH;AACzH,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,EAAE,CAYnD;AAYD,MAAM,WAAW,YAAY;IAC3B,0DAA0D;IAC1D,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,sDAAsD;IACtD,SAAS,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAChD,+CAA+C;IAC/C,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,oEAAoE;AACpE,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,cAAc,EAAE,GAAG,YAAY,CAyBjG;AAED,iEAAiE;AACjE,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,cAAc,EAAE,CASpF;AAID,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,OAAO,CAAC;IACf,sDAAsD;IACtD,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B,mEAAmE;IACnE,YAAY,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wFAAwF;IACxF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,8GAA8G;IAC9G,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mFAAmF;IACnF,aAAa,EAAE,MAAM,CAAC;IACtB,uEAAuE;IACvE,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;;GAIG;AACH,MAAM,MAAM,SAAS,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAAC;AAExF,4GAA4G;AAC5G,eAAO,MAAM,YAAY,QAA6B,CAAC;AAEvD,mHAAmH;AACnH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CAsElE;AAED,yFAAyF;AACzF,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,GAAG,MAAM,GAAG,MAAM,CAE/E;AAED,kGAAkG;AAClG,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAItE"}
@@ -34,6 +34,11 @@
34
34
  * tick's own `GITHUB_TOKEN`, which reads check runs, stays the Actions token:
35
35
  * a fine-grained personal access token can't call the Checks API.
36
36
  *
37
+ * `--runner-key-secret <NAME>` (#4031) hands the tick the runner key it
38
+ * signs its tags with, from `secrets.<NAME>` as `CHANT_RUNNER_KEY`. A
39
+ * declaration that sets `ci.green.signedSince` needs it: a tag outside that
40
+ * commit's strict first-parent ancestry without a statement is ignored.
41
+ *
37
42
  * Like a member's pipelines (./member-pipeline.ts), the file starts with the
38
43
  * generated-file header naming the command, and the member whose directory
39
44
  * the command runs in records it in its generated-file record, so `WSP081`
@@ -186,6 +191,7 @@ export function renderCiGreenWorkflow(input) {
186
191
  " GITHUB_TOKEN: ${{ github.token }}",
187
192
  " GIT_COMMITTER_NAME: github-actions[bot]",
188
193
  " GIT_COMMITTER_EMAIL: 41898282+github-actions[bot]@users.noreply.github.com",
194
+ ...(input.runnerKeySecret ? [` CHANT_RUNNER_KEY: \${{ secrets.${input.runnerKeySecret} }}`] : []),
189
195
  ` run: ${tick}`,
190
196
  ];
191
197
  return lines.join("\n") + "\n";