@usine/executor 0.2.1 → 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 -128
  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 +140 -41
  38. package/dist/executor.d.ts.map +1 -1
  39. package/dist/executor.js +90 -19
  40. package/dist/executor.js.map +1 -1
  41. package/dist/guard.d.ts +57 -7
  42. package/dist/guard.d.ts.map +1 -1
  43. package/dist/guard.js +273 -59
  44. package/dist/guard.js.map +1 -1
  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 +163 -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 -31
  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 -12
  159. package/dist/exe-dev/channel.d.ts.map +0 -1
  160. package/dist/exe-dev/channel.js +0 -42
  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 -27
  175. package/dist/run-host-session.d.ts.map +0 -1
  176. package/dist/run-host-session.js +0 -303
  177. package/dist/run-host-session.js.map +0 -1
@@ -1,21 +1,25 @@
1
+ import { workerLeftoversFor } from "./leftovers.js";
2
+ import { localCredentialsFor } from "./credentials.js";
3
+ import { LocalProcess } from "@usine/agents/child-host";
4
+ import { ClaudeLoginLock } from "@usine/agents/runtime";
1
5
  import * as AttemptChannel from "@usine/core/attempt/channel";
2
- import { RepositoryName } from "@usine/core/repository";
6
+ import { InfraFailure } from "@usine/core/attempt/failure";
7
+ import { RepositoryName, safeSegment } from "@usine/core/repository";
3
8
  import { InstanceDirectory } from "@usine/core/instance";
4
- import { Effect, FileSystem, Layer, Path, Redacted, Result, Schema, Stream, } from "effect";
5
- import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process";
9
+ import { harvestFacts, harvestPostedComments, } from "@usine/core/step/harvest";
10
+ import { Effect, FileSystem, Layer, Option, Path, Result, Schema, } from "effect";
11
+ import { ChildProcessSpawner } from "effect/unstable/process";
12
+ import { platform, totalmem } from "node:os";
6
13
  import { allowlistedEnvironment, collectCommand, requireSuccess } from "../child-command.js";
14
+ import { durableSessionFor } from "../durable-session.js";
7
15
  import { CheckoutRequest, CredentialProvider, Executor, ExecutorError, ExecutorOperationError, logPreflightFailure, WorkerCapabilityError, } from "../executor.js";
8
- import { verifyHarnesses } from "../harness-preflight.js";
9
- import { prepareAttempt } from "../prepared-attempt.js";
16
+ import { agentsHarnessProbe, verifyHarnessReadiness, } from "../harness-preflight.js";
10
17
  import { keyedLockFor } from "../keyed-lock.js";
11
- import { cacheDirectoryName, isCacheDirectoryName, provisionWorktree, safeSegment, } from "../provision.js";
12
- import { runHostSessionFor } from "../run-host-session.js";
18
+ import { withGitHooks } from "../pre-push-hook.js";
19
+ import { SwapOnDemand, verifyLinuxMemory, verifyWorkerMemory, WorkerMemory, } from "../memory-preflight.js";
20
+ import { cacheDirectoryName, isCacheDirectoryName, provisionWorktree, reattachWorktree, recoverWorktree, } from "../provision.js";
13
21
  const isExecutorError = Schema.is(ExecutorError);
