@intentius/chant 0.124.40 → 0.124.42

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 (346) hide show
  1. package/dist/__fixtures__/oidc-emulator.d.ts +49 -0
  2. package/dist/__fixtures__/oidc-emulator.d.ts.map +1 -0
  3. package/dist/__fixtures__/oidc-emulator.js +89 -0
  4. package/dist/ci-handover.d.ts +117 -0
  5. package/dist/ci-handover.d.ts.map +1 -0
  6. package/dist/ci-handover.js +217 -0
  7. package/dist/ci-identity.d.ts +190 -0
  8. package/dist/ci-identity.d.ts.map +1 -0
  9. package/dist/ci-identity.js +219 -0
  10. package/dist/cli/handlers/approve.d.ts +2 -1
  11. package/dist/cli/handlers/approve.d.ts.map +1 -1
  12. package/dist/cli/handlers/approve.js +20 -6
  13. package/dist/cli/handlers/build.d.ts.map +1 -1
  14. package/dist/cli/handlers/build.js +18 -1
  15. package/dist/cli/handlers/fan-out.d.ts.map +1 -1
  16. package/dist/cli/handlers/fan-out.js +42 -5
  17. package/dist/cli/handlers/gate-resume.d.ts +3 -0
  18. package/dist/cli/handlers/gate-resume.d.ts.map +1 -1
  19. package/dist/cli/handlers/gate-resume.js +15 -2
  20. package/dist/cli/handlers/lock.d.ts +8 -0
  21. package/dist/cli/handlers/lock.d.ts.map +1 -0
  22. package/dist/cli/handlers/lock.js +197 -0
  23. package/dist/cli/handlers/pr-env.d.ts +34 -0
  24. package/dist/cli/handlers/pr-env.d.ts.map +1 -0
  25. package/dist/cli/handlers/pr-env.js +436 -0
  26. package/dist/cli/handlers/pr.d.ts +76 -0
  27. package/dist/cli/handlers/pr.d.ts.map +1 -1
  28. package/dist/cli/handlers/pr.js +615 -55
  29. package/dist/cli/handlers/promote.d.ts.map +1 -1
  30. package/dist/cli/handlers/promote.js +9 -0
  31. package/dist/cli/handlers/query.d.ts +6 -0
  32. package/dist/cli/handlers/query.d.ts.map +1 -0
  33. package/dist/cli/handlers/query.js +80 -0
  34. package/dist/cli/handlers/run.d.ts.map +1 -1
  35. package/dist/cli/handlers/run.js +11 -0
  36. package/dist/cli/main.d.ts.map +1 -1
  37. package/dist/cli/main.js +49 -4
  38. package/dist/cli/parse-args.d.ts.map +1 -1
  39. package/dist/cli/parse-args.js +46 -2
  40. package/dist/cli/registry.d.ts +31 -2
  41. package/dist/cli/registry.d.ts.map +1 -1
  42. package/dist/components/capability.d.ts +47 -0
  43. package/dist/components/capability.d.ts.map +1 -1
  44. package/dist/components/capability.js +44 -0
  45. package/dist/components/cli-support.d.ts +6 -0
  46. package/dist/components/cli-support.d.ts.map +1 -1
  47. package/dist/components/cli-support.js +8 -1
  48. package/dist/components/driver.d.ts +10 -0
  49. package/dist/components/driver.d.ts.map +1 -1
  50. package/dist/components/driver.js +52 -2
  51. package/dist/components/fan-out-run.d.ts +37 -0
  52. package/dist/components/fan-out-run.d.ts.map +1 -1
  53. package/dist/components/fan-out-run.js +44 -4
  54. package/dist/components/gate-plan.d.ts +2 -0
  55. package/dist/components/gate-plan.d.ts.map +1 -1
  56. package/dist/components/gate-plan.js +1 -0
  57. package/dist/components/pr-environment.d.ts +298 -0
  58. package/dist/components/pr-environment.d.ts.map +1 -0
  59. package/dist/components/pr-environment.js +406 -0
  60. package/dist/components/pr-hooks.d.ts +66 -0
  61. package/dist/components/pr-hooks.d.ts.map +1 -0
  62. package/dist/components/pr-hooks.js +119 -0
  63. package/dist/components/pr-pipeline.d.ts +92 -2
  64. package/dist/components/pr-pipeline.d.ts.map +1 -1
  65. package/dist/components/pr-pipeline.js +150 -21
  66. package/dist/components/pr-policy.d.ts +109 -0
  67. package/dist/components/pr-policy.d.ts.map +1 -0
  68. package/dist/components/pr-policy.js +150 -0
  69. package/dist/components/pr-run.d.ts +6 -0
  70. package/dist/components/pr-run.d.ts.map +1 -1
  71. package/dist/components/pr-run.js +8 -3
  72. package/dist/components/wave-plan.d.ts +14 -1
  73. package/dist/components/wave-plan.d.ts.map +1 -1
  74. package/dist/components/wave-plan.js +34 -2
  75. package/dist/gate-decision.d.ts +15 -2
  76. package/dist/gate-decision.d.ts.map +1 -1
  77. package/dist/gate-decision.js +17 -2
  78. package/dist/gate-policy.d.ts +140 -0
  79. package/dist/gate-policy.d.ts.map +1 -0
  80. package/dist/gate-policy.js +242 -0
  81. package/dist/lifecycle/gate-checkpoint.d.ts +1 -1
  82. package/dist/lifecycle/gate-checkpoint.js +1 -1
  83. package/dist/{workspace/trust → lifecycle}/gate-seal.d.ts +1 -1
  84. package/dist/lifecycle/gate-seal.d.ts.map +1 -0
  85. package/dist/lifecycle/query.d.ts +68 -0
  86. package/dist/lifecycle/query.d.ts.map +1 -0
  87. package/dist/lifecycle/query.js +246 -0
  88. package/dist/lifecycle/run-ledger.d.ts +13 -0
  89. package/dist/lifecycle/run-ledger.d.ts.map +1 -1
  90. package/dist/lifecycle/run-ledger.js +16 -0
  91. package/dist/lifecycle/target-lock.d.ts +97 -0
  92. package/dist/lifecycle/target-lock.d.ts.map +1 -0
  93. package/dist/lifecycle/target-lock.js +286 -0
  94. package/dist/op/activities/activity-contracts.d.ts +30 -0
  95. package/dist/op/activities/activity-contracts.d.ts.map +1 -1
  96. package/dist/op/activities/activity-contracts.js +26 -0
  97. package/dist/op/activities/index.d.ts +2 -0
  98. package/dist/op/activities/index.d.ts.map +1 -1
  99. package/dist/op/activities/index.js +4 -0
  100. package/dist/op/activities/pr-refs.d.ts +10 -0
  101. package/dist/op/activities/pr-refs.d.ts.map +1 -0
  102. package/dist/op/activities/pr-refs.js +26 -0
  103. package/dist/op/activities/predict-behaviour.d.ts +2 -4
  104. package/dist/op/activities/predict-behaviour.d.ts.map +1 -1
  105. package/dist/op/activities/predict-behaviour.js +2 -21
  106. package/dist/op/activities/review-agent.d.ts +137 -0
  107. package/dist/op/activities/review-agent.d.ts.map +1 -0
  108. package/dist/op/activities/review-agent.js +266 -0
  109. package/dist/op/builders.d.ts +9 -0
  110. package/dist/op/builders.d.ts.map +1 -1
  111. package/dist/op/builders.js +11 -0
  112. package/dist/op/cron.d.ts +8 -0
  113. package/dist/op/cron.d.ts.map +1 -1
  114. package/dist/op/cron.js +51 -0
  115. package/dist/op/gate-approval.d.ts +20 -13
  116. package/dist/op/gate-approval.d.ts.map +1 -1
  117. package/dist/op/gate-approval.js +13 -18
  118. package/dist/op/gate-quorum.d.ts +131 -0
  119. package/dist/op/gate-quorum.d.ts.map +1 -0
  120. package/dist/op/gate-quorum.js +183 -0
  121. package/dist/op/gate-resume.d.ts +4 -2
  122. package/dist/op/gate-resume.d.ts.map +1 -1
  123. package/dist/op/gate-resume.js +5 -4
  124. package/dist/op/gate-review.js +1 -1
  125. package/dist/op/gate.d.ts +32 -4
  126. package/dist/op/gate.d.ts.map +1 -1
  127. package/dist/op/gate.js +40 -24
  128. package/dist/op/index.d.ts +6 -4
  129. package/dist/op/index.d.ts.map +1 -1
  130. package/dist/op/index.js +4 -3
  131. package/dist/op/local-executor.d.ts.map +1 -1
  132. package/dist/op/local-executor.js +9 -3
  133. package/dist/op/op-waves-run.d.ts +28 -43
  134. package/dist/op/op-waves-run.d.ts.map +1 -1
  135. package/dist/op/op-waves-run.js +170 -120
  136. package/dist/op/op-waves.d.ts +55 -3
  137. package/dist/op/op-waves.d.ts.map +1 -1
  138. package/dist/op/op-waves.js +63 -8
  139. package/dist/op/schedule-overdue.d.ts +57 -0
  140. package/dist/op/schedule-overdue.d.ts.map +1 -0
  141. package/dist/op/schedule-overdue.js +138 -0
  142. package/dist/op/stage-hooks.d.ts +132 -0
  143. package/dist/op/stage-hooks.d.ts.map +1 -0
  144. package/dist/op/stage-hooks.js +142 -0
  145. package/dist/override-gate.d.ts +2 -2
  146. package/dist/override-gate.d.ts.map +1 -1
  147. package/dist/override-gate.js +1 -1
  148. package/dist/pr-forge.d.ts +64 -0
  149. package/dist/pr-forge.d.ts.map +1 -1
  150. package/dist/pr-forge.js +331 -44
  151. package/dist/pr-loop.d.ts +107 -1
  152. package/dist/pr-loop.d.ts.map +1 -1
  153. package/dist/pr-loop.js +84 -3
  154. package/dist/pr-post.d.ts +72 -0
  155. package/dist/pr-post.d.ts.map +1 -0
  156. package/dist/pr-post.js +134 -0
  157. package/dist/pr-requires.d.ts +38 -0
  158. package/dist/pr-requires.d.ts.map +1 -0
  159. package/dist/pr-requires.js +48 -0
  160. package/dist/wave-blocked.d.ts +79 -0
  161. package/dist/wave-blocked.d.ts.map +1 -0
  162. package/dist/wave-blocked.js +245 -0
  163. package/dist/wave-engine.d.ts +6 -0
  164. package/dist/wave-engine.d.ts.map +1 -1
  165. package/dist/wave-engine.js +2 -0
  166. package/dist/wave-runtime.mjs +243 -243
  167. package/dist/workspace/__fixtures__/two-member-workspace.d.ts +1 -0
  168. package/dist/workspace/__fixtures__/two-member-workspace.d.ts.map +1 -1
  169. package/dist/workspace/__fixtures__/two-member-workspace.js +1 -1
  170. package/dist/workspace/checks/ci-workflow.d.ts.map +1 -1
  171. package/dist/workspace/checks/ci-workflow.js +19 -4
  172. package/dist/workspace/ci-branches.d.ts +51 -0
  173. package/dist/workspace/ci-branches.d.ts.map +1 -0
  174. package/dist/workspace/ci-branches.js +69 -0
  175. package/dist/workspace/ci-cloud-identity.d.ts +11 -0
  176. package/dist/workspace/ci-cloud-identity.d.ts.map +1 -0
  177. package/dist/workspace/ci-cloud-identity.js +24 -0
  178. package/dist/workspace/ci-init.d.ts.map +1 -1
  179. package/dist/workspace/ci-init.js +5 -4
  180. package/dist/workspace/ci-locks.d.ts +12 -0
  181. package/dist/workspace/ci-locks.d.ts.map +1 -0
  182. package/dist/workspace/ci-locks.js +6 -0
  183. package/dist/workspace/ci-run.d.ts +17 -1
  184. package/dist/workspace/ci-run.d.ts.map +1 -1
  185. package/dist/workspace/ci-run.js +66 -4
  186. package/dist/workspace/ci-workflow-at.d.ts +14 -0
  187. package/dist/workspace/ci-workflow-at.d.ts.map +1 -0
  188. package/dist/workspace/ci-workflow-at.js +17 -0
  189. package/dist/workspace/ci-workflow.d.ts +11 -3
  190. package/dist/workspace/ci-workflow.d.ts.map +1 -1
  191. package/dist/workspace/ci-workflow.js +10 -2
  192. package/dist/workspace/declaration.d.ts +69 -3
  193. package/dist/workspace/declaration.d.ts.map +1 -1
  194. package/dist/workspace/declaration.js +72 -1
  195. package/dist/workspace/declaration.schema.json +149 -2
  196. package/dist/workspace/identity-gate-rule.d.ts +1 -1
  197. package/dist/workspace/identity-gate-rule.d.ts.map +1 -1
  198. package/dist/workspace/identity-gate-rule.js +1 -1
  199. package/dist/workspace/identity.d.ts +1 -1
  200. package/dist/workspace/identity.d.ts.map +1 -1
  201. package/dist/workspace/lineage-upgrade.d.ts.map +1 -1
  202. package/dist/workspace/lineage-upgrade.js +8 -5
  203. package/dist/workspace/member-pipeline.d.ts +6 -0
  204. package/dist/workspace/member-pipeline.d.ts.map +1 -1
  205. package/dist/workspace/member-pipeline.js +23 -0
  206. package/dist/workspace/pr-report.schema.json +94 -3
  207. package/dist/workspace/reason-codes.d.ts +1 -1
  208. package/dist/workspace/reason-codes.d.ts.map +1 -1
  209. package/dist/workspace/reason-codes.js +1 -1
  210. package/dist/workspace/security.d.ts.map +1 -1
  211. package/dist/workspace/security.js +4 -0
  212. package/dist/workspace/status-gates.d.ts +3 -2
  213. package/dist/workspace/status-gates.d.ts.map +1 -1
  214. package/dist/workspace/status-gates.js +8 -7
  215. package/dist/workspace/status.d.ts.map +1 -1
  216. package/dist/workspace/status.js +4 -1
  217. package/dist/workspace/trust/seal.d.ts +2 -2
  218. package/dist/workspace/trust/seal.d.ts.map +1 -1
  219. package/dist/workspace/trust/seal.js +2 -2
  220. package/package.json +1 -1
  221. package/src/__fixtures__/oidc-emulator.ts +118 -0
  222. package/src/ci-handover.test.ts +209 -0
  223. package/src/ci-handover.ts +237 -0
  224. package/src/ci-identity.test.ts +201 -0
  225. package/src/ci-identity.ts +310 -0
  226. package/src/cli/handlers/approve.ts +18 -5
  227. package/src/cli/handlers/build.ts +18 -1
  228. package/src/cli/handlers/fan-out.ts +43 -6
  229. package/src/cli/handlers/gate-resume.ts +16 -2
  230. package/src/cli/handlers/lock.test.ts +98 -0
  231. package/src/cli/handlers/lock.ts +202 -0
  232. package/src/cli/handlers/operator.test.ts +3 -1
  233. package/src/cli/handlers/pr-before-merge.test.ts +276 -0
  234. package/src/cli/handlers/pr-env.ts +462 -0
  235. package/src/cli/handlers/pr-waves-blocked.test.ts +247 -0
  236. package/src/cli/handlers/pr.test.ts +184 -0
  237. package/src/cli/handlers/pr.ts +605 -61
  238. package/src/cli/handlers/promote.ts +9 -0
  239. package/src/cli/handlers/query.ts +78 -0
  240. package/src/cli/handlers/run.ts +10 -0
  241. package/src/cli/main.ts +49 -4
  242. package/src/cli/parse-args.ts +34 -2
  243. package/src/cli/registry.ts +31 -2
  244. package/src/components/capability-targets.test.ts +162 -0
  245. package/src/components/capability.ts +71 -0
  246. package/src/components/cli-support.ts +14 -1
  247. package/src/components/driver.ts +54 -3
  248. package/src/components/fan-out-run.ts +58 -3
  249. package/src/components/fan-out-waves.test.ts +45 -1
  250. package/src/components/gate-plan.ts +3 -0
  251. package/src/components/pr-environment.test.ts +249 -0
  252. package/src/components/pr-environment.ts +538 -0
  253. package/src/components/pr-hooks.test.ts +118 -0
  254. package/src/components/pr-hooks.ts +157 -0
  255. package/src/components/pr-pipeline.ts +194 -21
  256. package/src/components/pr-policy.test.ts +145 -0
  257. package/src/components/pr-policy.ts +211 -0
  258. package/src/components/pr-run.ts +14 -2
  259. package/src/components/wave-plan.ts +38 -3
  260. package/src/gate-decision-bundle.test.ts +4 -3
  261. package/src/gate-decision.ts +39 -2
  262. package/src/gate-policy-bundle.test.ts +28 -0
  263. package/src/gate-policy.test.ts +162 -0
  264. package/src/gate-policy.ts +298 -0
  265. package/src/lifecycle/gate-checkpoint.ts +1 -1
  266. package/src/{workspace/trust → lifecycle}/gate-seal.ts +1 -1
  267. package/src/lifecycle/query.test.ts +91 -0
  268. package/src/lifecycle/query.ts +315 -0
  269. package/src/lifecycle/run-ledger.ts +18 -0
  270. package/src/lifecycle/target-lock.test.ts +195 -0
  271. package/src/lifecycle/target-lock.ts +347 -0
  272. package/src/op/activities/activity-contracts.ts +31 -0
  273. package/src/op/activities/index.ts +6 -0
  274. package/src/op/activities/pr-refs.ts +28 -0
  275. package/src/op/activities/predict-behaviour.ts +3 -23
  276. package/src/op/activities/review-agent.test.ts +240 -0
  277. package/src/op/activities/review-agent.ts +355 -0
  278. package/src/op/builders.ts +13 -0
  279. package/src/op/cron.ts +44 -0
  280. package/src/op/gate-alias.test.ts +2 -2
  281. package/src/op/gate-approval.test.ts +30 -9
  282. package/src/op/gate-approval.ts +23 -26
  283. package/src/op/gate-quorum.test.ts +139 -0
  284. package/src/op/gate-quorum.ts +248 -0
  285. package/src/op/gate-resume.ts +6 -3
  286. package/src/op/gate-review.ts +1 -1
  287. package/src/op/gate.ts +64 -23
  288. package/src/op/index.ts +13 -1
  289. package/src/op/local-executor.ts +9 -2
  290. package/src/op/op-waves-hook-targets.test.ts +126 -0
  291. package/src/op/op-waves-policy-hold.test.ts +66 -0
  292. package/src/op/op-waves-quorum.test.ts +101 -0
  293. package/src/op/op-waves-run.ts +197 -183
  294. package/src/op/op-waves.ts +83 -10
  295. package/src/op/schedule-overdue.test.ts +220 -0
  296. package/src/op/schedule-overdue.ts +161 -0
  297. package/src/op/stage-hooks.ts +251 -0
  298. package/src/override-gate-bundle.test.ts +1 -1
  299. package/src/override-gate.ts +2 -2
  300. package/src/pr-forge-bundle.test.ts +2 -2
  301. package/src/pr-forge.test.ts +33 -0
  302. package/src/pr-forge.ts +347 -35
  303. package/src/pr-loop-bundle.test.ts +2 -2
  304. package/src/pr-loop.test.ts +58 -0
  305. package/src/pr-loop.ts +170 -4
  306. package/src/pr-post.test.ts +141 -0
  307. package/src/pr-post.ts +159 -0
  308. package/src/pr-requires.test.ts +184 -0
  309. package/src/pr-requires.ts +79 -0
  310. package/src/review-agent-bundle.test.ts +35 -0
  311. package/src/stage-hooks-bundle.test.ts +38 -0
  312. package/src/wave-blocked-bundle.test.ts +25 -0
  313. package/src/wave-blocked.test.ts +146 -0
  314. package/src/wave-blocked.ts +271 -0
  315. package/src/wave-engine.ts +8 -0
  316. package/src/workspace/__fixtures__/two-member-workspace.ts +2 -2
  317. package/src/workspace/checks/ci-workflow.test.ts +9 -0
  318. package/src/workspace/checks/ci-workflow.ts +18 -4
  319. package/src/workspace/ci-branches.test.ts +62 -0
  320. package/src/workspace/ci-branches.ts +79 -0
  321. package/src/workspace/ci-cloud-identity.test.ts +53 -0
  322. package/src/workspace/ci-cloud-identity.ts +23 -0
  323. package/src/workspace/ci-init.ts +5 -4
  324. package/src/workspace/ci-locks.ts +16 -0
  325. package/src/workspace/ci-run-index.test.ts +2 -1
  326. package/src/workspace/ci-run.test.ts +107 -8
  327. package/src/workspace/ci-run.ts +74 -5
  328. package/src/workspace/ci-workflow-at.ts +23 -0
  329. package/src/workspace/ci-workflow.ts +13 -2
  330. package/src/workspace/declaration.schema.json +149 -2
  331. package/src/workspace/declaration.test.ts +76 -0
  332. package/src/workspace/declaration.ts +140 -5
  333. package/src/workspace/identity-gate-rule.ts +1 -1
  334. package/src/workspace/identity.ts +1 -1
  335. package/src/workspace/lineage-upgrade.ts +11 -8
  336. package/src/workspace/member-pipeline.test.ts +29 -0
  337. package/src/workspace/member-pipeline.ts +30 -0
  338. package/src/workspace/pr-report.schema.json +94 -3
  339. package/src/workspace/reason-codes.ts +1 -1
  340. package/src/workspace/security.ts +4 -0
  341. package/src/workspace/status-gates.ts +9 -6
  342. package/src/workspace/status.ts +4 -1
  343. package/src/workspace/trust/gate-seal.test.ts +1 -1
  344. package/src/workspace/trust/seal.ts +2 -2
  345. package/dist/workspace/trust/gate-seal.d.ts.map +0 -1
  346. /package/dist/{workspace/trust → lifecycle}/gate-seal.js +0 -0
