@intentius/chant 0.124.16 → 0.124.18

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 (154) hide show
  1. package/dist/__golden__/wave-loop/fan-out-applied.json +511 -0
  2. package/dist/__golden__/wave-loop/fan-out-apply-fails.json +406 -0
  3. package/dist/__golden__/wave-loop/fan-out-gated.json +707 -0
  4. package/dist/__golden__/wave-loop/fan-out-no-members.json +898 -0
  5. package/dist/__golden__/wave-loop/fan-out-only.json +514 -0
  6. package/dist/__golden__/wave-loop/fan-out-plan-fails.json +359 -0
  7. package/dist/__golden__/wave-loop/fan-out-same-root.json +311 -0
  8. package/dist/__golden__/wave-loop/op-by-apply-after-fails.json +401 -0
  9. package/dist/__golden__/wave-loop/op-by-apply-hold.json +756 -0
  10. package/dist/__golden__/wave-loop/op-by-apply-ignored.json +340 -0
  11. package/dist/__golden__/wave-loop/op-by-apply-pass.json +400 -0
  12. package/dist/__golden__/wave-loop/op-by-apply-skip.json +404 -0
  13. package/dist/__golden__/wave-loop/op-cost-member-clash.json +62 -0
  14. package/dist/__golden__/wave-loop/op-cost-member.json +191 -0
  15. package/dist/__golden__/wave-loop/op-denied-source.json +407 -0
  16. package/dist/__golden__/wave-loop/op-denied.json +399 -0
  17. package/dist/__golden__/wave-loop/op-discover-rest-short.json +92 -0
  18. package/dist/__golden__/wave-loop/op-discover-rest-stops.json +340 -0
  19. package/dist/__golden__/wave-loop/op-discover-rest.json +659 -0
  20. package/dist/__golden__/wave-loop/op-discover-wide.json +290 -0
  21. package/dist/__golden__/wave-loop/op-held-on-again.json +176 -0
  22. package/dist/__golden__/wave-loop/op-held-on-before-apply.json +689 -0
  23. package/dist/__golden__/wave-loop/op-held-on.json +1455 -0
  24. package/dist/__golden__/wave-loop/op-hooks-apply-fails.json +673 -0
  25. package/dist/__golden__/wave-loop/op-hooks-fail-after-apply.json +737 -0
  26. package/dist/__golden__/wave-loop/op-hooks-fail-before-apply.json +450 -0
  27. package/dist/__golden__/wave-loop/op-hooks-fail-before-plan.json +97 -0
  28. package/dist/__golden__/wave-loop/op-hooks-held.json +1059 -0
  29. package/dist/__golden__/wave-loop/op-hooks-hold-before-apply.json +693 -0
  30. package/dist/__golden__/wave-loop/op-hooks-pass.json +735 -0
  31. package/dist/__golden__/wave-loop/op-hooks-refused-at-base.json +148 -0
  32. package/dist/__golden__/wave-loop/op-hooks-share.json +1225 -0
  33. package/dist/__golden__/wave-loop/op-outcome-held.json +202 -0
  34. package/dist/__golden__/wave-loop/op-outcome-replan-approved.json +286 -0
  35. package/dist/__golden__/wave-loop/op-outcome-replan-forever.json +823 -0
  36. package/dist/__golden__/wave-loop/op-outcome-replan.json +259 -0
  37. package/dist/__golden__/wave-loop/op-outcome-stood-down.json +196 -0
  38. package/dist/__golden__/wave-loop/op-outcome-unreadable.json +193 -0
  39. package/dist/__golden__/wave-loop/op-overridden.json +508 -0
  40. package/dist/__golden__/wave-loop/op-per-run.json +518 -0
  41. package/dist/__golden__/wave-loop/op-point.json +495 -0
  42. package/dist/__golden__/wave-loop/op-pr-review.json +397 -0
  43. package/dist/__golden__/wave-loop/op-sealed.json +125 -0
  44. package/dist/__golden__/wave-loop/op-spend-change-only.json +168 -0
  45. package/dist/__golden__/wave-loop/op-spend.json +328 -0
  46. package/dist/__golden__/wave-loop/op-wave-commands.json +1808 -0
  47. package/dist/__golden__/wave-loop/op-wide-refused.json +291 -0
  48. package/dist/__golden__/wave-loop/op-wide-waiting.json +231 -0
  49. package/dist/__golden__/wave-loop/op-wide.json +440 -0
  50. package/dist/cli/commands/check-lexicon-plugin.d.ts.map +1 -1
  51. package/dist/cli/commands/check-lexicon-plugin.js +2 -1
  52. package/dist/cli/commands/lint.d.ts.map +1 -1
  53. package/dist/cli/commands/lint.js +3 -2
  54. package/dist/components/discover.d.ts.map +1 -1
  55. package/dist/components/discover.js +2 -1
  56. package/dist/components/fan-out-run.d.ts +4 -3
  57. package/dist/components/fan-out-run.d.ts.map +1 -1
  58. package/dist/components/fan-out-run.js +138 -123
  59. package/dist/config-sandbox.d.ts.map +1 -1
  60. package/dist/config-sandbox.js +5 -1
  61. package/dist/discovery/import.d.ts.map +1 -1
  62. package/dist/discovery/import.js +2 -1
  63. package/dist/discovery/sandbox/driver.d.ts.map +1 -1
  64. package/dist/discovery/sandbox/driver.js +8 -3
  65. package/dist/lexicon-module.d.ts.map +1 -1
  66. package/dist/lexicon-module.js +4 -3
  67. package/dist/lint/policy-import.d.ts.map +1 -1
  68. package/dist/lint/policy-import.js +2 -1
  69. package/dist/lint/rule-loader.d.ts.map +1 -1
  70. package/dist/lint/rule-loader.js +2 -1
  71. package/dist/module-interop.d.ts +20 -0
  72. package/dist/module-interop.d.ts.map +1 -0
  73. package/dist/module-interop.js +39 -0
  74. package/dist/op/discover.d.ts.map +1 -1
  75. package/dist/op/discover.js +3 -2
  76. package/dist/op/op-waves-run.d.ts +7 -1
  77. package/dist/op/op-waves-run.d.ts.map +1 -1
  78. package/dist/op/op-waves-run.js +129 -72
  79. package/dist/wave-engine.d.ts +74 -5
  80. package/dist/wave-engine.d.ts.map +1 -1
  81. package/dist/wave-engine.js +47 -5
  82. package/dist/wave-runtime.mjs +218 -218
  83. package/dist/workspace/lineage-migrations.d.ts.map +1 -1
  84. package/dist/workspace/lineage-migrations.js +2 -1
  85. package/package.json +1 -1
  86. package/src/__golden__/wave-loop/fan-out-applied.json +511 -0
  87. package/src/__golden__/wave-loop/fan-out-apply-fails.json +406 -0
  88. package/src/__golden__/wave-loop/fan-out-gated.json +707 -0
  89. package/src/__golden__/wave-loop/fan-out-no-members.json +898 -0
  90. package/src/__golden__/wave-loop/fan-out-only.json +514 -0
  91. package/src/__golden__/wave-loop/fan-out-plan-fails.json +359 -0
  92. package/src/__golden__/wave-loop/fan-out-same-root.json +311 -0
  93. package/src/__golden__/wave-loop/op-by-apply-after-fails.json +401 -0
  94. package/src/__golden__/wave-loop/op-by-apply-hold.json +756 -0
  95. package/src/__golden__/wave-loop/op-by-apply-ignored.json +340 -0
  96. package/src/__golden__/wave-loop/op-by-apply-pass.json +400 -0
  97. package/src/__golden__/wave-loop/op-by-apply-skip.json +404 -0
  98. package/src/__golden__/wave-loop/op-cost-member-clash.json +62 -0
  99. package/src/__golden__/wave-loop/op-cost-member.json +191 -0
  100. package/src/__golden__/wave-loop/op-denied-source.json +407 -0
  101. package/src/__golden__/wave-loop/op-denied.json +399 -0
  102. package/src/__golden__/wave-loop/op-discover-rest-short.json +92 -0
  103. package/src/__golden__/wave-loop/op-discover-rest-stops.json +340 -0
  104. package/src/__golden__/wave-loop/op-discover-rest.json +659 -0
  105. package/src/__golden__/wave-loop/op-discover-wide.json +290 -0
  106. package/src/__golden__/wave-loop/op-held-on-again.json +176 -0
  107. package/src/__golden__/wave-loop/op-held-on-before-apply.json +689 -0
  108. package/src/__golden__/wave-loop/op-held-on.json +1455 -0
  109. package/src/__golden__/wave-loop/op-hooks-apply-fails.json +673 -0
  110. package/src/__golden__/wave-loop/op-hooks-fail-after-apply.json +737 -0
  111. package/src/__golden__/wave-loop/op-hooks-fail-before-apply.json +450 -0
  112. package/src/__golden__/wave-loop/op-hooks-fail-before-plan.json +97 -0
  113. package/src/__golden__/wave-loop/op-hooks-held.json +1059 -0
  114. package/src/__golden__/wave-loop/op-hooks-hold-before-apply.json +693 -0
  115. package/src/__golden__/wave-loop/op-hooks-pass.json +735 -0
  116. package/src/__golden__/wave-loop/op-hooks-refused-at-base.json +148 -0
  117. package/src/__golden__/wave-loop/op-hooks-share.json +1225 -0
  118. package/src/__golden__/wave-loop/op-outcome-held.json +202 -0
  119. package/src/__golden__/wave-loop/op-outcome-replan-approved.json +286 -0
  120. package/src/__golden__/wave-loop/op-outcome-replan-forever.json +823 -0
  121. package/src/__golden__/wave-loop/op-outcome-replan.json +259 -0
  122. package/src/__golden__/wave-loop/op-outcome-stood-down.json +196 -0
  123. package/src/__golden__/wave-loop/op-outcome-unreadable.json +193 -0
  124. package/src/__golden__/wave-loop/op-overridden.json +508 -0
  125. package/src/__golden__/wave-loop/op-per-run.json +518 -0
  126. package/src/__golden__/wave-loop/op-point.json +495 -0
  127. package/src/__golden__/wave-loop/op-pr-review.json +397 -0
  128. package/src/__golden__/wave-loop/op-sealed.json +125 -0
  129. package/src/__golden__/wave-loop/op-spend-change-only.json +168 -0
  130. package/src/__golden__/wave-loop/op-spend.json +328 -0
  131. package/src/__golden__/wave-loop/op-wave-commands.json +1808 -0
  132. package/src/__golden__/wave-loop/op-wide-refused.json +291 -0
  133. package/src/__golden__/wave-loop/op-wide-waiting.json +231 -0
  134. package/src/__golden__/wave-loop/op-wide.json +440 -0
  135. package/src/cli/commands/check-lexicon-plugin.ts +2 -1
  136. package/src/cli/commands/lint.ts +3 -2
  137. package/src/cli/compiled-cli.e2e.test.ts +42 -1
  138. package/src/components/discover.ts +2 -1
  139. package/src/components/fan-out-run.ts +156 -128
  140. package/src/config-sandbox.ts +5 -1
  141. package/src/discovery/import.ts +2 -1
  142. package/src/discovery/sandbox/driver.ts +8 -3
  143. package/src/lexicon-module.ts +4 -3
  144. package/src/lint/policy-import.ts +2 -1
  145. package/src/lint/rule-loader.ts +2 -1
  146. package/src/meta/peer-deps.test.ts +39 -0
  147. package/src/module-interop.test.ts +65 -0
  148. package/src/module-interop.ts +39 -0
  149. package/src/op/discover.ts +3 -2
  150. package/src/op/op-waves-run.ts +184 -68
  151. package/src/wave-engine.test.ts +38 -1
  152. package/src/wave-engine.ts +101 -5
  153. package/src/wave-loop-golden.test.ts +627 -0
  154. package/src/workspace/lineage-migrations.ts +2 -1