14
- /**
15
- * The run host inherits only these variables. The App private key and every
16
- * other orchestrator secret stay out; the single-repo worker token is the only
17
- * credential it receives (ADR 0011).
18
- */
22
+ /** The only process variables passed to an Attempt's git and gh commands (ADR 0011). */
19
23
  const HOST_ENVIRONMENT_ALLOWLIST = [
20
24
  "HOME",
21
25
  "LANG",
@@ -26,31 +30,20 @@ const HOST_ENVIRONMENT_ALLOWLIST = [
26
30
  "USER",
27
31
  ];
28
32
  const executorError = (operation, message, cause) => new ExecutorOperationError({ operation, message, cause });
29
- /** Removes the credential from text before it can reach a persisted error message. */
30
- const scrubbed = (text, credential) => text.replaceAll(Redacted.value(credential), "[REDACTED]");
31
- const credentialEnvironment = (base, credential) => {
32
- const token = Redacted.value(credential);
33
- return {
34
- ...base,
35
- GH_TOKEN: token,
36
- GITHUB_TOKEN: token,
37
- GIT_CONFIG_COUNT: "1",
38
- GIT_CONFIG_KEY_0: "credential.helper",
39
- GIT_CONFIG_VALUE_0: "!f() { echo username=x-access-token; echo password=$GITHUB_TOKEN; }; f",
40
- };
41
- };
42
33
  const makeLocalExecutor = (options) => Effect.gen(function* () {
43
- const credentials = yield* CredentialProvider;
34
+ const credentials = yield* localCredentialsFor;
44
35
  const fileSystem = yield* FileSystem.FileSystem;
45
36
  const path = yield* Path.Path;
46
37
  const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;
47
38
  const fetches = yield* keyedLockFor();
39
+ const logins = yield* ClaudeLoginLock;
48
40
  const baseEnvironment = yield* allowlistedEnvironment(HOST_ENVIRONMENT_ALLOWLIST);
41
+ const harnessReadiness = options.harnessReadiness ?? agentsHarnessProbe(spawner, new LocalProcess(), baseEnvironment);
49
42
  const repositoryUrl = options.repositoryUrl ??
50
43
  ((repository) => `https://github.com/${repository}.git`);
51
- const runHost = options.runHost;
52
44
  const interruptGrace = options.interruptGrace ?? "2 seconds";
53
45
  const workersRoot = path.join(options.instanceDirectory, ".usine", "workers");
46
+ const session = yield* durableSessionFor({ interruptGrace });
54
47
  const executeCommand = Effect.fn("LocalExecutor.executeCommand")(function* (operation, command, args, commandOptions = {}) {
55
48
  yield* Effect.annotateCurrentSpan({ host: "local", operation });
56
49
  const result = yield* collectCommand(spawner, operation, command, args, {
@@ -63,27 +56,27 @@ const makeLocalExecutor = (options) => Effect.gen(function* () {
63
56
  const run = Effect.fn("LocalExecutor.run")(function* (operation, command, args, commandOptions = {}) {
64
57
  yield* executeCommand(operation, command, args, commandOptions);
65
58
  });
66
- // Worktrees never outlive their Attempt (ADR 0006). A crashed orchestrator
67
- // leaves directories and bare-cache registrations behind; the sweep reclaims
68
- // them at the next layer build, before new Attempts start.
59
+ // Git can print the token in diagnostics, so output is scrubbed before it's put in an error or
60
+ // parsed.
61
+ const credentialedGit = (credential) => (operation, args) => Effect.gen(function* () {
62
+ yield* credential.refresh();
63
+ const result = yield* collectCommand(spawner, operation, "git", args, {
64
+ env: credential.environment,
65
+ extendEnv: false,
66
+ });
67
+ return yield* requireSuccess(operation, "local", "git", args, {
68
+ ...result,
69
+ stdout: credential.scrub(result.stdout),
70
+ stderr: credential.scrub(result.stderr),
71
+ });
72
+ });
73
+ // Startup only prunes worktree registrations whose directories are gone; recovery removes
74
+ // checkouts. Unknown leftovers and checkouts awaiting reattachment stay on disk.
69
75
  const sweepAbandonedWorktrees = Effect.fn("LocalExecutor.sweepAbandonedWorktrees")(function* () {
70
76
  if (!(yield* fileSystem.exists(workersRoot)))
71
77
  return;
72
78
  const workers = yield* fileSystem.readDirectory(workersRoot);
73
79
  for (const worker of workers) {
74
- const attemptsRoot = path.join(workersRoot, worker, "attempts");
75
- if (yield* fileSystem.exists(attemptsRoot)) {
76
- const leftovers = yield* fileSystem.readDirectory(attemptsRoot);
77
- for (const leftover of leftovers) {
78
- const target = path.join(attemptsRoot, leftover);
79
- yield* Effect.logInfo("Sweeping abandoned Attempt worktree", {
80
- worker,
81
- host: "local",
82
- worktree: target,
83
- });
84
- yield* fileSystem.remove(target, { recursive: true, force: true });
85
- }
86
- }
87
80
  const reposRoot = path.join(workersRoot, worker, "repos");
88
81
  if (yield* fileSystem.exists(reposRoot)) {
89
82
  const entries = yield* fileSystem.readDirectory(reposRoot);
@@ -131,58 +124,110 @@ const makeLocalExecutor = (options) => Effect.gen(function* () {
131
124
  yield* sweepAbandonedWorktrees().pipe(Effect.tapError((error) => Effect.logWarning("Abandoned-worktree sweep failed; continuing", {
132
125
  message: String(error),
133
126
  })), Effect.ignore);
134
- const preflight = Effect.fn("LocalExecutor.preflight")(function* (worker, brains) {
135
- yield* Effect.annotateCurrentSpan({ worker, host: "local" });
127
+ const workerLeftovers = yield* workerLeftoversFor(workersRoot);
128
+ const harvestCommand = (operation, worktree, credential, environment) => (command, args) => Effect.gen(function* () {
129
+ yield* credential.refresh();
130
+ const result = yield* collectCommand(spawner, operation, command, args, {
131
+ cwd: worktree,
132
+ env: environment,
133
+ extendEnv: false,
134
+ });
135
+ const stdout = yield* requireSuccess(operation, "local", command, args, {
136
+ ...result,
137
+ stdout: credential.scrub(result.stdout),
138
+ stderr: credential.scrub(result.stderr),
139
+ });
140
+ return stdout === "" ? [] : stdout.replace(/\n$/u, "").split("\n");
141
+ });
142
+ const recover = Effect.fn("LocalExecutor.recover")(function* (attempt, record) {
143
+ yield* Effect.annotateCurrentSpan({ ...attempt, host: "local" });
144
+ yield* session.stopForRecovery(attempt);
145
+ const root = path.join(workersRoot, attempt.worker);
146
+ const worktree = path.join(root, "attempts", safeSegment(attempt.attemptId));
147
+ const present = (yield* workerLeftovers(attempt.worker)).has(worktree) &&
148
+ (yield* fileSystem.exists(worktree));
149
+ yield* session.recoverPostedComments(attempt, present
150
+ ? Option.some((spec, windows) => Effect.scoped(Effect.gen(function* () {
151
+ const credential = yield* credentials(attempt.repository, attempt.attemptId, attempt.permissions, baseEnvironment);
152
+ return yield* harvestPostedComments(spec, harvestCommand("cleanup", worktree, credential, credential.environment), windows);
153
+ })))
154
+ : Option.none(), record);
155
+ if (!present)
156
+ return;
157
+ const cache = path.join(root, "repos", cacheDirectoryName(attempt.repository));
158
+ if (attempt.succeeded || attempt.permissions === "read") {
159
+ return yield* recoverWorktree({
160
+ attempt,
161
+ host: "local",
162
+ worktree,
163
+ cache,
164
+ git: (args) => executeCommand("cleanup", "git", args),
165
+ }, record.salvage);
166
+ }
167
+ yield* Effect.scoped(Effect.gen(function* () {
168
+ const credential = yield* credentials(attempt.repository, attempt.attemptId, attempt.permissions, baseEnvironment);
169
+ const git = credentialedGit(credential);
170
+ yield* recoverWorktree({ attempt, host: "local", worktree, cache, git: (args) => git("cleanup", args) }, record.salvage);
171
+ }));
172
+ });
173
+ const preflight = Effect.fn("LocalExecutor.preflight")(function* (worker, brains, maxConcurrentAttempts) {
174
+ yield* Effect.annotateCurrentSpan({ worker, host: "local", maxConcurrentAttempts });
136
175
  const gitVersion = (yield* executeCommand("preflight", "git", ["--version"])).trim();
137
176
  if (!gitVersion.startsWith("git version ")) {
138
177
  return yield* new WorkerCapabilityError({
139
178
  worker,
140
179
  capability: "toolchain",
141
- message: `Worker ${worker} returned an unrecognized git version`,
180
+ message: `Worker "${worker}" returned an unrecognized Git version`,
142
181
  cause: new Error(gitVersion),
143
182
  });
144
183
  }
145
- const reported = (yield* executeCommand("preflight", runHost.command, [
146
- ...runHost.args,
147
- "--protocol-version",
148
- ])).trim();
149
- if (reported !== String(AttemptChannel.PROTOCOL_VERSION)) {
150
- return yield* new WorkerCapabilityError({
151
- worker,
152
- capability: "run-host",
153
- message: `Worker ${worker} has run-host protocol ${reported || "unknown"}; expected ${AttemptChannel.PROTOCOL_VERSION}`,
154
- cause: new Error("run-host protocol mismatch"),
155
- });
156
- }
157
- yield* verifyHarnesses(worker, brains, runHost, (command, args) => executeCommand("preflight", command, args));
184
+ // macOS has no /proc/meminfo and adds swap files as memory runs short.
185
+ yield* platform() === "darwin"
186
+ ? verifyWorkerMemory(worker, maxConcurrentAttempts, new WorkerMemory({ totalBytes: totalmem(), swap: SwapOnDemand.make({}) }))
187
+ : verifyLinuxMemory(worker, maxConcurrentAttempts, executeCommand("preflight", "cat", ["/proc/meminfo"]));
188
+ yield* verifyHarnessReadiness(worker, brains, harnessReadiness, logins);
158
189
  yield* Effect.logInfo("Worker preflight verified", {
159
190
  worker,
160
191
  host: "local",
161
192
  gitVersion,
162
- protocolVersion: AttemptChannel.PROTOCOL_VERSION,
163
193
  });
164
194
  }, logPreflightFailure);
195
+ // Attempt commands receive only the allowlist and the Attempt's credential, never this
196
+ // process's environment, which contains the App private key (ADR 0011).
197
+ const attemptEnvironment = (workspace, credential) => ({
198
+ ...credential.environment,
199
+ // Turbo writes its cache next to the git common dir, which for a linked worktree is the bare
200
+ // cache. One cache per Worker, outside the directory the startup sweep treats as cache storage.
201
+ TURBO_CACHE_DIR: path.join(workersRoot, workspace.worker, "turbo"),
202
+ });
203
+ const harvest = (workspace, credential, environment, windows) => harvestFacts(workspace.spec, harvestCommand("launch", workspace.worktree, credential, environment), windows).pipe(Effect.mapError((error) => new InfraFailure({
204
+ message: `Can't harvest the attempt's checkout: ${error.message}`,
205
+ cause: error,
206
+ })));
165
207
  const prepare = Effect.fn("LocalExecutor.prepare")(function* (request) {
166
208
  yield* Effect.annotateCurrentSpan({
167
209
  attemptId: request.attemptId,
168
210
  worker: request.worker,
169
211
  host: "local",
170
212
  repository: request.repository,
213
+ loop: request.loop,
214
+ permissions: request.permissions,
215
+ reattach: request.reattach,
171
216
  });
172
- yield* verifyHarnesses(request.worker, [request.agent.brain], runHost, (command, args) => executeCommand("preflight", command, args));
173
- const credential = yield* Effect.acquireRelease(credentials.issue(request.repository, request.attemptId), (token) => Effect.sync(() => {
174
- Redacted.wipeUnsafe(token);
175
- }), { interruptible: true });
217
+ yield* verifyHarnessReadiness(request.worker, [request.agent.brain], harnessReadiness, logins);
218
+ const credential = yield* credentials(request.repository, request.attemptId, request.permissions, baseEnvironment);
176
219
  const workerRoot = path.join(workersRoot, request.worker);
177
220
  const cache = path.join(workerRoot, "repos", cacheDirectoryName(request.repository));
178
221
  const worktree = path.join(workerRoot, "attempts", safeSegment(request.attemptId));
179
- const environment = credentialEnvironment(baseEnvironment, credential);
180
- const commandOptions = { env: environment, extendEnv: false };
181
- yield* Effect.logInfo("Preparing Attempt workspace", {
222
+ yield* Effect.logInfo(request.reattach
223
+ ? "Reattaching the Attempt to its checkout"
224
+ : "Preparing Attempt workspace", {
182
225
  attemptId: request.attemptId,
183
226
  worker: request.worker,
184
227
  repository: request.repository,
185
228
  revision: request.revision,
229
+ loop: request.loop,
230
+ permissions: request.permissions,
186
231
  cache,
187
232
  worktree,
188
233
  });
@@ -192,83 +237,72 @@ const makeLocalExecutor = (options) => Effect.gen(function* () {
192
237
  removePath: remove,
193
238
  cacheExists: fileSystem.exists(cache),
194
239
  promoteStaging: fileSystem.rename(`${cache}.cloning`, cache),
195
- git: (operation, args) => Effect.gen(function* () {
196
- // Git can echo the ambient token in diagnostics. Scrub before forming
197
- // an error or passing its stdout to the revision parser.
198
- const result = yield* collectCommand(spawner, operation, "git", args, commandOptions);
199
- return yield* requireSuccess(operation, "local", "git", args, {
200
- ...result,
201
- stdout: scrubbed(result.stdout, credential),
202
- stderr: scrubbed(result.stderr, credential),
203
- });
204
- }),
240
+ git: credentialedGit(credential),
241
+ writeExecutable: (target, content) => fileSystem
242
+ .makeDirectory(path.dirname(target), { recursive: true })
243
+ .pipe(Effect.andThen(fileSystem.writeFileString(target, content, { mode: 0o755 }))),
205
244
  };
206
- const prepared = yield* fetches
207
- .withLock(request.repository)(provisionWorktree({
208
- request,
209
- url: repositoryUrl(request.repository),
210
- host: "local",
211
- layout: { cache, staging: `${cache}.cloning`, worktree },
212
- ops,
213
- }))
214
- .pipe(Effect.mapError((error) => isExecutorError(error)
245
+ const acquire = Effect.gen(function* () {
246
+ if (!request.reattach)
247
+ return yield* fetches.withLock(request.repository)(provisionWorktree({
248
+ request,
249
+ url: repositoryUrl(request.repository),
250
+ host: "local",
251
+ layout: { cache, staging: `${cache}.cloning`, worktree },
252
+ ops,
253
+ }));
254
+ if (!(yield* fileSystem.exists(worktree)))
255
+ return yield* executorError("prepare", "The reattached attempt's checkout no longer exists", new Error(worktree));
256
+ const { spec } = yield* session.storedRequest(request.attemptId);
257
+ return yield* reattachWorktree({
258
+ request,
259
+ host: "local",
260
+ layout: { cache, worktree },
261
+ ops,
262
+ spec,
263
+ });
264
+ });
265
+ const prepared = yield* acquire.pipe(Effect.mapError((error) => isExecutorError(error)
215
266
  ? error
216
- : executorError("prepare", "Attempt workspace preparation failed", error)));
267
+ : executorError("prepare", "Can't prepare the attempt workspace", error)));
217
268
  yield* Effect.logInfo("Attempt workspace ready", {
218
269
  attemptId: request.attemptId,
219
- baseCommit: prepared.spec.baseCommit,
270
+ baseCommit: prepared.workspace.spec.baseCommit,
271
+ resume: Option.map(prepared.workspace.spec.resume, ({ ref }) => ref),
272
+ reattach: request.reattach,
220
273
  worktree,
221
274
  });
275
+ const environment = withGitHooks(attemptEnvironment(prepared.workspace, credential), prepared.gitHooks);
222
276
  return {
223
- workspace: prepared,
224
- launch: (io) => session.launch(prepared, io, (input) => spawn(prepared, credential, input)),
225
- };
226
- }, prepareAttempt);
227
- const spawn = Effect.fn("LocalExecutor.spawnRunHost")(function* (prepared, credential, input) {
228
- const attemptId = prepared.spec.attemptId;
229
- yield* Effect.annotateCurrentSpan({
230
- attemptId,
231
- worker: prepared.worker,
232
- host: "local",
233
- });
234
- // A linked worktree's git common dir is the bare cache itself, and Turbo
235
- // puts its cache next to the common dir, so an unscoped run from the
236
- // worktree would write `repos/.turbo` beside the bare caches. The Worker
237
- // cache is shared across that Worker's Attempts and stays out of the
238
- // directory the startup sweep treats as cache storage.
239
- const turboCache = path.join(workersRoot, prepared.worker, "turbo");
240
- yield* Effect.logInfo("Launching the run host", {
241
- attemptId,
242
- worker: prepared.worker,
243
- host: "local",
244
- command: runHost.command,
245
- worktree: prepared.worktree,
246
- turboCache,
247
- });
248
- const handle = yield* spawner.spawn(ChildProcess.make(runHost.command, runHost.args, {
249
- cwd: prepared.worktree,
250
- env: {
251
- ...credentialEnvironment(baseEnvironment, credential),
252
- TURBO_CACHE_DIR: turboCache,
253
- },
254
- extendEnv: false,
255
- stdin: { stream: Stream.fromQueue(input), endOnDone: true },
256
- }));
257
- return {
258
- handle,
259
- host: "local",
260
- scrub: (text) => scrubbed(text, credential),
277
+ workspace: prepared.workspace,
278
+ launch: (io) => session.launch(prepared.workspace, io, {
279
+ host: new LocalProcess(),
280
+ environment,
281
+ // Local Workers have no Gateway; every harness uses its own login.
282
+ gatewayCredential: Effect.succeedNone,
283
+ harvest: (windows) => harvest(prepared.workspace, credential, environment, windows),
284
+ harvestComments: (windows) => harvestPostedComments(prepared.workspace.spec, harvestCommand("launch", prepared.workspace.worktree, credential, environment), windows),
285
+ keepForReattach: prepared.keepForReattach,
286
+ }),
287
+ salvaged: prepared.salvaged,
288
+ recordSalvage: prepared.recordSalvage,
261
289
  };
262
- });
263
- const session = yield* runHostSessionFor({ interruptGrace });
290
+ }, session.prepare);
264
291
  return Executor.of({
265
292
  kind: "local",
293
+ recover: (attempt, record) => recover(attempt, record).pipe(Effect.catchTag("PlatformError", (cause) => Effect.fail(executorError("cleanup", "Can't reconcile the local salvage", cause)))),
266
294
  cancel: session.cancel,
267
295
  intervene: session.intervene,
296
+ isLive: session.isLive,
297
+ outcome: session.outcome,
268
298
  preflight,
269
299
  prepare,
270
300
  });
271
301
  });
272
- /** Runs Attempts in isolated checkouts on the local machine. Requires Node; worker contracts are platform-free. */
302
+ /**
303
+ * The executor for the local machine. Each Attempt runs in its own checkout with its Pi parent
304
+ * as a durable task in this process (`AttemptRuntime`), so a live Attempt reattaches after an
305
+ * orchestrator restart. Requires Node.
306
+ */
273
307
  export const layer = (options) => Layer.effect(Executor, makeLocalExecutor(options));
274
308
  //# sourceMappingURL=local.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"local.js","sourceRoot":"","sources":["../../src/local/local.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"local.js","sourceRoot":"","sources":["../../src/local/local.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import { Effect, Schema } from "effect";
2
+ import { type ExecutorOperationError, WorkerCapabilityError } from "./executor.ts";
3
+ /** Swap that the OS allocates on demand, as on macOS. */
4
+ export declare const SwapOnDemand: Schema.TaggedStruct<"SwapOnDemand", {}>;
5
+ declare const WorkerMemory_base: Schema.Class<WorkerMemory, Schema.Struct<{
6
+ readonly totalBytes: Schema.Int;
7
+ readonly swap: Schema.Union<readonly [Schema.TaggedStruct<"NoSwap", {}>, Schema.TaggedStruct<"SwapSpace", {
8
+ readonly bytes: Schema.Int;
9
+ }>, Schema.TaggedStruct<"SwapOnDemand", {}>]>;
10
+ }>, {}>;
11
+ export declare class WorkerMemory extends WorkerMemory_base {
12
+ }
13
+ /**
14
+ * Checks that `worker`'s machine can run `maxConcurrentAttempts` concurrent Attempts. Fails
15
+ * below 1.5 GiB per Attempt or for more than one Attempt without swap; logs a warning below
16
+ * 3 GiB per Attempt.
17
+ */
18
+ export declare const verifyWorkerMemory: (worker: string & import("effect/Brand").Brand<"WorkerName">, maxConcurrentAttempts: number, memory: WorkerMemory) => Effect.Effect<undefined, WorkerCapabilityError, never>;
19
+ /**
20
+ * Runs `verifyWorkerMemory` for a Linux machine whose `/proc/meminfo` is returned by `meminfo`.
21
+ * Fails if the output lacks MemTotal or SwapTotal.
22
+ */
23
+ export declare const verifyLinuxMemory: (worker: string & import("effect/Brand").Brand<"WorkerName">, maxConcurrentAttempts: number, meminfo: Effect.Effect<string, ExecutorOperationError, never>) => Effect.Effect<undefined, WorkerCapabilityError, never>;
24
+ export {};
25
+ //# sourceMappingURL=memory-preflight.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-preflight.d.ts","sourceRoot":"","sources":["../src/memory-preflight.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAiB,MAAM,EAAE,MAAM,QAAQ,CAAC;AACvD,OAAO,EAAE,KAAK,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAgBnF,yDAAyD;AACzD,eAAO,MAAM,YAAY,yCAA0C,CAAC;;;;;;;AAKpE,qBAAa,YAAa,SAAQ,iBAGhC;CAAG;AAiCL;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,8KA8C7B,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,iBAAiB,uNAkB5B,CAAC"}
@@ -0,0 +1,83 @@
1
+ import { Effect, Match, Option, Schema } from "effect";
2
+ import { WorkerCapabilityError } from "./executor.js";
3
+ const GIB = 1024 ** 3;
4
+ // Two Attempts running the usine monorepo gates on a 4 GB Worker without swap made sshd
5
+ // unresponsive (#270).
6
+ const MEMORY_PER_ATTEMPT_WARNING = 3 * GIB;
7
+ const MEMORY_PER_ATTEMPT_MINIMUM = 1.5 * GIB;
8
+ const NoSwap = Schema.TaggedStruct("NoSwap", {});
9
+ /** A fixed swap size in bytes, as reported by Linux. */
10
+ const SwapSpace = Schema.TaggedStruct("SwapSpace", {
11
+ bytes: Schema.Int.check(Schema.isGreaterThan(0)),
12
+ });
13
+ /** Swap that the OS allocates on demand, as on macOS. */
14
+ export const SwapOnDemand = Schema.TaggedStruct("SwapOnDemand", {});
15
+ const WorkerSwap = Schema.Union([NoSwap, SwapSpace, SwapOnDemand]);
16
+ export class WorkerMemory extends Schema.Class("@usine/executor/WorkerMemory")({
17
+ totalBytes: Schema.Int.check(Schema.isGreaterThan(0)),
18
+ swap: WorkerSwap,
19
+ }) {
20
+ }
21
+ const decodeWorkerMemory = Schema.decodeUnknownOption(WorkerMemory);
22
+ const kibibytes = (meminfo, pattern) => Option.map(Option.fromNullishOr(pattern.exec(meminfo)?.[1]), Number);
23
+ /** Parses `/proc/meminfo`. Returns `None` if MemTotal or SwapTotal is missing. */
24
+ const memoryFromMeminfo = (meminfo) => Option.flatMap(Option.all({
25
+ total: kibibytes(meminfo, /^MemTotal:\s+(\d+) kB$/mu),
26
+ swap: kibibytes(meminfo, /^SwapTotal:\s+(\d+) kB$/mu),
27
+ }), ({ total, swap }) => decodeWorkerMemory({
28
+ totalBytes: total * 1024,
29
+ swap: swap === 0 ? NoSwap.make({}) : SwapSpace.make({ bytes: swap * 1024 }),
30
+ }));
31
+ const gib = (bytes) => `${(bytes / GIB).toFixed(1)} GiB`;
32
+ const swapText = (swap) => Match.valueTags(swap, {
33
+ NoSwap: () => "none",
34
+ SwapSpace: ({ bytes }) => gib(bytes),
35
+ SwapOnDemand: () => "on demand",
36
+ });
37
+ const memoryError = (worker, message, cause) => new WorkerCapabilityError({ worker, capability: "memory", message, cause });
38
+ /**
39
+ * Checks that `worker`'s machine can run `maxConcurrentAttempts` concurrent Attempts. Fails
40
+ * below 1.5 GiB per Attempt or for more than one Attempt without swap; logs a warning below
41
+ * 3 GiB per Attempt.
42
+ */
43
+ export const verifyWorkerMemory = Effect.fn("Executor.verifyWorkerMemory")(function* (worker, maxConcurrentAttempts, memory) {
44
+ const perAttempt = memory.totalBytes / maxConcurrentAttempts;
45
+ const fields = {
46
+ worker,
47
+ maxConcurrentAttempts,
48
+ memory: gib(memory.totalBytes),
49
+ swap: swapText(memory.swap),
50
+ perAttempt: gib(perAttempt),
51
+ };
52
+ yield* Effect.annotateCurrentSpan(fields);
53
+ const withoutSwap = memory.swap._tag === "NoSwap";
54
+ if (perAttempt < MEMORY_PER_ATTEMPT_MINIMUM) {
55
+ const fitting = Math.floor(memory.totalBytes / MEMORY_PER_ATTEMPT_MINIMUM);
56
+ const carried = withoutSwap ? Math.min(fitting, 1) : fitting;
57
+ const advice = carried === 0
58
+ ? "Add memory to the machine."
59
+ : `Set max_concurrent_attempts to ${carried} or less, or add memory to the machine.`;
60
+ return yield* memoryError(worker, `Worker "${worker}" has ${gib(memory.totalBytes)} of memory, which is ${gib(perAttempt)} per attempt with max_concurrent_attempts set to ${maxConcurrentAttempts}. An attempt needs at least ${gib(MEMORY_PER_ATTEMPT_MINIMUM)}. ${advice}`, memory);
61
+ }
62
+ if (withoutSwap && maxConcurrentAttempts > 1)
63
+ return yield* memoryError(worker, `Worker "${worker}" has no swap, and max_concurrent_attempts is ${maxConcurrentAttempts}. Concurrent attempts without swap can make the machine thrash until SSH stops responding. Add swap, or set max_concurrent_attempts to 1.`, memory);
64
+ if (perAttempt < MEMORY_PER_ATTEMPT_WARNING)
65
+ yield* Effect.logWarning(`Worker memory is below ${gib(MEMORY_PER_ATTEMPT_WARNING)} per concurrent Attempt`, {
66
+ ...fields,
67
+ suggestedMaxConcurrentAttempts: Math.max(1, Math.floor(memory.totalBytes / MEMORY_PER_ATTEMPT_WARNING)),
68
+ });
69
+ else
70
+ yield* Effect.logInfo("Worker memory verified", fields);
71
+ });
72
+ /**
73
+ * Runs `verifyWorkerMemory` for a Linux machine whose `/proc/meminfo` is returned by `meminfo`.
74
+ * Fails if the output lacks MemTotal or SwapTotal.
75
+ */
76
+ export const verifyLinuxMemory = Effect.fn("Executor.verifyLinuxMemory")(function* (worker, maxConcurrentAttempts, meminfo) {
77
+ const output = yield* meminfo.pipe(Effect.mapError((cause) => memoryError(worker, `Can't read /proc/meminfo on worker "${worker}"`, cause)));
78
+ const memory = memoryFromMeminfo(output);
79
+ if (Option.isNone(memory))
80
+ return yield* memoryError(worker, `/proc/meminfo on worker "${worker}" has no MemTotal or SwapTotal`, new Error(output.slice(0, 200)));
81
+ yield* verifyWorkerMemory(worker, maxConcurrentAttempts, memory.value);
82
+ });
83
+ //# sourceMappingURL=memory-preflight.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-preflight.js","sourceRoot":"","sources":["../src/memory-preflight.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import type { LoopName } from "@usine/core/loop";
2
+ import { Option } from "effect";
3
+ /**
4
+ * The hooks directory inside the checkout's git directory for `permissions: read` Loops.
5
+ * `git worktree remove` deletes it with the checkout.
6
+ */
7
+ export declare const PRE_PUSH_HOOKS_DIRECTORY = "usine-hooks";
8
+ /**
9
+ * Returns a pre-push hook that rejects every push with `pushRefusal`, so the Agent sees the
10
+ * reason instead of GitHub's 403. `git push --no-verify` skips it; the `contents: read` token is
11
+ * what blocks the push (ADR 0011).
12
+ */
13
+ export declare const prePushHook: (loop: LoopName) => string;
14
+ /**
15
+ * Returns `environment` with `core.hooksPath` set to `hooks`, if any, after the entries counted
16
+ * in `GIT_CONFIG_COUNT`. Environment config overrides repository config, so the hook runs even
17
+ * if the repository sets `core.hooksPath`.
18
+ */
19
+ export declare const withGitHooks: (environment: Readonly<Record<string, string>>, hooks: Option.Option<string>) => Record<string, string>;
20
+ //# sourceMappingURL=pre-push-hook.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pre-push-hook.d.ts","sourceRoot":"","sources":["../src/pre-push-hook.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC;;;GAGG;AACH,eAAO,MAAM,wBAAwB,gBAAgB,CAAC;AAQtD;;;;GAIG;AACH,eAAO,MAAM,WAAW,SAAU,QAAQ,KAAG,MACgB,CAAC;AAE9D;;;;GAIG;AACH,eAAO,MAAM,YAAY,gBACV,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,SACtC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,KAC3B,MAAM,CAAC,MAAM,EAAE,MAAM,CAYpB,CAAC"}
@@ -0,0 +1,33 @@
1
+ import { Option } from "effect";
2
+ /**
3
+ * The hooks directory inside the checkout's git directory for `permissions: read` Loops.
4
+ * `git worktree remove` deletes it with the checkout.
5
+ */
6
+ export const PRE_PUSH_HOOKS_DIRECTORY = "usine-hooks";
7
+ const quote = (value) => `'${value.replaceAll("'", `'"'"'`)}'`;
8
+ /** Returns the message printed when a push from a `permissions: read` checkout is rejected. */
9
+ const pushRefusal = (loop) => `usine refused this push: the Loop ${loop} has permissions: read, so its Attempts cannot push to the repository.`;
10
+ /**
11
+ * Returns a pre-push hook that rejects every push with `pushRefusal`, so the Agent sees the
12
+ * reason instead of GitHub's 403. `git push --no-verify` skips it; the `contents: read` token is
13
+ * what blocks the push (ADR 0011).
14
+ */
15
+ export const prePushHook = (loop) => `#!/bin/sh\necho ${quote(pushRefusal(loop))} >&2\nexit 1\n`;
16
+ /**
17
+ * Returns `environment` with `core.hooksPath` set to `hooks`, if any, after the entries counted
18
+ * in `GIT_CONFIG_COUNT`. Environment config overrides repository config, so the hook runs even
19
+ * if the repository sets `core.hooksPath`.
20
+ */
21
+ export const withGitHooks = (environment, hooks) => Option.match(hooks, {
22
+ onNone: () => ({ ...environment }),
23
+ onSome: (directory) => {
24
+ const index = Number(environment.GIT_CONFIG_COUNT ?? "0");
25
+ return {
26
+ ...environment,
27
+ GIT_CONFIG_COUNT: String(index + 1),
28
+ [`GIT_CONFIG_KEY_${index}`]: "core.hooksPath",
29
+ [`GIT_CONFIG_VALUE_${index}`]: directory,
30
+ };
31
+ },
32
+ });
33
+ //# sourceMappingURL=pre-push-hook.js.map