@usine/executor 0.2.0 → 0.3.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 (177) hide show
  1. package/README.md +115 -37
  2. package/dist/child-command.d.ts +4 -7
  3. package/dist/child-command.d.ts.map +1 -1
  4. package/dist/child-command.js +6 -12
  5. package/dist/child-command.js.map +1 -1
  6. package/dist/claude-login-lock.d.ts +8 -0
  7. package/dist/claude-login-lock.d.ts.map +1 -0
  8. package/dist/claude-login-lock.js +9 -0
  9. package/dist/claude-login-lock.js.map +1 -0
  10. package/dist/credential-environment.d.ts +20 -0
  11. package/dist/credential-environment.d.ts.map +1 -0
  12. package/dist/credential-environment.js +20 -0
  13. package/dist/credential-environment.js.map +1 -0
  14. package/dist/durable-session.d.ts +63 -0
  15. package/dist/durable-session.d.ts.map +1 -0
  16. package/dist/durable-session.js +491 -0
  17. package/dist/durable-session.js.map +1 -0
  18. package/dist/exe-dev/commands.d.ts +23 -13
  19. package/dist/exe-dev/commands.d.ts.map +1 -1
  20. package/dist/exe-dev/commands.js +11 -57
  21. package/dist/exe-dev/commands.js.map +1 -1
  22. package/dist/exe-dev/exe-dev.d.ts +9 -3
  23. package/dist/exe-dev/exe-dev.d.ts.map +1 -1
  24. package/dist/exe-dev/exe-dev.js +53 -127
  25. package/dist/exe-dev/exe-dev.js.map +1 -1
  26. package/dist/exe-dev/grants.d.ts.map +1 -1
  27. package/dist/exe-dev/grants.js +35 -15
  28. package/dist/exe-dev/grants.js.map +1 -1
  29. package/dist/exe-dev/model.d.ts +15 -19
  30. package/dist/exe-dev/model.d.ts.map +1 -1
  31. package/dist/exe-dev/model.js +9 -12
  32. package/dist/exe-dev/model.js.map +1 -1
  33. package/dist/exe-dev/preflight.d.ts +8 -4
  34. package/dist/exe-dev/preflight.d.ts.map +1 -1
  35. package/dist/exe-dev/preflight.js +23 -33
  36. package/dist/exe-dev/preflight.js.map +1 -1
  37. package/dist/executor.d.ts +141 -38
  38. package/dist/executor.d.ts.map +1 -1
  39. package/dist/executor.js +90 -17
  40. package/dist/executor.js.map +1 -1
  41. package/dist/guard.d.ts +61 -0
  42. package/dist/guard.d.ts.map +1 -0
  43. package/dist/guard.js +288 -0
  44. package/dist/guard.js.map +1 -0
  45. package/dist/harness-preflight.d.ts +25 -4
  46. package/dist/harness-preflight.d.ts.map +1 -1
  47. package/dist/harness-preflight.js +25 -29
  48. package/dist/harness-preflight.js.map +1 -1
  49. package/dist/keyed-lock.d.ts +2 -3
  50. package/dist/keyed-lock.d.ts.map +1 -1
  51. package/dist/keyed-lock.js +2 -3
  52. package/dist/keyed-lock.js.map +1 -1
  53. package/dist/leftovers.d.ts +9 -0
  54. package/dist/leftovers.d.ts.map +1 -0
  55. package/dist/leftovers.js +14 -0
  56. package/dist/leftovers.js.map +1 -0
  57. package/dist/local/credentials.d.ts +21 -0
  58. package/dist/local/credentials.d.ts.map +1 -0
  59. package/dist/local/credentials.js +39 -0
  60. package/dist/local/credentials.js.map +1 -0
  61. package/dist/local/leftovers.d.ts +8 -0
  62. package/dist/local/leftovers.d.ts.map +1 -0
  63. package/dist/local/leftovers.js +23 -0
  64. package/dist/local/leftovers.js.map +1 -0
  65. package/dist/local/local.d.ts +16 -10
  66. package/dist/local/local.d.ts.map +1 -1
  67. package/dist/local/local.js +164 -129
  68. package/dist/local/local.js.map +1 -1
  69. package/dist/memory-preflight.d.ts +25 -0
  70. package/dist/memory-preflight.d.ts.map +1 -0
  71. package/dist/memory-preflight.js +83 -0
  72. package/dist/memory-preflight.js.map +1 -0
  73. package/dist/pre-push-hook.d.ts +20 -0
  74. package/dist/pre-push-hook.d.ts.map +1 -0
  75. package/dist/pre-push-hook.js +33 -0
  76. package/dist/pre-push-hook.js.map +1 -0
  77. package/dist/prepared-attempt.d.ts +33 -3
  78. package/dist/prepared-attempt.d.ts.map +1 -1
  79. package/dist/prepared-attempt.js +109 -39
  80. package/dist/prepared-attempt.js.map +1 -1
  81. package/dist/provision.d.ts +77 -14
  82. package/dist/provision.d.ts.map +1 -1
  83. package/dist/provision.js +357 -55
  84. package/dist/provision.js.map +1 -1
  85. package/dist/remote/commands.d.ts +51 -0
  86. package/dist/remote/commands.d.ts.map +1 -0
  87. package/dist/remote/commands.js +94 -0
  88. package/dist/remote/commands.js.map +1 -0
  89. package/dist/remote/leftovers.d.ts +14 -0
  90. package/dist/remote/leftovers.d.ts.map +1 -0
  91. package/dist/remote/leftovers.js +22 -0
  92. package/dist/remote/leftovers.js.map +1 -0
  93. package/dist/remote/liveness.d.ts +33 -0
  94. package/dist/remote/liveness.d.ts.map +1 -0
  95. package/dist/remote/liveness.js +194 -0
  96. package/dist/remote/liveness.js.map +1 -0
  97. package/dist/remote/machine.d.ts +64 -0
  98. package/dist/remote/machine.d.ts.map +1 -0
  99. package/dist/remote/machine.js +2 -0
  100. package/dist/remote/machine.js.map +1 -0
  101. package/dist/remote/remote.d.ts +24 -0
  102. package/dist/remote/remote.d.ts.map +1 -0
  103. package/dist/remote/remote.js +308 -0
  104. package/dist/remote/remote.js.map +1 -0
  105. package/dist/remote/sweep.d.ts +15 -0
  106. package/dist/remote/sweep.d.ts.map +1 -0
  107. package/dist/remote/sweep.js +116 -0
  108. package/dist/remote/sweep.js.map +1 -0
  109. package/dist/renewable-credential.d.ts +17 -0
  110. package/dist/renewable-credential.d.ts.map +1 -0
  111. package/dist/renewable-credential.js +58 -0
  112. package/dist/renewable-credential.js.map +1 -0
  113. package/dist/salvage.d.ts +30 -0
  114. package/dist/salvage.d.ts.map +1 -0
  115. package/dist/salvage.js +104 -0
  116. package/dist/salvage.js.map +1 -0
  117. package/dist/ssh/credentials.d.ts +40 -0
  118. package/dist/ssh/credentials.d.ts.map +1 -0
  119. package/dist/ssh/credentials.js +83 -0
  120. package/dist/ssh/credentials.js.map +1 -0
  121. package/dist/ssh/gateway/admin.d.ts +45 -0
  122. package/dist/ssh/gateway/admin.d.ts.map +1 -0
  123. package/dist/ssh/gateway/admin.js +129 -0
  124. package/dist/ssh/gateway/admin.js.map +1 -0
  125. package/dist/ssh/gateway/attachments.d.ts +22 -0
  126. package/dist/ssh/gateway/attachments.d.ts.map +1 -0
  127. package/dist/ssh/gateway/attachments.js +154 -0
  128. package/dist/ssh/gateway/attachments.js.map +1 -0
  129. package/dist/ssh/gateway/environment.d.ts +52 -0
  130. package/dist/ssh/gateway/environment.d.ts.map +1 -0
  131. package/dist/ssh/gateway/environment.js +78 -0
  132. package/dist/ssh/gateway/environment.js.map +1 -0
  133. package/dist/ssh/gateway/forward.d.ts +74 -0
  134. package/dist/ssh/gateway/forward.d.ts.map +1 -0
  135. package/dist/ssh/gateway/forward.js +247 -0
  136. package/dist/ssh/gateway/forward.js.map +1 -0
  137. package/dist/ssh/gateway/preflight.d.ts +28 -0
  138. package/dist/ssh/gateway/preflight.d.ts.map +1 -0
  139. package/dist/ssh/gateway/preflight.js +234 -0
  140. package/dist/ssh/gateway/preflight.js.map +1 -0
  141. package/dist/ssh/model.d.ts +65 -0
  142. package/dist/ssh/model.d.ts.map +1 -0
  143. package/dist/ssh/model.js +2 -0
  144. package/dist/ssh/model.js.map +1 -0
  145. package/dist/ssh/preflight.d.ts +16 -0
  146. package/dist/ssh/preflight.d.ts.map +1 -0
  147. package/dist/ssh/preflight.js +47 -0
  148. package/dist/ssh/preflight.js.map +1 -0
  149. package/dist/ssh/ssh.d.ts +20 -0
  150. package/dist/ssh/ssh.d.ts.map +1 -0
  151. package/dist/ssh/ssh.js +78 -0
  152. package/dist/ssh/ssh.js.map +1 -0
  153. package/dist/ssh/workers.d.ts +53 -0
  154. package/dist/ssh/workers.d.ts.map +1 -0
  155. package/dist/ssh/workers.js +173 -0
  156. package/dist/ssh/workers.js.map +1 -0
  157. package/package.json +12 -4
  158. package/dist/exe-dev/channel.d.ts +0 -11
  159. package/dist/exe-dev/channel.d.ts.map +0 -1
  160. package/dist/exe-dev/channel.js +0 -41
  161. package/dist/exe-dev/channel.js.map +0 -1
  162. package/dist/exe-dev/shell.d.ts +0 -12
  163. package/dist/exe-dev/shell.d.ts.map +0 -1
  164. package/dist/exe-dev/shell.js +0 -31
  165. package/dist/exe-dev/shell.js.map +0 -1
  166. package/dist/exe-dev/sweep.d.ts +0 -10
  167. package/dist/exe-dev/sweep.d.ts.map +0 -1
  168. package/dist/exe-dev/sweep.js +0 -117
  169. package/dist/exe-dev/sweep.js.map +0 -1
  170. package/dist/invalid-frame.d.ts +0 -17
  171. package/dist/invalid-frame.d.ts.map +0 -1
  172. package/dist/invalid-frame.js +0 -111
  173. package/dist/invalid-frame.js.map +0 -1
  174. package/dist/run-host-session.d.ts +0 -26
  175. package/dist/run-host-session.d.ts.map +0 -1
  176. package/dist/run-host-session.js +0 -241
  177. package/dist/run-host-session.js.map +0 -1
