@intentius/chant 0.124.39 → 0.124.41

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 (337) 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/component-endpoint.d.ts +20 -0
  11. package/dist/cli/component-endpoint.d.ts.map +1 -0
  12. package/dist/cli/component-endpoint.js +36 -0
  13. package/dist/cli/handlers/approve.d.ts +2 -1
  14. package/dist/cli/handlers/approve.d.ts.map +1 -1
  15. package/dist/cli/handlers/approve.js +20 -6
  16. package/dist/cli/handlers/build.d.ts.map +1 -1
  17. package/dist/cli/handlers/build.js +15 -1
  18. package/dist/cli/handlers/fan-out.d.ts.map +1 -1
  19. package/dist/cli/handlers/fan-out.js +26 -4
  20. package/dist/cli/handlers/gate-resume.d.ts +3 -0
  21. package/dist/cli/handlers/gate-resume.d.ts.map +1 -1
  22. package/dist/cli/handlers/gate-resume.js +15 -2
  23. package/dist/cli/handlers/lock.d.ts +8 -0
  24. package/dist/cli/handlers/lock.d.ts.map +1 -0
  25. package/dist/cli/handlers/lock.js +197 -0
  26. package/dist/cli/handlers/pr-env.d.ts +34 -0
  27. package/dist/cli/handlers/pr-env.d.ts.map +1 -0
  28. package/dist/cli/handlers/pr-env.js +436 -0
  29. package/dist/cli/handlers/pr.d.ts +74 -0
  30. package/dist/cli/handlers/pr.d.ts.map +1 -1
  31. package/dist/cli/handlers/pr.js +514 -58
  32. package/dist/cli/handlers/promote.d.ts.map +1 -1
  33. package/dist/cli/handlers/promote.js +16 -2
  34. package/dist/cli/handlers/query.d.ts +6 -0
  35. package/dist/cli/handlers/query.d.ts.map +1 -0
  36. package/dist/cli/handlers/query.js +80 -0
  37. package/dist/cli/handlers/run.d.ts +4 -1
  38. package/dist/cli/handlers/run.d.ts.map +1 -1
  39. package/dist/cli/handlers/run.js +17 -6
  40. package/dist/cli/main.d.ts.map +1 -1
  41. package/dist/cli/main.js +41 -2
  42. package/dist/cli/parse-args.d.ts.map +1 -1
  43. package/dist/cli/parse-args.js +31 -2
  44. package/dist/cli/registry.d.ts +12 -2
  45. package/dist/cli/registry.d.ts.map +1 -1
  46. package/dist/components/auto-release.d.ts +35 -3
  47. package/dist/components/auto-release.d.ts.map +1 -1
  48. package/dist/components/auto-release.js +29 -2
  49. package/dist/components/cli-support.d.ts +2 -0
  50. package/dist/components/cli-support.d.ts.map +1 -1
  51. package/dist/components/cli-support.js +2 -0
  52. package/dist/components/deploy-units.d.ts.map +1 -1
  53. package/dist/components/deploy-units.js +5 -0
  54. package/dist/components/fan-out-run.d.ts +28 -0
  55. package/dist/components/fan-out-run.d.ts.map +1 -1
  56. package/dist/components/fan-out-run.js +27 -3
  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 +72 -2
  64. package/dist/components/pr-pipeline.d.ts.map +1 -1
  65. package/dist/components/pr-pipeline.js +96 -5
  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.map +1 -1
  70. package/dist/components/pr-run.js +5 -3
  71. package/dist/components/promote.d.ts.map +1 -1
  72. package/dist/components/promote.js +39 -16
  73. package/dist/gate-decision.d.ts +15 -2
  74. package/dist/gate-decision.d.ts.map +1 -1
  75. package/dist/gate-decision.js +17 -2
  76. package/dist/gate-policy.d.ts +140 -0
  77. package/dist/gate-policy.d.ts.map +1 -0
  78. package/dist/gate-policy.js +242 -0
  79. package/dist/lifecycle/__fixtures__/publish-fakes.d.ts.map +1 -1
  80. package/dist/lifecycle/__fixtures__/publish-fakes.js +6 -1
  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/publish-declaration.d.ts.map +1 -1
  86. package/dist/lifecycle/publish-declaration.js +4 -3
  87. package/dist/lifecycle/publish-npm.d.ts +2 -2
  88. package/dist/lifecycle/publish-npm.d.ts.map +1 -1
  89. package/dist/lifecycle/publish-npm.js +31 -8
  90. package/dist/lifecycle/query.d.ts +68 -0
  91. package/dist/lifecycle/query.d.ts.map +1 -0
  92. package/dist/lifecycle/query.js +246 -0
  93. package/dist/lifecycle/release-ledger.d.ts +31 -0
  94. package/dist/lifecycle/release-ledger.d.ts.map +1 -1
  95. package/dist/lifecycle/release-ledger.js +19 -1
  96. package/dist/lifecycle/run-ledger.d.ts +13 -0
  97. package/dist/lifecycle/run-ledger.d.ts.map +1 -1
  98. package/dist/lifecycle/run-ledger.js +16 -0
  99. package/dist/lifecycle/status.d.ts +5 -1
  100. package/dist/lifecycle/status.d.ts.map +1 -1
  101. package/dist/lifecycle/status.js +10 -5
  102. package/dist/lifecycle/target-lock.d.ts +97 -0
  103. package/dist/lifecycle/target-lock.d.ts.map +1 -0
  104. package/dist/lifecycle/target-lock.js +286 -0
  105. package/dist/live-endpoint.d.ts +18 -0
  106. package/dist/live-endpoint.d.ts.map +1 -1
  107. package/dist/live-endpoint.js +27 -0
  108. package/dist/op/activities/activity-contracts.d.ts +30 -0
  109. package/dist/op/activities/activity-contracts.d.ts.map +1 -1
  110. package/dist/op/activities/activity-contracts.js +26 -0
  111. package/dist/op/activities/index.d.ts +2 -0
  112. package/dist/op/activities/index.d.ts.map +1 -1
  113. package/dist/op/activities/index.js +4 -0
  114. package/dist/op/activities/review-agent.d.ts +137 -0
  115. package/dist/op/activities/review-agent.d.ts.map +1 -0
  116. package/dist/op/activities/review-agent.js +266 -0
  117. package/dist/op/builders.d.ts +9 -0
  118. package/dist/op/builders.d.ts.map +1 -1
  119. package/dist/op/builders.js +11 -0
  120. package/dist/op/cron.d.ts +8 -0
  121. package/dist/op/cron.d.ts.map +1 -1
  122. package/dist/op/cron.js +51 -0
  123. package/dist/op/gate-approval.d.ts +20 -13
  124. package/dist/op/gate-approval.d.ts.map +1 -1
  125. package/dist/op/gate-approval.js +13 -18
  126. package/dist/op/gate-quorum.d.ts +131 -0
  127. package/dist/op/gate-quorum.d.ts.map +1 -0
  128. package/dist/op/gate-quorum.js +183 -0
  129. package/dist/op/gate-resume.d.ts +4 -2
  130. package/dist/op/gate-resume.d.ts.map +1 -1
  131. package/dist/op/gate-resume.js +5 -4
  132. package/dist/op/gate-review.js +1 -1
  133. package/dist/op/gate.d.ts +32 -4
  134. package/dist/op/gate.d.ts.map +1 -1
  135. package/dist/op/gate.js +40 -24
  136. package/dist/op/index.d.ts +6 -4
  137. package/dist/op/index.d.ts.map +1 -1
  138. package/dist/op/index.js +4 -3
  139. package/dist/op/local-executor.d.ts.map +1 -1
  140. package/dist/op/local-executor.js +9 -3
  141. package/dist/op/op-waves-run.d.ts +62 -1
  142. package/dist/op/op-waves-run.d.ts.map +1 -1
  143. package/dist/op/op-waves-run.js +190 -11
  144. package/dist/op/op-waves.d.ts +55 -3
  145. package/dist/op/op-waves.d.ts.map +1 -1
  146. package/dist/op/op-waves.js +63 -8
  147. package/dist/op/schedule-overdue.d.ts +57 -0
  148. package/dist/op/schedule-overdue.d.ts.map +1 -0
  149. package/dist/op/schedule-overdue.js +138 -0
  150. package/dist/override-gate.d.ts +2 -2
  151. package/dist/override-gate.d.ts.map +1 -1
  152. package/dist/override-gate.js +1 -1
  153. package/dist/pr-forge.d.ts +36 -0
  154. package/dist/pr-forge.d.ts.map +1 -1
  155. package/dist/pr-forge.js +82 -0
  156. package/dist/pr-loop.d.ts +90 -1
  157. package/dist/pr-loop.d.ts.map +1 -1
  158. package/dist/pr-loop.js +77 -3
  159. package/dist/pr-post.d.ts +72 -0
  160. package/dist/pr-post.d.ts.map +1 -0
  161. package/dist/pr-post.js +134 -0
  162. package/dist/wave-blocked.d.ts +79 -0
  163. package/dist/wave-blocked.d.ts.map +1 -0
  164. package/dist/wave-blocked.js +245 -0
  165. package/dist/wave-engine.d.ts +6 -0
  166. package/dist/wave-engine.d.ts.map +1 -1
  167. package/dist/wave-engine.js +2 -0
  168. package/dist/wave-runtime.mjs +239 -239
  169. package/dist/workspace/__fixtures__/two-member-workspace.d.ts +1 -0
  170. package/dist/workspace/__fixtures__/two-member-workspace.d.ts.map +1 -1
  171. package/dist/workspace/__fixtures__/two-member-workspace.js +1 -1
  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-locks.d.ts +12 -0
  179. package/dist/workspace/ci-locks.d.ts.map +1 -0
  180. package/dist/workspace/ci-locks.js +6 -0
  181. package/dist/workspace/ci-run.d.ts +24 -1
  182. package/dist/workspace/ci-run.d.ts.map +1 -1
  183. package/dist/workspace/ci-run.js +85 -6
  184. package/dist/workspace/declaration.d.ts +63 -0
  185. package/dist/workspace/declaration.d.ts.map +1 -1
  186. package/dist/workspace/declaration.js +72 -1
  187. package/dist/workspace/declaration.schema.json +147 -0
  188. package/dist/workspace/identity-gate-rule.d.ts +1 -1
  189. package/dist/workspace/identity-gate-rule.d.ts.map +1 -1
  190. package/dist/workspace/identity-gate-rule.js +1 -1
  191. package/dist/workspace/identity.d.ts +1 -1
  192. package/dist/workspace/identity.d.ts.map +1 -1
  193. package/dist/workspace/lineage-upgrade.d.ts.map +1 -1
  194. package/dist/workspace/lineage-upgrade.js +8 -5
  195. package/dist/workspace/member-pipeline.d.ts +6 -0
  196. package/dist/workspace/member-pipeline.d.ts.map +1 -1
  197. package/dist/workspace/member-pipeline.js +23 -0
  198. package/dist/workspace/pr-report.schema.json +73 -2
  199. package/dist/workspace/security.d.ts.map +1 -1
  200. package/dist/workspace/security.js +4 -0
  201. package/dist/workspace/status-gates.d.ts +3 -2
  202. package/dist/workspace/status-gates.d.ts.map +1 -1
  203. package/dist/workspace/status-gates.js +8 -7
  204. package/dist/workspace/status.d.ts +3 -1
  205. package/dist/workspace/status.d.ts.map +1 -1
  206. package/dist/workspace/status.js +7 -3
  207. package/dist/workspace/status.schema.json +1 -0
  208. package/dist/workspace/trust/seal.d.ts +2 -2
  209. package/dist/workspace/trust/seal.d.ts.map +1 -1
  210. package/dist/workspace/trust/seal.js +2 -2
  211. package/package.json +1 -1
  212. package/src/__fixtures__/oidc-emulator.ts +118 -0
  213. package/src/ci-handover.test.ts +209 -0
  214. package/src/ci-handover.ts +237 -0
  215. package/src/ci-identity.test.ts +201 -0
  216. package/src/ci-identity.ts +310 -0
  217. package/src/cli/component-endpoint.ts +43 -0
  218. package/src/cli/handlers/approve.ts +18 -5
  219. package/src/cli/handlers/build.ts +15 -1
  220. package/src/cli/handlers/fan-out.test.ts +10 -0
  221. package/src/cli/handlers/fan-out.ts +29 -4
  222. package/src/cli/handlers/gate-resume.ts +16 -2
  223. package/src/cli/handlers/lock.test.ts +98 -0
  224. package/src/cli/handlers/lock.ts +202 -0
  225. package/src/cli/handlers/operator.test.ts +3 -1
  226. package/src/cli/handlers/pr-endpoint.test.ts +169 -0
  227. package/src/cli/handlers/pr-env.ts +462 -0
  228. package/src/cli/handlers/pr-waves-blocked.test.ts +247 -0
  229. package/src/cli/handlers/pr.test.ts +184 -0
  230. package/src/cli/handlers/pr.ts +508 -64
  231. package/src/cli/handlers/promote.ts +25 -2
  232. package/src/cli/handlers/query.ts +78 -0
  233. package/src/cli/handlers/run.test.ts +2 -1
  234. package/src/cli/handlers/run.ts +16 -5
  235. package/src/cli/main.ts +41 -2
  236. package/src/cli/parse-args.ts +23 -2
  237. package/src/cli/registry.ts +12 -2
  238. package/src/components/auto-release-infra.test.ts +131 -0
  239. package/src/components/auto-release.test.ts +40 -1
  240. package/src/components/auto-release.ts +50 -4
  241. package/src/components/cli-support.ts +4 -0
  242. package/src/components/deploy-units.ts +5 -0
  243. package/src/components/fan-out-run.ts +39 -2
  244. package/src/components/fan-out-waves.test.ts +45 -1
  245. package/src/components/pr-environment.test.ts +249 -0
  246. package/src/components/pr-environment.ts +538 -0
  247. package/src/components/pr-hooks.test.ts +118 -0
  248. package/src/components/pr-hooks.ts +157 -0
  249. package/src/components/pr-pipeline.ts +130 -5
  250. package/src/components/pr-policy.test.ts +145 -0
  251. package/src/components/pr-policy.ts +211 -0
  252. package/src/components/pr-run.ts +5 -2
  253. package/src/components/promote.test.ts +39 -0
  254. package/src/components/promote.ts +38 -14
  255. package/src/gate-decision-bundle.test.ts +4 -3
  256. package/src/gate-decision.ts +39 -2
  257. package/src/gate-policy-bundle.test.ts +28 -0
  258. package/src/gate-policy.test.ts +162 -0
  259. package/src/gate-policy.ts +298 -0
  260. package/src/lifecycle/__fixtures__/publish-fakes.ts +6 -1
  261. package/src/lifecycle/gate-checkpoint.ts +1 -1
  262. package/src/{workspace/trust → lifecycle}/gate-seal.ts +1 -1
  263. package/src/lifecycle/publish-declaration.ts +4 -3
  264. package/src/lifecycle/publish-npm.ts +33 -8
  265. package/src/lifecycle/publish-targets.test.ts +36 -3
  266. package/src/lifecycle/query.test.ts +91 -0
  267. package/src/lifecycle/query.ts +315 -0
  268. package/src/lifecycle/release-ledger.ts +42 -1
  269. package/src/lifecycle/run-ledger.ts +18 -0
  270. package/src/lifecycle/status.test.ts +19 -0
  271. package/src/lifecycle/status.ts +14 -6
  272. package/src/lifecycle/target-lock.test.ts +195 -0
  273. package/src/lifecycle/target-lock.ts +347 -0
  274. package/src/live-endpoint.ts +31 -0
  275. package/src/op/activities/activity-contracts.ts +31 -0
  276. package/src/op/activities/index.ts +6 -0
  277. package/src/op/activities/review-agent.test.ts +240 -0
  278. package/src/op/activities/review-agent.ts +355 -0
  279. package/src/op/builders.ts +13 -0
  280. package/src/op/cron.ts +44 -0
  281. package/src/op/gate-alias.test.ts +2 -2
  282. package/src/op/gate-approval.test.ts +30 -9
  283. package/src/op/gate-approval.ts +23 -26
  284. package/src/op/gate-quorum.test.ts +139 -0
  285. package/src/op/gate-quorum.ts +248 -0
  286. package/src/op/gate-resume.ts +6 -3
  287. package/src/op/gate-review.ts +1 -1
  288. package/src/op/gate.ts +64 -23
  289. package/src/op/index.ts +13 -1
  290. package/src/op/local-executor.ts +9 -2
  291. package/src/op/op-waves-hook-targets.test.ts +126 -0
  292. package/src/op/op-waves-policy-hold.test.ts +66 -0
  293. package/src/op/op-waves-quorum.test.ts +101 -0
  294. package/src/op/op-waves-run.ts +233 -11
  295. package/src/op/op-waves.ts +83 -10
  296. package/src/op/schedule-overdue.test.ts +220 -0
  297. package/src/op/schedule-overdue.ts +161 -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 +114 -0
  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 +146 -4
  306. package/src/pr-post.test.ts +141 -0
  307. package/src/pr-post.ts +159 -0
  308. package/src/wave-blocked-bundle.test.ts +25 -0
  309. package/src/wave-blocked.test.ts +146 -0
  310. package/src/wave-blocked.ts +271 -0
  311. package/src/wave-engine.ts +8 -0
  312. package/src/workspace/__fixtures__/two-member-workspace.ts +2 -2
  313. package/src/workspace/ci-branches.test.ts +62 -0
  314. package/src/workspace/ci-branches.ts +79 -0
  315. package/src/workspace/ci-cloud-identity.test.ts +53 -0
  316. package/src/workspace/ci-cloud-identity.ts +23 -0
  317. package/src/workspace/ci-locks.ts +16 -0
  318. package/src/workspace/ci-run-index.test.ts +2 -1
  319. package/src/workspace/ci-run.test.ts +133 -8
  320. package/src/workspace/ci-run.ts +92 -7
  321. package/src/workspace/declaration.schema.json +147 -0
  322. package/src/workspace/declaration.test.ts +76 -0
  323. package/src/workspace/declaration.ts +134 -2
  324. package/src/workspace/identity-gate-rule.ts +1 -1
  325. package/src/workspace/identity.ts +1 -1
  326. package/src/workspace/lineage-upgrade.ts +11 -8
  327. package/src/workspace/member-pipeline.test.ts +29 -0
  328. package/src/workspace/member-pipeline.ts +30 -0
  329. package/src/workspace/pr-report.schema.json +73 -2
  330. package/src/workspace/security.ts +4 -0
  331. package/src/workspace/status-gates.ts +9 -6
  332. package/src/workspace/status.schema.json +1 -0
  333. package/src/workspace/status.ts +11 -4
  334. package/src/workspace/trust/gate-seal.test.ts +1 -1
  335. package/src/workspace/trust/seal.ts +2 -2
  336. package/dist/workspace/trust/gate-seal.d.ts.map +0 -1
  337. /package/dist/{workspace/trust → lifecycle}/gate-seal.js +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"run-ledger.d.ts","sourceRoot":"","sources":["../../src/lifecycle/run-ledger.ts"],"names":[],"mappings":"AAsCA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAkB,KAAK,WAAW,EAAE,KAAK,gBAAgB,EAA+C,MAAM,eAAe,CAAC;AASrI,0EAA0E;AAC1E,eAAO,MAAM,eAAe,UAAU,CAAC;AAMvC,8FAA8F;AAC9F,wBAAgB,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,GAAG,MAAM,CAEjE;AAQD;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,CAAC,EACzC,OAAO,EAAE,SAAS,UAAU,EAAE,EAC9B,KAAK,EAAE;IACL,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAC;IAC9B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC3B,KAAK,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mEAAmE;IACnE,OAAO,CAAC,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;IACjC,6CAA6C;IAC7C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2DAA2D;IAC3D,SAAS,CAAC,EAAE,WAAW,CAAC,WAAW,CAAC,CAAC;IACrC,0EAA0E;IAC1E,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACzC,GACA,gBAAgB,CAkDlB;AAED;;;;;;;;;GASG;AACH,wBAAsB,eAAe,CACnC,KAAK,EAAE,gBAAgB,EACvB,IAAI,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GACtB,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,WAAW,CAAA;CAAE,CAAC,CAsBlD;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,WAAW,EAAE,MAAM,EACnB,EAAE,EAAE,MAAM,EACV,IAAI,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GACtB,OAAO,CAAC;IAAE,OAAO,EAAE,WAAW,EAAE,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,CAkCxD"}
