@intentius/chant 0.124.40 → 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 (281) 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 +15 -1
  15. package/dist/cli/handlers/fan-out.js +16 -3
  16. package/dist/cli/handlers/gate-resume.d.ts +3 -0
  17. package/dist/cli/handlers/gate-resume.d.ts.map +1 -1
  18. package/dist/cli/handlers/gate-resume.js +15 -2
  19. package/dist/cli/handlers/lock.d.ts +8 -0
  20. package/dist/cli/handlers/lock.d.ts.map +1 -0
  21. package/dist/cli/handlers/lock.js +197 -0
  22. package/dist/cli/handlers/pr-env.d.ts +34 -0
  23. package/dist/cli/handlers/pr-env.d.ts.map +1 -0
  24. package/dist/cli/handlers/pr-env.js +436 -0
  25. package/dist/cli/handlers/pr.d.ts +74 -0
  26. package/dist/cli/handlers/pr.d.ts.map +1 -1
  27. package/dist/cli/handlers/pr.js +503 -53
  28. package/dist/cli/handlers/promote.d.ts.map +1 -1
  29. package/dist/cli/handlers/promote.js +9 -0
  30. package/dist/cli/handlers/query.d.ts +6 -0
  31. package/dist/cli/handlers/query.d.ts.map +1 -0
  32. package/dist/cli/handlers/query.js +80 -0
  33. package/dist/cli/main.d.ts.map +1 -1
  34. package/dist/cli/main.js +41 -2
  35. package/dist/cli/parse-args.d.ts.map +1 -1
  36. package/dist/cli/parse-args.js +31 -2
  37. package/dist/cli/registry.d.ts +12 -2
  38. package/dist/cli/registry.d.ts.map +1 -1
  39. package/dist/components/fan-out-run.d.ts +28 -0
  40. package/dist/components/fan-out-run.d.ts.map +1 -1
  41. package/dist/components/fan-out-run.js +27 -3
  42. package/dist/components/pr-environment.d.ts +298 -0
  43. package/dist/components/pr-environment.d.ts.map +1 -0
  44. package/dist/components/pr-environment.js +406 -0
  45. package/dist/components/pr-hooks.d.ts +66 -0
  46. package/dist/components/pr-hooks.d.ts.map +1 -0
  47. package/dist/components/pr-hooks.js +119 -0
  48. package/dist/components/pr-pipeline.d.ts +72 -2
  49. package/dist/components/pr-pipeline.d.ts.map +1 -1
  50. package/dist/components/pr-pipeline.js +96 -5
  51. package/dist/components/pr-policy.d.ts +109 -0
  52. package/dist/components/pr-policy.d.ts.map +1 -0
  53. package/dist/components/pr-policy.js +150 -0
  54. package/dist/components/pr-run.d.ts.map +1 -1
  55. package/dist/components/pr-run.js +5 -3
  56. package/dist/gate-decision.d.ts +15 -2
  57. package/dist/gate-decision.d.ts.map +1 -1
  58. package/dist/gate-decision.js +17 -2
  59. package/dist/gate-policy.d.ts +140 -0
  60. package/dist/gate-policy.d.ts.map +1 -0
  61. package/dist/gate-policy.js +242 -0
  62. package/dist/lifecycle/gate-checkpoint.d.ts +1 -1
  63. package/dist/lifecycle/gate-checkpoint.js +1 -1
  64. package/dist/{workspace/trust → lifecycle}/gate-seal.d.ts +1 -1
  65. package/dist/lifecycle/gate-seal.d.ts.map +1 -0
  66. package/dist/lifecycle/query.d.ts +68 -0
  67. package/dist/lifecycle/query.d.ts.map +1 -0
  68. package/dist/lifecycle/query.js +246 -0
  69. package/dist/lifecycle/run-ledger.d.ts +13 -0
  70. package/dist/lifecycle/run-ledger.d.ts.map +1 -1
  71. package/dist/lifecycle/run-ledger.js +16 -0
  72. package/dist/lifecycle/target-lock.d.ts +97 -0
  73. package/dist/lifecycle/target-lock.d.ts.map +1 -0
  74. package/dist/lifecycle/target-lock.js +286 -0
  75. package/dist/op/activities/activity-contracts.d.ts +30 -0
  76. package/dist/op/activities/activity-contracts.d.ts.map +1 -1
  77. package/dist/op/activities/activity-contracts.js +26 -0
  78. package/dist/op/activities/index.d.ts +2 -0
  79. package/dist/op/activities/index.d.ts.map +1 -1
  80. package/dist/op/activities/index.js +4 -0
  81. package/dist/op/activities/review-agent.d.ts +137 -0
  82. package/dist/op/activities/review-agent.d.ts.map +1 -0
  83. package/dist/op/activities/review-agent.js +266 -0
  84. package/dist/op/builders.d.ts +9 -0
  85. package/dist/op/builders.d.ts.map +1 -1
  86. package/dist/op/builders.js +11 -0
  87. package/dist/op/cron.d.ts +8 -0
  88. package/dist/op/cron.d.ts.map +1 -1
  89. package/dist/op/cron.js +51 -0
  90. package/dist/op/gate-approval.d.ts +20 -13
  91. package/dist/op/gate-approval.d.ts.map +1 -1
  92. package/dist/op/gate-approval.js +13 -18
  93. package/dist/op/gate-quorum.d.ts +131 -0
  94. package/dist/op/gate-quorum.d.ts.map +1 -0
  95. package/dist/op/gate-quorum.js +183 -0
  96. package/dist/op/gate-resume.d.ts +4 -2
  97. package/dist/op/gate-resume.d.ts.map +1 -1
  98. package/dist/op/gate-resume.js +5 -4
  99. package/dist/op/gate-review.js +1 -1
  100. package/dist/op/gate.d.ts +32 -4
  101. package/dist/op/gate.d.ts.map +1 -1
  102. package/dist/op/gate.js +40 -24
  103. package/dist/op/index.d.ts +6 -4
  104. package/dist/op/index.d.ts.map +1 -1
  105. package/dist/op/index.js +4 -3
  106. package/dist/op/local-executor.d.ts.map +1 -1
  107. package/dist/op/local-executor.js +9 -3
  108. package/dist/op/op-waves-run.d.ts +62 -1
  109. package/dist/op/op-waves-run.d.ts.map +1 -1
  110. package/dist/op/op-waves-run.js +190 -11
  111. package/dist/op/op-waves.d.ts +55 -3
  112. package/dist/op/op-waves.d.ts.map +1 -1
  113. package/dist/op/op-waves.js +63 -8
  114. package/dist/op/schedule-overdue.d.ts +57 -0
  115. package/dist/op/schedule-overdue.d.ts.map +1 -0
  116. package/dist/op/schedule-overdue.js +138 -0
  117. package/dist/override-gate.d.ts +2 -2
  118. package/dist/override-gate.d.ts.map +1 -1
  119. package/dist/override-gate.js +1 -1
  120. package/dist/pr-forge.d.ts +36 -0
  121. package/dist/pr-forge.d.ts.map +1 -1
  122. package/dist/pr-forge.js +82 -0
  123. package/dist/pr-loop.d.ts +90 -1
  124. package/dist/pr-loop.d.ts.map +1 -1
  125. package/dist/pr-loop.js +77 -3
  126. package/dist/pr-post.d.ts +72 -0
  127. package/dist/pr-post.d.ts.map +1 -0
  128. package/dist/pr-post.js +134 -0
  129. package/dist/wave-blocked.d.ts +79 -0
  130. package/dist/wave-blocked.d.ts.map +1 -0
  131. package/dist/wave-blocked.js +245 -0
  132. package/dist/wave-engine.d.ts +6 -0
  133. package/dist/wave-engine.d.ts.map +1 -1
  134. package/dist/wave-engine.js +2 -0
  135. package/dist/wave-runtime.mjs +242 -242
  136. package/dist/workspace/__fixtures__/two-member-workspace.d.ts +1 -0
  137. package/dist/workspace/__fixtures__/two-member-workspace.d.ts.map +1 -1
  138. package/dist/workspace/__fixtures__/two-member-workspace.js +1 -1
  139. package/dist/workspace/ci-branches.d.ts +51 -0
  140. package/dist/workspace/ci-branches.d.ts.map +1 -0
  141. package/dist/workspace/ci-branches.js +69 -0
  142. package/dist/workspace/ci-cloud-identity.d.ts +11 -0
  143. package/dist/workspace/ci-cloud-identity.d.ts.map +1 -0
  144. package/dist/workspace/ci-cloud-identity.js +24 -0
  145. package/dist/workspace/ci-locks.d.ts +12 -0
  146. package/dist/workspace/ci-locks.d.ts.map +1 -0
  147. package/dist/workspace/ci-locks.js +6 -0
  148. package/dist/workspace/ci-run.d.ts +17 -1
  149. package/dist/workspace/ci-run.d.ts.map +1 -1
  150. package/dist/workspace/ci-run.js +64 -3
  151. package/dist/workspace/declaration.d.ts +63 -0
  152. package/dist/workspace/declaration.d.ts.map +1 -1
  153. package/dist/workspace/declaration.js +72 -1
  154. package/dist/workspace/declaration.schema.json +147 -0
  155. package/dist/workspace/identity-gate-rule.d.ts +1 -1
  156. package/dist/workspace/identity-gate-rule.d.ts.map +1 -1
  157. package/dist/workspace/identity-gate-rule.js +1 -1
  158. package/dist/workspace/identity.d.ts +1 -1
  159. package/dist/workspace/identity.d.ts.map +1 -1
  160. package/dist/workspace/lineage-upgrade.d.ts.map +1 -1
  161. package/dist/workspace/lineage-upgrade.js +8 -5
  162. package/dist/workspace/member-pipeline.d.ts +6 -0
  163. package/dist/workspace/member-pipeline.d.ts.map +1 -1
  164. package/dist/workspace/member-pipeline.js +23 -0
  165. package/dist/workspace/pr-report.schema.json +73 -2
  166. package/dist/workspace/security.d.ts.map +1 -1
  167. package/dist/workspace/security.js +4 -0
  168. package/dist/workspace/status-gates.d.ts +3 -2
  169. package/dist/workspace/status-gates.d.ts.map +1 -1
  170. package/dist/workspace/status-gates.js +8 -7
  171. package/dist/workspace/status.d.ts.map +1 -1
  172. package/dist/workspace/status.js +4 -1
  173. package/dist/workspace/trust/seal.d.ts +2 -2
  174. package/dist/workspace/trust/seal.d.ts.map +1 -1
  175. package/dist/workspace/trust/seal.js +2 -2
  176. package/package.json +1 -1
  177. package/src/__fixtures__/oidc-emulator.ts +118 -0
  178. package/src/ci-handover.test.ts +209 -0
  179. package/src/ci-handover.ts +237 -0
  180. package/src/ci-identity.test.ts +201 -0
  181. package/src/ci-identity.ts +310 -0
  182. package/src/cli/handlers/approve.ts +18 -5
  183. package/src/cli/handlers/build.ts +15 -1
  184. package/src/cli/handlers/fan-out.ts +17 -4
  185. package/src/cli/handlers/gate-resume.ts +16 -2
  186. package/src/cli/handlers/lock.test.ts +98 -0
  187. package/src/cli/handlers/lock.ts +202 -0
  188. package/src/cli/handlers/operator.test.ts +3 -1
  189. package/src/cli/handlers/pr-env.ts +462 -0
  190. package/src/cli/handlers/pr-waves-blocked.test.ts +247 -0
  191. package/src/cli/handlers/pr.test.ts +184 -0
  192. package/src/cli/handlers/pr.ts +496 -59
  193. package/src/cli/handlers/promote.ts +9 -0
  194. package/src/cli/handlers/query.ts +78 -0
  195. package/src/cli/main.ts +41 -2
  196. package/src/cli/parse-args.ts +23 -2
  197. package/src/cli/registry.ts +12 -2
  198. package/src/components/fan-out-run.ts +39 -2
  199. package/src/components/fan-out-waves.test.ts +45 -1
  200. package/src/components/pr-environment.test.ts +249 -0
  201. package/src/components/pr-environment.ts +538 -0
  202. package/src/components/pr-hooks.test.ts +118 -0
  203. package/src/components/pr-hooks.ts +157 -0
  204. package/src/components/pr-pipeline.ts +130 -5
  205. package/src/components/pr-policy.test.ts +145 -0
  206. package/src/components/pr-policy.ts +211 -0
  207. package/src/components/pr-run.ts +5 -2
  208. package/src/gate-decision-bundle.test.ts +4 -3
  209. package/src/gate-decision.ts +39 -2
  210. package/src/gate-policy-bundle.test.ts +28 -0
  211. package/src/gate-policy.test.ts +162 -0
  212. package/src/gate-policy.ts +298 -0
  213. package/src/lifecycle/gate-checkpoint.ts +1 -1
  214. package/src/{workspace/trust → lifecycle}/gate-seal.ts +1 -1
  215. package/src/lifecycle/query.test.ts +91 -0
  216. package/src/lifecycle/query.ts +315 -0
  217. package/src/lifecycle/run-ledger.ts +18 -0
  218. package/src/lifecycle/target-lock.test.ts +195 -0
  219. package/src/lifecycle/target-lock.ts +347 -0
  220. package/src/op/activities/activity-contracts.ts +31 -0
  221. package/src/op/activities/index.ts +6 -0
  222. package/src/op/activities/review-agent.test.ts +240 -0
  223. package/src/op/activities/review-agent.ts +355 -0
  224. package/src/op/builders.ts +13 -0
  225. package/src/op/cron.ts +44 -0
  226. package/src/op/gate-alias.test.ts +2 -2
  227. package/src/op/gate-approval.test.ts +30 -9
  228. package/src/op/gate-approval.ts +23 -26
  229. package/src/op/gate-quorum.test.ts +139 -0
  230. package/src/op/gate-quorum.ts +248 -0
  231. package/src/op/gate-resume.ts +6 -3
  232. package/src/op/gate-review.ts +1 -1
  233. package/src/op/gate.ts +64 -23
  234. package/src/op/index.ts +13 -1
  235. package/src/op/local-executor.ts +9 -2
  236. package/src/op/op-waves-hook-targets.test.ts +126 -0
  237. package/src/op/op-waves-policy-hold.test.ts +66 -0
  238. package/src/op/op-waves-quorum.test.ts +101 -0
  239. package/src/op/op-waves-run.ts +233 -11
  240. package/src/op/op-waves.ts +83 -10
  241. package/src/op/schedule-overdue.test.ts +220 -0
  242. package/src/op/schedule-overdue.ts +161 -0
  243. package/src/override-gate-bundle.test.ts +1 -1
  244. package/src/override-gate.ts +2 -2
  245. package/src/pr-forge-bundle.test.ts +2 -2
  246. package/src/pr-forge.test.ts +33 -0
  247. package/src/pr-forge.ts +114 -0
  248. package/src/pr-loop-bundle.test.ts +2 -2
  249. package/src/pr-loop.test.ts +58 -0
  250. package/src/pr-loop.ts +146 -4
  251. package/src/pr-post.test.ts +141 -0
  252. package/src/pr-post.ts +159 -0
  253. package/src/wave-blocked-bundle.test.ts +25 -0
  254. package/src/wave-blocked.test.ts +146 -0
  255. package/src/wave-blocked.ts +271 -0
  256. package/src/wave-engine.ts +8 -0
  257. package/src/workspace/__fixtures__/two-member-workspace.ts +2 -2
  258. package/src/workspace/ci-branches.test.ts +62 -0
  259. package/src/workspace/ci-branches.ts +79 -0
  260. package/src/workspace/ci-cloud-identity.test.ts +53 -0
  261. package/src/workspace/ci-cloud-identity.ts +23 -0
  262. package/src/workspace/ci-locks.ts +16 -0
  263. package/src/workspace/ci-run-index.test.ts +2 -1
  264. package/src/workspace/ci-run.test.ts +107 -8
  265. package/src/workspace/ci-run.ts +72 -4
  266. package/src/workspace/declaration.schema.json +147 -0
  267. package/src/workspace/declaration.test.ts +76 -0
  268. package/src/workspace/declaration.ts +134 -2
  269. package/src/workspace/identity-gate-rule.ts +1 -1
  270. package/src/workspace/identity.ts +1 -1
  271. package/src/workspace/lineage-upgrade.ts +11 -8
  272. package/src/workspace/member-pipeline.test.ts +29 -0
  273. package/src/workspace/member-pipeline.ts +30 -0
  274. package/src/workspace/pr-report.schema.json +73 -2
  275. package/src/workspace/security.ts +4 -0
  276. package/src/workspace/status-gates.ts +9 -6
  277. package/src/workspace/status.ts +4 -1
  278. package/src/workspace/trust/gate-seal.test.ts +1 -1
  279. package/src/workspace/trust/seal.ts +2 -2
  280. package/dist/workspace/trust/gate-seal.d.ts.map +0 -1
  281. /package/dist/{workspace/trust → lifecycle}/gate-seal.js +0 -0