package/dist/provision.js CHANGED
@@ -1,50 +1,110 @@
1
1
  import * as AttemptChannel from "@usine/core/attempt/channel";
2
- import { RepositoryName, CommitSha } from "@usine/core/repository";
3
- import { Effect, Schema } from "effect";
2
+ import { SalvagePushed, } from "@usine/core/attempt/salvage";
3
+ import { RepositoryName, CommitSha, safeSegment } from "@usine/core/repository";
4
+ import { DateTime, Deferred, Effect, Exit, Option, Ref, Result, Schema } from "effect";
4
5
  import { ExecutorOperationError, AttemptWorkspace, WorktreePath, } from "./executor.js";
5
- export const safeSegment = (value) => value.replaceAll(/[^A-Za-z0-9_.-]/gu, "_");
6
+ import { PRE_PUSH_HOOKS_DIRECTORY, prePushHook } from "./pre-push-hook.js";
7
+ import { failureMessage, SALVAGE_GIT_CONFIG, salvageWorktree } from "./salvage.js";
6
8
  const CACHE_DIRECTORY_SUFFIX = ".git";
7
- /** The bare cache directory name for a repository under `repos/`, shared by every adapter. */
9
+ /** Returns the bare cache directory name for `repository` under `repos/`. */
8
10
  export const cacheDirectoryName = (repository) => `${safeSegment(repository)}${CACHE_DIRECTORY_SUFFIX}`;