@@ -8,8 +8,11 @@
8
8
  * values they read from the forge live here so the three cannot disagree.
9
9
  *
10
10
  * - The plan job runs `chant components pr-plan` against the pull request's
11
- * target commit. It posts the note and the `chant/plan` status and writes
12
- * nothing to `chant/lifecycle`, since it runs the pull request's code.
11
+ * target commit. It writes nothing to `chant/lifecycle` and holds no forge
12
+ * token, since it runs the pull request's code (#4295): it writes the note
13
+ * and the status into its report with `--no-status`, and the `plan-note`
14
+ * job after it posts them with `chant components pr-post`
15
+ * ({@link prLoopPostJob}, ../ci-handover.ts).
13
16
  * - The record job (#4168 step 1, the default) runs `chant components
14
17
  * pr-record` against the commit the push replaced. It plans the same
15
18
  * members on the merged commit, stores the change set and writes the merge
@@ -80,6 +83,7 @@
80
83
  import type { ForgeKind } from "../pr-forge.js";
81
84
  import type { DriverComponent } from "./driver.js";
82
85
  import type { GatedWavePipelineOptions } from "./gated-wave-pipeline.js";
86
+ import type { PipelineCloudIdentity } from "../ci-identity.js";
83
87
  /** Where both jobs write their reports, kept as a CI artifact. */
84
88
  export declare const PR_LOOP_REPORT_DIR = ".chant/pr";
85
89
  /**
@@ -124,6 +128,16 @@ export interface PrLoopPipelineOptions {
124
128
  * false, so a merge deploys nothing. `waveGate` needs it.
125
129
  */
126
130
  applyOnMerge?: boolean;
131
+ /**
132
+ * Apply an open pull request before it merges (#4301, ws-106): the apply
133
+ * job runs `pr-apply --before-merge` at the pull request's head, started
134
+ * by a `/chant apply` comment on GitHub and Forgejo, or on GitLab by a
135
+ * pipeline of the target branch with `CHANT_APPLY_PR` set. A merge still
136
+ * records. `pr-apply` refuses unless the declaration at base sets
137
+ * `ci.workflow: "apply-before-merge"`. It takes neither `applyOnMerge`,
138
+ * `waveGate` nor `build`.
139
+ */
140
+ applyBeforeMerge?: boolean;
127
141
  /**
128
142
  * Stream each job's run events (#4007): `--events-json` on both commands,
129
143
  * and `CHANT_RUN_EVENTS_DIR` set to {@link PR_LOOP_EVENTS_DIR}. Default false.
@@ -156,11 +170,27 @@ export interface PrLoopPipelineOptions {
156
170
  * wave. Set from `--wave-gate` beside `--pr-loop` ({@link prLoopWithWaves}).
157
171
  */
158
172
  waveGate?: string;
173
+ /**
174
+ * The plan and apply cloud identities (#4296), from `ci.identity.cloud`
175
+ * resolved for the pipeline's environment and member
176
+ * (`resolveCloudIdentity` in ../ci-identity.ts). The plan job trades its
177
+ * OIDC token for the plan identity before the checkout, the record job
178
+ * for the plan identity, and the apply jobs for the apply identity.
179
+ * Absent: no job requests an OIDC token.
180
+ */
181
+ identity?: PipelineCloudIdentity;
159
182
  /**
160
183
  * Which GitHub-shaped forge the workflow is for. Set by the forgejo
161
184
  * generator, which reuses the github one; a caller never needs to.
162
185
  */
163
186
  forge?: "github" | "forgejo";
187
+ /**
188
+ * An environment per open pull request (#4298, `ci.prEnvironment`): an
189
+ * `env-up` job on each opened, updated or reopened pull request, an
190
+ * `env-down` job when it closes, and an `env-sweep` job on a schedule
191
+ * ({@link prEnvJobs}). Set from `--pr-env` beside `--pr-loop`. Default false.
192
+ */
193
+ prEnvironment?: boolean;
164
194
  }
165
195
  /** One job's command and the forge values it reads, as environment variables for its step. */
166
196
  export interface PrLoopJob {
@@ -215,6 +245,22 @@ export declare function prLoopBuildLines(env: string, options?: PrLoopPipelineOp
215
245
  * the commands then run in its directory, so `--output` is relative to it.
216
246
  */
217
247
  export declare function prLoopJobs(forge: ForgeKind, env: string, options?: PrLoopPipelineOptions, member?: string): PrLoopJob[];
248
+ /** The name of the job that posts the plan's note and status (#4295). */
249
+ export declare const PR_PLAN_NOTE_JOB = "plan-note";
250
+ /**
251
+ * The plan-note job's command and the values it reads (#4295). It runs in a
252
+ * fresh job after the plan, at the target branch's commit, and posts the
253
+ * note and the `chant/plan` status from the report the plan job handed on,
254
+ * with the forge token the plan job never held. `HEAD_SHA` is the commit
255
+ * the plan job checked out, `PR_NUMBER` the pull request, and on GitHub and
256
+ * Forgejo `PLAN_RESULT` the plan job's result, which fails the status when
257
+ * the plan job failed. `BASE_SHA` is the commit the note job checks out on
258
+ * GitLab, whose runner checks out the pipeline's own commit.
259
+ */
260
+ export declare function prLoopPostJob(forge: ForgeKind, env: string, member?: string): {
261
+ command: string;
262
+ env: Record<string, string>;
263
+ };
218
264
  /**
219
265
  * What starts the apply under apply on merge (#4168 step 9): on GitHub the
220
266
  * tick's workflow finishing (`workflow_run`, since tags its token pushes start
@@ -264,6 +310,16 @@ export declare function prRecordGroup(env: string, member?: string): string;
264
310
  * refuses a record made for another pull request, gate or digest.
265
311
  */
266
312
  export declare function prApplyRecordKey(env: string, commit: string, member?: string): string;
313
+ /** The GitLab variable a person sets on a pipeline of the target branch to apply a merge request before it merges (#4301). */
314
+ export declare const GITLAB_APPLY_PR_VAR = "CHANT_APPLY_PR";
315
+ /** The comment that starts the apply before merge on GitHub and Forgejo (#4301). */
316
+ export declare const APPLY_COMMENT = "/chant apply";
317
+ /**
318
+ * The line that checks out pull request `$PR_NUMBER`'s head (#4301) in a job
319
+ * of the target branch: the forge's `refs/pull/<n>/head`, or GitLab's
320
+ * `refs/merge-requests/<n>/head`. A number that is not one fails the job.
321
+ */
322
+ export declare function pullRequestCheckout(forge: ForgeKind): string;
267
323
  /**
268
324
  * The line that checks out the newest green commit of `branch` (#4168 step
269
325
  * 9), after fetching the branch and its tags, for the apply job. `chant ci
@@ -290,4 +346,38 @@ export declare function gitlabBaseFallback(branch?: string): string;
290
346
  * generators' default.
291
347
  */
292
348
  export declare function githubBaseFallback(branch?: string): string;
349
+ /** Where the pull request environment jobs (#4298) write their reports, kept as a CI artifact. */
350
+ export declare const PR_ENV_REPORT_DIR = ".chant/pr-env";
351
+ /** The cron the generated `env-sweep` job runs on (#4298): hourly, at a minute off the hour. */
352
+ export declare const PR_ENV_SWEEP_CRON = "17 * * * *";
353
+ /** One job of a pull request's environment (#4298): its command and the forge values it reads. */
354
+ export interface PrEnvJob {
355
+ jobName: "env-up" | "env-post" | "env-down" | "env-sweep";
356
+ /** The command line. `env-up` reads `$BASE_SHA` and `$PR_NUMBER`, `env-down` `$PR_NUMBER`. */
357
+ command: string;
358
+ /** Values the command reads, as the forge spells them. `CHANT_ENV` is the pull request's environment. */
359
+ env: Record<string, string>;
360
+ /** With `build`: the build and lint lines, run before the command. */
361
+ build?: string[];
362
+ }
363
+ /** The name of the job that keeps an environment's record and posts its note (#4298, #4295). */
364
+ export declare const PR_ENV_POST_JOB = "env-post";
365
+ /**
366
+ * The jobs of a pull request's environment (#4298), when `prEnvironment` is
367
+ * on, in this order:
368
+ *
369
+ * - `env-up` runs `chant components pr-env up --no-push`. It runs the
370
+ * change's code, so it gets no forge token (#4295): it passes no
371
+ * `--forge`, and it hands its report and its record on.
372
+ * - `env-post` runs `pr-env post` in a fresh job at the target branch's
373
+ * commit, with the token: it keeps the record on chant/lifecycle and posts
374
+ * the note and the `chant/pr-env` status. On GitHub and Forgejo it reads
375
+ * the up job's result as `UP_RESULT`.
376
+ * - `env-down` runs `pr-env down --reason closed`, and `env-sweep` runs
377
+ * `pr-env sweep`. Neither builds the change's code: a teardown reads the
378
+ * markers off the live resources.
379
+ *
380
+ * Each writes its report under {@link PR_ENV_REPORT_DIR}.
381
+ */
382
+ export declare function prEnvJobs(forge: ForgeKind, options?: PrLoopPipelineOptions, member?: string): PrEnvJob[];
293
383
  //# sourceMappingURL=pr-pipeline.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pr-pipeline.d.ts","sourceRoot":"","sources":["../../src/components/pr-pipeline.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pr-pipeline.d.ts","sourceRoot":"","sources":["../../src/components/pr-pipeline.ts"],"names":[],"mappings":"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"}
@@ -8,8 +8,11 @@
8
8
  * values they read from the forge live here so the three cannot disagree.
9
9
  *
10
10
  * - The plan job runs `chant components pr-plan` against the pull request's
11
- * target commit. It posts the note and the `chant/plan` status and writes
12
- * nothing to `chant/lifecycle`, since it runs the pull request's code.
11
+ * target commit. It writes nothing to `chant/lifecycle` and holds no forge
12
+ * token, since it runs the pull request's code (#4295): it writes the note
13
+ * and the status into its report with `--no-status`, and the `plan-note`
14
+ * job after it posts them with `chant components pr-post`
15
+ * ({@link prLoopPostJob}, ../ci-handover.ts).
13
16
  * - The record job (#4168 step 1, the default) runs `chant components
14
17
  * pr-record` against the commit the push replaced. It plans the same
15
18
  * members on the merged commit, stores the change set and writes the merge
@@ -79,6 +82,7 @@
79
82
  */
80
83
  import { PR_APPLY_GATE } from "../pr-loop.js";
81
84
  import { CI_IMAGE, GITHUB_JOB_TOKEN } from "../ci-jobs.js";
85
+ import { withoutForgeTokens } from "../ci-handover.js";
82
86
  import { EMPTY_TREE_SHA } from "./changed-files.js";
83
87
  import { layerWaves } from "../gated-waves.js";
84
88
  /** The variable `chant ci run` reads its runner key from (`RUNNER_KEY_ENV` in ../workspace/ci-green.ts). */
@@ -126,6 +130,13 @@ export function prLoopBuildLines(env, options = {}) {
126
130
  */
127
131
  export function prLoopJobs(forge, env, options = {}, member) {
128
132
  const gate = options.gate ?? PR_APPLY_GATE;
133
+ const early = options.applyBeforeMerge === true;
134
+ if (early && options.applyOnMerge)
135
+ throw new Error("--apply-before-merge applies an open pull request and a merge records, so it takes no --apply-on-merge; pass one of them");
136
+ if (early && options.waveGate)
137
+ throw new Error("--apply-before-merge applies the pull request's plan in one job, so it takes no --wave-gate");
138
+ if (early && (options.build || options.buildCommand))
139
+ throw new Error("--apply-before-merge runs no build before its requires checks, so it takes no --pr-build or --pr-build-command yet");
129
140
  const common = [
130
141
  "--env", env, "--gate", gate, "--output", PR_LOOP_REPORT_DIR, "--forge", forge,
131
142
  ...(member ? ["--member", member] : []),
@@ -142,7 +153,8 @@ export function prLoopJobs(forge, env, options = {}, member) {
142
153
  // #4156: the flags `chant ci run` rebuilds `command` from. It finds the member from the directory it runs in.
143
154
  const ciRun = (job) => [
144
155
  "chant", "ci", "run", job, "--in-place", ...(job === "plan" ? ["--no-push"] : []),
145
- ...(job === "apply" ? [] : ["--base", '"$BASE_SHA"']), ...(job === "plan" ? ["--pr", '"$PR_NUMBER"'] : []),
156
+ ...(job === "apply" && !early ? [] : ["--base", '"$BASE_SHA"']), ...(job === "plan" || (job === "apply" && early) ? ["--pr", '"$PR_NUMBER"'] : []),
157
+ ...(job === "apply" && early ? ["--apply-before-merge"] : []),
146
158
  "--env", env, "--gate", gate, "--forge", forge,
147
159
  ...(job !== "record" && options.waveGate ? ["--wave-gate", options.waveGate] : []),
148
160
  ...(job !== "plan" && options.branch ? ["--branch", JSON.stringify(options.branch)] : []),
@@ -152,35 +164,54 @@ export function prLoopJobs(forge, env, options = {}, member) {
152
164
  ...(options.reportUrl ? ["--report-url", JSON.stringify(options.reportUrl)] : []),
153
165
  ];
154
166
  const runEnv = (env) => (github ? { ...env, [RUNNER_KEY_ENV]: `\${{ secrets.${RUNNER_KEY_ENV} }}` } : env);
167
+ // #4295: the plan runs the pull request's code, so it gets no forge token. It writes the note and the
168
+ // status into its report (--no-status), and the plan-note job posts them (prLoopPostJob).
155
169
  const planEnv = github
156
- ? { BASE_SHA: "${{ github.event.pull_request.base.sha }}", PR_NUMBER: "${{ github.event.pull_request.number }}", ...jobEnv }
157
- : { BASE_SHA: "$CI_MERGE_REQUEST_DIFF_BASE_SHA", PR_NUMBER: "$CI_MERGE_REQUEST_IID", ...jobEnv };
170
+ ? { BASE_SHA: "${{ github.event.pull_request.base.sha }}", PR_NUMBER: "${{ github.event.pull_request.number }}", ...withoutForgeTokens(jobEnv) }
171
+ : { BASE_SHA: "$CI_MERGE_REQUEST_DIFF_BASE_SHA", PR_NUMBER: "$CI_MERGE_REQUEST_IID", ...withoutForgeTokens(jobEnv) };
158
172
  const greenBranch = github ? JSON.stringify(options.branch ?? "main") : options.branch ? JSON.stringify(options.branch) : "$CI_DEFAULT_BRANCH";
159
173
  const applyEnv = github ? { BASE_SHA: "${{ github.event.before }}", ...jobEnv } : { BASE_SHA: "$CI_COMMIT_BEFORE_SHA", ...jobEnv };
174
+ // #4301: the apply before merge runs in a job of the target branch, whose commit is the base, at the pull request's head.
175
+ const earlyEnv = github
176
+ ? { BASE_SHA: "${{ github.sha }}", PR_NUMBER: "${{ github.event.issue.number }}", ...jobEnv }
177
+ : { BASE_SHA: "$CI_COMMIT_SHA", PR_NUMBER: `$${GITLAB_APPLY_PR_VAR}`, ...jobEnv };
178
+ const greenApply = {
179
+ // #4168 step 9: the apply applies the newest green commit, measured from the one applied before it.
180
+ jobName: "apply",
181
+ command: [
182
+ "chant", "components", "pr-apply", "--green", ...common,
183
+ ...(options.requireReview === true ? ["--require-review"] : []),
184
+ ...(options.waveGate ? ["--wave-gate", options.waveGate] : []),
185
+ "--resume", PR_APPLY_RECORD,
186
+ ].join(" "),
187
+ env: jobEnv,
188
+ checkout: [greenCheckout(greenBranch)],
189
+ greenBranch,
190
+ ...build,
191
+ run: { command: ciRun("apply").join(" "), env: runEnv(jobEnv) },
192
+ };
193
+ const earlyApply = {
194
+ // #4301: the requires checks run inside pr-apply, before any of the head's code loads.
195
+ jobName: "apply",
196
+ command: [
197
+ "chant", "components", "pr-apply", "--before-merge", "--base", '"$BASE_SHA"', "--pr", '"$PR_NUMBER"', ...common,
198
+ ...(options.requireReview === true ? ["--require-review"] : []),
199
+ "--resume", PR_APPLY_RECORD,
200
+ ].join(" "),
201
+ env: earlyEnv,
202
+ checkout: [pullRequestCheckout(forge)],
203
+ run: { command: ciRun("apply").join(" "), env: runEnv(earlyEnv) },
204
+ };
160
205
  return [
161
206
  {
162
207
  jobName: "plan",
163
208
  // With `waveGate` the plan's note says the later waves may stop at their own gates (#4003).
164
- command: ["chant", "components", "pr-plan", "--base", '"$BASE_SHA"', "--pr", '"$PR_NUMBER"', ...common, ...(options.waveGate ? ["--wave-gate", options.waveGate] : [])].join(" "),
209
+ command: ["chant", "components", "pr-plan", "--base", '"$BASE_SHA"', "--pr", '"$PR_NUMBER"', ...common, ...(options.waveGate ? ["--wave-gate", options.waveGate] : []), "--no-status"].join(" "),
165
210
  env: planEnv,
166
211
  ...build,
167
212
  run: { command: ciRun("plan").join(" "), env: runEnv(planEnv) },
168
213
  },
169
- {
170
- // #4168 step 9: the apply applies the newest green commit, measured from the one applied before it.
171
- jobName: "apply",
172
- command: [
173
- "chant", "components", "pr-apply", "--green", ...common,
174
- ...(options.requireReview === true ? ["--require-review"] : []),
175
- ...(options.waveGate ? ["--wave-gate", options.waveGate] : []),
176
- "--resume", PR_APPLY_RECORD,
177
- ].join(" "),
178
- env: jobEnv,
179
- checkout: [greenCheckout(greenBranch)],
180
- greenBranch,
181
- ...build,
182
- run: { command: ciRun("apply").join(" "), env: runEnv(jobEnv) },
183
- },
214
+ early ? earlyApply : greenApply,
184
215
  {
185
216
  jobName: "record",
186
217
  command: ["chant", "components", "pr-record", "--base", '"$BASE_SHA"', ...common].join(" "),
@@ -191,6 +222,33 @@ export function prLoopJobs(forge, env, options = {}, member) {
191
222
  },
192
223
  ];
193
224
  }
225
+ /** The name of the job that posts the plan's note and status (#4295). */
226
+ export const PR_PLAN_NOTE_JOB = "plan-note";
227
+ /**
228
+ * The plan-note job's command and the values it reads (#4295). It runs in a
229
+ * fresh job after the plan, at the target branch's commit, and posts the
230
+ * note and the `chant/plan` status from the report the plan job handed on,
231
+ * with the forge token the plan job never held. `HEAD_SHA` is the commit
232
+ * the plan job checked out, `PR_NUMBER` the pull request, and on GitHub and
233
+ * Forgejo `PLAN_RESULT` the plan job's result, which fails the status when
234
+ * the plan job failed. `BASE_SHA` is the commit the note job checks out on
235
+ * GitLab, whose runner checks out the pipeline's own commit.
236
+ */
237
+ export function prLoopPostJob(forge, env, member) {
238
+ const github = forge !== "gitlab";
239
+ const command = [
240
+ "chant", "components", "pr-post", "--pr", '"$PR_NUMBER"', "--head", '"$HEAD_SHA"',
241
+ "--env", env, "--output", PR_LOOP_REPORT_DIR, "--forge", forge,
242
+ ...(member ? ["--member", member] : []),
243
+ ...(github ? ["--result", '"$PLAN_RESULT"'] : []),
244
+ ].join(" ");
245
+ return {
246
+ command,
247
+ env: github
248
+ ? { PR_NUMBER: "${{ github.event.pull_request.number }}", HEAD_SHA: "${{ github.sha }}", PLAN_RESULT: "${{ needs.plan.result }}", GITHUB_TOKEN: GITHUB_JOB_TOKEN }
249
+ : { PR_NUMBER: "$CI_MERGE_REQUEST_IID", HEAD_SHA: "$CI_COMMIT_SHA", BASE_SHA: "$CI_MERGE_REQUEST_DIFF_BASE_SHA" },
250
+ };
251
+ }
194
252
  /**
195
253
  * What starts the apply under apply on merge (#4168 step 9): on GitHub the
196
254
  * tick's workflow finishing (`workflow_run`, since tags its token pushes start
@@ -286,6 +344,19 @@ function pushBaseFallback(target, commit, diffBase) {
286
344
  (diffBase ? `BASE_SHA="\${${diffBase}:-}"; if [ -z "$BASE_SHA" ]; then ${fromBranch}fi; ` : fromBranch) +
287
345
  "fi; export BASE_SHA");
288
346
  }
347
+ /** The GitLab variable a person sets on a pipeline of the target branch to apply a merge request before it merges (#4301). */
348
+ export const GITLAB_APPLY_PR_VAR = "CHANT_APPLY_PR";
349
+ /** The comment that starts the apply before merge on GitHub and Forgejo (#4301). */
350
+ export const APPLY_COMMENT = "/chant apply";
351
+ /**
352
+ * The line that checks out pull request `$PR_NUMBER`'s head (#4301) in a job
353
+ * of the target branch: the forge's `refs/pull/<n>/head`, or GitLab's
354
+ * `refs/merge-requests/<n>/head`. A number that is not one fails the job.
355
+ */
356
+ export function pullRequestCheckout(forge) {
357
+ const ref = forge === "gitlab" ? 'refs/merge-requests/$PR_NUMBER/head' : 'refs/pull/$PR_NUMBER/head';
358
+ return `echo "$PR_NUMBER" | grep -Eq '^[0-9]+$' && git fetch --quiet origin "+${ref}:refs/remotes/origin/chant-apply/$PR_NUMBER" && git checkout --quiet --detach "refs/remotes/origin/chant-apply/$PR_NUMBER"`;
359
+ }
289
360
  /**
290
361
  * The line that checks out the newest green commit of `branch` (#4168 step
291
362
  * 9), after fetching the branch and its tags, for the apply job. `chant ci
@@ -324,3 +395,61 @@ export function gitlabBaseFallback(branch) {
324
395
  export function githubBaseFallback(branch) {
325
396
  return pushBaseFallback(JSON.stringify(branch ?? "main"), "$GITHUB_SHA");
326
397
  }
398
+ /** Where the pull request environment jobs (#4298) write their reports, kept as a CI artifact. */
399
+ export const PR_ENV_REPORT_DIR = ".chant/pr-env";
400
+ /** The cron the generated `env-sweep` job runs on (#4298): hourly, at a minute off the hour. */
401
+ export const PR_ENV_SWEEP_CRON = "17 * * * *";
402
+ /** The name of the job that keeps an environment's record and posts its note (#4298, #4295). */
403
+ export const PR_ENV_POST_JOB = "env-post";
404
+ /**
405
+ * The jobs of a pull request's environment (#4298), when `prEnvironment` is
406
+ * on, in this order:
407
+ *
408
+ * - `env-up` runs `chant components pr-env up --no-push`. It runs the
409
+ * change's code, so it gets no forge token (#4295): it passes no
410
+ * `--forge`, and it hands its report and its record on.
411
+ * - `env-post` runs `pr-env post` in a fresh job at the target branch's
412
+ * commit, with the token: it keeps the record on chant/lifecycle and posts
413
+ * the note and the `chant/pr-env` status. On GitHub and Forgejo it reads
414
+ * the up job's result as `UP_RESULT`.
415
+ * - `env-down` runs `pr-env down --reason closed`, and `env-sweep` runs
416
+ * `pr-env sweep`. Neither builds the change's code: a teardown reads the
417
+ * markers off the live resources.
418
+ *
419
+ * Each writes its report under {@link PR_ENV_REPORT_DIR}.
420
+ */
421
+ export function prEnvJobs(forge, options = {}, member) {
422
+ const github = forge !== "gitlab";
423
+ const out = ["--output", PR_ENV_REPORT_DIR, ...(member ? ["--member", member] : [])];
424
+ const common = ["--forge", forge, ...out];
425
+ const token = github ? { GITHUB_TOKEN: GITHUB_JOB_TOKEN } : {};
426
+ const prNumber = github ? "${{ github.event.pull_request.number }}" : "$CI_MERGE_REQUEST_IID";
427
+ const prEnv = { CHANT_ENV: `pr-${prNumber}` };
428
+ const buildLines = prLoopBuildLines('"$CHANT_ENV"', options);
429
+ return [
430
+ {
431
+ jobName: "env-up",
432
+ // #4295: no --forge and no token; the record stays in the report directory for env-post.
433
+ command: ["chant", "components", "pr-env", "up", "--base", '"$BASE_SHA"', "--pr", '"$PR_NUMBER"', ...out, "--no-push"].join(" "),
434
+ env: { BASE_SHA: github ? "${{ github.event.pull_request.base.sha }}" : "$CI_MERGE_REQUEST_DIFF_BASE_SHA", PR_NUMBER: prNumber, ...prEnv },
435
+ ...(buildLines.length > 0 ? { build: buildLines } : {}),
436
+ },
437
+ {
438
+ jobName: PR_ENV_POST_JOB,
439
+ command: ["chant", "components", "pr-env", "post", "--pr", '"$PR_NUMBER"', "--head", '"$HEAD_SHA"', ...common, ...(github ? ["--result", '"$UP_RESULT"'] : [])].join(" "),
440
+ env: github
441
+ ? { PR_NUMBER: prNumber, HEAD_SHA: "${{ github.sha }}", UP_RESULT: "${{ needs.env-up.result }}", ...token }
442
+ : { PR_NUMBER: prNumber, HEAD_SHA: "$CI_COMMIT_SHA", BASE_SHA: "$CI_MERGE_REQUEST_DIFF_BASE_SHA" },
443
+ },
444
+ {
445
+ jobName: "env-down",
446
+ command: ["chant", "components", "pr-env", "down", "--pr", '"$PR_NUMBER"', "--reason", "closed", ...common].join(" "),
447
+ env: { PR_NUMBER: prNumber, ...prEnv, ...token },
448
+ },
449
+ {
450
+ jobName: "env-sweep",
451
+ command: ["chant", "components", "pr-env", "sweep", ...common].join(" "),
452
+ env: { ...token },
453
+ },
454
+ ];
455
+ }
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Gate-time policy on the pull-request path (#4294): `ci.policy` in the
3
+ * workspace declaration, run by `chant components pr-plan` and `pr-apply`
4
+ * over the change-set document the gate binds (`CapabilityPlan.changeSet`,
5
+ * composed by `planPrSet`).
6
+ *
7
+ * The settings and the policy directory are both read at the base the job
8
+ * measures the change from, so a pull request cannot loosen, edit or delete
9
+ * the policy that judges it. The engine and its result shapes are
10
+ * `../gate-policy.ts`.
11
+ *
12
+ * - deny: pr-apply applies nothing unless an override counts
13
+ * (`../override-gate.ts`, subject the gate's op, such as `pr-12`). The
14
+ * first refusal records the denial on `_gates/policy-override.jsonl`, so
15
+ * `chant approve policy-override <op> --rule <id> --reason <text>` can
16
+ * answer it. The gate's own approval is still needed. The override is
17
+ * spent just before anything applies.
18
+ * - hold: the plan needs a person's approval of its own digest. pr-apply
19
+ * always asks for one, so a hold changes one path: a green commit's plan
20
+ * no longer applies under the approvals of the merges it carries.
21
+ * - error: the policy did not run or gave no readable answer. pr-apply
22
+ * applies nothing.
23
+ */
24
+ import type { WorkspaceTree } from "../workspace/tree.js";
25
+ import { type GatePolicyExec, type GatePolicySettings, type GatePolicyVerdict } from "../gate-policy.js";
26
+ import type { ChangeSetDocument } from "../change-set.js";
27
+ import type { GateLedgerPort } from "../op/gate.js";
28
+ import type { PrPolicyReport } from "../pr-loop.js";
29
+ /** `ci.policy` as read at base. */
30
+ export interface PrLoopPolicy {
31
+ /** Absent when the declaration at base sets none. */
32
+ settings?: GatePolicySettings;
33
+ /** The commit it was read at. */
34
+ base: string;
35
+ /** The tree of the declaration's directory at base, where the policy directory is read. */
36
+ tree?: WorkspaceTree;
37
+ /** A line for the log when no policy runs because the base has no declaration, or could not be read. */
38
+ note?: string;
39
+ }
40
+ /**
41
+ * The policy a pull-request job in `cwd` runs, from the declaration at
42
+ * `base`. Throws when the declaration at base cannot be read and the
43
+ * working tree's names a policy: running none would let the change waive it.
44
+ */
45
+ export declare function prLoopPolicyAt(cwd: string, base: string): PrLoopPolicy;
46
+ /** What the engine reads as `input`. */
47
+ export interface PrPolicyInput {
48
+ version: 1;
49
+ stage: "plan" | "apply";
50
+ /** The gate's op, `pr-<n>`. */
51
+ op: string;
52
+ gate: string;
53
+ env: string;
54
+ pr: number | null;
55
+ base: string;
56
+ head: string;
57
+ /** The change-set document the gate binds. Its `entries` are every change the plan proposes. */
58
+ changeSet: ChangeSetDocument;
59
+ }
60
+ /** Run the policy over `input`. Undefined when the base sets no policy. */
61
+ export declare function runPrPolicy(read: PrLoopPolicy, input: PrPolicyInput, exec?: GatePolicyExec): GatePolicyVerdict | undefined;
62
+ /** The verdict as the report keeps it. */
63
+ export declare function prPolicyReport(verdict: GatePolicyVerdict, base: string): PrPolicyReport;
64
+ export interface PrPolicyOverrideInput {
65
+ port: GateLedgerPort;
66
+ /** The override's subject: the gate's op. */
67
+ subject: string;
68
+ /** The digest the gate binds: the change-set document's. */
69
+ digest: string;
70
+ rules: readonly string[];
71
+ /** The commit the overriders and signers are read at. */
72
+ base: string;
73
+ cwd: string;
74
+ /** Count only sealed overrides, as a sealed gate counts only sealed approvals. */
75
+ sealed: boolean;
76
+ /** Record the denial when no override counts and none stands. The plan stage records nothing. */
77
+ record: boolean;
78
+ description?: string;
79
+ now?: string;
80
+ }
81
+ /** Where an override of a denial stands. */
82
+ export type PrPolicyOverride = {
83
+ status: "overridden";
84
+ override: NonNullable<PrPolicyReport["override"]>;
85
+ } | {
86
+ status: "none";
87
+ refusals: string[];
88
+ command: string;
89
+ overriders: string[];
90
+ recorded: boolean;
91
+ moved?: {
92
+ by: string;
93
+ };
94
+ };
95
+ /**
96
+ * Decide a denied plan against the override ledger, as an Op waves job
97
+ * decides a denied run (`settleDenials` in `../op/op-waves-run.ts`).
98
+ */
99
+ export declare function decidePrPolicyOverride(input: PrPolicyOverrideInput): Promise<PrPolicyOverride>;
100
+ /**
101
+ * Spend the override the apply runs under: append its applied record before
102
+ * anything applies. Throws when it could not be written or did not reach the
103
+ * remote, and the caller applies nothing.
104
+ */
105
+ export declare function spendPrPolicyOverride(port: GateLedgerPort, subject: string, override: NonNullable<PrPolicyReport["override"]>, at?: {
106
+ now?: string;
107
+ commit?: string;
108
+ }): Promise<void>;
109
+ //# sourceMappingURL=pr-policy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pr-policy.d.ts","sourceRoot":"","sources":["../../src/components/pr-policy.ts"],"names":[],"mappings":"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"}