@usine/engine 0.3.0 → 0.5.0

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 (201) hide show
  1. package/LICENSE +661 -21
  2. package/README.md +112 -38
  3. package/dist/board-moves/board-moves.d.ts +20 -0
  4. package/dist/board-moves/board-moves.d.ts.map +1 -0
  5. package/dist/board-moves/board-moves.js +74 -0
  6. package/dist/board-moves/board-moves.js.map +1 -0
  7. package/dist/board-moves/model.d.ts +21 -0
  8. package/dist/board-moves/model.d.ts.map +1 -0
  9. package/dist/board-moves/model.js +22 -0
  10. package/dist/board-moves/model.js.map +1 -0
  11. package/dist/cursor/cursor.d.ts +2 -6
  12. package/dist/cursor/cursor.d.ts.map +1 -1
  13. package/dist/cursor/cursor.js +2 -6
  14. package/dist/cursor/cursor.js.map +1 -1
  15. package/dist/cycle-budget/cycle-budget.d.ts +14 -8
  16. package/dist/cycle-budget/cycle-budget.d.ts.map +1 -1
  17. package/dist/cycle-budget/cycle-budget.js +51 -10
  18. package/dist/cycle-budget/cycle-budget.js.map +1 -1
  19. package/dist/cycle-budget/model.d.ts +6 -2
  20. package/dist/cycle-budget/model.d.ts.map +1 -1
  21. package/dist/cycle-budget/model.js +5 -2
  22. package/dist/cycle-budget/model.js.map +1 -1
  23. package/dist/cycle-budget/queries.d.ts +1 -1
  24. package/dist/cycle-budget/queries.d.ts.map +1 -1
  25. package/dist/cycle-budget/queries.js +3 -3
  26. package/dist/cycle-budget/queries.js.map +1 -1
  27. package/dist/database/database.d.ts +1 -1
  28. package/dist/database/database.d.ts.map +1 -1
  29. package/dist/database/local-sqlite.d.ts +13 -10
  30. package/dist/database/local-sqlite.d.ts.map +1 -1
  31. package/dist/database/local-sqlite.js +22 -17
  32. package/dist/database/local-sqlite.js.map +1 -1
  33. package/dist/database/schema.d.ts +668 -36
  34. package/dist/database/schema.d.ts.map +1 -1
  35. package/dist/database/schema.js +123 -23
  36. package/dist/database/schema.js.map +1 -1
  37. package/dist/{workflow → engine}/admission.d.ts +2 -2
  38. package/dist/engine/admission.d.ts.map +1 -0
  39. package/dist/{workflow → engine}/admission.js +4 -4
  40. package/dist/engine/admission.js.map +1 -0
  41. package/dist/engine/checkout-recovery.d.ts +79 -0
  42. package/dist/engine/checkout-recovery.d.ts.map +1 -0
  43. package/dist/engine/checkout-recovery.js +238 -0
  44. package/dist/engine/checkout-recovery.js.map +1 -0
  45. package/dist/engine/engine.d.ts +67 -26
  46. package/dist/engine/engine.d.ts.map +1 -1
  47. package/dist/engine/engine.js +136 -129
  48. package/dist/engine/engine.js.map +1 -1
  49. package/dist/engine/error.d.ts +29 -10
  50. package/dist/engine/error.d.ts.map +1 -1
  51. package/dist/engine/error.js +28 -8
  52. package/dist/engine/error.js.map +1 -1
  53. package/dist/engine/lifecycle.d.ts +83 -28
  54. package/dist/engine/lifecycle.d.ts.map +1 -1
  55. package/dist/engine/lifecycle.js +94 -45
  56. package/dist/engine/lifecycle.js.map +1 -1
  57. package/dist/engine/retry.d.ts +16 -0
  58. package/dist/engine/retry.d.ts.map +1 -0
  59. package/dist/engine/retry.js +18 -0
  60. package/dist/engine/retry.js.map +1 -0
  61. package/dist/engine/run-again.d.ts +45 -0
  62. package/dist/engine/run-again.d.ts.map +1 -0
  63. package/dist/engine/run-again.js +56 -0
  64. package/dist/engine/run-again.js.map +1 -0
  65. package/dist/engine/run-driver.d.ts +68 -0
  66. package/dist/engine/run-driver.d.ts.map +1 -0
  67. package/dist/engine/run-driver.js +448 -0
  68. package/dist/engine/run-driver.js.map +1 -0
  69. package/dist/engine/shutdown.d.ts +3 -4
  70. package/dist/engine/shutdown.d.ts.map +1 -1
  71. package/dist/engine/shutdown.js +3 -4
  72. package/dist/engine/shutdown.js.map +1 -1
  73. package/dist/engine/submission.d.ts +31 -11
  74. package/dist/engine/submission.d.ts.map +1 -1
  75. package/dist/engine/submission.js +43 -12
  76. package/dist/engine/submission.js.map +1 -1
  77. package/dist/engine/unconfirmed-stops.d.ts +27 -0
  78. package/dist/engine/unconfirmed-stops.d.ts.map +1 -0
  79. package/dist/engine/unconfirmed-stops.js +26 -0
  80. package/dist/engine/unconfirmed-stops.js.map +1 -0
  81. package/dist/item-projection/item-projection.d.ts +14 -4
  82. package/dist/item-projection/item-projection.d.ts.map +1 -1
  83. package/dist/item-projection/item-projection.js +60 -14
  84. package/dist/item-projection/item-projection.js.map +1 -1
  85. package/dist/item-projection/model.d.ts +5 -1
  86. package/dist/item-projection/model.d.ts.map +1 -1
  87. package/dist/item-projection/model.js +6 -2
  88. package/dist/item-projection/model.js.map +1 -1
  89. package/dist/loop-control/loop-control.d.ts +5 -5
  90. package/dist/loop-control/loop-control.d.ts.map +1 -1
  91. package/dist/loop-control/loop-control.js +4 -4
  92. package/dist/loop-control/loop-control.js.map +1 -1
  93. package/dist/loop-control/model.d.ts +1 -1
  94. package/dist/loop-control/model.d.ts.map +1 -1
  95. package/dist/loop-control/model.js +1 -1
  96. package/dist/loop-control/model.js.map +1 -1
  97. package/dist/repository-label-projection/model.d.ts +2 -2
  98. package/dist/repository-label-projection/model.d.ts.map +1 -1
  99. package/dist/repository-label-projection/model.js +2 -2
  100. package/dist/repository-label-projection/model.js.map +1 -1
  101. package/dist/repository-label-projection/repository-label-projection.d.ts +1 -1
  102. package/dist/repository-label-projection/repository-label-projection.d.ts.map +1 -1
  103. package/dist/repository-label-projection/repository-label-projection.js +1 -1
  104. package/dist/repository-label-projection/repository-label-projection.js.map +1 -1
  105. package/dist/run-reader/model.d.ts +62 -4
  106. package/dist/run-reader/model.d.ts.map +1 -1
  107. package/dist/run-reader/model.js +66 -7
  108. package/dist/run-reader/model.js.map +1 -1
  109. package/dist/run-reader/run-reader.d.ts +25 -10
  110. package/dist/run-reader/run-reader.d.ts.map +1 -1
  111. package/dist/run-reader/run-reader.js +25 -7
  112. package/dist/run-reader/run-reader.js.map +1 -1
  113. package/dist/step-executor.d.ts +86 -13
  114. package/dist/step-executor.d.ts.map +1 -1
  115. package/dist/step-executor.js +10 -2
  116. package/dist/step-executor.js.map +1 -1
  117. package/dist/store/attempt-windows.d.ts +8 -0
  118. package/dist/store/attempt-windows.d.ts.map +1 -0
  119. package/dist/store/attempt-windows.js +53 -0
  120. package/dist/store/attempt-windows.js.map +1 -0
  121. package/dist/store/codec.d.ts +242 -43
  122. package/dist/store/codec.d.ts.map +1 -1
  123. package/dist/store/codec.js +61 -16
  124. package/dist/store/codec.js.map +1 -1
  125. package/dist/store/leftovers.d.ts +10 -0
  126. package/dist/store/leftovers.d.ts.map +1 -0
  127. package/dist/store/leftovers.js +43 -0
  128. package/dist/store/leftovers.js.map +1 -0
  129. package/dist/store/loop-items.d.ts +16 -0
  130. package/dist/store/loop-items.d.ts.map +1 -0
  131. package/dist/store/loop-items.js +185 -0
  132. package/dist/store/loop-items.js.map +1 -0
  133. package/dist/store/queries.d.ts +385 -36
  134. package/dist/store/queries.d.ts.map +1 -1
  135. package/dist/store/queries.js +355 -107
  136. package/dist/store/queries.js.map +1 -1
  137. package/dist/store/store.d.ts +106 -54
  138. package/dist/store/store.d.ts.map +1 -1
  139. package/dist/store/store.js +497 -190
  140. package/dist/store/store.js.map +1 -1
  141. package/dist/store/transcript.d.ts +3 -3
  142. package/dist/store/transcript.d.ts.map +1 -1
  143. package/dist/store/transcript.js +25 -6
  144. package/dist/store/transcript.js.map +1 -1
  145. package/dist/transcript.d.ts +19 -20
  146. package/dist/transcript.d.ts.map +1 -1
  147. package/dist/transcript.js +23 -21
  148. package/dist/transcript.js.map +1 -1
  149. package/dist/trigger-condition.d.ts +23 -0
  150. package/dist/trigger-condition.d.ts.map +1 -0
  151. package/dist/trigger-condition.js +8 -0
  152. package/dist/trigger-condition.js.map +1 -0
  153. package/drizzle/20260917071139_resolve_run_failure/migration.sql +1 -0
  154. package/drizzle/20260917071139_resolve_run_failure/snapshot.json +1471 -0
  155. package/drizzle/20260918032643_attempt_salvage/migration.sql +1 -0
  156. package/drizzle/20260918032643_attempt_salvage/snapshot.json +1481 -0
  157. package/drizzle/20261011153856_drop_workflow_tables/migration.sql +4 -0
  158. package/drizzle/20261011153856_drop_workflow_tables/snapshot.json +1433 -0
  159. package/drizzle/20261017155043_attempt_salvage_check/migration.sql +41 -0
  160. package/drizzle/20261017155043_attempt_salvage_check/snapshot.json +1421 -0
  161. package/drizzle/20261018162700_discard_attempt_leftovers/migration.sql +1 -0
  162. package/drizzle/20261018162700_discard_attempt_leftovers/snapshot.json +1431 -0
  163. package/drizzle/20261018172605_loop_items_and_reopenings/migration.sql +15 -0
  164. package/drizzle/20261018172605_loop_items_and_reopenings/snapshot.json +1574 -0
  165. package/drizzle/20261018180339_attempt_ended_at/migration.sql +1 -0
  166. package/drizzle/20261018180339_attempt_ended_at/snapshot.json +1584 -0
  167. package/drizzle/20261019104043_run_approval_source/migration.sql +15 -0
  168. package/drizzle/20261019104043_run_approval_source/snapshot.json +1610 -0
  169. package/drizzle/20261019133538_board_moves/migration.sql +14 -0
  170. package/drizzle/20261019133538_board_moves/snapshot.json +1731 -0
  171. package/drizzle/20261019170538_item_projection_gone/migration.sql +1 -0
  172. package/drizzle/20261019170538_item_projection_gone/snapshot.json +1741 -0
  173. package/drizzle/20261019180649_run_again_events/migration.sql +7 -0
  174. package/drizzle/20261019180649_run_again_events/snapshot.json +1804 -0
  175. package/drizzle/20261019185008_trigger_event_permissions/migration.sql +1 -0
  176. package/drizzle/20261019185008_trigger_event_permissions/snapshot.json +1814 -0
  177. package/drizzle/20261020103746_attempt_start/migration.sql +5 -0
  178. package/drizzle/20261020103746_attempt_start/snapshot.json +1844 -0
  179. package/drizzle/20261020125211_attempt_comments/migration.sql +1 -0
  180. package/drizzle/20261020125211_attempt_comments/snapshot.json +1854 -0
  181. package/drizzle/20261020191320_run_closed_at/migration.sql +6 -0
  182. package/drizzle/20261020191320_run_closed_at/snapshot.json +1864 -0
  183. package/drizzle/20261023091428_rename_loop_item_hold_to_suppression/migration.sql +2 -0
  184. package/drizzle/20261023091428_rename_loop_item_hold_to_suppression/snapshot.json +1867 -0
  185. package/drizzle/20261024162954_cycle_ask_closures/migration.sql +10 -0
  186. package/drizzle/20261024162954_cycle_ask_closures/snapshot.json +1948 -0
  187. package/drizzle/20261027104206_attempt_out_of_memory/migration.sql +1 -0
  188. package/drizzle/20261027104206_attempt_out_of_memory/snapshot.json +1958 -0
  189. package/drizzle/20261027191944_failure_resolution/migration.sql +1 -0
  190. package/drizzle/20261027191944_failure_resolution/snapshot.json +1968 -0
  191. package/package.json +22 -12
  192. package/dist/workflow/admission.d.ts.map +0 -1
  193. package/dist/workflow/admission.js.map +0 -1
  194. package/dist/workflow/command.d.ts +0 -13
  195. package/dist/workflow/command.d.ts.map +0 -1
  196. package/dist/workflow/command.js +0 -17
  197. package/dist/workflow/command.js.map +0 -1
  198. package/dist/workflow/workflow.d.ts +0 -18
  199. package/dist/workflow/workflow.d.ts.map +0 -1
  200. package/dist/workflow/workflow.js +0 -108
  201. package/dist/workflow/workflow.js.map +0 -1