9
11
  /**
10
- * Whether a `repos/` entry is one of our bare caches, decided by the name we
11
- * mint rather than by probing contents: a `HEAD` lookup fails with ENOTDIR on
12
- * a stray file, and a `.cloning` leftover or a tool's scratch directory must
13
- * never reach `git worktree prune`.
12
+ * Returns whether a `repos/` entry is a bare cache, by name only. Probing `HEAD` fails with
13
+ * ENOTDIR on a stray file, and a `.cloning` leftover or another tool's directory must never be
14
+ * passed to `git worktree prune`.
14
15
  */
15
16
  export const isCacheDirectoryName = (entry) => entry.length > CACHE_DIRECTORY_SUFFIX.length && entry.endsWith(CACHE_DIRECTORY_SUFFIX);
16
17
  const decodeCommit = Schema.decodeUnknownEffect(CommitSha);
18
+ /** Returns a function that runs one cleanup step and logs and ignores its failure, so later steps still run. */
19
+ const cleanupFor = (options) => (resource, effect) => effect.pipe(Effect.tapError((error) => Effect.logError("Attempt cleanup operation failed", {
20
+ attemptId: options.request.attemptId,
21
+ worker: options.request.worker,
22
+ host: options.host,
23
+ worktree: options.layout.worktree,
24
+ resource,
25
+ message: String(error),
26
+ })), Effect.ignore);
17
27
  /**
18
- * The clone-to-worktree sequence every Executor shares: clone into a staging
19
- * sibling and promote it on success, so an interrupted clone never leaves a
20
- * half-initialized cache that later fetches would poison; then fetch the
21
- * requested revision and check out a detached worktree at the resolved commit.
28
+ * Registers the checkout's finalizer. On a non-success exit, salvages a checked-out worktree
29
+ * before removing it; a worktree with unpreserved work stays on disk. `checkedOut` contains the
30
+ * base commit once a worktree exists.
22
31
  */