@@ -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
+ }
@@ -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"}
@@ -107,6 +107,32 @@ export const behaviourFindingContract = activityContract("behaviourFinding", z.s
107
107
  pullRequest: z.string().optional(),
108
108
  mergeRequest: z.string().optional(),
109
109
  }));
110
+ /**
111
+ * The review agent (#4299). `changeSet` is `composeChangeSet`'s document,
112
+ * checked only for the fields the prompt reads. `returns` names what a later
113
+ * step may read; no gate reads it.
114
+ */
115
+ export const reviewAgentContract = activityContract("reviewAgent", z.strictObject({
116
+ op: z.string(),
117
+ changeSet: z.object({ digest: z.string(), entries: z.array(z.unknown()) }).passthrough().optional(),
118
+ changeSetFile: z.string().optional(),
119
+ mode: z.enum(["comment", "report"]).optional(),
120
+ title: z.string().optional(),
121
+ description: z.string().optional(),
122
+ base: z.string().optional(),
123
+ instructions: z.string().optional(),
124
+ command: z.string().optional(),
125
+ keyEnv: z.string().optional(),
126
+ timeout: z.number().positive().optional(),
127
+ }), z.object({
128
+ mode: z.enum(["comment", "report"]),
129
+ risk: z.enum(["low", "medium", "high", "unknown"]),
130
+ exitCode: z.number().nullable(),
131
+ summary: z.string(),
132
+ commentUrl: z.string().optional(),
133
+ pullRequest: z.string().optional(),
134
+ mergeRequest: z.string().optional(),
135
+ }));
110
136
  /**
111
137
  * The propose-only template upgrade (#2550, ws-032). `args` mirrors
112
138
  * `ProposeWorkspaceUpgradeArgs` without its test hooks. `returns` names what
@@ -38,6 +38,8 @@ export { lexiconUpgrade, isPinned, isRolling, severityToLabel, upgradeBranchName
38
38
  export type { LexiconUpgradeArgs, LexiconUpgradeResult, LexiconUpgradeMode, SupportedLexicon, SemverLabel, CheckPinnedFn, CheckRollingFn, GhRunner, ApplyBumpFn, } from "./lexicon-upgrade.js";
39
39
  export { predictBehaviour, behaviourFinding, behaviourFindingMarker, declaredEdgeCoverage, baseRefFrom, headRefFrom, noBaseRefMessage, noContributedRowsMessage, } from "./predict-behaviour.js";
40
40
  export type { PredictBehaviourArgs, BehaviourFindingArgs, BehaviourFindingResult, BehaviourFindingMode, BehaviourFindingDeps, BaseCheckout, } from "./predict-behaviour.js";
41
+ export { reviewAgent, reviewMarker } from "./review-agent.js";
42
+ export type { ReviewAgentArgs, ReviewAgentResult, ReviewAgentMode, ReviewRisk } from "./review-agent.js";
41
43
  export { proposeWorkspaceUpgrade } from "./propose-upgrade.js";
42
44
  export type { ProposeWorkspaceUpgradeArgs, ProposeWorkspaceUpgradeResult, ProposeUpgradeMode, CommandRunner, } from "./propose-upgrade.js";
43
45
  export { changeCoverage } from "./change-coverage.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/op/activities/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/op/activities/index.ts"],"names":[],"mappings":"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"}
@@ -43,6 +43,10 @@ export { lexiconUpgrade, isPinned, isRolling, severityToLabel, upgradeBranchName
43
43
  // collects every exported function as an activity, so `createBehaviourFinding`
44
44
  // and `checkoutBase` stay on the module.
45
45
  export { predictBehaviour, behaviourFinding, behaviourFindingMarker, declaredEdgeCoverage, baseRefFrom, headRefFrom, noBaseRefMessage, noContributedRowsMessage, } from "./predict-behaviour.js";
46
+ // The review agent (#4299): a model reviews the change set against the pull
47
+ // request's own text and posts one sticky note. Only the activity and its
48
+ // marker are re-exported, since the registry collects every exported function.
49
+ export { reviewAgent, reviewMarker } from "./review-agent.js";
46
50
  // The propose-only template upgrade (#2550). Loads the workspace code on first
47
51
  // call only, so importing this module loads nothing under `workspace/`.
48
52
  export { proposeWorkspaceUpgrade } from "./propose-upgrade.js";
@@ -0,0 +1,137 @@
1
+ /**
2
+ * The `reviewAgent` activity (#4299): a model compares what a pull request
3
+ * says it does with what its change set would do, and the finding is posted
4
+ * as one sticky note on the pull request.
5
+ *
6
+ * Lifted from terragucci's `review-agent.ts` (INTENTIUS/terragucci e6cb431,
7
+ * `packages/terragucci/src/review-agent.ts`): the prompt, the `risk:` line,
8
+ * the default command and the quoting of untrusted text are its. What differs
9
+ * is where the plan comes from. terragucci reads a Terraform plan note; here
10
+ * the input is the change-set document `composeChangeSet` returns, so every
11
+ * lexicon's plan can be reviewed.
12
+ *
13
+ * The review never approves and never gates. The activity posts through
14
+ * {@link reconcilePr} in `comment` mode and nothing else: no review, no
15
+ * approval, no status. Its result is data a later step may read; no gate reads
16
+ * it, and an agent principal never counts toward a quorum
17
+ * (`../gate-approval.ts`).
18
+ *
19
+ * The model command runs with the prompt on stdin and prints the review on
20
+ * stdout. Its environment is built from scratch ({@link reviewCommandEnv}):
21
+ * the model key and a few process basics, never a forge token. The
22
+ * instructions file is read from the base branch with `git show`, so a pull
23
+ * request that edits it changes nothing until it merges.
24
+ */
25
+ import type { ChangeSetDocument } from "../../change-set.js";
26
+ import { reconcilePr } from "./reconcile.js";
27
+ /** The Claude Code release the default review command runs (terragucci's pin). */
28
+ export declare const REVIEW_CLAUDE_CODE_VERSION = "2.1.290";
29
+ /**
30
+ * The default review command: Claude Code in print mode with no tools, no MCP
31
+ * servers, no project settings and no session kept. The prompt arrives on
32
+ * stdin and the review leaves on stdout.
33
+ */
34
+ export declare const REVIEW_COMMAND: string;
35
+ /** Where the review instructions live on the base branch unless `instructions` names another file. */
36
+ export declare const REVIEW_INSTRUCTIONS = ".chant/review.md";
37
+ /** The environment variable that holds the model's key unless `keyEnv` names another. */
38
+ export declare const REVIEW_KEY_ENV = "ANTHROPIC_API_KEY";
39
+ export declare const REVIEW_RISKS: readonly ["low", "medium", "high"];
40
+ export type ReviewRisk = (typeof REVIEW_RISKS)[number];
41
+ /** How the review leaves the run. */
42
+ export type ReviewAgentMode = "comment" | "report";
43
+ export interface ReviewAgentArgs {
44
+ /** The Op this step belongs to. It keys the note's marker ({@link reviewMarker}). */
45
+ op: string;
46
+ /** The change set to review: `composeChangeSet`'s `document`, usually a step output. */
47
+ changeSet?: ChangeSetDocument;
48
+ /** A file holding the change-set document, read when `changeSet` is not given. */
49
+ changeSetFile?: string;
50
+ /** `comment` posts the note on the triggering pull or merge request; `report` returns it. Default: `comment`. */
51
+ mode?: ReviewAgentMode;
52
+ /** The pull request's title. Default: read from the run's event. */
53
+ title?: string;
54
+ /** The pull request's description. Default: read from the run's event. */
55
+ description?: string;
56
+ /** The base branch the instructions are read from. Default: `GITHUB_BASE_REF`, then `CI_MERGE_REQUEST_TARGET_BRANCH_NAME`. */
57
+ base?: string;
58
+ /** The instructions file on the base branch. Default: {@link REVIEW_INSTRUCTIONS}. */
59
+ instructions?: string;
60
+ /** The model command, run through the shell. Default: {@link REVIEW_COMMAND}. */
61
+ command?: string;
62
+ /** The variable that holds the model's key, the one secret the command sees. Default: {@link REVIEW_KEY_ENV}. */
63
+ keyEnv?: string;
64
+ /** Minutes the command may run. Default: 10. */
65
+ timeout?: number;
66
+ }
67
+ export interface ReviewAgentResult {
68
+ mode: ReviewAgentMode;
69
+ /** The risk the review's last `risk:` line names, or `unknown`. Informational: nothing gates on it. */
70
+ risk: ReviewRisk | "unknown";
71
+ /** The command's exit code, or null when it was killed or could not start. */
72
+ exitCode: number | null;
73
+ /** The note's Markdown, whether or not it was posted. */
74
+ summary: string;
75
+ commentUrl?: string;
76
+ pullRequest?: string;
77
+ mergeRequest?: string;
78
+ }
79
+ /** The note's hidden marker, keyed on the Op. Its prefix differs from every `reconcilePr` and behaviour marker. */
80
+ export declare function reviewMarker(op: string): string;
81
+ /** Text as it goes between the prompt's tags: a closing tag of ours inside it cannot end the section. */
82
+ export declare function quoted(text: string): string;
83
+ /** The change set as the prompt carries it: one line per entry that changes something, members that failed, and holes. */
84
+ export declare function changeSetText(doc: ChangeSetDocument): string;
85
+ export interface ReviewPromptParts {
86
+ title: string;
87
+ description: string;
88
+ changeSet: ChangeSetDocument;
89
+ /** The base branch's instructions, or undefined when it has none. */
90
+ instructions?: string;
91
+ instructionsPath: string;
92
+ base: string;
93
+ }
94
+ /** The review's prompt. Everything the author wrote and everything made from the change is quoted as data. */
95
+ export declare function reviewPrompt(p: ReviewPromptParts): string;
96
+ /** The risk the review's last `risk:` line names, or unknown. */
97
+ export declare function riskOf(review: string): ReviewRisk | "unknown";
98
+ /** The note's body. The review is the model's text: shown, never trusted, and no HTML comment of it survives. */
99
+ export declare function reviewNoteBody(o: {
100
+ review: string;
101
+ exitCode: number | null;
102
+ digest: string;
103
+ instructions: "base" | "none";
104
+ }): string;
105
+ /** The variables the review command sees: the model key and process basics. Never a forge or cloud token. */
106
+ export declare function reviewCommandEnv(env: Record<string, string | undefined>, keyEnv: string): Record<string, string>;
107
+ /** The pull request's title and description from the run: the event payload on GitHub and Forgejo, CI variables on GitLab. */
108
+ export declare function pullRequestTextFrom(env: Record<string, string | undefined>, payload?: unknown): {
109
+ title: string;
110
+ description: string;
111
+ };
112
+ /** What a run of the model command returns. */
113
+ export interface CommandOutcome {
114
+ stdout: string;
115
+ exitCode: number | null;
116
+ }
117
+ export type RunReviewCommand = (command: string, input: string, env: Record<string, string>, timeoutMs: number, signal?: AbortSignal) => Promise<CommandOutcome>;
118
+ /** Run the command through the shell with the prompt on stdin. A failure is an outcome, not a throw: the note says so. */
119
+ export declare const runReviewCommand: RunReviewCommand;
120
+ /** Read a file at the base branch, or undefined when it has none. */
121
+ export type ShowAtBase = (base: string, path: string, signal?: AbortSignal) => Promise<string | undefined>;
122
+ /** `git show` of the base branch's copy, fetching the branch at depth one first since a CI clone may not carry it. */
123
+ export declare const showAtBase: ShowAtBase;
124
+ export interface ReviewAgentDeps {
125
+ run?: RunReviewCommand;
126
+ show?: ShowAtBase;
127
+ post?: typeof reconcilePr;
128
+ env?: Record<string, string | undefined>;
129
+ /** Read the event payload. Default: `GITHUB_EVENT_PATH` parsed, or undefined. */
130
+ event?: () => Promise<unknown>;
131
+ readFile?: (path: string) => Promise<string>;
132
+ }
133
+ /** Build the activity with its side effects injected, so a test drives it with fakes. */
134
+ export declare function createReviewAgent(deps?: ReviewAgentDeps): (args: ReviewAgentArgs, signal?: AbortSignal) => Promise<ReviewAgentResult>;
135
+ /** Review the pull request's change set with the configured model and post the finding as one sticky note. Never approves, never gates. */
136
+ export declare const reviewAgent: (args: ReviewAgentArgs, signal?: AbortSignal) => Promise<ReviewAgentResult>;
137
+ //# sourceMappingURL=review-agent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-agent.d.ts","sourceRoot":"","sources":["../../../src/op/activities/review-agent.ts"],"names":[],"mappings":"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"}