@@ -0,0 +1,238 @@
1
+ import { AttemptId } from "@usine/core/attempt";
2
+ import { WorkerName } from "@usine/core/worker";
3
+ import { Array as EffectArray, Effect, Option, Ref, Result, Schema } from "effect";
4
+ /**
5
+ * An error for an Attempt whose parent task couldn't be confirmed stopped. Its slot of `worker`,
6
+ * and any checkout startup kept, stay kept, and the Run's next Attempt doesn't start.
7
+ */
8
+ class ParentStopUnconfirmedError extends Schema.TaggedError("@usine/engine/internal/ParentStopUnconfirmedError")("ParentStopUnconfirmedError", {
9
+ attemptId: AttemptId,
10
+ worker: WorkerName,
11
+ cause: Schema.Defect(),
12
+ }) {
13
+ }
14
+ /** Returns `map` without `key`. */
15
+ export const without = (map, key) => {
16
+ const remaining = new Map(map);
17
+ remaining.delete(key);
18
+ return remaining;
19
+ };
20
+ /**
21
+ * Creates the checkout recovery steps that `RunDriver` uses at startup, on reattach, and on cancel.
22
+ *
23
+ * `atStartup` reconciles the checkouts left on Workers through `StepExecutor.recover`. It keeps
24
+ * the checkout, and occupies a Worker slot through `StepExecutor.occupy` (#177), for an open
25
+ * Attempt whose parent task is live or unreadable and for a closed Attempt whose parent task
26
+ * isn't confirmed stopped. `acquired` hands a kept checkout and slot to the reattaching
27
+ * execution. `hold` keeps the slot of an Attempt whose parent task may still run after a cancel
28
+ * or a failure (#475, #512). `reconcile` reconciles a kept checkout that the Run closes without
29
+ * that hand-off (#180), and releases the slot once the parent task is confirmed stopped.
30
+ */
31
+ export const checkoutRecoveryFor = Effect.fn("CheckoutRecovery.for")(function* (store, executor) {
32
+ // The slots of Attempts whose parent task may still run, by Attempt.
33
+ const kept = yield* Ref.make(new Map());
34
+ /** Reconciles `attempt`'s checkout. On failure, logs an error and leaves the checkout on its Worker. */
35
+ const recover = (attempt) => executor
36
+ .recover(attempt, {
37
+ salvage: (salvage) => store.recordSalvage(attempt.attemptId, salvage),
38
+ comments: (comments) => store.recordComments(attempt.attemptId, comments),
39
+ windows: store.attemptWindows(attempt.attemptId),
40
+ })
41
+ .pipe(Effect.tapError((error) => Effect.logError("Attempt salvage reconciliation failed; work retained", {
42
+ attemptId: attempt.attemptId,
43
+ worker: attempt.worker,
44
+ message: String(error),
45
+ })), Effect.ignore);
46
+ /**
47
+ * Keeps `attempt`'s checkout and occupies a slot on its Worker, recording the lease in the same
48
+ * uninterruptible step.
49
+ */
50
+ const keep = Effect.fn("CheckoutRecovery.keep")(function* (attempt) {
51
+ yield* executor.occupy(attempt.worker, attempt.attemptId).pipe(Effect.flatMap((lease) => Effect.cached(lease.release).pipe(Effect.map((release) => ({
52
+ worker: lease.worker,
53
+ release,
54
+ checkoutKept: true,
55
+ })))), Effect.flatMap((occupied) => Ref.update(kept, (leases) => new Map(leases).set(attempt.attemptId, occupied))), Effect.uninterruptible);
56
+ });
57
+ /**
58
+ * Keeps the checkout and a slot for an open Attempt whose parent task is live or whose liveness
59
+ * can't be read. Otherwise reconciles the checkout.
60
+ */
61
+ const recoverOpen = Effect.fn("CheckoutRecovery.recoverOpen")(function* (attempt) {
62
+ const fields = { attemptId: attempt.attemptId, worker: attempt.worker };
63
+ yield* Effect.annotateCurrentSpan(fields);
64
+ const live = yield* executor.isLive(attempt.attemptId).pipe(Effect.result);
65
+ if (Result.isSuccess(live) && !live.success)
66
+ return yield* recover(attempt);
67
+ if (Result.isFailure(live))
68
+ yield* Effect.logWarning("Could not read whether an open Attempt's parent task is live; its checkout stays for its Run to decide", { ...fields, errorTag: live.failure._tag, message: live.failure.message });
69
+ else
70
+ yield* Effect.logInfo("Leaving the checkout of an open Attempt whose parent task is live for its Run to reattach", fields);
71
+ yield* keep(attempt);
72
+ yield* Effect.logInfo("Occupied a slot on the Worker of an open Attempt kept for its Run to reattach", fields);
73
+ });
74
+ /**
75
+ * Reconciles a closed Attempt's checkout if its parent task is confirmed stopped. Otherwise
76
+ * keeps the checkout and a slot, and returns the Attempt (#177).
77
+ */
78
+ const recoverClosed = Effect.fn("CheckoutRecovery.recoverClosed")(function* (attempt) {
79
+ const fields = { attemptId: attempt.attemptId, runId: attempt.runId, worker: attempt.worker };
80
+ yield* Effect.annotateCurrentSpan(fields);
81
+ // `recover` also stops the task, but its failure doesn't distinguish an unconfirmed stop from
82
+ // a failed salvage.
83
+ const stopped = yield* executor.interrupt(attempt.attemptId, "startup").pipe(Effect.result);
84
+ if (Result.isSuccess(stopped)) {
85
+ yield* recover(attempt);
86
+ return Option.none();
87
+ }
88
+ yield* Effect.logWarning("Could not confirm that the parent task of a closed Attempt stopped; its checkout and a slot of its Worker stay kept, and no Attempt starts on its Loop's Item, until a reconcile confirms the stop", { ...fields, errorTag: stopped.failure._tag, message: stopped.failure.message });
89
+ yield* keep(attempt);
90
+ return Option.some(attempt);
91
+ });
92
+ /**
93
+ * Reconciles every persisted Attempt on a configured Worker. Returns the closed Attempts whose
94
+ * parent task isn't confirmed stopped.
95
+ */
96
+ const atStartup = Effect.fn("CheckoutRecovery.atStartup")(function* () {
97
+ const configured = new Set(yield* executor.workers);
98
+ const candidates = yield* store.salvageCandidates;
99
+ const reconcilable = candidates.filter(({ worker }) => configured.has(worker));
100
+ const unconfigured = candidates.filter(({ worker }) => !configured.has(worker));
101
+ if (unconfigured.length > 0) {
102
+ yield* Effect.logWarning("Attempts recorded on Workers that are not configured were not reconciled; their checkouts stay until those Workers are configured again or their leftovers are discarded", {
103
+ attempts: unconfigured.length,
104
+ workers: [...new Set(unconfigured.map(({ worker }) => worker))].sort().join(","),
105
+ });
106
+ }
107
+ // Runs before Run recovery, so a retry starts only after the previous Attempt's work is
108
+ // recorded. A failed recovery leaves the checkout on disk.
109
+ const unstopped = yield* Effect.forEach(reconcilable, (attempt) => attempt.open
110
+ ? recoverOpen(attempt).pipe(Effect.as(Option.none()))
111
+ : recoverClosed(attempt));
112
+ return EffectArray.getSomes(unstopped);
113
+ });
114
+ /**
115
+ * Returns the slot that startup occupied with the checkout it kept for `attemptId`, or `None`.
116
+ * Until the execution acquires the checkout, the slot's `release` does nothing; `reconcile`
117
+ * frees it.
118
+ */
119
+ const reattachSlot = Effect.fn("CheckoutRecovery.reattachSlot")(function* (attemptId) {
120
+ const occupied = Option.filter(Option.fromUndefinedOr((yield* Ref.get(kept)).get(attemptId)), ({ checkoutKept }) => checkoutKept);
121
+ return Option.map(occupied, (entry) => ({
122
+ worker: entry.worker,
123
+ release: Ref.get(kept).pipe(Effect.flatMap((leases) => leases.get(attemptId) === entry
124
+ ? Effect.logInfo("The slot startup occupied stays kept with the checkout no execution acquired, until the Attempt's parent task is confirmed stopped", { attemptId, worker: entry.worker })
125
+ : entry.release)),
126
+ }));
127
+ });
128
+ /**
129
+ * Hands the kept checkout of `attemptId` to its execution; the Run then releases the slot when
130
+ * the Attempt ends. Does nothing for other Attempts.
131
+ */
132
+ const acquired = Effect.fn("CheckoutRecovery.acquired")(function* (attemptId) {
133
+ const handedOver = yield* Ref.modify(kept, (leases) => leases.get(attemptId)?.checkoutKept === true
134
+ ? [true, without(leases, attemptId)]
135
+ : [false, leases]);
136
+ if (handedOver)
137
+ yield* Effect.logInfo("The reattached Attempt's execution acquired the checkout startup kept; its executor releases the checkout from here, and its Run the slot once the Attempt ends", { attemptId });
138
+ });
139
+ /**
140
+ * Keeps `lease` as the slot of `attemptId`, an Attempt whose parent task may still run, until
141
+ * `reconcile` confirms that the task stopped. If the Attempt already has a slot here, releases
142
+ * `lease` instead.
143
+ */
144
+ const hold = Effect.fn("CheckoutRecovery.hold")(function* (attemptId, lease) {
145
+ const fields = { attemptId, worker: lease.worker };
146
+ yield* Effect.annotateCurrentSpan(fields);
147
+ const release = yield* Effect.cached(lease.release);
148
+ const held = yield* Ref.modify(kept, (leases) => leases.has(attemptId)
149
+ ? [false, leases]
150
+ : [
151
+ true,
152
+ new Map(leases).set(attemptId, {
153
+ worker: lease.worker,
154
+ release,
155
+ checkoutKept: false,
156
+ }),
157
+ ]);
158
+ if (held) {
159
+ yield* Effect.logInfo("The Attempt keeps its Run's slot until its parent task is confirmed stopped", fields);
160
+ return;
161
+ }
162
+ yield* Effect.logDebug("The Attempt already has a slot kept until its parent task is confirmed stopped; releasing its Run's lease", fields);
163
+ yield* release;
164
+ }, Effect.uninterruptible);
165
+ /**
166
+ * Stops the parent task of `attemptId` for `reason`. Fails with `ParentStopUnconfirmedError` if
167
+ * the stop isn't confirmed.
168
+ */
169
+ const confirmStop = Effect.fn("CheckoutRecovery.confirmStop")(function* (attemptId, occupied, reason) {
170
+ const fields = {
171
+ attemptId,
172
+ worker: occupied.worker,
173
+ checkoutKept: occupied.checkoutKept,
174
+ reason,
175
+ };
176
+ yield* Effect.annotateCurrentSpan(fields);
177
+ const stopped = yield* executor.interrupt(attemptId, reason).pipe(Effect.result);
178
+ if (Result.isSuccess(stopped))
179
+ return;
180
+ const failure = { ...fields, errorTag: stopped.failure._tag, message: stopped.failure.message };
181
+ yield* occupied.checkoutKept
182
+ ? Effect.logWarning("Could not confirm that the parent task of an Attempt its Run does not reattach stopped; its checkout and its Worker's slot stay, and the Run starts no next Attempt until the stop is confirmed", failure)
183
+ : Effect.logWarning("Could not confirm that the parent task of a closed Attempt stopped; its Worker's slot stays taken, and no Attempt starts on its Loop's Item, until a reconcile confirms the stop", failure);
184
+ return yield* new ParentStopUnconfirmedError({
185
+ attemptId,
186
+ worker: occupied.worker,
187
+ cause: stopped.failure,
188
+ });
189
+ });
190
+ /** Reconciles the checkout startup kept for `attemptId`, whose parent task is confirmed stopped. */
191
+ const recoverKept = Effect.fn("CheckoutRecovery.recoverKept")(function* (attemptId) {
192
+ const found = yield* store.salvageCandidate(attemptId).pipe(Effect.result);
193
+ if (Result.isFailure(found)) {
194
+ yield* Effect.logError("Could not read the Attempt whose checkout startup kept; the checkout stays until the next startup", { attemptId, errorTag: found.failure._tag });
195
+ return;
196
+ }
197
+ if (Option.isNone(found.success)) {
198
+ yield* Effect.logWarning("The leftovers of the Attempt whose checkout startup kept were discarded; the checkout stays", { attemptId });
199
+ return;
200
+ }
201
+ const attempt = found.success.value;
202
+ const fields = { attemptId, worker: attempt.worker, open: attempt.open };
203
+ yield* Effect.annotateCurrentSpan(fields);
204
+ if (!(yield* executor.workers).includes(attempt.worker)) {
205
+ yield* Effect.logWarning("The Worker of the Attempt whose checkout startup kept is no longer configured; the checkout stays until it is configured again or its leftovers are discarded", fields);
206
+ return;
207
+ }
208
+ // The Run doesn't reattach the Attempt, so reconcile even if `isLive` still reports it, as for
209
+ // an unharvested parent report.
210
+ yield* Effect.logInfo("Reconciling the checkout startup kept for an Attempt that was not reattached", fields);
211
+ yield* recover(attempt);
212
+ });
213
+ /**
214
+ * Stops the parent task of `attemptId` for `reason` if a slot is kept for it, then reconciles a
215
+ * checkout startup kept and releases the slot. Fails with `ParentStopUnconfirmedError` and keeps
216
+ * both if the stop isn't confirmed.
217
+ */
218
+ const reconcile = Effect.fn("CheckoutRecovery.reconcile")(function* (attemptId, reason) {
219
+ yield* Effect.annotateCurrentSpan({ attemptId, reason });
220
+ const occupied = (yield* Ref.get(kept)).get(attemptId);
221
+ if (occupied === undefined) {
222
+ yield* Effect.logDebug("No slot kept for the Attempt awaits its parent task's stop", {
223
+ attemptId,
224
+ });
225
+ return;
226
+ }
227
+ // The parent task must stop before the reconcile, the next Attempt, or the slot's release.
228
+ yield* confirmStop(attemptId, occupied, reason);
229
+ if (occupied.checkoutKept)
230
+ yield* recoverKept(attemptId);
231
+ // Removed only after reconciling, so a cancel during the reconcile reconciles again and the
232
+ // slot stays taken while the parent task can still run (#177).
233
+ yield* Ref.update(kept, (leases) => without(leases, attemptId)).pipe(Effect.andThen(occupied.release), Effect.uninterruptible);
234
+ yield* Effect.logInfo("Released the slot kept for an Attempt whose parent task is confirmed stopped", { attemptId, worker: occupied.worker, checkoutKept: occupied.checkoutKept });
235
+ });
236
+ return { atStartup, reattachSlot, acquired, hold, reconcile };
237
+ });
238
+ //# sourceMappingURL=checkout-recovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkout-recovery.js","sourceRoot":"","sources":["../../src/engine/checkout-recovery.ts"],"names":[],"mappings":"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"}
@@ -1,59 +1,100 @@
1
1
  import { Event } from "@usine/core/event";
