@usine/executor 0.2.1 → 0.4.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 (250) hide show
  1. package/LICENSE +661 -21
  2. package/README.md +212 -37
  3. package/dist/child-command.d.ts +5 -8
  4. package/dist/child-command.d.ts.map +1 -1
  5. package/dist/child-command.js +10 -14
  6. package/dist/child-command.js.map +1 -1
  7. package/dist/child-environment.d.ts +19 -0
  8. package/dist/child-environment.d.ts.map +1 -0
  9. package/dist/child-environment.js +18 -0
  10. package/dist/child-environment.js.map +1 -0
  11. package/dist/claude-login-lock.d.ts +9 -0
  12. package/dist/claude-login-lock.d.ts.map +1 -0
  13. package/dist/claude-login-lock.js +15 -0
  14. package/dist/claude-login-lock.js.map +1 -0
  15. package/dist/cloudflare/client.d.ts +50 -0
  16. package/dist/cloudflare/client.d.ts.map +1 -0
  17. package/dist/cloudflare/client.js +108 -0
  18. package/dist/cloudflare/client.js.map +1 -0
  19. package/dist/cloudflare/cloudflare.d.ts +17 -0
  20. package/dist/cloudflare/cloudflare.d.ts.map +1 -0
  21. package/dist/cloudflare/cloudflare.js +704 -0
  22. package/dist/cloudflare/cloudflare.js.map +1 -0
  23. package/dist/cloudflare/model.d.ts +42 -0
  24. package/dist/cloudflare/model.d.ts.map +1 -0
  25. package/dist/cloudflare/model.js +2 -0
  26. package/dist/cloudflare/model.js.map +1 -0
  27. package/dist/cloudflare/shell/environment.d.ts +12 -0
  28. package/dist/cloudflare/shell/environment.d.ts.map +1 -0
  29. package/dist/cloudflare/shell/environment.js +12 -0
  30. package/dist/cloudflare/shell/environment.js.map +1 -0
  31. package/dist/cloudflare/shell/shell.d.ts +2 -0
  32. package/dist/cloudflare/shell/shell.d.ts.map +1 -0
  33. package/dist/cloudflare/shell/shell.js +155 -0
  34. package/dist/cloudflare/shell/shell.js.map +1 -0
  35. package/dist/credential-environment.d.ts +20 -0
  36. package/dist/credential-environment.d.ts.map +1 -0
  37. package/dist/credential-environment.js +20 -0
  38. package/dist/credential-environment.js.map +1 -0
  39. package/dist/durable-session.d.ts +81 -0
  40. package/dist/durable-session.d.ts.map +1 -0
  41. package/dist/durable-session.js +550 -0
  42. package/dist/durable-session.js.map +1 -0
  43. package/dist/exe-dev/commands.d.ts +23 -13
  44. package/dist/exe-dev/commands.d.ts.map +1 -1
  45. package/dist/exe-dev/commands.js +11 -57
  46. package/dist/exe-dev/commands.js.map +1 -1
  47. package/dist/exe-dev/exe-dev.d.ts +9 -3
  48. package/dist/exe-dev/exe-dev.d.ts.map +1 -1
  49. package/dist/exe-dev/exe-dev.js +61 -128
  50. package/dist/exe-dev/exe-dev.js.map +1 -1
  51. package/dist/exe-dev/grants.d.ts.map +1 -1
  52. package/dist/exe-dev/grants.js +35 -15
  53. package/dist/exe-dev/grants.js.map +1 -1
  54. package/dist/exe-dev/model.d.ts +15 -19
  55. package/dist/exe-dev/model.d.ts.map +1 -1
  56. package/dist/exe-dev/model.js +9 -12
  57. package/dist/exe-dev/model.js.map +1 -1
  58. package/dist/exe-dev/preflight.d.ts +8 -4
  59. package/dist/exe-dev/preflight.d.ts.map +1 -1
  60. package/dist/exe-dev/preflight.js +26 -35
  61. package/dist/exe-dev/preflight.js.map +1 -1
  62. package/dist/executor.d.ts +292 -44
  63. package/dist/executor.d.ts.map +1 -1
  64. package/dist/executor.js +187 -19
  65. package/dist/executor.js.map +1 -1
  66. package/dist/guard.d.ts +57 -7
  67. package/dist/guard.d.ts.map +1 -1
  68. package/dist/guard.js +274 -59
  69. package/dist/guard.js.map +1 -1
  70. package/dist/harness-preflight.d.ts +27 -5
  71. package/dist/harness-preflight.d.ts.map +1 -1
  72. package/dist/harness-preflight.js +32 -31
  73. package/dist/harness-preflight.js.map +1 -1
  74. package/dist/keyed-lock.d.ts +2 -3
  75. package/dist/keyed-lock.d.ts.map +1 -1
  76. package/dist/keyed-lock.js +2 -3
  77. package/dist/keyed-lock.js.map +1 -1
  78. package/dist/leftovers.d.ts +9 -0
  79. package/dist/leftovers.d.ts.map +1 -0
  80. package/dist/leftovers.js +14 -0
  81. package/dist/leftovers.js.map +1 -0
  82. package/dist/local/credentials.d.ts +21 -0
  83. package/dist/local/credentials.d.ts.map +1 -0
  84. package/dist/local/credentials.js +39 -0
  85. package/dist/local/credentials.js.map +1 -0
  86. package/dist/local/leftovers.d.ts +8 -0
  87. package/dist/local/leftovers.d.ts.map +1 -0
  88. package/dist/local/leftovers.js +23 -0
  89. package/dist/local/leftovers.js.map +1 -0
  90. package/dist/local/local.d.ts +17 -11
  91. package/dist/local/local.d.ts.map +1 -1
  92. package/dist/local/local.js +205 -132
  93. package/dist/local/local.js.map +1 -1
  94. package/dist/memory-preflight.d.ts +27 -0
  95. package/dist/memory-preflight.d.ts.map +1 -0
  96. package/dist/memory-preflight.js +83 -0
  97. package/dist/memory-preflight.js.map +1 -0
  98. package/dist/pre-push-hook.d.ts +20 -0
  99. package/dist/pre-push-hook.d.ts.map +1 -0
  100. package/dist/pre-push-hook.js +33 -0
  101. package/dist/pre-push-hook.js.map +1 -0
  102. package/dist/prepared-attempt.d.ts +41 -3
  103. package/dist/prepared-attempt.d.ts.map +1 -1
  104. package/dist/prepared-attempt.js +109 -31
  105. package/dist/prepared-attempt.js.map +1 -1
  106. package/dist/provision.d.ts +129 -15
  107. package/dist/provision.d.ts.map +1 -1
  108. package/dist/provision.js +428 -69
  109. package/dist/provision.js.map +1 -1
  110. package/dist/remote/commands.d.ts +51 -0
  111. package/dist/remote/commands.d.ts.map +1 -0
  112. package/dist/remote/commands.js +94 -0
  113. package/dist/remote/commands.js.map +1 -0
  114. package/dist/remote/container.d.ts +90 -0
  115. package/dist/remote/container.d.ts.map +1 -0
  116. package/dist/remote/container.js +480 -0
  117. package/dist/remote/container.js.map +1 -0
  118. package/dist/remote/leftovers.d.ts +14 -0
  119. package/dist/remote/leftovers.d.ts.map +1 -0
  120. package/dist/remote/leftovers.js +22 -0
  121. package/dist/remote/leftovers.js.map +1 -0
  122. package/dist/remote/liveness.d.ts +33 -0
  123. package/dist/remote/liveness.d.ts.map +1 -0
  124. package/dist/remote/liveness.js +196 -0
  125. package/dist/remote/liveness.js.map +1 -0
  126. package/dist/remote/machine.d.ts +110 -0
  127. package/dist/remote/machine.d.ts.map +1 -0
  128. package/dist/remote/machine.js +2 -0
  129. package/dist/remote/machine.js.map +1 -0
  130. package/dist/remote/remote.d.ts +28 -0
  131. package/dist/remote/remote.d.ts.map +1 -0
  132. package/dist/remote/remote.js +556 -0
  133. package/dist/remote/remote.js.map +1 -0
  134. package/dist/remote/sweep.d.ts +17 -0
  135. package/dist/remote/sweep.d.ts.map +1 -0
  136. package/dist/remote/sweep.js +117 -0
  137. package/dist/remote/sweep.js.map +1 -0
  138. package/dist/renewable-credential.d.ts +17 -0
  139. package/dist/renewable-credential.d.ts.map +1 -0
  140. package/dist/renewable-credential.js +58 -0
  141. package/dist/renewable-credential.js.map +1 -0
  142. package/dist/salvage.d.ts +38 -0
  143. package/dist/salvage.d.ts.map +1 -0
  144. package/dist/salvage.js +198 -0
  145. package/dist/salvage.js.map +1 -0
  146. package/dist/ssh/api-keys.d.ts +36 -0
  147. package/dist/ssh/api-keys.d.ts.map +1 -0
  148. package/dist/ssh/api-keys.js +72 -0
  149. package/dist/ssh/api-keys.js.map +1 -0
  150. package/dist/ssh/codex-homes.d.ts +21 -0
  151. package/dist/ssh/codex-homes.d.ts.map +1 -0
  152. package/dist/ssh/codex-homes.js +78 -0
  153. package/dist/ssh/codex-homes.js.map +1 -0
  154. package/dist/ssh/container.d.ts +32 -0
  155. package/dist/ssh/container.d.ts.map +1 -0
  156. package/dist/ssh/container.js +282 -0
  157. package/dist/ssh/container.js.map +1 -0
  158. package/dist/ssh/credentials.d.ts +43 -0
  159. package/dist/ssh/credentials.d.ts.map +1 -0
  160. package/dist/ssh/credentials.js +86 -0
  161. package/dist/ssh/credentials.js.map +1 -0
  162. package/dist/ssh/gateway/admin.d.ts +45 -0
  163. package/dist/ssh/gateway/admin.d.ts.map +1 -0
  164. package/dist/ssh/gateway/admin.js +129 -0
  165. package/dist/ssh/gateway/admin.js.map +1 -0
  166. package/dist/ssh/gateway/attachments.d.ts +31 -0
  167. package/dist/ssh/gateway/attachments.d.ts.map +1 -0
  168. package/dist/ssh/gateway/attachments.js +168 -0
  169. package/dist/ssh/gateway/attachments.js.map +1 -0
  170. package/dist/ssh/gateway/environment.d.ts +71 -0
  171. package/dist/ssh/gateway/environment.d.ts.map +1 -0
  172. package/dist/ssh/gateway/environment.js +148 -0
  173. package/dist/ssh/gateway/environment.js.map +1 -0
  174. package/dist/ssh/gateway/forward.d.ts +74 -0
  175. package/dist/ssh/gateway/forward.d.ts.map +1 -0
  176. package/dist/ssh/gateway/forward.js +247 -0
  177. package/dist/ssh/gateway/forward.js.map +1 -0
  178. package/dist/ssh/gateway/preflight.d.ts +67 -0
  179. package/dist/ssh/gateway/preflight.d.ts.map +1 -0
  180. package/dist/ssh/gateway/preflight.js +320 -0
  181. package/dist/ssh/gateway/preflight.js.map +1 -0
  182. package/dist/ssh/limits.d.ts +60 -0
  183. package/dist/ssh/limits.d.ts.map +1 -0
  184. package/dist/ssh/limits.js +84 -0
  185. package/dist/ssh/limits.js.map +1 -0
  186. package/dist/ssh/model.d.ts +153 -0
  187. package/dist/ssh/model.d.ts.map +1 -0
  188. package/dist/ssh/model.js +2 -0
  189. package/dist/ssh/model.js.map +1 -0
  190. package/dist/ssh/preflight.d.ts +35 -0
  191. package/dist/ssh/preflight.d.ts.map +1 -0
  192. package/dist/ssh/preflight.js +87 -0
  193. package/dist/ssh/preflight.js.map +1 -0
  194. package/dist/ssh/provisioner/boat.d.ts +33 -0
  195. package/dist/ssh/provisioner/boat.d.ts.map +1 -0
  196. package/dist/ssh/provisioner/boat.js +247 -0
  197. package/dist/ssh/provisioner/boat.js.map +1 -0
  198. package/dist/ssh/provisioner/hetzner.d.ts +32 -0
  199. package/dist/ssh/provisioner/hetzner.d.ts.map +1 -0
  200. package/dist/ssh/provisioner/hetzner.js +337 -0
  201. package/dist/ssh/provisioner/hetzner.js.map +1 -0
  202. package/dist/ssh/provisioner/host-key.d.ts +11 -0
  203. package/dist/ssh/provisioner/host-key.d.ts.map +1 -0
  204. package/dist/ssh/provisioner/host-key.js +57 -0
  205. package/dist/ssh/provisioner/host-key.js.map +1 -0
  206. package/dist/ssh/provisioner/http.d.ts +45 -0
  207. package/dist/ssh/provisioner/http.d.ts.map +1 -0
  208. package/dist/ssh/provisioner/http.js +72 -0
  209. package/dist/ssh/provisioner/http.js.map +1 -0
  210. package/dist/ssh/provisioner/machines.d.ts +48 -0
  211. package/dist/ssh/provisioner/machines.d.ts.map +1 -0
  212. package/dist/ssh/provisioner/machines.js +686 -0
  213. package/dist/ssh/provisioner/machines.js.map +1 -0
  214. package/dist/ssh/provisioner/model.d.ts +92 -0
  215. package/dist/ssh/provisioner/model.d.ts.map +1 -0
  216. package/dist/ssh/provisioner/model.js +37 -0
  217. package/dist/ssh/provisioner/model.js.map +1 -0
  218. package/dist/ssh/ssh.d.ts +23 -0
  219. package/dist/ssh/ssh.d.ts.map +1 -0
  220. package/dist/ssh/ssh.js +145 -0
  221. package/dist/ssh/ssh.js.map +1 -0
  222. package/dist/ssh/worker-records.d.ts +18 -0
  223. package/dist/ssh/worker-records.d.ts.map +1 -0
  224. package/dist/ssh/worker-records.js +100 -0
  225. package/dist/ssh/worker-records.js.map +1 -0
  226. package/dist/ssh/workers.d.ts +80 -0
  227. package/dist/ssh/workers.d.ts.map +1 -0
  228. package/dist/ssh/workers.js +247 -0
  229. package/dist/ssh/workers.js.map +1 -0
  230. package/package.json +25 -9
  231. package/dist/exe-dev/channel.d.ts +0 -12
  232. package/dist/exe-dev/channel.d.ts.map +0 -1
  233. package/dist/exe-dev/channel.js +0 -42
  234. package/dist/exe-dev/channel.js.map +0 -1
  235. package/dist/exe-dev/shell.d.ts +0 -12
  236. package/dist/exe-dev/shell.d.ts.map +0 -1
  237. package/dist/exe-dev/shell.js +0 -31
  238. package/dist/exe-dev/shell.js.map +0 -1
  239. package/dist/exe-dev/sweep.d.ts +0 -10
  240. package/dist/exe-dev/sweep.d.ts.map +0 -1
  241. package/dist/exe-dev/sweep.js +0 -117
  242. package/dist/exe-dev/sweep.js.map +0 -1
  243. package/dist/invalid-frame.d.ts +0 -17
  244. package/dist/invalid-frame.d.ts.map +0 -1
  245. package/dist/invalid-frame.js +0 -111
  246. package/dist/invalid-frame.js.map +0 -1
  247. package/dist/run-host-session.d.ts +0 -27
  248. package/dist/run-host-session.d.ts.map +0 -1
  249. package/dist/run-host-session.js +0 -303
  250. package/dist/run-host-session.js.map +0 -1