1
+ {"version":3,"file":"run-ledger.d.ts","sourceRoot":"","sources":["../../src/lifecycle/run-ledger.ts"],"names":[],"mappings":"AAsCA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAkB,KAAK,WAAW,EAAE,KAAK,gBAAgB,EAA+C,MAAM,eAAe,CAAC;AASrI,0EAA0E;AAC1E,eAAO,MAAM,eAAe,UAAU,CAAC;AAMvC,8FAA8F;AAC9F,wBAAgB,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,GAAG,MAAM,CAEjE;AAQD;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,CAAC,EACzC,OAAO,EAAE,SAAS,UAAU,EAAE,EAC9B,KAAK,EAAE;IACL,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAC;IAC9B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC3B,KAAK,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mEAAmE;IACnE,OAAO,CAAC,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;IACjC,6CAA6C;IAC7C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2DAA2D;IAC3D,SAAS,CAAC,EAAE,WAAW,CAAC,WAAW,CAAC,CAAC;IACrC,0EAA0E;IAC1E,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACzC,GACA,gBAAgB,CAkDlB;AAED;;;;;;;;;GASG;AACH,wBAAsB,eAAe,CACnC,KAAK,EAAE,gBAAgB,EACvB,IAAI,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GACtB,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,WAAW,CAAA;CAAE,CAAC,CAsBlD;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,WAAW,EAAE,MAAM,EACnB,EAAE,EAAE,MAAM,EACV,IAAI,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GACtB,OAAO,CAAC;IAAE,OAAO,EAAE,WAAW,EAAE,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,CAIxD;AAED,4EAA4E;AAC5E,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED,2EAA2E;AAC3E,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAE7D;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,WAAW,EAAE,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CA+B7F"}
@@ -163,6 +163,22 @@ export async function readRunLedger(environment, op, opts) {
163
163
  const content = await readBlobFromPath(environment, fileFor(op), opts);
164
164
  if (!content)
165
165
  return { records: [], malformed: 0 };
166
+ return parseRunLedger(content);
167
+ }
168
+ /** The run ledger file name for `op` under `<env>/`, `runs__<op>.jsonl`. */
169
+ export function runLedgerFile(op) {
170
+ return fileFor(op);
171
+ }
172
+ /** The op a run ledger file name holds, or null when `file` is not one. */
173
+ export function opOfRunLedgerFile(file) {
174
+ return file.startsWith(PREFIX) && file.endsWith(".jsonl") && file.length > PREFIX.length + ".jsonl".length ? file.slice(PREFIX.length, -".jsonl".length) : null;
175
+ }
176
+ /**
177
+ * Parse the text of one run ledger file the way {@link readRunLedger} reads
178
+ * it (#4297): a reader that fetches the file itself, such as `chant query`,
179
+ * gets the same records and the same malformed count.
180
+ */
181
+ export function parseRunLedger(content) {
166
182
  const lines = content.split("\n").map((l) => l.trim()).filter(Boolean);
167
183
  const records = [];
168
184
  let malformed = 0;
@@ -361,7 +361,9 @@ export interface CrossEnvComparison {
361
361
  * environments legitimately render to different bytes, so cross-environment
362
362
  * "is prod running what staging tested" joins on the input side while
363
363
  * `digest` proves the exact bytes each cluster got. Records without it
364
- * compare on `digest` exactly as before.
364
+ * compare on `digest` exactly as before. An apply record (#4274) compares
365
+ * on its `gitSha`, since its plan or deploy-input digest takes in the
366
+ * environment and so differs between any two.
365
367
  */
366
368
  same: boolean;
367
369
  /** The identities `same` was decided on (`inputDigest ?? digest` per side), when both sides had one and they differ from the digests shown. */
@@ -377,6 +379,8 @@ export interface CrossEnvComparison {
377
379
  */
378
380
  mixedDigestForms?: true;
379
381
  }
382
+ /** What two environments' records of a component are compared on: the input side when there is one, the commit for an apply (#4274). */
383
+ export declare function comparableIdentity(record: ReleaseRecord): string;
380
384
  /** Compare the latest recorded digest for `component` between two environments' release records. */
381
385
  export declare function compareAcrossEnvironments(component: string, envA: {
382
386
  name: string;
@@ -1 +1 @@
1
- {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/lifecycle/status.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/lifecycle/status.ts"],"names":[],"mappings":"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"}
@@ -40,7 +40,7 @@
40
40
  * (`buildIsInBothEnvs`) is the query the epic actually asks for ("which
41
41
  * build is in prod, and is it the one tested in staging").
42
42
  */
43
- import { latestPerComponent } from "./release-ledger.js";
43
+ import { isApplyRecord, latestPerComponent } from "./release-ledger.js";
44
44
  import { isLegacyContentDigest } from "./legacy-digest.js";
45
45
  import { unobservedReasonText } from "../observation.js";
46
46
  /**
@@ -396,7 +396,8 @@ function notBefore(since, recordedAt) {
396
396
  */
397
397
  function contradictsRecord(recorded, evidence) {
398
398
  for (const id of evidence.identities ?? []) {
399
- if (id.digest !== undefined) {
399
+ // #4274: an apply's digest is a plan or deploy-input digest, which no live resource reports.
400
+ if (id.digest !== undefined && !isApplyRecord(recorded)) {
400
401
  const matches = sameDigest(id.digest, recorded.digest) ||
401
402
  (recorded.inputDigest !== undefined && sameDigest(id.digest, recorded.inputDigest));
402
403
  if (!matches)
@@ -425,13 +426,17 @@ function contradictsRecord(recorded, evidence) {
425
426
  return "live configuration has drifted since";
426
427
  return undefined;
427
428
  }
429
+ /** What two environments' records of a component are compared on: the input side when there is one, the commit for an apply (#4274). */
430
+ export function comparableIdentity(record) {
431
+ return isApplyRecord(record) ? `git:${record.gitSha}` : record.inputDigest ?? record.digest;
432
+ }
428
433
  /** Compare the latest recorded digest for `component` between two environments' release records. */
429
434
  export function compareAcrossEnvironments(component, envA, envB) {
430
435
  const latestA = latestPerComponent(envA.records).get(component);
431
436
  const latestB = latestPerComponent(envB.records).get(component);
432
- const idA = latestA ? latestA.inputDigest ?? latestA.digest : undefined;
433
- const idB = latestB ? latestB.inputDigest ?? latestB.digest : undefined;
434
- const comparedOnInputs = (latestA?.inputDigest ?? latestB?.inputDigest) !== undefined;
437
+ const idA = latestA ? comparableIdentity(latestA) : undefined;
438
+ const idB = latestB ? comparableIdentity(latestB) : undefined;
439
+ const comparedOnInputs = (latestA !== undefined && idA !== latestA.digest) || (latestB !== undefined && idB !== latestB.digest);
435
440
  return {
436
441
  component,
437
442
  envA: envA.name,
@@ -0,0 +1,97 @@
1
+ /** The directory on `chant/lifecycle` that holds the lock files. */
2
+ export declare const LOCKS_DIR = "_locks";
3
+ /**
4
+ * How a lock was taken. `plan`: the pull request's plan took it (`ci.locks:
5
+ * plan`). `apply`: its apply took it. `lock`: someone ran `chant lock`.
6
+ */
7
+ export type TargetLockStage = "plan" | "apply" | "lock";
8
+ export declare const TARGET_LOCK_STAGES: readonly ["plan", "apply", "lock"];
9
+ /** One target's lock: the pull request that holds it, who took it, when, how, and the head it took it at. */
10
+ export interface TargetLock {
11
+ pr: number;
12
+ by: string;
13
+ at: string;
14
+ stage: TargetLockStage;
15
+ /** The pull request's head commit when the lock was taken. Absent when the caller did not say. */
16
+ head?: string;
17
+ }
18
+ /** `_locks/<gate>.json`. */
19
+ export interface TargetLockFile {
20
+ version: 1;
21
+ locks: Record<string, TargetLock>;
22
+ }
23
+ /** A lock another open pull request holds on a target the caller needs. */
24
+ export interface HeldTargetLock extends TargetLock {
25
+ target: string;
26
+ }
27
+ /** Says whether pull request `pr` is still open. */
28
+ export type PullRequestOpen = (pr: number) => Promise<boolean>;
29
+ export interface TargetLockOptions {
30
+ cwd?: string;
31
+ /** Whether a holder is still open. Absent: every holder counts as open. */
32
+ isOpen?: PullRequestOpen;
33
+ }
34
+ export type TakeTargetLocksResult = {
35
+ ok: true;
36
+ /** The targets now locked, sorted. */
37
+ taken: string[];
38
+ /** Plan locks of the same pull request on targets it no longer reaches, released (`releaseStalePlan`). */
39
+ released: string[];
40
+ /** Locks of merged or closed pull requests that this write dropped. */
41
+ expired: string[];
42
+ /** Whether the remote has the write. False with no remote, or when recording is off. */
43
+ pushed: boolean;
44
+ } | {
45
+ ok: false;
46
+ held: HeldTargetLock[];
47
+ };
48
+ /** The path of `gate`'s lock file on `chant/lifecycle`, under a member's prefix when it has one. */
49
+ export declare function targetLockPath(gate: string, memberPrefix?: string): string;
50
+ /** A gate name that is safe as a file name. */
51
+ export declare function targetLockGateProblem(gate: string): string | null;
52
+ /** Parse a lock file. Anything that is not a version 1 file with a map of locks reads as no locks; a malformed entry is dropped. */
53
+ export declare function parseTargetLocks(text: string | null): TargetLockFile;
54
+ /** The file's text: targets sorted, so two writes of the same locks are the same blob. */
55
+ export declare function renderTargetLocks(file: TargetLockFile): string;
56
+ /** The locks of `gate` as the remote holds them now, fetched first. */
57
+ export declare function readTargetLocks(gate: string, opts?: {
58
+ cwd?: string;
59
+ }): Promise<TargetLockFile>;
60
+ /**
61
+ * The locks on `targets` that an open pull request other than `pr` holds.
62
+ * Reads only: an apply calls this to refuse a target another pull request
63
+ * holds. `pr` null (an apply of a green commit) counts every open holder.
64
+ */
65
+ export declare function heldTargetLocks(gate: string, targets: readonly string[], pr: number | null, opts?: TargetLockOptions): Promise<HeldTargetLock[]>;
66
+ /**
67
+ * Lock `targets` for pull request `holder.pr`. A target locked by another
68
+ * pull request that is still open is held, and nothing is locked. A target
69
+ * locked by one that merged or closed is taken over, and its lock dropped.
70
+ * Targets this pull request already holds stay its own, with the new head.
71
+ * An apply or a `chant lock` takes over the pull request's own plan locks;
72
+ * a plan keeps its own apply and `chant lock` locks as they are. With
73
+ * `releaseStalePlan`, the pull request's plan locks on targets it no longer
74
+ * reaches are released.
75
+ */
76
+ export declare function takeTargetLocks(gate: string, targets: readonly string[], holder: TargetLock, opts?: TargetLockOptions & {
77
+ releaseStalePlan?: boolean;
78
+ }): Promise<TakeTargetLocksResult>;
79
+ /**
80
+ * Release the locks pull request `pr` holds on `gate`: every one, or only
81
+ * those on `targets`. Returns the targets released, sorted.
82
+ */
83
+ export declare function releaseTargetLocks(gate: string, pr: number, opts?: {
84
+ cwd?: string;
85
+ targets?: readonly string[];
86
+ }): Promise<{
87
+ released: string[];
88
+ pushed: boolean;
89
+ }>;
90
+ /** The lock file's path for the project at `cwd`, for messages. */
91
+ export declare function targetLockPathAt(gate: string, cwd?: string): Promise<string>;
92
+ /**
93
+ * One line naming the targets others hold, for a refusal or a note.
94
+ * `name` says how the forge names a holder (GitLab: `merge request !7`).
95
+ */
96
+ export declare function describeHeldTargetLocks(held: readonly HeldTargetLock[], name?: (pr: number) => string): string;
97
+ //# sourceMappingURL=target-lock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"target-lock.d.ts","sourceRoot":"","sources":["../../src/lifecycle/target-lock.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,286 @@
1
+ /**
2
+ * Target locks (#4293): a pull request holds a lock on each target its
3
+ * change reaches, so no other pull request applies or locks those targets
4
+ * until it merges or closes, or someone runs `chant unlock` on it.
5
+ *
6
+ * A target is a name the caller picks: a component, a workspace member, or
7
+ * a lexicon's own unit such as a Terraform root. The locks of one gate live
8
+ * in one file, `_locks/<gate>.json` on `chant/lifecycle`, under the member's
9
+ * ledger prefix in a workspace member (./git.ts `ledgerDir`). The gate is
10
+ * the pull-request loop's, `pr-apply` unless the pipeline names another, so
11
+ * two pipelines with their own gates keep their own locks.
12
+ *
13
+ * Every change is a new commit on the branch, written with the read-then-CAS
14
+ * the other ledgers use and then pushed. A lock counts only once the remote
15
+ * has it: when the push is refused because another writer moved the branch,
16
+ * the local commit is dropped, the branch is read again and the decision is
17
+ * made again. So two jobs that lock the same target at once cannot both win.
18
+ * A repository with no remote is one machine, and the local write decides.
19
+ *
20
+ * A lock held by a pull request that is no longer open is released: the
21
+ * holder merged or closed. The caller says which pull requests are open
22
+ * (`isOpen`, from the forge). Without it every lock counts as held, and only
23
+ * `chant unlock` releases one.
24
+ *
25
+ * The file is coordination, not a record of work. ws-074 holds: the
26
+ * repository is the database, and the file is one more ledger on the
27
+ * branch, so any clone can read who holds what.
28
+ */
29
+ import { getRuntime } from "../runtime-adapter.js";
30
+ import { fetchLifecycleStatus, pushLifecycleStatus, readBlobBySha, readPathSha, RefCASConflictError, writeBlobToPath, } from "./git.js";
31
+ import { resolveMemberLedger } from "./member-ledger.js";
32
+ /** The directory on `chant/lifecycle` that holds the lock files. */
33
+ export const LOCKS_DIR = "_locks";
34
+ const STATE_BRANCH = "chant/lifecycle";
35
+ /** A scratch ref this module owns, for reading the remote tip after a refused push. */
36
+ const PROBE_REF = "refs/chant/target-lock-probe";
37
+ const ATTEMPTS = 5;
38
+ export const TARGET_LOCK_STAGES = ["plan", "apply", "lock"];
39
+ /** The path of `gate`'s lock file on `chant/lifecycle`, under a member's prefix when it has one. */
40
+ export function targetLockPath(gate, memberPrefix = "") {
41
+ return `${memberPrefix}${LOCKS_DIR}/${gate}.json`;
42
+ }
43
+ /** A gate name that is safe as a file name. */
44
+ export function targetLockGateProblem(gate) {
45
+ return /^[A-Za-z0-9][A-Za-z0-9_.-]{0,127}$/.test(gate) ? null : `the gate name ${JSON.stringify(gate)} is not a lock file name: letters, digits, '.', '_' and '-', starting with a letter or digit`;
46
+ }
47
+ const isStage = (v) => typeof v === "string" && TARGET_LOCK_STAGES.includes(v);
48
+ /** Parse a lock file. Anything that is not a version 1 file with a map of locks reads as no locks; a malformed entry is dropped. */
49
+ export function parseTargetLocks(text) {
50
+ if (!text)
51
+ return { version: 1, locks: {} };
52
+ try {
53
+ const doc = JSON.parse(text);
54
+ if (doc?.version === 1 && doc.locks && typeof doc.locks === "object" && !Array.isArray(doc.locks)) {
55
+ const locks = {};
56
+ for (const [target, raw] of Object.entries(doc.locks)) {
57
+ if (!raw || !Number.isInteger(raw.pr) || typeof raw.by !== "string" || typeof raw.at !== "string" || !isStage(raw.stage))
58
+ continue;
59
+ locks[target] = { pr: raw.pr, by: raw.by, at: raw.at, stage: raw.stage, ...(typeof raw.head === "string" ? { head: raw.head } : {}) };
60
+ }
61
+ return { version: 1, locks };
62
+ }
63
+ }
64
+ catch {
65
+ // An unreadable file holds no locks.
66
+ }
67
+ return { version: 1, locks: {} };
68
+ }
69
+ /** The file's text: targets sorted, so two writes of the same locks are the same blob. */
70
+ export function renderTargetLocks(file) {
71
+ const locks = Object.fromEntries(Object.keys(file.locks).sort().map((t) => [t, file.locks[t]]));
72
+ return `${JSON.stringify({ version: 1, locks }, null, 2)}\n`;
73
+ }
74
+ /** Fetch `chant/lifecycle`, refusing a ledger this checkout cannot read: a lock decided on a stale branch is no lock. */
75
+ async function fetchForLocks(cwd) {
76
+ const fetched = await fetchLifecycleStatus({ cwd });
77
+ if (fetched.status === "diverged")
78
+ throw new Error(`the local ${STATE_BRANCH} has forked from ${fetched.remote}'s, so the locks cannot be read: ${fetched.stderr}`);
79
+ if (fetched.status === "unreachable")
80
+ throw new Error(`cannot fetch ${STATE_BRANCH} from ${fetched.remote}, so the locks cannot be read${fetched.stderr ? `: ${fetched.stderr}` : ""}`);
81
+ }
82
+ async function readCurrent(gate, cwd) {
83
+ const sha = await readPathSha(LOCKS_DIR, `${gate}.json`, { cwd });
84
+ return { sha, file: parseTargetLocks(sha ? await readBlobBySha(sha, { cwd }) : null) };
85
+ }
86
+ /** The locks of `gate` as the remote holds them now, fetched first. */
87
+ export async function readTargetLocks(gate, opts = {}) {
88
+ const problem = targetLockGateProblem(gate);
89
+ if (problem)
90
+ throw new Error(problem);
91
+ await fetchForLocks(opts.cwd);
92
+ return (await readCurrent(gate, opts.cwd)).file;
93
+ }
94
+ /** A memo of `isOpen`, so one decision asks the forge about each pull request once. */
95
+ function openMemo(isOpen) {
96
+ const seen = new Map();
97
+ return (pr) => {
98
+ if (!isOpen)
99
+ return Promise.resolve(true);
100
+ if (!seen.has(pr))
101
+ seen.set(pr, isOpen(pr));
102
+ return seen.get(pr);
103
+ };
104
+ }
105
+ /** The locks on `targets` that an open pull request other than `pr` holds, by target. */
106
+ async function heldIn(file, targets, pr, open) {
107
+ const held = [];
108
+ for (const target of [...new Set(targets)].sort()) {
109
+ const l = file.locks[target];
110
+ if (l && l.pr !== pr && (await open(l.pr)))
111
+ held.push({ target, ...l });
112
+ }
113
+ return held;
114
+ }
115
+ /**
116
+ * The locks on `targets` that an open pull request other than `pr` holds.
117
+ * Reads only: an apply calls this to refuse a target another pull request
118
+ * holds. `pr` null (an apply of a green commit) counts every open holder.
119
+ */
120
+ export async function heldTargetLocks(gate, targets, pr, opts = {}) {
121
+ if (targets.length === 0)
122
+ return [];
123
+ const file = await readTargetLocks(gate, opts);
124
+ return heldIn(file, targets, pr, openMemo(opts.isOpen));
125
+ }
126
+ /** The local tip of `chant/lifecycle`, or "" when there is none. */
127
+ async function localTip(cwd) {
128
+ const out = await getRuntime().spawn(["git", "rev-parse", "--verify", "--quiet", `refs/heads/${STATE_BRANCH}`], { cwd });
129
+ return out.exitCode === 0 ? out.stdout.trim() : "";
130
+ }
131
+ /**
132
+ * After a refused push: drop the lock commit `ours` from the local branch by
133
+ * moving it to the remote's tip, so the next attempt reads what the other
134
+ * writer pushed. Done only when `parent`, the tip before the write, is in
135
+ * the remote's history, so no other local commit is lost. Throws otherwise.
136
+ */
137
+ async function dropRefusedWrite(remote, ours, parent, cwd) {
138
+ const rt = getRuntime();
139
+ const env = { LC_ALL: "C", LANGUAGE: "" };
140
+ const probe = await rt.spawn(["git", "fetch", "--force", remote, `${STATE_BRANCH}:${PROBE_REF}`], { cwd, env });
141
+ if (probe.exitCode !== 0)
142
+ throw new Error(`the push of the locks was refused and ${STATE_BRANCH} could not be read again from ${remote}: ${probe.stderr.trim()}`);
143
+ try {
144
+ if (parent) {
145
+ const contains = await rt.spawn(["git", "merge-base", "--is-ancestor", parent, PROBE_REF], { cwd, env });
146
+ if (contains.exitCode !== 0)
147
+ throw new Error(`the push of the locks was refused, and the local ${STATE_BRANCH} holds commits ${remote} does not; push or fetch ${STATE_BRANCH} and lock again`);
148
+ }
149
+ const tip = (await rt.spawn(["git", "rev-parse", "--verify", PROBE_REF], { cwd, env })).stdout.trim();
150
+ const moved = await rt.spawn(["git", "update-ref", `refs/heads/${STATE_BRANCH}`, tip, ours], { cwd, env });
151
+ if (moved.exitCode !== 0)
152
+ throw new Error(`could not drop the refused lock commit from ${STATE_BRANCH}: ${moved.stderr.trim()}`);
153
+ await rt.spawn(["git", "update-ref", `refs/remotes/${remote}/${STATE_BRANCH}`, tip], { cwd, env });
154
+ }
155
+ finally {
156
+ await rt.spawn(["git", "update-ref", "-d", PROBE_REF], { cwd, env });
157
+ }
158
+ }
159
+ /**
160
+ * Write `next` over the file read at `sha`, then push. Returns null when the
161
+ * branch moved under the write (locally or on the remote), so the caller
162
+ * reads and decides again.
163
+ */
164
+ async function writeAndPush(gate, sha, next, message, cwd) {
165
+ const parent = await localTip(cwd);
166
+ let commit;
167
+ try {
168
+ commit = await writeBlobToPath(LOCKS_DIR, `${gate}.json`, renderTargetLocks(next), message, { cwd, expectPriorPathSha: sha });
169
+ }
170
+ catch (err) {
171
+ if (err instanceof RefCASConflictError)
172
+ return null;
173
+ throw err;
174
+ }
175
+ const push = await pushLifecycleStatus({ cwd });
176
+ switch (push.status) {
177
+ case "pushed":
178
+ return { pushed: true };
179
+ case "no-remote":
180
+ case "not-recorded":
181
+ return { pushed: false };
182
+ case "stale":
183
+ await dropRefusedWrite(push.remote, commit, parent, cwd);
184
+ await fetchForLocks(cwd);
185
+ return null;
186
+ case "failed":
187
+ throw new Error(`the locks were written but the push of ${STATE_BRANCH} to ${push.remote} failed, so they do not count yet: ${push.stderr}`);
188
+ }
189
+ }
190
+ /**
191
+ * Lock `targets` for pull request `holder.pr`. A target locked by another
192
+ * pull request that is still open is held, and nothing is locked. A target
193
+ * locked by one that merged or closed is taken over, and its lock dropped.
194
+ * Targets this pull request already holds stay its own, with the new head.
195
+ * An apply or a `chant lock` takes over the pull request's own plan locks;
196
+ * a plan keeps its own apply and `chant lock` locks as they are. With
197
+ * `releaseStalePlan`, the pull request's plan locks on targets it no longer
198
+ * reaches are released.
199
+ */
200
+ export async function takeTargetLocks(gate, targets, holder, opts = {}) {
201
+ const problem = targetLockGateProblem(gate);
202
+ if (problem)
203
+ throw new Error(problem);
204
+ for (const t of targets)
205
+ if (t.trim() === "")
206
+ throw new Error("a lock target is a non-empty name");
207
+ const wanted = [...new Set(targets)].sort();
208
+ const open = openMemo(opts.isOpen);
209
+ await fetchForLocks(opts.cwd);
210
+ for (let attempt = 1; attempt <= ATTEMPTS; attempt++) {
211
+ const { sha, file } = await readCurrent(gate, opts.cwd);
212
+ const held = await heldIn(file, wanted, holder.pr, open);
213
+ if (held.length > 0)
214
+ return { ok: false, held };
215
+ const next = { version: 1, locks: {} };
216
+ const released = [];
217
+ const expired = [];
218
+ for (const [target, l] of Object.entries(file.locks)) {
219
+ if (l.pr === holder.pr) {
220
+ if (opts.releaseStalePlan && l.stage === "plan" && !wanted.includes(target)) {
221
+ released.push(target);
222
+ continue;
223
+ }
224
+ }
225
+ else if (opts.isOpen && !(await open(l.pr))) {
226
+ expired.push(target);
227
+ continue;
228
+ }
229
+ next.locks[target] = l;
230
+ }
231
+ for (const target of wanted) {
232
+ const own = file.locks[target];
233
+ next.locks[target] = holder.stage === "plan" && own?.pr === holder.pr && own.stage !== "plan" ? own : holder;
234
+ }
235
+ const done = { ok: true, taken: wanted, released: released.sort(), expired: expired.sort() };
236
+ if (renderTargetLocks(next) === renderTargetLocks(file) && sha !== null)
237
+ return { ...done, pushed: false };
238
+ if (wanted.length === 0 && released.length === 0 && expired.length === 0)
239
+ return { ...done, pushed: false };
240
+ const wrote = await writeAndPush(gate, sha, next, `Lock ${wanted.length} target${wanted.length === 1 ? "" : "s"} of ${gate} for pull request ${holder.pr} (${holder.stage})`, opts.cwd);
241
+ if (wrote)
242
+ return { ...done, pushed: wrote.pushed };
243
+ }
244
+ throw new Error(`could not write the locks of ${gate}: ${STATE_BRANCH} kept moving; lock again`);
245
+ }
246
+ /**
247
+ * Release the locks pull request `pr` holds on `gate`: every one, or only
248
+ * those on `targets`. Returns the targets released, sorted.
249
+ */
250
+ export async function releaseTargetLocks(gate, pr, opts = {}) {
251
+ const problem = targetLockGateProblem(gate);
252
+ if (problem)
253
+ throw new Error(problem);
254
+ await fetchForLocks(opts.cwd);
255
+ for (let attempt = 1; attempt <= ATTEMPTS; attempt++) {
256
+ const { sha, file } = await readCurrent(gate, opts.cwd);
257
+ const mine = Object.keys(file.locks)
258
+ .filter((t) => file.locks[t].pr === pr && (!opts.targets || opts.targets.includes(t)))
259
+ .sort();
260
+ if (mine.length === 0)
261
+ return { released: [], pushed: false };
262
+ const next = { version: 1, locks: Object.fromEntries(Object.entries(file.locks).filter(([t]) => !mine.includes(t))) };
263
+ const wrote = await writeAndPush(gate, sha, next, `Unlock ${mine.length} target${mine.length === 1 ? "" : "s"} of ${gate} held by pull request ${pr}`, opts.cwd);
264
+ if (wrote)
265
+ return { released: mine, pushed: wrote.pushed };
266
+ }
267
+ throw new Error(`could not write the locks of ${gate}: ${STATE_BRANCH} kept moving; unlock again`);
268
+ }
269
+ /** The lock file's path for the project at `cwd`, for messages. */
270
+ export async function targetLockPathAt(gate, cwd) {
271
+ const { prefix } = await resolveMemberLedger(cwd ?? process.cwd());
272
+ return targetLockPath(gate, prefix);
273
+ }
274
+ const STAGE_WORDS = { plan: "planned", apply: "applied", lock: "locked with chant lock" };
275
+ /**
276
+ * One line naming the targets others hold, for a refusal or a note.
277
+ * `name` says how the forge names a holder (GitLab: `merge request !7`).
278
+ */
279
+ export function describeHeldTargetLocks(held, name = (pr) => `pull request ${pr}`) {
280
+ const byPr = new Map();
281
+ for (const h of held)
282
+ byPr.set(h.pr, [...(byPr.get(h.pr) ?? []), h]);
283
+ return [...byPr]
284
+ .map(([pr, hs]) => `${hs.map((h) => h.target).join(", ")} ${hs.length === 1 ? "is" : "are"} locked by ${name(pr)} (${STAGE_WORDS[hs[0].stage]} by ${hs[0].by})`)
285
+ .join("; ");
286
+ }
@@ -88,4 +88,22 @@ export declare function zeroResourcesWarning(lexicon: string, environment: strin
88
88
  resources: Record<string, unknown>;
89
89
  unobserved: Record<string, unknown>;
90
90
  }): string | undefined;
91
+ /**
92
+ * Run `run` with `environment`'s declared endpoint applied, as
93
+ * {@link applyLiveEndpoint} applies it to a `--live` read, and restored after
94
+ * (#4281). The component plan and apply paths (`components pr-plan`,
95
+ * `pr-apply`, `pr-record`, `fan-out`, `promote`, `rollback`, `redeploy` and
96
+ * `chant run --components`) run capabilities that honor the same ambient vars:
97
+ * azure's `arm-deploy` reads `AZURE_ENDPOINT_URL`, gcp's `gcp-apply`
98
+ * `GCP_ENDPOINT_URL`, aws's `cfn-deploy` `AWS_ENDPOINT_URL`. Without this, a
99
+ * plan for an environment declared against an emulator went to the real cloud
100
+ * unless the shell exported the var by hand.
101
+ *
102
+ * `lexicons` is called only when the environment declares an endpoint, so a
103
+ * caller that has to load its plugins pays for that only then.
104
+ */
105
+ export declare function withEnvironmentEndpoint<T>(environments: EnvironmentDeclaration[] | undefined, environment: string, lexicons: () => Promise<readonly EndpointLexicon[]> | readonly EndpointLexicon[], run: () => Promise<T>, options?: {
106
+ warn?: (message: string) => void;
107
+ env?: NodeJS.ProcessEnv;
108
+ }): Promise<T>;
91
109
  //# sourceMappingURL=live-endpoint.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"live-endpoint.d.ts","sourceRoot":"","sources":["../src/live-endpoint.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,OAAO,EAAuB,KAAK,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAC5E,OAAO,EAAgC,KAAK,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAEjG;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,eAAe,GAAG,MAAM,EAAE,CAErE;AAED,oFAAoF;AACpF,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,mBAAmB,CAAC;CAChC;AACD,yHAAyH;AACzH,MAAM,WAAW,eAAe;IAC9B;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yEAAyE;IACzE,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAC/B,YAAY,EAAE,sBAAsB,EAAE,GAAG,SAAS,EAClD,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,SAAS,eAAe,EAAE,EACpC,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,eAAe,CAsCjB;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GACpF,MAAM,GAAG,SAAS,CAKpB"}
1
+ {"version":3,"file":"live-endpoint.d.ts","sourceRoot":"","sources":["../src/live-endpoint.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,OAAO,EAAuB,KAAK,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAC5E,OAAO,EAAgC,KAAK,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAEjG;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,eAAe,GAAG,MAAM,EAAE,CAErE;AAED,oFAAoF;AACpF,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,mBAAmB,CAAC;CAChC;AACD,yHAAyH;AACzH,MAAM,WAAW,eAAe;IAC9B;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yEAAyE;IACzE,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAC/B,YAAY,EAAE,sBAAsB,EAAE,GAAG,SAAS,EAClD,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,SAAS,eAAe,EAAE,EACpC,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,eAAe,CAsCjB;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GACpF,MAAM,GAAG,SAAS,CAKpB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,uBAAuB,CAAC,CAAC,EAC7C,YAAY,EAAE,sBAAsB,EAAE,GAAG,SAAS,EAClD,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,OAAO,CAAC,SAAS,eAAe,EAAE,CAAC,GAAG,SAAS,eAAe,EAAE,EAChF,GAAG,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACrB,OAAO,GAAE;IAAE,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAA;CAAO,GAC1E,OAAO,CAAC,CAAC,CAAC,CASZ"}
@@ -111,3 +111,30 @@ export function zeroResourcesWarning(lexicon, environment, declaredCount, observ
111
111
  return undefined;
112
112
  return `${lexicon}: 0 live resources for env "${environment}" (${declaredCount} declared) — check the endpoint/credentials`;
113
113
  }
114
+ /**
115
+ * Run `run` with `environment`'s declared endpoint applied, as
116
+ * {@link applyLiveEndpoint} applies it to a `--live` read, and restored after
117
+ * (#4281). The component plan and apply paths (`components pr-plan`,
118
+ * `pr-apply`, `pr-record`, `fan-out`, `promote`, `rollback`, `redeploy` and
119
+ * `chant run --components`) run capabilities that honor the same ambient vars:
120
+ * azure's `arm-deploy` reads `AZURE_ENDPOINT_URL`, gcp's `gcp-apply`
121
+ * `GCP_ENDPOINT_URL`, aws's `cfn-deploy` `AWS_ENDPOINT_URL`. Without this, a
122
+ * plan for an environment declared against an emulator went to the real cloud
123
+ * unless the shell exported the var by hand.
124
+ *
125
+ * `lexicons` is called only when the environment declares an endpoint, so a
126
+ * caller that has to load its plugins pays for that only then.
127
+ */
128
+ export async function withEnvironmentEndpoint(environments, environment, lexicons, run, options = {}) {
129
+ if (!environmentEndpoint(environments, environment))
130
+ return run();
131
+ const applied = applyLiveEndpoint(environments, environment, await lexicons(), options.env);
132
+ if (applied.notice)
133
+ options.warn?.(applied.notice);
134
+ try {
135
+ return await run();
136
+ }
137
+ finally {
138
+ applied.restore();
139
+ }
140
+ }
@@ -121,6 +121,36 @@ export declare const behaviourFindingContract: import("../index.js").ActivityCon
121
121
  pullRequest?: string | undefined;
122
122
  mergeRequest?: string | undefined;
123
123
  }>;
124
+ /**
125
+ * The review agent (#4299). `changeSet` is `composeChangeSet`'s document,
126
+ * checked only for the fields the prompt reads. `returns` names what a later
127
+ * step may read; no gate reads it.
128
+ */
129
+ export declare const reviewAgentContract: import("../index.js").ActivityContract<{
130
+ op: string;
131
+ changeSet?: {
132
+ [x: string]: unknown;
133
+ digest: string;
134
+ entries: unknown[];
135
+ } | undefined;
136
+ changeSetFile?: string | undefined;
137
+ mode?: "comment" | "report" | undefined;
138
+ title?: string | undefined;
139
+ description?: string | undefined;
140
+ base?: string | undefined;
141
+ instructions?: string | undefined;
142
+ command?: string | undefined;
143
+ keyEnv?: string | undefined;
144
+ timeout?: number | undefined;
145
+ }, {
146
+ mode: "comment" | "report";
147
+ risk: "high" | "low" | "medium" | "unknown";
148
+ exitCode: number | null;
149
+ summary: string;
150
+ commentUrl?: string | undefined;
151
+ pullRequest?: string | undefined;
152
+ mergeRequest?: string | undefined;
153
+ }>;
124
154
  /**
125
155
  * The propose-only template upgrade (#2550, ws-032). `args` mirrors
126
156
  * `ProposeWorkspaceUpgradeArgs` without its test hooks. `returns` names what
@@ -1 +1 @@
1
- {"version":3,"file":"activity-contracts.d.ts","sourceRoot":"","sources":["../../../src/op/activities/activity-contracts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAMH,eAAO,MAAM,yBAAyB;;SAGrC,CAAC;AAEF,eAAO,MAAM,qBAAqB;;;;;;;EAIjC,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;EAmB5B,CAAC;AAEF,eAAO,MAAM,iBAAiB;;;;;;;;;EAgB7B,CAAC;AAEF,eAAO,MAAM,qBAAqB;;SAGjC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB;;;;;;;;;EAUpC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;EAuBpC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,+BAA+B;;;;;;;;;;;;;;;;;;;;;;;;;;EA8B3C,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgClC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;EAkBhC,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;EAIjC,CAAC;AAOF,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;EAIpC,CAAC;AAEF,eAAO,MAAM,8BAA8B;;;;;;;;;;;;;;EAI1C,CAAC;AAEF,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;EAIrC,CAAC;AAEF,eAAO,MAAM,mBAAmB;;;;;;;;;;;EAW/B,CAAC;AAEF,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;EAWjC,CAAC;AAUF,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6B1B,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;EAoBvC,CAAC;AAEF,eAAO,MAAM,6BAA6B;;;;;;;;;;;;;;;;EAWzC,CAAC;AAWF,eAAO,MAAM,mBAAmB;;;;;;;;;;;EAQ/B,CAAC;AAEF,eAAO,MAAM,oBAAoB;;;;YAIhC,CAAC;AAEF,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;EAU9B,CAAC;AAEF,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;EAIhC,CAAC;AAEF,eAAO,MAAM,oBAAoB;;;;;;;;;;;;EAIhC,CAAC;AAEF,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;EASjC,CAAC"}
1
+ {"version":3,"file":"activity-contracts.d.ts","sourceRoot":"","sources":["../../../src/op/activities/activity-contracts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAMH,eAAO,MAAM,yBAAyB;;SAGrC,CAAC;AAEF,eAAO,MAAM,qBAAqB;;;;;;;EAIjC,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;EAmB5B,CAAC;AAEF,eAAO,MAAM,iBAAiB;;;;;;;;;EAgB7B,CAAC;AAEF,eAAO,MAAM,qBAAqB;;SAGjC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB;;;;;;;;;EAUpC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;EAuBpC,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;EAwB/B,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,+BAA+B;;;;;;;;;;;;;;;;;;;;;;;;;;EA8B3C,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgClC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;EAkBhC,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;EAIjC,CAAC;AAOF,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;EAIpC,CAAC;AAEF,eAAO,MAAM,8BAA8B;;;;;;;;;;;;;;EAI1C,CAAC;AAEF,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;EAIrC,CAAC;AAEF,eAAO,MAAM,mBAAmB;;;;;;;;;;;EAW/B,CAAC;AAEF,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;EAWjC,CAAC;AAUF,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6B1B,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;EAoBvC,CAAC;AAEF,eAAO,MAAM,6BAA6B;;;;;;;;;;;;;;;;EAWzC,CAAC;AAWF,eAAO,MAAM,mBAAmB;;;;;;;;;;;EAQ/B,CAAC;AAEF,eAAO,MAAM,oBAAoB;;;;YAIhC,CAAC;AAEF,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;EAU9B,CAAC;AAEF,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;EAIhC,CAAC;AAEF,eAAO,MAAM,oBAAoB;;;;;;;;;;;;EAIhC,CAAC;AAEF,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;EASjC,CAAC"}