2
- import { AttemptContext, AttemptId } from "@usine/core/attempt";
2
+ import { AttemptId } from "@usine/core/attempt";
3
3
  import { Intervention } from "@usine/core/attempt/channel";
4
4
  import { ItemKey } from "@usine/core/item";
5
5
  import { LoopName } from "@usine/core/loop";
6
+ import type { OperatorLogin } from "@usine/core/operator";
6
7
  import { RunId } from "@usine/core/run";
7
- import { Context, Crypto, Effect, Layer, Option } from "effect";
8
- import { SqlClient } from "effect/unstable/sql";
8
+ import { ApprovalSource } from "@usine/core/run/approval";
9
+ import type { WorkerName } from "@usine/core/worker";
10
+ import { Context, Crypto, type Duration, Effect, Layer, Option } from "effect";
9
11
  import { RunDatabase } from "../database/database.ts";
10
- import { type RunEngineError } from "./error.ts";
12
+ import { LeftoversDiscardRejectedError, type RunEngineError } from "./error.ts";
11
13
  import type { RunSnapshot } from "../run-reader/model.ts";
12
- import type { Submission, SubmissionResult } from "./submission.ts";
14
+ import { type Submission, type SubmissionResult } from "./submission.ts";
15
+ import type { RunAgainRequest, RunAgainResult } from "./run-again.ts";
16
+ import { type RetryRequest } from "./retry.ts";
13
17
  import type { TranscriptEntry, TranscriptQuery } from "../transcript.ts";