23
- export const provisionWorktree = Effect.fn("Executor.provisionWorktree")(function* (options) {
32
+ const registerRelease = Effect.fn("Executor.registerRelease")(function* (options) {
24
33
  const { layout, ops, request } = options;
25
- yield* Effect.annotateCurrentSpan({
26
- attemptId: request.attemptId,
27
- worker: request.worker,
28
- host: options.host,
29
- repository: request.repository,
30
- });
31
- const cleanup = (resource, effect) => effect.pipe(Effect.tapError((error) => Effect.logError("Attempt cleanup operation failed", {
32
- attemptId: request.attemptId,
33
- worker: request.worker,
34
- host: options.host,
35
- worktree: layout.worktree,
36
- resource,
37
- message: String(error),
38
- })), Effect.ignore);
39
- // Register before any filesystem mutation. This also covers failed worktree
40
- // creation, which can leave both a directory and a bare-cache registration.
41
- yield* Effect.addFinalizer(Effect.fn("Executor.releaseWorktree")(function* () {
34
+ const checkedOut = yield* Ref.make(Option.none());
35
+ const salvaged = yield* Deferred.make();
36
+ const recorder = yield* Ref.make(Option.none());
37
+ const cleanup = cleanupFor(options);
38
+ const kept = yield* Ref.make(false);
39
+ // `kept` is checked even after a successful launch: a failed result write keeps the checkout.
40
+ yield* Effect.addFinalizer(Effect.fn("Executor.releaseWorktree")(function* (exit) {
42
41
  yield* Effect.annotateCurrentSpan({
43
42
  attemptId: request.attemptId,
44
43
  worker: request.worker,
45
44
  repository: request.repository,
46
45
  host: options.host,
47
46
  });
47
+ if (yield* Ref.get(kept)) {
48
+ yield* Deferred.succeed(salvaged, Option.none());
49
+ yield* Effect.logInfo("Leaving the checkout in place for the Attempt's reattachment", {
50
+ attemptId: request.attemptId,
51
+ worker: request.worker,
52
+ host: options.host,
53
+ worktree: layout.worktree,
54
+ });
55
+ return;
56
+ }
57
+ const baseCommit = yield* Ref.get(checkedOut);
58
+ const salvage = Option.isSome(baseCommit) && !Exit.isSuccess(exit)
59
+ ? request.permissions === "read"
60
+ ? yield* Effect.logInfo("The Attempt's Loop has read permissions, so its checkout is removed without salvage", {
61
+ attemptId: request.attemptId,
62
+ worker: request.worker,
63
+ loop: request.loop,
64
+ host: options.host,
65
+ worktree: layout.worktree,
66
+ }).pipe(Effect.as(Option.none()))
67
+ : yield* salvageWorktree({
68
+ attemptId: request.attemptId,
69
+ worker: request.worker,
70
+ host: options.host,
71
+ worktree: layout.worktree,
72
+ baseCommit,
73
+ ref: request.salvageRef,
74
+ git: (args) => ops.git("cleanup", args),
75
+ })
76
+ : Option.none();
77
+ if (Option.isSome(salvage)) {
78
+ const record = yield* Ref.get(recorder);
79
+ if (Option.isNone(record)) {
80
+ yield* Deferred.succeed(salvaged, salvage);
81
+ yield* Effect.logWarning("Attempt worktree retained; no salvage recorder installed", {
82
+ attemptId: request.attemptId,
83
+ worktree: layout.worktree,
84
+ });
85
+ return;
86
+ }
87
+ const recorded = yield* Effect.result(record.value(salvage.value));
88
+ if (Result.isFailure(recorded)) {
89
+ yield* Deferred.fail(salvaged, recorded.failure);
90
+ yield* Effect.logError("Attempt salvage could not be recorded; checkout retained", {
91
+ attemptId: request.attemptId,
92
+ worktree: layout.worktree,
93
+ errorTag: recorded.failure._tag,
94
+ });
95
+ return;
96
+ }
97
+ }
98
+ yield* Deferred.succeed(salvaged, salvage);
99
+ if (Option.exists(salvage, ({ _tag }) => _tag === "Retained")) {
100
+ yield* Effect.logWarning("Attempt worktree retained; salvage did not preserve all work", {
101
+ attemptId: request.attemptId,
102
+ worker: request.worker,
103
+ host: options.host,
104
+ worktree: layout.worktree,
105
+ });
106
+ return;
107
+ }
48
108
  yield* Effect.logInfo("Cleaning Attempt workspace", {
49
109
  attemptId: request.attemptId,
50
110
  worker: request.worker,
@@ -70,6 +130,132 @@ export const provisionWorktree = Effect.fn("Executor.provisionWorktree")(functio
70
130
  yield* cleanup("cache-registration", ops.git("cleanup", ["--git-dir", layout.cache, "worktree", "prune"]));
71
131
  }
72
132
  }));
133
+ return {
134
+ checkedOut,
135
+ salvaged: Deferred.await(salvaged),
136
+ recordSalvage: (record) => Ref.set(recorder, Option.some(record)),
137
+ keepForReattach: Ref.set(kept, true),
138
+ };
139
+ });
140
+ /**
141
+ * For a `permissions: read` Loop, writes `prePushHook` to a hooks directory inside the
142
+ * checkout's git directory and returns the directory. Returns `None` for `write`.
143
+ */
144
+ const installPrePushHook = Effect.fn("Executor.installPrePushHook")(function* (options) {
145
+ const { layout, ops, request } = options;
146
+ const fields = {
147
+ attemptId: request.attemptId,
148
+ worker: request.worker,
149
+ loop: request.loop,
150
+ permissions: request.permissions,
151
+ host: options.host,
152
+ };
153
+ yield* Effect.annotateCurrentSpan(fields);
154
+ if (request.permissions === "write") {
155
+ yield* Effect.logDebug("The Attempt's Loop may push; its checkout keeps git's own hooks", fields);
156
+ return Option.none();
157
+ }
158
+ const gitDirectory = (yield* ops.git("prepare", [
159
+ "-C",
160
+ layout.worktree,
161
+ "rev-parse",
162
+ "--absolute-git-dir",
163
+ ])).trim();
164
+ const hooks = `${gitDirectory}/${PRE_PUSH_HOOKS_DIRECTORY}`;
165
+ yield* ops.writeExecutable(`${hooks}/pre-push`, prePushHook(request.loop));
166
+ yield* Effect.logInfo("The Attempt's Loop has read permissions; its checkout's pre-push hook explains a refused push", { ...fields, hooks });
167
+ return Option.some(hooks);
168
+ });
169
+ const withoutSalvage = { resume: Option.none(), conflicting: Option.none() };
170
+ /**
171
+ * Creates the Attempt's detached worktree at `base`, with the previous Attempt's salvage rebased
172
+ * on top if the request resumes one (#282). A salvage with no changes beyond `base` is dropped;
173
+ * one that doesn't rebase cleanly isn't applied.
174
+ */
175
+ const checkOutWorktree = Effect.fn("Executor.checkOutWorktree")(function* (options, base, salvage) {
176
+ const { layout, ops, request } = options;
177
+ const inCache = (args) => ops.git("prepare", ["--git-dir", layout.cache, ...args]);
178
+ const add = (commit) => inCache(["worktree", "add", "--detach", layout.worktree, commit]);
179
+ if (Option.isNone(salvage)) {
180
+ yield* add(base);
181
+ return withoutSalvage;
182
+ }
183
+ const { ref, commit } = salvage.value;
184
+ const fields = {
185
+ attemptId: request.attemptId,
186
+ worker: request.worker,
187
+ host: options.host,
188
+ ref,
189
+ commit,
190
+ base,
191
+ };
192
+ const setAside = (reason, message) => Effect.gen(function* () {
193
+ yield* Effect.logWarning(reason, { ...fields, message });
194
+ yield* add(base);
195
+ return { resume: Option.none(), conflicting: salvage };
196
+ });
197
+ const forkPoint = yield* inCache(["merge-base", base, commit]).pipe(Effect.map((output) => output.trim()), Effect.result);
198
+ if (Result.isFailure(forkPoint)) {
199
+ return yield* setAside("The previous salvage shares no history with the revision; the Attempt starts from the revision and the salvage stays on its branch", failureMessage(forkPoint.failure));
200
+ }
201
+ const changed = (yield* inCache(["diff", "--name-only", forkPoint.success, commit])).trim();
202
+ if (changed === "") {
203
+ yield* Effect.logInfo("The previous salvage holds no changes beyond the revision; the Attempt starts from the revision", fields);
204
+ yield* add(base);
205
+ return withoutSalvage;
206
+ }
207
+ yield* add(commit);
208
+ if (forkPoint.success === base) {
209
+ yield* Effect.logInfo("Resuming the Attempt from the previous salvage", fields);
210
+ return { resume: salvage, conflicting: Option.none() };
211
+ }
212
+ const rebased = yield* ops
213
+ .git("prepare", [
214
+ "-C",
215
+ layout.worktree,
216
+ ...SALVAGE_GIT_CONFIG,
217
+ "rebase",
218
+ "--no-verify",
219
+ "--onto",
220
+ base,
221
+ forkPoint.success,
222
+ ])
223
+ .pipe(Effect.result);
224
+ if (Result.isFailure(rebased)) {
225
+ yield* inCache(["worktree", "remove", "--force", layout.worktree]);
226
+ return yield* setAside("The previous salvage does not rebase onto the revision; the Attempt starts from the revision and the salvage stays on its branch", failureMessage(rebased.failure));
227
+ }
228
+ const rebasedHead = (yield* ops.git("prepare", [
229
+ "-C",
230
+ layout.worktree,
231
+ "rev-parse",
232
+ "HEAD",
233
+ ])).trim();
234
+ if (rebasedHead === base) {
235
+ yield* Effect.logInfo("The revision already holds the previous salvage's changes; the Attempt starts from the revision", fields);
236
+ return withoutSalvage;
237
+ }
238
+ yield* Effect.logInfo("Resuming the Attempt from the previous salvage, rebased onto the revision", { ...fields, forkPoint: forkPoint.success, rebasedHead });
239
+ return { resume: salvage, conflicting: Option.none() };
240
+ });
241
+ /**
242
+ * Clones into a staging directory and promotes it on success, fetches the requested revision,
243
+ * and checks out a detached worktree at the resolved commit, applying the previous Attempt's
244
+ * salvage if the request resumes one. Registers the release finalizer before the first
245
+ * filesystem change.
246
+ */
247
+ export const provisionWorktree = Effect.fn("Executor.provisionWorktree")(function* (options) {
248
+ const { layout, ops, request } = options;
249
+ yield* Effect.annotateCurrentSpan({
250
+ attemptId: request.attemptId,
251
+ worker: request.worker,
252
+ host: options.host,
253
+ repository: request.repository,
254
+ });
255
+ // Registered first so a failed worktree creation, which can leave a directory and a
256
+ // bare-cache registration, is also cleaned up.
257
+ const release = yield* registerRelease(options);
258
+ const cleanup = cleanupFor(options);
73
259
  yield* ops.ensureRoots;
74
260
  yield* ops.removePath("prepare", layout.worktree);
75
261
  if (yield* ops.cacheExists) {
@@ -83,8 +269,8 @@ export const provisionWorktree = Effect.fn("Executor.provisionWorktree")(functio
83
269
  ]);
84
270
  }
85
271
  else {
86
- // Staging belongs to this locked clone only. Release it before unlocking,
87
- // including interruption between clone completion and cache promotion.
272
+ // Removes the staging clone before releasing the lock, including on interruption between
273
+ // clone and promotion.
88
274
  yield* Effect.scoped(Effect.gen(function* () {
89
275
  yield* Effect.addFinalizer(() => cleanup("partial-clone", ops.removePath("cleanup", layout.staging)));
90
276
  yield* ops.removePath("prepare", layout.staging);
@@ -115,33 +301,149 @@ export const provisionWorktree = Effect.fn("Executor.provisionWorktree")(functio
115
301
  ])).trim();
116
302
  const baseCommit = yield* decodeCommit(resolved).pipe(Effect.mapError((cause) => new ExecutorOperationError({
117
303
  operation: "prepare",
118
- message: "git returned an invalid object id",
304
+ message: "Git returned an invalid object ID",
119
305
  cause,
120
306
  })));
121
- yield* ops.git("prepare", [
122
- "--git-dir",
123
- layout.cache,
124
- "worktree",
125
- "add",
126
- "--detach",
127
- layout.worktree,
128
- baseCommit,
129
- ]);
130
- return new AttemptWorkspace({
307
+ const salvage = yield* fetchSalvage(options, request.resume);
308
+ const checkout = yield* checkOutWorktree(options, baseCommit, salvage);
309
+ yield* Ref.set(release.checkedOut, Option.some(baseCommit));
310
+ const gitHooks = yield* installPrePushHook(options);
311
+ const preparedAt = yield* DateTime.now;
312
+ return {
313
+ workspace: new AttemptWorkspace({
314
+ worker: request.worker,
315
+ spec: new AttemptChannel.RunSpec({
316
+ attemptId: request.attemptId,
317
+ repository: request.repository,
318
+ revision: request.revision,
319
+ baseCommit,
320
+ payload: request.payload,
321
+ task: request.task,
322
+ agent: request.agent,
323
+ parentModel: request.parentModel,
324
+ maxChildren: request.maxChildren,
325
+ parentEffort: request.parentEffort,
326
+ resume: checkout.resume,
327
+ conflictingSalvage: checkout.conflicting,
328
+ preparedAt: Option.some(preparedAt),
329
+ botLogin: request.botLogin,
330
+ }),
331
+ worktree: WorktreePath.make(layout.worktree),
332
+ }),
333
+ salvaged: release.salvaged,
334
+ recordSalvage: release.recordSalvage,
335
+ keepForReattach: release.keepForReattach,
336
+ gitHooks,
337
+ };
338
+ });
339
+ /**
340
+ * Reuses an Attempt's checkout after an orchestrator restart without cloning, fetching, or
341
+ * checking out. The same release as a new checkout salvages and removes it when the Attempt
342
+ * ends.
343
+ */
344
+ export const reattachWorktree = Effect.fn("Executor.reattachWorktree")(function* (options) {
345
+ const { layout, request, spec } = options;
346
+ yield* Effect.annotateCurrentSpan({
347
+ attemptId: request.attemptId,
131
348
  worker: request.worker,
132
- spec: new AttemptChannel.RunSpec({
133
- attemptId: request.attemptId,
134
- repository: request.repository,
135
- revision: request.revision,
136
- baseCommit,
137
- payload: request.payload,
138
- task: request.task,
139
- agent: request.agent,
140
- parentModel: request.parentModel,
141
- maxChildren: request.maxChildren,
142
- parentEffort: request.parentEffort,
349
+ host: options.host,
350
+ repository: request.repository,
351
+ });
352
+ const release = yield* registerRelease(options);
353
+ yield* Ref.set(release.checkedOut, Option.some(spec.baseCommit));
354
+ const gitHooks = yield* installPrePushHook(options);
355
+ return {
356
+ workspace: new AttemptWorkspace({
357
+ worker: request.worker,
358
+ spec,
359
+ worktree: WorktreePath.make(layout.worktree),
143
360
  }),
144
- worktree: WorktreePath.make(layout.worktree),
361
+ salvaged: release.salvaged,
362
+ recordSalvage: release.recordSalvage,
363
+ keepForReattach: release.keepForReattach,
364
+ gitHooks,
365
+ };
366
+ });
367
+ /**
368
+ * Reconciles a checkout left by an earlier process: salvages it without a known base, records
369
+ * the result, and removes the worktree only after its work is pushed. Checkouts of succeeded
370
+ * Attempts and of `permissions: read` Loops are removed without salvage.
371
+ */
372
+ export const recoverWorktree = Effect.fn("Executor.recoverWorktree")(function* (options, record) {
373
+ const { attempt, host, worktree } = options;
374
+ yield* Effect.annotateCurrentSpan({ ...attempt, host, worktree });
375
+ if (attempt.succeeded || attempt.permissions === "read") {
376
+ yield* options.git(["--git-dir", options.cache, "worktree", "remove", "--force", worktree]);
377
+ yield* Effect.logInfo(attempt.succeeded
378
+ ? "Released the checkout of a succeeded Attempt"
379
+ : "Released the checkout of an Attempt whose Loop has read permissions, without salvage", { ...attempt, host, worktree });
380
+ return;
381
+ }
382
+ const salvage = yield* salvageWorktree({
383
+ ...attempt,
384
+ host,
385
+ worktree,
386
+ baseCommit: Option.none(),
387
+ git: options.git,
145
388
  });
389
+ if (Option.isNone(salvage))
390
+ return;
391
+ yield* record(salvage.value);
392
+ if (salvage.value._tag === "Retained")
393
+ return;
394
+ yield* options.git(["--git-dir", options.cache, "worktree", "remove", "--force", worktree]);
395
+ yield* Effect.logInfo("Reconciled and released Attempt salvage", { ...attempt, host, worktree });
396
+ });
397
+ /**
398
+ * Fetches the previous Attempt's salvage ref into the cache. If the ref no longer exists, logs
399
+ * a warning and the Attempt starts from its base revision.
400
+ */
401
+ const fetchSalvage = Effect.fn("Executor.fetchSalvage")(function* (options, resume) {
402
+ if (Option.isNone(resume))
403
+ return Option.none();
404
+ const { layout, ops, request } = options;
405
+ const fields = {
406
+ attemptId: request.attemptId,
407
+ worker: request.worker,
408
+ host: options.host,
409
+ ref: resume.value.ref,
410
+ };
411
+ yield* Effect.annotateCurrentSpan(fields);
412
+ const ref = `refs/heads/${resume.value.ref}`;
413
+ const advertised = yield* ops.git("prepare", [
414
+ "--git-dir",
415
+ layout.cache,
416
+ "ls-remote",
417
+ "--heads",
418
+ "origin",
419
+ ref,
420
+ ]);
421
+ if (advertised.trim() === "") {
422
+ yield* Effect.logWarning("Salvage ref deleted; the Attempt starts from its base revision", fields);
423
+ return Option.none();
424
+ }
425
+ const fetched = yield* ops
426
+ .git("prepare", [
427
+ "--git-dir",
428
+ layout.cache,
429
+ "fetch",
430
+ "--force",
431
+ "origin",
432
+ `refs/heads/${resume.value.ref}`,
433
+ ])
434
+ .pipe(Effect.andThen(ops.git("prepare", ["--git-dir", layout.cache, "rev-parse", "FETCH_HEAD"])), Effect.flatMap((output) => decodeCommit(output.trim()).pipe(Effect.mapError((cause) => new ExecutorOperationError({
435
+ operation: "prepare",
436
+ message: "Git returned an invalid salvage object ID",
437
+ cause,
438
+ })))));
439
+ if (fetched !== resume.value.commit) {
440
+ yield* Effect.logWarning("Salvage ref moved since it was recorded; resuming from its head", {
441
+ ...fields,
442
+ recorded: resume.value.commit,
443
+ current: fetched,
444
+ });
445
+ }
446
+ yield* Effect.logInfo("Fetched the previous Attempt's salvage", { ...fields, commit: fetched });
447
+ return Option.some(new SalvagePushed({ ref: resume.value.ref, commit: fetched }));
146
448
  });
147
449
  //# sourceMappingURL=provision.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"provision.js","sourceRoot":"","sources":["../src/provision.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"provision.js","sourceRoot":"","sources":["../src/provision.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ import { type HostInvocation, RemoteShell, type SshCommand } from "@usine/agents/child-host";
2
+ import type { SshDestination } from "@usine/core/worker";
3
+ import { Effect, Redacted } from "effect";
4
+ import { ChildProcessSpawner } from "effect/unstable/process";
5
+ import { type CommandResult } from "../child-command.ts";
6
+ import type { ExecutorOperation, ExecutorOperationError } from "../executor.ts";
7
+ /**
8
+ * The working directory and extra environment for a remote command. `scrub` is applied to the
9
+ * output first, so a credential printed by git or gh isn't kept in any error, log, or parsed
10
+ * result.
11
+ */
12
+ export interface RemoteContext extends Pick<HostInvocation, "cwd" | "environment"> {
13
+ readonly scrub?: (text: string) => string;
14
+ }
15
+ export interface RemoteCommands {
16
+ /** Returns the shell for one machine, used by the Attempt's children and the commands below. */
17
+ readonly shellFor: (ssh: SshCommand, destination: SshDestination) => RemoteShell;
18
+ /** Runs a local command, such as the exe.dev lobby, with only the SSH client's environment. */
19
+ readonly local: (operation: ExecutorOperation, host: string, command: string, args: ReadonlyArray<string>) => Effect.Effect<string, ExecutorOperationError>;
20
+ /** Runs a remote command and returns its exit code and output without checking the exit code. */
21
+ readonly inspect: (operation: ExecutorOperation, shell: RemoteShell, command: string, args: ReadonlyArray<string>) => Effect.Effect<CommandResult, ExecutorOperationError>;
22
+ /** Runs a remote command and returns its stdout. Fails if it exits non-zero. */
23
+ readonly run: (operation: ExecutorOperation, shell: RemoteShell, command: string, args: ReadonlyArray<string>, context?: RemoteContext) => Effect.Effect<string, ExecutorOperationError>;
24
+ /** Runs a remote command with `input` on stdin, so a secret isn't in the command line or logs. */
25
+ readonly runWithInput: (operation: ExecutorOperation, shell: RemoteShell, command: string, args: ReadonlyArray<string>, input: Redacted.Redacted<string>) => Effect.Effect<string, ExecutorOperationError>;
26
+ }
27
+ /**
28
+ * The variables the local SSH client inherits. GitHub and factory credentials in the
29
+ * orchestrator environment aren't passed to the client or the machine.
30
+ */
31
+ export declare const SSH_ENVIRONMENT_ALLOWLIST: readonly ["HOME", "LANG", "LC_ALL", "PATH", "SHELL", "SSH_AGENT_PID", "SSH_AUTH_SOCK", "TMPDIR", "USER"];
32
+ /**
33
+ * The default SSH client for remote Workers. Its keepalive options make a dead TCP connection
34
+ * exit non-zero instead of hanging.
35
+ */
36
+ export declare const DEFAULT_SSH: SshCommand;
37
+ /**
38
+ * Returns `shell` with `variables` sent through OpenSSH `SendEnv` instead of the command line,
39
+ * so the values aren't in arguments, logs, or process listings. The remote sshd drops names
40
+ * not in its `AcceptEnv`.
41
+ */
42
+ export declare const sendingShell: (shell: RemoteShell, variables: Readonly<Record<string, Redacted.Redacted<string>>>) => RemoteShell;
43
+ /** The `RemoteCommands` that use this process's spawner and the allowlisted SSH environment. */
44
+ export declare const remoteCommandsFor: Effect.Effect<{
45
+ shellFor: (ssh: SshCommand, destination: SshDestination) => RemoteShell;
46
+ local: (operation: "cancel" | "cleanup" | "launch" | "preflight" | "prepare", host: string, command: string, args: readonly string[]) => Effect.Effect<string, ExecutorOperationError, never>;
47
+ inspect: (operation: ExecutorOperation, shell: RemoteShell, command: string, args: ReadonlyArray<string>) => Effect.Effect<CommandResult, ExecutorOperationError>;
48
+ run: (operation: "cancel" | "cleanup" | "launch" | "preflight" | "prepare", shell: RemoteShell, command: string, args: readonly string[], context?: RemoteContext | undefined) => Effect.Effect<string, ExecutorOperationError, never>;
49
+ runWithInput: (operation: "cancel" | "cleanup" | "launch" | "preflight" | "prepare", shell: RemoteShell, command: string, args: readonly string[], input: Redacted.Redacted<string>) => Effect.Effect<string, ExecutorOperationError, never>;
50
+ }, never, ChildProcessSpawner.ChildProcessSpawner>;
51
+ //# sourceMappingURL=commands.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/remote/commands.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,cAAc,EACnB,WAAW,EACX,KAAK,UAAU,EAEhB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAU,MAAM,QAAQ,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAGL,KAAK,aAAa,EAEnB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAEhF;;;;GAIG;AACH,MAAM,WAAW,aAAc,SAAQ,IAAI,CAAC,cAAc,EAAE,KAAK,GAAG,aAAa,CAAC;IAChF,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;CAC3C;AAED,MAAM,WAAW,cAAc;IAC7B,gGAAgG;IAChG,QAAQ,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,UAAU,EAAE,WAAW,EAAE,cAAc,KAAK,WAAW,CAAC;IACjF,+FAA+F;IAC/F,QAAQ,CAAC,KAAK,EAAE,CACd,SAAS,EAAE,iBAAiB,EAC5B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,KACxB,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;IACnD,iGAAiG;IACjG,QAAQ,CAAC,OAAO,EAAE,CAChB,SAAS,EAAE,iBAAiB,EAC5B,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,KACxB,MAAM,CAAC,MAAM,CAAC,aAAa,EAAE,sBAAsB,CAAC,CAAC;IAC1D,gFAAgF;IAChF,QAAQ,CAAC,GAAG,EAAE,CACZ,SAAS,EAAE,iBAAiB,EAC5B,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,EAC3B,OAAO,CAAC,EAAE,aAAa,KACpB,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;IACnD,kGAAkG;IAClG,QAAQ,CAAC,YAAY,EAAE,CACrB,SAAS,EAAE,iBAAiB,EAC5B,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,EAC3B,KAAK,EAAE,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,KAC7B,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;CACpD;AAED;;;GAGG;AACH,eAAO,MAAM,yBAAyB,YACpC,MAAM,EACN,MAAM,EACN,QAAQ,EACR,MAAM,EACN,OAAO,EACP,eAAe,EACf,eAAe,EACf,QAAQ,EACR,MAAM,CACE,CAAC;AAEX;;;GAGG;AACH,eAAO,MAAM,WAAW,EAAE,UAGzB,CAAC;AAIF;;;;GAIG;AACH,eAAO,MAAM,YAAY,UAChB,WAAW,aACP,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,KAC7D,WAcF,CAAC;AAEF,gGAAgG;AAChG,eAAO,MAAM,iBAAiB;oBAIL,UAAU,eAAe,cAAc;;yBA4BjD,iBAAiB,SACrB,WAAW,WACT,MAAM,QACT,aAAa,CAAC,MAAM,CAAC,KAC1B,MAAM,CAAC,MAAM,CAAC,aAAa,EAAE,sBAAsB,CAAC;;;kDAuDvD,CAAC"}