package/dist/executor.js CHANGED
@@ -4,11 +4,13 @@ import { ChildSessionBudget } from "@usine/core/agent/session";
4
4
  import { AttemptTask, AttemptId } from "@usine/core/attempt";
5
5
  import * as AttemptChannel from "@usine/core/attempt/channel";
6
6
  import { AttemptFailure } from "@usine/core/attempt/failure";
7
+ import { LoopName, LoopPermissions } from "@usine/core/loop";
8
+ import { SalvagePushed, SalvageRef } from "@usine/core/attempt/salvage";
7
9
  import { RepositoryName, RepositoryRevision } from "@usine/core/repository";
8
- import { WorkerName, WorkerKind } from "@usine/core/worker";
10
+ import { RunId } from "@usine/core/run";
11
+ import { BotAccount, BotLogin, ContainerLimits, MachineId, MachineProvider, WorkerName, WorkerKind, } from "@usine/core/worker";
9
12
  import { StepResult } from "@usine/core/step/result";
10
- import { Context, Effect, Redacted, Schema, Scope } from "effect";
11
- /** The Worker operation that failed during readiness checks or an Attempt's lifecycle. */
13
+ import { Context, Effect, Option, Predicate, Redacted, Schema, Scope } from "effect";
12
14
  export const ExecutorOperation = Schema.Literals([
13
15
  "preflight",
14
16
  "prepare",
@@ -16,43 +18,104 @@ export const ExecutorOperation = Schema.Literals([
16
18
  "cancel",
17
19
  "cleanup",
18
20
  ]);
19
- /** A prerequisite a Worker must satisfy before it can accept Attempts. */
20
21
  export const WorkerCapability = Schema.Literals([
21
22
  "machine",
22
23
  "toolchain",
23
- "run-host",
24
+ "memory",
24
25
  "harness-login",
25
26
  "credentials",
27
+ "gateway",
28
+ "container",
29
+ "provider",
26
30
  ]);
27
- /** A Worker operation failed before its requested work completed. */
28
31
  export class ExecutorOperationError extends Schema.TaggedError("@usine/executor/ExecutorOperationError")("ExecutorOperationError", {
32
+ /** `cleanup` includes removing a checkout, its credential, or credentials left by an earlier process. */
29
33
  operation: ExecutorOperation,
34
+ /** An operator-facing summary without the Worker name. Not part of the contract; branch on `operation`. */
30
35
  message: Schema.NonEmptyString,
36
+ /** The underlying failure, for example an `Error` with the command's stderr, or a timeout. */
31
37
  cause: Schema.Defect(),
32
38
  }) {
33
39
  }
34
- /** A Worker could not obtain access to the repository assigned to an Attempt. */
40
+ /**
41
+ * `refused` if a retry gets the same result: the installation doesn't cover the repository,
42
+ * lacks a permission, or is suspended, or an exe.dev Worker has no integration for it.
43
+ * `unreachable` if a retry can succeed: a GitHub outage or rate limit, or no response from a
44
+ * Gateway or exe.dev command.
45
+ */
46
+ export const CredentialUnavailableReason = Schema.Literals(["refused", "unreachable"]);
35
47
  export class CredentialUnavailableError extends Schema.TaggedError("@usine/executor/CredentialUnavailableError")("CredentialUnavailableError", {
36
48
  repository: RepositoryName,
49
+ reason: CredentialUnavailableReason,
50
+ /** An operator-facing summary, including GitHub's reason for a refusal. */
37
51
  message: Schema.NonEmptyString,
52
+ /** The underlying failure, for example the GitHub API error from minting the token. */
38
53
  cause: Schema.Defect(),
39
54
  }) {
40
55
  }
41
- /** A verify-only preflight found a Worker capability missing or incompatible. */
56
+ /** The error when preflight finds a Worker capability missing or incompatible. */
42
57
  export class WorkerCapabilityError extends Schema.TaggedError("@usine/executor/WorkerCapabilityError")("WorkerCapabilityError", {
43
58
  worker: WorkerName,
59
+ /**
60
+ * - `machine`: the machine or VM is absent, stopped, or unreachable, or its Worker directory
61
+ * isn't writable.
62
+ * - `toolchain`: Git or a brain's harness doesn't run.
63
+ * - `memory`: less than 1.5 GiB per concurrent Attempt, no swap for more than one, or memory
64
+ * not reported.
65
+ * - `harness-login`: a brain's harness isn't logged in.
66
+ * - `credentials`: an exe.dev integration isn't ready, or the Worker kind can't issue a
67
+ * read-only credential for a `permissions: read` Loop.
68
+ * - `gateway`: the Gateway doesn't respond or isn't reachable from the machine.
69
+ * - `container`: the machine's Docker doesn't respond to the SSH user, the SSH user can use
70
+ * Docker's socket without the `docker` CLI, the Attempt image can't be pulled, or its user ID
71
+ * differs from the SSH user's.
72
+ * - `provider`: a provisioned Worker's provider refuses its token, or its image, SSH key,
73
+ * network, server type, or location doesn't exist there.
74
+ */
44
75
  capability: WorkerCapability,
45
76
  message: Schema.NonEmptyString,
77
+ /** The observed value, for example unrecognized `git --version` output or the harness readiness report. */
46
78
  cause: Schema.Defect(),
47
79
  }) {
48
80
  }
49
- /** A readiness, access, or lifecycle failure reported by a Worker operation. */
81
+ /**
82
+ * `capacity` if the provider has no machine of the configured type now, `quota` if the account's
83
+ * limits are reached, `refused` if the provider refuses the token or the request, `provider` for
84
+ * an API error or rate limit, `unreachable` if the API doesn't respond, and `timeout` if the
85
+ * machine didn't answer over SSH in time. Each is retried later.
86
+ */
87
+ export const MachineUnavailableReason = Schema.Literals([
88
+ "capacity",
89
+ "quota",
90
+ "refused",
91
+ "provider",
92
+ "unreachable",
93
+ "timeout",
94
+ ]);
95
+ /**
96
+ * The error when a provisioned Worker can't create a machine for an Attempt. The Run keeps
97
+ * waiting, and the scheduler tries again later; it isn't an Attempt failure.
98
+ */
99
+ export class MachineUnavailableError extends Schema.TaggedError("@usine/executor/MachineUnavailableError")("MachineUnavailableError", {
100
+ worker: WorkerName,
101
+ provider: MachineProvider,
102
+ reason: MachineUnavailableReason,
103
+ /** An operator-facing summary with the provider's own message. Contains no token. */
104
+ message: Schema.NonEmptyString,
105
+ }) {
106
+ }
50
107
  export const ExecutorError = Schema.Union([
51
108
  ExecutorOperationError,
52
109
  CredentialUnavailableError,
53
110
  WorkerCapabilityError,
54
111
  ]);
55
- /** Logs every preflight refusal so a missing capability is explainable from logs alone. */
112
+ /** The report of a Worker that runs Attempts as designed, without containers. */
113
+ export const fullPreflight = {
114
+ degraded: Option.none(),
115
+ deferred: Option.none(),
116
+ containerLimits: Option.none(),
117
+ };
118
+ /** Logs each preflight failure at error level. */
56
119
  export const logPreflightFailure = (effect) => Effect.tapError(effect, (error) => error instanceof WorkerCapabilityError
57
120
  ? Effect.logError("Worker preflight failed", {
58
121
  error: error._tag,
@@ -64,37 +127,142 @@ export const logPreflightFailure = (effect) => Effect.tapError(effect, (error) =
64
127
  error: error._tag,
65
128
  message: error.message,
66
129
  }));
67
- /** The repository, revision, and Agent task assigned to a Worker for one fresh Attempt checkout. */
68
130
  export class CheckoutRequest extends Schema.Class("@usine/executor/CheckoutRequest")({
131
+ /** The checkout directory name, and the key for `cancel`, `intervene`, `isLive`, and `outcome`. */
69
132
  attemptId: AttemptId,
70
133
  worker: WorkerName,
134
+ /** The only repository the Attempt's credential can access (ADR 0011). */
71
135
  repository: RepositoryName,
136
+ /** The Loop of the Attempt's Run, shown in a `read` checkout's pre-push hook message. */
137
+ loop: LoopName,
138
+ /**
139
+ * The Attempt's access to `repository` (ADR 0011). With `read`, the credential can't push, a
140
+ * pre-push hook explains rejected pushes, and an unsuccessful Attempt's checkout is removed
141
+ * without salvage. A Worker kind that can't issue such a credential fails `prepare` with a
142
+ * `credentials` capability error.
143
+ */
144
+ permissions: LoopPermissions,
145
+ /** The revision to fetch, resolved to a commit during preparation and stored as the RunSpec's `baseCommit`. */
72
146
  revision: RepositoryRevision,
147
+ /** The payload of the event that triggered the Run, included as JSON in the parent's prompt. */
73
148
  payload: Schema.Json,
149
+ /** The parent's task text, after Loop interpolation or operator amendment. */
74
150
  task: AttemptTask,
151
+ /**
152
+ * The Agent whose persona and name go in the parent's prompt and whose brain runs the
153
+ * children. Preparation verifies the brain on the Worker.
154
+ */
75
155
  agent: Agent,
156
+ /**
157
+ * The Pi parent's model. If `None`, uses the configured default model, then the first model
158
+ * with a credential. A model unknown to Pi fails the launch.
159
+ */
76
160
  parentModel: Schema.Option(ModelId),
161
+ /** The maximum child sessions per Attempt. One more fails the Attempt with `ChildSessionBudgetFailure`. */
77
162
  maxChildren: ChildSessionBudget,
78
- /** Maximum minutes of live run-host execution; preparation and resource cleanup are outside this budget. */
79
- maxAttemptMinutes: Schema.Int.check(Schema.isGreaterThan(0)),
80
- /** Maximum reported tokens across the parent and every child; operator Holds never pause this ceiling. */
81
- maxAttemptTokens: Schema.Int.check(Schema.isGreaterThan(0)),
163
+ /** The maximum minutes of Attempt execution, excluding preparation and cleanup, or `None` for no limit. */
164
+ maxAttemptMinutes: Schema.Option(Schema.Int.check(Schema.isGreaterThan(0))),
165
+ /** The maximum tokens consumed by the parent and all children, or `None` for no limit. Holds don't pause it. */
166
+ maxAttemptTokens: Schema.Option(Schema.Int.check(Schema.isGreaterThan(0))),
167
+ /** The Pi parent's reasoning effort. The launch fails if the model doesn't support it. */
82
168
  parentEffort: Effort,
169
+ /** The ref that unfinished work is pushed to if the Attempt doesn't succeed. */
170
+ salvageRef: SalvageRef,
171
+ /** The previous Attempt's pushed salvage, checked out instead of `revision`. */
172
+ resume: Schema.Option(SalvagePushed),
173
+ /**
174
+ * Whether the parent task is still live after an orchestrator restart. If true, preparation
175
+ * reuses the existing checkout and launch reattaches to the parent.
176
+ */
177
+ reattach: Schema.Boolean.pipe(Schema.withConstructorDefault(Effect.succeed(false))),
178
+ /**
179
+ * The GitHub login the Attempt writes as, copied into the RunSpec; harvesting collects comments
180
+ * by this author. If `None`, harvesting asks GitHub for the credential's login.
181
+ */
182
+ botLogin: Schema.Option(BotLogin).pipe(Schema.withConstructorDefault(Effect.succeed(Option.none()))),
183
+ /**
184
+ * The author and committer of every commit that the Attempt's parent and children make. Their
185
+ * environment sets it, so no git config on the Worker's machine applies.
186
+ */
187
+ commitAuthor: BotAccount,
83
188
  }) {
84
189
  }
85
- /** One Attempt's disposable checkout directory. */
86
190
  export const WorktreePath = Schema.NonEmptyString.pipe(Schema.brand("WorktreePath"));
87
- /** The serializable location and RunSpec of an Attempt checkout. Owning this record does not grant access to live resources or credentials. */
191
+ /** A serializable checkout location and RunSpec, without credentials or live resources. */
88
192
  export class AttemptWorkspace extends Schema.Class("@usine/executor/AttemptWorkspace")({
89
193
  worker: WorkerName,
194
+ /** The request's fields plus the commit that `revision` resolved to. */
90
195
  spec: AttemptChannel.RunSpec,
196
+ /** The checkout path on the Worker's machine, where the children run. */
91
197
  worktree: WorktreePath,
92
198
  }) {
93
199
  }
94
- /** Mints exactly one repository-scoped credential for each prepared Attempt. */
200
+ /**
201
+ * A `Redacted` string, kept as the instance it was given, so wiping it wipes the token the
202
+ * provider issued. `Schema.Redacted` stores a copy instead.
203
+ */
204
+ const IssuedToken = Schema.declare((input) => Redacted.isRedacted(input) && Predicate.isString(Redacted.value(input)), { expected: "Redacted<string>" });
205
+ export class WorkerCredential extends Schema.Class("@usine/executor/WorkerCredential")({
206
+ /**
207
+ * The token for git and gh, never written inside the checkout. Wiped when the Attempt's scope
208
+ * closes; `Redacted.value` then throws.
209
+ */
210
+ value: IssuedToken,
211
+ /** A new credential is requested when five minutes or less remain. */
212
+ expiresAt: Schema.DateTimeUtc,
213
+ }) {
214
+ }
95
215
  export class CredentialProvider extends Context.Service()("@usine/executor/CredentialProvider") {
96
216
  }
97
- /** Prepares isolated checkouts, runs Attempts on a Worker, and releases their resources (ADR 0006). */
217
+ /** The service that prepares checkouts, runs Attempts on a Worker, and releases their resources (ADR 0006). */
98
218
  export class Executor extends Context.Service()("@usine/executor/Executor") {
99
219
  }
220
+ /** The executor's hold on one provisioned machine, which `WorkerMachines.release` ends. */
221
+ export const MachineHold = Schema.NonEmptyString.pipe(Schema.brand("MachineHold"));
222
+ /** The machine preflight of a provisioned Worker's first machine each day. */
223
+ export class MachineCheck extends Schema.Class("@usine/executor/MachineCheck")({
224
+ brains: Schema.Array(BrainSpec),
225
+ /**
226
+ * The limits of each Attempt container that the Worker's machines get until the next check,
227
+ * or `None` if the machine has no Docker.
228
+ */
229
+ containerLimits: Schema.Option(ContainerLimits),
230
+ }) {
231
+ }
232
+ /** A machine that a provisioned Worker created for an Attempt and holds until `release`. */
233
+ export class MachineGrant extends Schema.Class("@usine/executor/MachineGrant")({
234
+ hold: MachineHold,
235
+ id: MachineId,
236
+ worker: WorkerName,
237
+ provider: MachineProvider,
238
+ /** The check that this machine got as the Worker's first each day, or `None` if it got none. */
239
+ checked: Schema.Option(MachineCheck),
240
+ }) {
241
+ }
242
+ /**
243
+ * `creating` until the machine answers over SSH, `ready` while an Attempt holds it, and
244
+ * `deleting` until its deletion succeeds.
245
+ */
246
+ export const MachineState = Schema.Literals(["creating", "ready", "deleting"]);
247
+ /** A machine in flight on a provisioned Worker. */
248
+ export class MachineStatus extends Schema.Class("@usine/executor/MachineStatus")({
249
+ worker: WorkerName,
250
+ provider: MachineProvider,
251
+ state: MachineState,
252
+ /** `None` until the provider accepts the creation. */
253
+ id: Schema.Option(MachineId),
254
+ /** The Run the machine was created for, or `None` for a machine found after a restart. */
255
+ runId: Schema.Option(RunId),
256
+ attemptId: Schema.Option(AttemptId),
257
+ /** When the creation started, or when the provider created a machine found after a restart. */
258
+ since: Schema.DateTimeUtc,
259
+ }) {
260
+ }
261
+ /**
262
+ * The machines of the provisioned Workers, which create one machine per Attempt and delete it
263
+ * afterwards (#550). Only the SSH executor provides it.
264
+ */
265
+ export class WorkerMachines extends Context.Service()("@usine/executor/WorkerMachines") {
266
+ }
267
+ export { claudeLoginLockLayer } from "./claude-login-lock.js";
100
268
  //# sourceMappingURL=executor.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"executor.js","sourceRoot":"","sources":["../src/executor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"executor.js","sourceRoot":"","sources":["../src/executor.ts"],"names":[],"mappings":"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"}
package/dist/guard.d.ts CHANGED
@@ -1,11 +1,61 @@
1
1
  import type { AttemptId } from "@usine/core/attempt";
2
+ import type { AgentSessionId } from "@usine/core/agent/session";
2
3
  import type * as AttemptChannel from "@usine/core/attempt/channel";
3
- import { AttemptFailure } from "@usine/core/attempt/failure";
4
- import { Effect } from "effect";
5
- /** Enforces Attempt ceilings: Holds pause elapsed execution time; reported tokens continue accumulating. */
6
- export declare const withAttemptGuard: <A>(limits: {
4
+ import { AttemptFailure, RunawayCeiling, RunawayFailure } from "@usine/core/attempt/failure";
5
+ import { Duration, Effect, Option } from "effect";
6
+ export interface AttemptGuardLimits {
7
7
  readonly attemptId: AttemptId;
8
- readonly maxAttemptMinutes: number;
9
- readonly maxAttemptTokens: number;
10
- }, io: AttemptChannel.Sink, run: (sink: AttemptChannel.Sink) => Effect.Effect<A, AttemptFailure>) => Effect.Effect<A, AttemptFailure>;
8
+ /** The wall-clock ceiling in minutes, or `None` for no limit. */
9
+ readonly maxAttemptMinutes: Option.Option<number>;
10
+ /** The token ceiling across the parent and all children, or `None` for no limit. */
11
+ readonly maxAttemptTokens: Option.Option<number>;
12
+ /**
13
+ * Sends the warning steer to the parent session. Can wait for the parent's channel without
14
+ * delaying the ceiling checks; failures are logged and don't fail the Attempt.
15
+ */
16
+ readonly warn: (message: string) => Effect.Effect<void, AttemptFailure>;
17
+ /**
18
+ * Persists the unsupervised time counted so far, including the seed, for a later reattachment.
19
+ * Called every `RECORD_INTERVAL` while the count grows and once on stop; failures are logged.
20
+ */
21
+ readonly recordUnsupervised: (unsupervised: Duration.Duration) => Effect.Effect<void, AttemptFailure>;
22
+ }
23
+ /**
24
+ * The counts restored from earlier guards, so a reattached Attempt's guard continues instead of
25
+ * starting over (#178). Empty for a new Attempt.
26
+ */
27
+ export interface AttemptGuardSeed {
28
+ /** The highest token count each session reported, including sessions that finished before the restart. */
29
+ readonly tokens: ReadonlyMap<AgentSessionId, number>;
30
+ /** The unsupervised time recorded by earlier guards, excluding time the orchestrator was stopped. */
31
+ readonly unsupervised: Duration.Duration;
32
+ /** Whether the parent was on Hold at the restart. A parent's Hold persists across restarts; a child's doesn't. */
33
+ readonly parentHeld: boolean;
34
+ /** The ceilings whose warning steer is already in the transcript. */
35
+ readonly warned: ReadonlySet<RunawayCeiling>;
36
+ }
37
+ /** Returns a reattached guard's seed from `unsupervised` and the transcript `envelopes` in append order. */
38
+ export declare const guardSeed: (transcript: ReadonlyArray<AttemptChannel.Envelope>, unsupervised: Duration.Duration) => AttemptGuardSeed;
39
+ export interface AttemptGuard {
40
+ /**
41
+ * The Attempt's sink, wrapped. The append that reaches the token ceiling fails with
42
+ * `RunawayFailure`. An append that reaches the warning point queues the warning for `tripped`
43
+ * without waiting, because awaiting delivery inside `append` would deadlock.
44
+ */
45
+ readonly sink: AttemptChannel.Sink;
46
+ /**
47
+ * Checks the restored token total, counts unsupervised time, and sends queued warnings through
48
+ * `limits.warn`. Fails with `RunawayFailure` when the restored token total or the wall-clock
49
+ * ceiling trips; never succeeds. On interruption, records the counted time within
50
+ * `LAST_RECORD_GRACE`.
51
+ */
52
+ readonly tripped: Effect.Effect<never, RunawayFailure>;
53
+ }
54
+ /**
55
+ * Arms the configured Attempt ceilings, each with one warning steer at `WARNING_FRACTION` of
56
+ * its limit. Holds pause the wall clock; tokens keep accumulating. Counts continue from `seed`,
57
+ * so a reattached Attempt trips at the same totals as without the restart. With no ceiling set,
58
+ * `sink` is `io` and `tripped` never completes.
59
+ */
60
+ export declare const attemptGuard: (limits: AttemptGuardLimits, io: AttemptChannel.Sink, seed: AttemptGuardSeed) => Effect.Effect<AttemptGuard>;
11
61
  //# sourceMappingURL=guard.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"guard.d.ts","sourceRoot":"","sources":["../src/guard.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAErD,OAAO,KAAK,KAAK,cAAc,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,cAAc,EAAkB,MAAM,6BAA6B,CAAC;AAC7E,OAAO,EAAS,MAAM,EAAiB,MAAM,QAAQ,CAAC;AAEtD,4GAA4G;AAC5G,eAAO,MAAM,gBAAgB,GAAI,CAAC,UACxB;IACN,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;CACnC,MACG,cAAc,CAAC,IAAI,OAClB,CAAC,IAAI,EAAE,cAAc,CAAC,IAAI,KAAK,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,cAAc,CAAC,KACnE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,cAAc,CAwE9B,CAAC"}
1
+ {"version":3,"file":"guard.d.ts","sourceRoot":"","sources":["../src/guard.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,EAAgB,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC9E,OAAO,KAAK,KAAK,cAAc,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7F,OAAO,EAAS,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAS,MAAM,QAAQ,CAAC;AAyBhE,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,iEAAiE;IACjE,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAClD,oFAAoF;IACpF,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACjD;;;OAGG;IACH,QAAQ,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;IACxE;;;OAGG;IACH,QAAQ,CAAC,kBAAkB,EAAE,CAC3B,YAAY,EAAE,QAAQ,CAAC,QAAQ,KAC5B,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;CAC1C;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,0GAA0G;IAC1G,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;IACrD,qGAAqG;IACrG,QAAQ,CAAC,YAAY,EAAE,QAAQ,CAAC,QAAQ,CAAC;IACzC,kHAAkH;IAClH,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,qEAAqE;IACrE,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,cAAc,CAAC,CAAC;CAC9C;AA8ED,4GAA4G;AAC5G,eAAO,MAAM,SAAS,eACR,aAAa,CAAC,cAAc,CAAC,QAAQ,CAAC,gBACpC,QAAQ,CAAC,QAAQ,KAC9B,gBAYF,CAAC;AAsLF,MAAM,WAAW,YAAY;IAC3B;;;;OAIG;IACH,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC,IAAI,CAAC;IACnC;;;;;OAKG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC;CACxD;AAED;;;;;GAKG;AACH,eAAO,MAAM,YAAY,WACf,kBAAkB,MACtB,cAAc,CAAC,IAAI,QACjB,gBAAgB,KACrB,MAAM,CAAC,MAAM,CAAC,YAAY,CA6E5B,CAAC"}