14
18
  import { RunReader } from "../run-reader/run-reader.ts";
15
19
  import { ItemProjectionReader, ItemProjectionWriter } from "../item-projection/item-projection.ts";
16
20
  import { RepositoryLabelProjectionReader, RepositoryLabelProjectionWriter } from "../repository-label-projection/repository-label-projection.ts";
17
21
  import { StepExecutor } from "../step-executor.ts";
22
+ import { TriggerCondition } from "../trigger-condition.ts";
18
23
  import { CursorStore } from "../cursor/cursor.ts";
19
24
  import { LoopControl } from "../loop-control/loop-control.ts";
20
25
  import { CycleBudgets } from "../cycle-budget/cycle-budget.ts";
26
+ import { BoardMoves } from "../board-moves/board-moves.ts";
27
+ import { UnconfirmedStops } from "./unconfirmed-stops.ts";
28
+ /** The interval between periodic reconciles, which restart open Runs whose fiber stopped. */
29
+ export declare const ReconcileInterval: Context.Reference<Duration.Input>;
21
30
  declare const RunEngine_base: Context.ServiceClass<RunEngine, "@usine/engine/RunEngine", {
22
- /** Stops admitting Attempts, including retries, and waits for admitted work to settle. Interrupting this wait keeps admission closed until restart. */
31
+ /** Stops admitting Attempts, including retries, and waits for admitted Attempts to finish. Admission stays closed until restart. */
23
32
  readonly drain: () => Effect.Effect<void>;
24
- /** Records the operator's approval Event and opens the Run's gate; execution still waits for a Worker slot. */
25
- readonly approve: (runId: RunId, approval: Event) => Effect.Effect<void, RunEngineError>;
26
- /** Cancels an open Run and interrupts its active Attempt. An already closed Run is unchanged. */
33
+ /** Records the approval Event and its source, and opens the Run's approval gate. A repeated approval keeps the first source. */
34
+ readonly approve: (runId: RunId, approval: Event, source: ApprovalSource) => Effect.Effect<void, RunEngineError>;
35
+ /**
36
+ * Cancels an open Run and interrupts its active Attempt; does nothing for a closed Run. If the
37
+ * Attempt's parent task can't be confirmed stopped, fails with `AttemptCancellationError`, and
38
+ * until a reconcile confirms the stop, the Attempt keeps its Worker slot (#475) and no Run of
39
+ * the Loop on the Item starts an Attempt (#523).
40
+ */
27
41
  readonly cancel: (runId: RunId) => Effect.Effect<void, RunEngineError>;
28
- /** Reads the Run's current state, effective task and Agent, Step result, and Attempt history. */
42
+ /**
43
+ * Stops reconciling the Attempts recorded on `worker`, then removes with
44
+ * `StepExecutor.discard` what they left outside their checkouts, and returns the number of
45
+ * Attempts marked. Leaves their checkouts in place. Fails with
46
+ * `LeftoversDiscardRejectedError` if `worker` is in `StepExecutor.workers`.
47
+ */
48
+ readonly discardLeftovers: (worker: WorkerName) => Effect.Effect<number, RunEngineError | LeftoversDiscardRejectedError>;
49
+ /** Returns the Run's state, effective task and Agent, Step result, and Attempt history. */
29
50
  readonly inspect: (runId: RunId) => Effect.Effect<RunSnapshot, RunEngineError>;
30
- /** Addresses one current Attempt explicitly so an old drawer cannot steer its replacement. */
51
+ /** Sends operator input to `attemptId`. Fails with `RunInterventionRejectedError` if it isn't the Run's running Attempt. */
31
52
  readonly intervene: (runId: RunId, attemptId: AttemptId, intervention: Intervention) => Effect.Effect<void, RunEngineError>;
32
- /** Recovers unfinished Runs and outstanding actions from stored state; also runs when the engine starts. */
53
+ /**
54
+ * Starts a fiber for every open Run without one, except Runs waiting for approval, and opens the
55
+ * queued Events that no closed Run continued, and retries the parent task stops that a cancel,
56
+ * a failed Attempt, or startup couldn't confirm. A Run whose Loop and Item have an unconfirmed
57
+ * stop starts no Attempt until a reconcile confirms it. Runs at startup and every
58
+ * `ReconcileInterval`.
59
+ */
33
60
  readonly reconcile: () => Effect.Effect<void, RunEngineError>;
34
- /** Requests another Attempt for a failed Run using its existing Event and effective task and Agent. */
35
- readonly retry: (runId: RunId, amendment?: Option.Option<AttemptContext>) => Effect.Effect<void, RunEngineError>;
36
- /** Cancels unstarted Runs and discards queued Events for a Loop's Item when it stops matching; running Attempts continue. */
61
+ /**
62
+ * Marks the current failed Attempt as resolved without changing its outcome. If the Attempt
63
+ * stopped with a question or blocker, the Loop evaluates the Item's queued Events again.
64
+ */
65
+ readonly resolveFailure: (runId: RunId, attemptId: AttemptId, operator: Option.Option<OperatorLogin>) => Effect.Effect<void, RunEngineError>;
66
+ /**
67
+ * Requests another Attempt for a failed Run with its existing Event, applying the request's
68
+ * task and Agent if set. The Attempt records the request as its start reason.
69
+ */
70
+ readonly retry: (runId: RunId, request?: RetryRequest) => Effect.Effect<void, RunEngineError>;
71
+ /**
72
+ * Opens a new Run for the Item state of a succeeded or canceled Run, with the request's task
73
+ * and Agent, as an operator Event. The Item's cycle budget and the Loop's approval gate apply.
74
+ */
75
+ readonly runAgain: (runId: RunId, request: RunAgainRequest) => Effect.Effect<RunAgainResult, RunEngineError>;
76
+ /** Cancels unstarted Runs and discards queued Events for a Loop's Item that stopped matching; running Attempts continue. */
37
77
  readonly revoke: (loop: LoopName, itemKey: ItemKey) => Effect.Effect<ReadonlyArray<RunId>, RunEngineError>;
38
78
  /**
39
- * Records a matching Event and claims its Run, or queues it behind the Item's
40
- * running Attempt. Repeated Events are deduplicated; execution continues separately.
79
+ * Records a matching Event and claims its Run, or queues it behind the Item's running Attempt.
80
+ * Deduplicates repeated Events.
41
81
  */
42
82
  readonly submit: (submission: Submission) => Effect.Effect<SubmissionResult, RunEngineError>;
43
- /** Reads the requested portion of an Attempt's persisted transcript in append order. */
83
+ /** Returns the requested part of an Attempt's transcript, in append order. */
44
84
  readonly transcript: (query: TranscriptQuery) => Effect.Effect<ReadonlyArray<TranscriptEntry>, RunEngineError>;
45
85
  }>;