@@ -0,0 +1,1059 @@
1
+ {
2
+ "jobs": [
3
+ {
4
+ "label": "held, waits",
5
+ "job": {
6
+ "wave": 1
7
+ },
8
+ "result": {
9
+ "exitCode": 3,
10
+ "applied": [],
11
+ "failed": [],
12
+ "moved": [],
13
+ "hooks": [
14
+ {
15
+ "moment": "before-plan",
16
+ "name": "lint",
17
+ "exit": 0,
18
+ "outcome": "passed"
19
+ },
20
+ {
21
+ "moment": "after-plan",
22
+ "name": "check",
23
+ "target": "t1",
24
+ "exit": 0,
25
+ "outcome": "passed"
26
+ },
27
+ {
28
+ "moment": "after-plan",
29
+ "name": "check",
30
+ "target": "t2",
31
+ "exit": 1,
32
+ "outcome": "held"
33
+ }
34
+ ],
35
+ "decision": {
36
+ "wave": 1,
37
+ "name": "prod",
38
+ "op": "migrations",
39
+ "gate": "migrations-wave-1",
40
+ "policy": "never",
41
+ "approval": "ledger",
42
+ "policySource": "base",
43
+ "base": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
44
+ "digest": "jcs1-sha256:52d1b04601e89971eab0e24094024707e878042be4b79ad476d6230ac5ef383f",
45
+ "members": [
46
+ {
47
+ "member": "t1",
48
+ "planDigest": "sha256:tttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt",
49
+ "op": "migrate"
50
+ },
51
+ {
52
+ "member": "t2",
53
+ "planDigest": "sha256:tttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt",
54
+ "op": "migrate"
55
+ }
56
+ ],
57
+ "status": "waiting",
58
+ "hooks": {
59
+ "before-plan": [
60
+ {
61
+ "name": "lint",
62
+ "command": [
63
+ "hook",
64
+ "lint",
65
+ "{runs}"
66
+ ]
67
+ }
68
+ ],
69
+ "after-plan": [
70
+ {
71
+ "name": "check",
72
+ "command": [
73
+ "hook",
74
+ "check",
75
+ "{target}",
76
+ "{plan}"
77
+ ],
78
+ "perRun": true,
79
+ "onFailure": "approve"
80
+ }
81
+ ],
82
+ "before-apply": [
83
+ {
84
+ "name": "backup",
85
+ "command": [
86
+ "hook",
87
+ "backup",
88
+ "{runs}"
89
+ ]
90
+ }
91
+ ],
92
+ "after-apply": [
93
+ {
94
+ "name": "smoke",
95
+ "command": [
96
+ "hook",
97
+ "smoke",
98
+ "{wave}"
99
+ ]
100
+ }
101
+ ]
102
+ },
103
+ "heldBy": [
104
+ "after-plan hook check (t2)"
105
+ ],
106
+ "pendingFact": {
107
+ "version": 1,
108
+ "kind": "pending",
109
+ "approvalMode": "ledger",
110
+ "op": "migrations",
111
+ "gate": "migrations-wave-1",
112
+ "timestamp": "2026-10-11T00:00:00.000Z",
113
+ "expiresAt": "2026-10-13T00:00:00.000Z",
114
+ "description": "wave 1 (prod): 2 runs, gate never, approval ledger, held by after-plan hook check (t2)",
115
+ "planDigest": "jcs1-sha256:52d1b04601e89971eab0e24094024707e878042be4b79ad476d6230ac5ef383f"
116
+ },
117
+ "recorded": true,
118
+ "waitingSince": "2026-10-11T00:00:00.000Z",
119
+ "approve": "chant approve migrations migrations-wave-1 --plan jcs1-sha256:52d1b04601e89971eab0e24094024707e878042be4b79ad476d6230ac5ef383f",
120
+ "outcomes": [
121
+ {
122
+ "moment": "before-plan",
123
+ "name": "lint",
124
+ "exit": 0,
125
+ "outcome": "passed"
126
+ },
127
+ {
128
+ "moment": "after-plan",
129
+ "name": "check",
130
+ "target": "t1",
131
+ "exit": 0,
132
+ "outcome": "passed"
133
+ },
134
+ {
135
+ "moment": "after-plan",
136
+ "name": "check",
137
+ "target": "t2",
138
+ "exit": 1,
139
+ "outcome": "held"
140
+ }
141
+ ]
142
+ }
143
+ },
144
+ "ledger": {
145
+ "appended": [
146
+ {
147
+ "version": 1,
148
+ "kind": "pending",
149
+ "approvalMode": "ledger",
150
+ "op": "migrations",
151
+ "gate": "migrations-wave-1",
152
+ "timestamp": "2026-10-11T00:00:00.000Z",
153
+ "expiresAt": "2026-10-13T00:00:00.000Z",
154
+ "description": "wave 1 (prod): 2 runs, gate never, approval ledger, held by after-plan hook check (t2)",
155
+ "planDigest": "jcs1-sha256:52d1b04601e89971eab0e24094024707e878042be4b79ad476d6230ac5ef383f"
156
+ }
157
+ ],
158
+ "resolved": [],
159
+ "applied": []
160
+ },
161
+ "calls": 5,
162
+ "logs": 2
163
+ },
164
+ {
165
+ "label": "held, approved",
166
+ "job": {
167
+ "wave": 1
168
+ },
169
+ "result": {
170
+ "exitCode": 0,
171
+ "applied": [
172
+ "t1",
173
+ "t2"
174
+ ],
175
+ "failed": [],
176
+ "moved": [],
177
+ "hooks": [
178
+ {
179
+ "moment": "before-plan",
180
+ "name": "lint",
181
+ "exit": 0,
182
+ "outcome": "passed"
183
+ },
184
+ {
185
+ "moment": "after-plan",
186
+ "name": "check",
187
+ "target": "t1",
188
+ "exit": 0,
189
+ "outcome": "passed"
190
+ },
191
+ {
192
+ "moment": "after-plan",
193
+ "name": "check",
194
+ "target": "t2",
195
+ "exit": 1,
196
+ "outcome": "held"
197
+ },
198
+ {
199
+ "moment": "before-apply",
200
+ "name": "backup",
201
+ "exit": 0,
202
+ "outcome": "passed"
203
+ },
204
+ {
205
+ "moment": "after-apply",
206
+ "name": "smoke",
207
+ "exit": 0,
208
+ "outcome": "passed"
209
+ }
210
+ ],
211
+ "decision": {
212
+ "wave": 1,
213
+ "name": "prod",
214
+ "op": "migrations",
215
+ "gate": "migrations-wave-1",
216
+ "policy": "never",
217
+ "approval": "ledger",
218
+ "policySource": "base",
219
+ "base": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
220
+ "digest": "jcs1-sha256:52d1b04601e89971eab0e24094024707e878042be4b79ad476d6230ac5ef383f",
221
+ "members": [
222
+ {
223
+ "member": "t1",
224
+ "planDigest": "sha256:tttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt",
225
+ "op": "migrate"
226
+ },
227
+ {
228
+ "member": "t2",
229
+ "planDigest": "sha256:tttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt",
230
+ "op": "migrate"
231
+ }
232
+ ],
233
+ "status": "approved",
234
+ "hooks": {
235
+ "before-plan": [
236
+ {
237
+ "name": "lint",
238
+ "command": [
239
+ "hook",
240
+ "lint",
241
+ "{runs}"
242
+ ]
243
+ }
244
+ ],
245
+ "after-plan": [
246
+ {
247
+ "name": "check",
248
+ "command": [
249
+ "hook",
250
+ "check",
251
+ "{target}",
252
+ "{plan}"
253
+ ],
254
+ "perRun": true,
255
+ "onFailure": "approve"
256
+ }
257
+ ],
258
+ "before-apply": [
259
+ {
260
+ "name": "backup",
261
+ "command": [
262
+ "hook",
263
+ "backup",
264
+ "{runs}"
265
+ ]
266
+ }
267
+ ],
268
+ "after-apply": [
269
+ {
270
+ "name": "smoke",
271
+ "command": [
272
+ "hook",
273
+ "smoke",
274
+ "{wave}"
275
+ ]
276
+ }
277
+ ]
278
+ },
279
+ "heldBy": [
280
+ "after-plan hook check (t2)"
281
+ ],
282
+ "via": "ledger",
283
+ "approvedBy": "alice",
284
+ "approvedAt": "2026-10-10T00:00:00Z",
285
+ "outcomes": [
286
+ {
287
+ "moment": "before-plan",
288
+ "name": "lint",
289
+ "exit": 0,
290
+ "outcome": "passed"
291
+ },
292
+ {
293
+ "moment": "after-plan",
294
+ "name": "check",
295
+ "target": "t1",
296
+ "exit": 0,
297
+ "outcome": "passed"
298
+ },
299
+ {
300
+ "moment": "after-plan",
301
+ "name": "check",
302
+ "target": "t2",
303
+ "exit": 1,
304
+ "outcome": "held"
305
+ },
306
+ {
307
+ "moment": "before-apply",
308
+ "name": "backup",
309
+ "exit": 0,
310
+ "outcome": "passed"
311
+ },
312
+ {
313
+ "moment": "after-apply",
314
+ "name": "smoke",
315
+ "exit": 0,
316
+ "outcome": "passed"
317
+ }
318
+ ]
319
+ }
320
+ },
321
+ "ledger": {
322
+ "appended": [],
323
+ "resolved": [],
324
+ "applied": []
325
+ },
326
+ "calls": 9,
327
+ "logs": 2
328
+ }
329
+ ],
330
+ "calls": [
331
+ {
332
+ "argv": [
333
+ "hook",
334
+ "lint",
335
+ ".chant/op-waves/migrations/wave-1/runs.json"
336
+ ],
337
+ "env": {
338
+ "CHANT_OP_WAVES": "migrations",
339
+ "CHANT_WAVE": "prod",
340
+ "CHANT_WAVE_NUMBER": "1",
341
+ "CHANT_HOOK": "before-plan",
342
+ "CHANT_RUNS": ".chant/op-waves/migrations/wave-1/runs.json",
343
+ "CHANT_HOLD": ".chant/op-waves/migrations/wave-1/hold.json"
344
+ },
345
+ "read": {
346
+ "CHANT_RUNS": {
347
+ "wave": "prod",
348
+ "number": 1,
349
+ "runs": [
350
+ {
351
+ "target": "t1",
352
+ "op": "migrate"
353
+ },
354
+ {
355
+ "target": "t2",
356
+ "op": "migrate"
357
+ }
358
+ ]
359
+ },
360
+ ".chant/op-waves/migrations/wave-1/runs.json": {
361
+ "wave": "prod",
362
+ "number": 1,
363
+ "runs": [
364
+ {
365
+ "target": "t1",
366
+ "op": "migrate"
367
+ },
368
+ {
369
+ "target": "t2",
370
+ "op": "migrate"
371
+ }
372
+ ]
373
+ }
374
+ }
375
+ },
376
+ {
377
+ "argv": [
378
+ "tool",
379
+ "plan",
380
+ "t1",
381
+ ".chant/op-waves/migrations/wave-1/t1.plan.json"
382
+ ]
383
+ },
384
+ {
385
+ "argv": [
386
+ "tool",
387
+ "plan",
388
+ "t2",
389
+ ".chant/op-waves/migrations/wave-1/t2.plan.json"
390
+ ]
391
+ },
392
+ {
393
+ "argv": [
394
+ "hook",
395
+ "check",
396
+ "t1",
397
+ ".chant/op-waves/migrations/wave-1/t1.plan.json"
398
+ ],
399
+ "env": {
400
+ "CHANT_OP_WAVES": "migrations",
401
+ "CHANT_WAVE": "prod",
402
+ "CHANT_WAVE_NUMBER": "1",
403
+ "CHANT_HOOK": "after-plan",
404
+ "CHANT_RUNS": ".chant/op-waves/migrations/wave-1/runs.json",
405
+ "CHANT_HOLD": ".chant/op-waves/migrations/wave-1/hold.json",
406
+ "CHANT_TARGET": "t1",
407
+ "CHANT_PLAN": ".chant/op-waves/migrations/wave-1/t1.plan.json"
408
+ },
409
+ "read": {
410
+ "CHANT_RUNS": {
411
+ "wave": "prod",
412
+ "number": 1,
413
+ "digest": "jcs1-sha256:52d1b04601e89971eab0e24094024707e878042be4b79ad476d6230ac5ef383f",
414
+ "runs": [
415
+ {
416
+ "target": "t1",
417
+ "op": "migrate",
418
+ "planDigest": "sha256:tttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt"
419
+ },
420
+ {
421
+ "target": "t2",
422
+ "op": "migrate",
423
+ "planDigest": "sha256:tttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt"
424
+ }
425
+ ]
426
+ }
427
+ }
428
+ },
429
+ {
430
+ "argv": [
431
+ "hook",
432
+ "check",
433
+ "t2",
434
+ ".chant/op-waves/migrations/wave-1/t2.plan.json"
435
+ ],
436
+ "env": {
437
+ "CHANT_OP_WAVES": "migrations",
438
+ "CHANT_WAVE": "prod",
439
+ "CHANT_WAVE_NUMBER": "1",
440
+ "CHANT_HOOK": "after-plan",
441
+ "CHANT_RUNS": ".chant/op-waves/migrations/wave-1/runs.json",
442
+ "CHANT_HOLD": ".chant/op-waves/migrations/wave-1/hold.json",
443
+ "CHANT_TARGET": "t2",
444
+ "CHANT_PLAN": ".chant/op-waves/migrations/wave-1/t2.plan.json"
445
+ },
446
+ "read": {
447
+ "CHANT_RUNS": {
448
+ "wave": "prod",
449
+ "number": 1,
450
+ "digest": "jcs1-sha256:52d1b04601e89971eab0e24094024707e878042be4b79ad476d6230ac5ef383f",
451
+ "runs": [
452
+ {
453
+ "target": "t1",
454
+ "op": "migrate",
455
+ "planDigest": "sha256:tttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt"
456
+ },
457
+ {
458
+ "target": "t2",
459
+ "op": "migrate",
460
+ "planDigest": "sha256:tttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt"
461
+ }
462
+ ]
463
+ }
464
+ }
465
+ },
466
+ {
467
+ "argv": [
468
+ "hook",
469
+ "lint",
470
+ ".chant/op-waves/migrations/wave-1/runs.json"
471
+ ],
472
+ "env": {
473
+ "CHANT_OP_WAVES": "migrations",
474
+ "CHANT_WAVE": "prod",
475
+ "CHANT_WAVE_NUMBER": "1",
476
+ "CHANT_HOOK": "before-plan",
477
+ "CHANT_RUNS": ".chant/op-waves/migrations/wave-1/runs.json",
478
+ "CHANT_HOLD": ".chant/op-waves/migrations/wave-1/hold.json"
479
+ },
480
+ "read": {
481
+ "CHANT_RUNS": {
482
+ "wave": "prod",
483
+ "number": 1,
484
+ "runs": [
485
+ {
486
+ "target": "t1",
487
+ "op": "migrate"
488
+ },
489
+ {
490
+ "target": "t2",
491
+ "op": "migrate"
492
+ }
493
+ ]
494
+ },
495
+ ".chant/op-waves/migrations/wave-1/runs.json": {
496
+ "wave": "prod",
497
+ "number": 1,
498
+ "runs": [
499
+ {
500
+ "target": "t1",
501
+ "op": "migrate"
502
+ },
503
+ {
504
+ "target": "t2",
505
+ "op": "migrate"
506
+ }
507
+ ]
508
+ }
509
+ }
510
+ },
511
+ {
512
+ "argv": [
513
+ "tool",
514
+ "plan",
515
+ "t1",
516
+ ".chant/op-waves/migrations/wave-1/t1.plan.json"
517
+ ]
518
+ },
519
+ {
520
+ "argv": [
521
+ "tool",
522
+ "plan",
523
+ "t2",
524
+ ".chant/op-waves/migrations/wave-1/t2.plan.json"
525
+ ]
526
+ },
527
+ {
528
+ "argv": [
529
+ "hook",
530
+ "check",
531
+ "t1",
532
+ ".chant/op-waves/migrations/wave-1/t1.plan.json"
533
+ ],
534
+ "env": {
535
+ "CHANT_OP_WAVES": "migrations",
536
+ "CHANT_WAVE": "prod",
537
+ "CHANT_WAVE_NUMBER": "1",
538
+ "CHANT_HOOK": "after-plan",
539
+ "CHANT_RUNS": ".chant/op-waves/migrations/wave-1/runs.json",
540
+ "CHANT_HOLD": ".chant/op-waves/migrations/wave-1/hold.json",
541
+ "CHANT_TARGET": "t1",
542
+ "CHANT_PLAN": ".chant/op-waves/migrations/wave-1/t1.plan.json"
543
+ },
544
+ "read": {
545
+ "CHANT_RUNS": {
546
+ "wave": "prod",
547
+ "number": 1,
548
+ "digest": "jcs1-sha256:52d1b04601e89971eab0e24094024707e878042be4b79ad476d6230ac5ef383f",
549
+ "runs": [
550
+ {
551
+ "target": "t1",
552
+ "op": "migrate",
553
+ "planDigest": "sha256:tttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt"
554
+ },
555
+ {
556
+ "target": "t2",
557
+ "op": "migrate",
558
+ "planDigest": "sha256:tttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt"
559
+ }
560
+ ]
561
+ }
562
+ }
563
+ },
564
+ {
565
+ "argv": [
566
+ "hook",
567
+ "check",
568
+ "t2",
569
+ ".chant/op-waves/migrations/wave-1/t2.plan.json"
570
+ ],
571
+ "env": {
572
+ "CHANT_OP_WAVES": "migrations",
573
+ "CHANT_WAVE": "prod",
574
+ "CHANT_WAVE_NUMBER": "1",
575
+ "CHANT_HOOK": "after-plan",
576
+ "CHANT_RUNS": ".chant/op-waves/migrations/wave-1/runs.json",
577
+ "CHANT_HOLD": ".chant/op-waves/migrations/wave-1/hold.json",
578
+ "CHANT_TARGET": "t2",
579
+ "CHANT_PLAN": ".chant/op-waves/migrations/wave-1/t2.plan.json"
580
+ },
581
+ "read": {
582
+ "CHANT_RUNS": {
583
+ "wave": "prod",
584
+ "number": 1,
585
+ "digest": "jcs1-sha256:52d1b04601e89971eab0e24094024707e878042be4b79ad476d6230ac5ef383f",
586
+ "runs": [
587
+ {
588
+ "target": "t1",
589
+ "op": "migrate",
590
+ "planDigest": "sha256:tttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt"
591
+ },
592
+ {
593
+ "target": "t2",
594
+ "op": "migrate",
595
+ "planDigest": "sha256:tttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt"
596
+ }
597
+ ]
598
+ }
599
+ }
600
+ },
601
+ {
602
+ "argv": [
603
+ "hook",
604
+ "backup",
605
+ ".chant/op-waves/migrations/wave-1/runs.json"
606
+ ],
607
+ "env": {
608
+ "CHANT_OP_WAVES": "migrations",
609
+ "CHANT_WAVE": "prod",
610
+ "CHANT_WAVE_NUMBER": "1",
611
+ "CHANT_HOOK": "before-apply",
612
+ "CHANT_RUNS": ".chant/op-waves/migrations/wave-1/runs.json",
613
+ "CHANT_HOLD": ".chant/op-waves/migrations/wave-1/hold.json"
614
+ },
615
+ "read": {
616
+ "CHANT_RUNS": {
617
+ "wave": "prod",
618
+ "number": 1,
619
+ "digest": "jcs1-sha256:52d1b04601e89971eab0e24094024707e878042be4b79ad476d6230ac5ef383f",
620
+ "runs": [
621
+ {
622
+ "target": "t1",
623
+ "op": "migrate",
624
+ "planDigest": "sha256:tttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt"
625
+ },
626
+ {
627
+ "target": "t2",
628
+ "op": "migrate",
629
+ "planDigest": "sha256:tttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt"
630
+ }
631
+ ]
632
+ },
633
+ ".chant/op-waves/migrations/wave-1/runs.json": {
634
+ "wave": "prod",
635
+ "number": 1,
636
+ "digest": "jcs1-sha256:52d1b04601e89971eab0e24094024707e878042be4b79ad476d6230ac5ef383f",
637
+ "runs": [
638
+ {
639
+ "target": "t1",
640
+ "op": "migrate",
641
+ "planDigest": "sha256:tttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt"
642
+ },
643
+ {
644
+ "target": "t2",
645
+ "op": "migrate",
646
+ "planDigest": "sha256:tttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt"
647
+ }
648
+ ]
649
+ }
650
+ }
651
+ },
652
+ {
653
+ "argv": [
654
+ "tool",
655
+ "apply",
656
+ "t1",
657
+ ".chant/op-waves/migrations/wave-1/t1.plan.json"
658
+ ],
659
+ "env": {
660
+ "CHANT_HOOKS": ".chant/op-waves/migrations/wave-1/t1.hooks.json",
661
+ "CHANT_APPLY_OUTCOME": ".chant/op-waves/migrations/wave-1/t1.hooks-outcome.json"
662
+ },
663
+ "read": {
664
+ "CHANT_HOOKS": {
665
+ "version": 1,
666
+ "opWaves": "migrations",
667
+ "op": "migrate",
668
+ "wave": "prod",
669
+ "number": 1,
670
+ "base": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
671
+ "digest": "jcs1-sha256:52d1b04601e89971eab0e24094024707e878042be4b79ad476d6230ac5ef383f",
672
+ "approved": true,
673
+ "heldBy": [
674
+ "after-plan hook check (t2)"
675
+ ],
676
+ "runBy": "chant",
677
+ "runs": [
678
+ {
679
+ "target": "t1",
680
+ "op": "migrate",
681
+ "plan": ".chant/op-waves/migrations/wave-1/t1.plan.json"
682
+ }
683
+ ],
684
+ "runsFile": ".chant/op-waves/migrations/wave-1/runs.json",
685
+ "hooks": {},
686
+ "outcomes": [
687
+ {
688
+ "moment": "before-plan",
689
+ "name": "lint",
690
+ "exit": 0,
691
+ "outcome": "passed"
692
+ },
693
+ {
694
+ "moment": "after-plan",
695
+ "name": "check",
696
+ "target": "t1",
697
+ "exit": 0,
698
+ "outcome": "passed"
699
+ },
700
+ {
701
+ "moment": "after-plan",
702
+ "name": "check",
703
+ "target": "t2",
704
+ "exit": 1,
705
+ "outcome": "held"
706
+ },
707
+ {
708
+ "moment": "before-apply",
709
+ "name": "backup",
710
+ "exit": 0,
711
+ "outcome": "passed"
712
+ }
713
+ ]
714
+ }
715
+ }
716
+ },
717
+ {
718
+ "argv": [
719
+ "tool",
720
+ "apply",
721
+ "t2",
722
+ ".chant/op-waves/migrations/wave-1/t2.plan.json"
723
+ ],
724
+ "env": {
725
+ "CHANT_HOOKS": ".chant/op-waves/migrations/wave-1/t2.hooks.json",
726
+ "CHANT_APPLY_OUTCOME": ".chant/op-waves/migrations/wave-1/t2.hooks-outcome.json"
727
+ },
728
+ "read": {
729
+ "CHANT_HOOKS": {
730
+ "version": 1,
731
+ "opWaves": "migrations",
732
+ "op": "migrate",
733
+ "wave": "prod",
734
+ "number": 1,
735
+ "base": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
736
+ "digest": "jcs1-sha256:52d1b04601e89971eab0e24094024707e878042be4b79ad476d6230ac5ef383f",
737
+ "approved": true,
738
+ "heldBy": [
739
+ "after-plan hook check (t2)"
740
+ ],
741
+ "runBy": "chant",
742
+ "runs": [
743
+ {
744
+ "target": "t2",
745
+ "op": "migrate",
746
+ "plan": ".chant/op-waves/migrations/wave-1/t2.plan.json"
747
+ }
748
+ ],
749
+ "runsFile": ".chant/op-waves/migrations/wave-1/runs.json",
750
+ "hooks": {},
751
+ "outcomes": [
752
+ {
753
+ "moment": "before-plan",
754
+ "name": "lint",
755
+ "exit": 0,
756
+ "outcome": "passed"
757
+ },
758
+ {
759
+ "moment": "after-plan",
760
+ "name": "check",
761
+ "target": "t1",
762
+ "exit": 0,
763
+ "outcome": "passed"
764
+ },
765
+ {
766
+ "moment": "after-plan",
767
+ "name": "check",
768
+ "target": "t2",
769
+ "exit": 1,
770
+ "outcome": "held"
771
+ },
772
+ {
773
+ "moment": "before-apply",
774
+ "name": "backup",
775
+ "exit": 0,
776
+ "outcome": "passed"
777
+ }
778
+ ]
779
+ }
780
+ }
781
+ },
782
+ {
783
+ "argv": [
784
+ "hook",
785
+ "smoke",
786
+ "prod"
787
+ ],
788
+ "env": {
789
+ "CHANT_OP_WAVES": "migrations",
790
+ "CHANT_WAVE": "prod",
791
+ "CHANT_WAVE_NUMBER": "1",
792
+ "CHANT_HOOK": "after-apply",
793
+ "CHANT_RUNS": ".chant/op-waves/migrations/wave-1/runs.json",
794
+ "CHANT_HOLD": ".chant/op-waves/migrations/wave-1/hold.json"
795
+ },
796
+ "read": {
797
+ "CHANT_RUNS": {
798
+ "wave": "prod",
799
+ "number": 1,
800
+ "digest": "jcs1-sha256:52d1b04601e89971eab0e24094024707e878042be4b79ad476d6230ac5ef383f",
801
+ "runs": [
802
+ {
803
+ "target": "t1",
804
+ "op": "migrate",
805
+ "planDigest": "sha256:tttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt"
806
+ },
807
+ {
808
+ "target": "t2",
809
+ "op": "migrate",
810
+ "planDigest": "sha256:tttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt"
811
+ }
812
+ ]
813
+ }
814
+ }
815
+ }
816
+ ],
817
+ "logs": [
818
+ "after-plan hook check (t2) exited 1, so wave 1 (prod) waits for an approval of its set digest",
819
+ "Nothing in wave 1 or after it ran. Read the plans, then approve: chant approve migrations migrations-wave-1 --plan jcs1-sha256:52d1b04601e89971eab0e24094024707e878042be4b79ad476d6230ac5ef383f (with --resume, the approval also starts this job again)",
820
+ "after-plan hook check (t2) exited 1, so wave 1 (prod) waits for an approval of its set digest",
821
+ "wave 1 (prod): gate never (read at bbbbbbbbbbbb), digest jcs1-sha256:52d1b04601e89971eab0e24094024707e878042be4b79ad476d6230ac5ef383f: approved by alice; held by after-plan hook check (t2)"
822
+ ],
823
+ "files": {
824
+ ".chant/op-waves/migrations/wave-1/runs.json": {
825
+ "wave": "prod",
826
+ "number": 1,
827
+ "digest": "jcs1-sha256:52d1b04601e89971eab0e24094024707e878042be4b79ad476d6230ac5ef383f",
828
+ "runs": [
829
+ {
830
+ "target": "t1",
831
+ "op": "migrate",
832
+ "planDigest": "sha256:tttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt"
833
+ },
834
+ {
835
+ "target": "t2",
836
+ "op": "migrate",
837
+ "planDigest": "sha256:tttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt"
838
+ }
839
+ ]
840
+ },
841
+ ".chant/op-waves/migrations/wave-1/t1.hooks.json": {
842
+ "version": 1,
843
+ "opWaves": "migrations",
844
+ "op": "migrate",
845
+ "wave": "prod",
846
+ "number": 1,
847
+ "base": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
848
+ "digest": "jcs1-sha256:52d1b04601e89971eab0e24094024707e878042be4b79ad476d6230ac5ef383f",
849
+ "approved": true,
850
+ "heldBy": [
851
+ "after-plan hook check (t2)"
852
+ ],
853
+ "runBy": "chant",
854
+ "runs": [
855
+ {
856
+ "target": "t1",
857
+ "op": "migrate",
858
+ "plan": ".chant/op-waves/migrations/wave-1/t1.plan.json"
859
+ }
860
+ ],
861
+ "runsFile": ".chant/op-waves/migrations/wave-1/runs.json",
862
+ "hooks": {},
863
+ "outcomes": [
864
+ {
865
+ "moment": "before-plan",
866
+ "name": "lint",
867
+ "exit": 0,
868
+ "outcome": "passed"
869
+ },
870
+ {
871
+ "moment": "after-plan",
872
+ "name": "check",
873
+ "target": "t1",
874
+ "exit": 0,
875
+ "outcome": "passed"
876
+ },
877
+ {
878
+ "moment": "after-plan",
879
+ "name": "check",
880
+ "target": "t2",
881
+ "exit": 1,
882
+ "outcome": "held"
883
+ },
884
+ {
885
+ "moment": "before-apply",
886
+ "name": "backup",
887
+ "exit": 0,
888
+ "outcome": "passed"
889
+ }
890
+ ]
891
+ },
892
+ ".chant/op-waves/migrations/wave-1/t1.plan.json": {
893
+ "planDigest": "sha256:tttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt"
894
+ },
895
+ ".chant/op-waves/migrations/wave-1/t2.hooks.json": {
896
+ "version": 1,
897
+ "opWaves": "migrations",
898
+ "op": "migrate",
899
+ "wave": "prod",
900
+ "number": 1,
901
+ "base": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
902
+ "digest": "jcs1-sha256:52d1b04601e89971eab0e24094024707e878042be4b79ad476d6230ac5ef383f",
903
+ "approved": true,
904
+ "heldBy": [
905
+ "after-plan hook check (t2)"
906
+ ],
907
+ "runBy": "chant",
908
+ "runs": [
909
+ {
910
+ "target": "t2",
911
+ "op": "migrate",
912
+ "plan": ".chant/op-waves/migrations/wave-1/t2.plan.json"
913
+ }
914
+ ],
915
+ "runsFile": ".chant/op-waves/migrations/wave-1/runs.json",
916
+ "hooks": {},
917
+ "outcomes": [
918
+ {
919
+ "moment": "before-plan",
920
+ "name": "lint",
921
+ "exit": 0,
922
+ "outcome": "passed"
923
+ },
924
+ {
925
+ "moment": "after-plan",
926
+ "name": "check",
927
+ "target": "t1",
928
+ "exit": 0,
929
+ "outcome": "passed"
930
+ },
931
+ {
932
+ "moment": "after-plan",
933
+ "name": "check",
934
+ "target": "t2",
935
+ "exit": 1,
936
+ "outcome": "held"
937
+ },
938
+ {
939
+ "moment": "before-apply",
940
+ "name": "backup",
941
+ "exit": 0,
942
+ "outcome": "passed"
943
+ }
944
+ ]
945
+ },
946
+ ".chant/op-waves/migrations/wave-1/t2.plan.json": {
947
+ "planDigest": "sha256:tttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt"
948
+ },
949
+ ".chant/op-waves/migrations/wave-1.json": {
950
+ "wave": 1,
951
+ "name": "prod",
952
+ "op": "migrations",
953
+ "gate": "migrations-wave-1",
954
+ "policy": "never",
955
+ "approval": "ledger",
956
+ "policySource": "base",
957
+ "base": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
958
+ "digest": "jcs1-sha256:52d1b04601e89971eab0e24094024707e878042be4b79ad476d6230ac5ef383f",
959
+ "members": [
960
+ {
961
+ "member": "t1",
962
+ "planDigest": "sha256:tttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt",
963
+ "op": "migrate"
964
+ },
965
+ {
966
+ "member": "t2",
967
+ "planDigest": "sha256:tttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt",
968
+ "op": "migrate"
969
+ }
970
+ ],
971
+ "status": "approved",
972
+ "hooks": {
973
+ "before-plan": [
974
+ {
975
+ "name": "lint",
976
+ "command": [
977
+ "hook",
978
+ "lint",
979
+ "{runs}"
980
+ ]
981
+ }
982
+ ],
983
+ "after-plan": [
984
+ {
985
+ "name": "check",
986
+ "command": [
987
+ "hook",
988
+ "check",
989
+ "{target}",
990
+ "{plan}"
991
+ ],
992
+ "perRun": true,
993
+ "onFailure": "approve"
994
+ }
995
+ ],
996
+ "before-apply": [
997
+ {
998
+ "name": "backup",
999
+ "command": [
1000
+ "hook",
1001
+ "backup",
1002
+ "{runs}"
1003
+ ]
1004
+ }
1005
+ ],
1006
+ "after-apply": [
1007
+ {
1008
+ "name": "smoke",
1009
+ "command": [
1010
+ "hook",
1011
+ "smoke",
1012
+ "{wave}"
1013
+ ]
1014
+ }
1015
+ ]
1016
+ },
1017
+ "heldBy": [
1018
+ "after-plan hook check (t2)"
1019
+ ],
1020
+ "via": "ledger",
1021
+ "approvedBy": "alice",
1022
+ "approvedAt": "2026-10-10T00:00:00Z",
1023
+ "outcomes": [
1024
+ {
1025
+ "moment": "before-plan",
1026
+ "name": "lint",
1027
+ "exit": 0,
1028
+ "outcome": "passed"
1029
+ },
1030
+ {
1031
+ "moment": "after-plan",
1032
+ "name": "check",
1033
+ "target": "t1",
1034
+ "exit": 0,
1035
+ "outcome": "passed"
1036
+ },
1037
+ {
1038
+ "moment": "after-plan",
1039
+ "name": "check",
1040
+ "target": "t2",
1041
+ "exit": 1,
1042
+ "outcome": "held"
1043
+ },
1044
+ {
1045
+ "moment": "before-apply",
1046
+ "name": "backup",
1047
+ "exit": 0,
1048
+ "outcome": "passed"
1049
+ },
1050
+ {
1051
+ "moment": "after-apply",
1052
+ "name": "smoke",
1053
+ "exit": 0,
1054
+ "outcome": "passed"
1055
+ }
1056
+ ]
1057
+ }
1058
+ }
1059
+ }