46
- /** Records Events and manages their Runs through approval, execution, retry, and cancellation. */
86
+ /** The service that records Events and drives their Runs through approval, execution, retry, and cancellation. */
47
87
  export declare class RunEngine extends RunEngine_base {
48
88
  }
49
89
  /**
50
- * Provides Run execution and recovery on the supplied database.
51
- * `database` must supply Drizzle and Effect SQL clients for the same database,
52
- * so Run records and pending execution remain together across restarts.
53
- * The deployment supplies `Crypto` and the Worker implementation through `StepExecutor`.
90
+ * Returns the engine layers on `database`, which stores all durable Run state. Requires `Crypto`
91
+ * for Run IDs, `StepExecutor` for Workers, and `TriggerCondition` to re-check queued Events.
54
92
  */
55
- export declare const layerWithDatabase: <DatabaseError, DatabaseRequirements>(database: Layer.Layer<RunDatabase | SqlClient.SqlClient, DatabaseError, DatabaseRequirements>) => Layer.Layer<CursorStore | CycleBudgets | ItemProjectionReader | ItemProjectionWriter | LoopControl | RepositoryLabelProjectionReader | RepositoryLabelProjectionWriter | RunEngine | RunReader, RunEngineError | DatabaseError, Crypto.Crypto | StepExecutor | DatabaseRequirements>;
56
- export { Submission, Claimed, Queued, Ignored, CycleBlocked, IgnoreReason, SubmissionResult, } from "./submission.ts";
93
+ export declare const layerWithDatabase: <DatabaseError, DatabaseRequirements>(database: Layer.Layer<RunDatabase, DatabaseError, DatabaseRequirements>) => Layer.Layer<BoardMoves | CursorStore | CycleBudgets | ItemProjectionReader | ItemProjectionWriter | LoopControl | RepositoryLabelProjectionReader | RepositoryLabelProjectionWriter | RunEngine | RunReader | UnconfirmedStops, RunEngineError | DatabaseError, Crypto.Crypto | StepExecutor | TriggerCondition | DatabaseRequirements>;
94
+ export { Submission, Claimed, Queued, Suppressed, Ignored, CycleBlocked, IgnoreReason, SubmissionResult, } from "./submission.ts";
95
+ export { RunAgainRequest, RunAgainResult } from "./run-again.ts";
96
+ export { RetryRequest } from "./retry.ts";
57
97
  export { RunEngineShutdown } from "./shutdown.ts";
58
- export { RunNotFoundError, RunOperationRejectedError, EnginePersistenceError, AttemptCancellationError, RunInterventionRejectedError, RunStoreError, RunEngineError, } from "./error.ts";
98
+ export { UnconfirmedStop, UnconfirmedStops } from "./unconfirmed-stops.ts";
99
+ export { RunNotFoundError, RunOperationRejectedError, RunRetryBlockedError, EnginePersistenceError, AttemptCancellationError, RunInterventionRejectedError, LeftoversDiscardRejectedError, RunStoreError, RunEngineError, } from "./error.ts";
59
100
  //# sourceMappingURL=engine.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/engine/engine.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/engine/engine.ts"],"names":[],"mappings":"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"}