@usine/executor 0.1.0 → 0.2.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 (79) hide show
  1. package/README.md +52 -21
  2. package/dist/child-command.d.ts +8 -5
  3. package/dist/child-command.d.ts.map +1 -1
  4. package/dist/child-command.js +10 -7
  5. package/dist/child-command.js.map +1 -1
  6. package/dist/exe-dev/channel.d.ts +7 -4
  7. package/dist/exe-dev/channel.d.ts.map +1 -1
  8. package/dist/exe-dev/channel.js +15 -19
  9. package/dist/exe-dev/channel.js.map +1 -1
  10. package/dist/exe-dev/commands.d.ts +1 -1
  11. package/dist/exe-dev/commands.d.ts.map +1 -1
  12. package/dist/exe-dev/commands.js +7 -8
  13. package/dist/exe-dev/commands.js.map +1 -1
  14. package/dist/exe-dev/exe-dev.d.ts +8 -0
  15. package/dist/exe-dev/exe-dev.d.ts.map +1 -0
  16. package/dist/exe-dev/exe-dev.js +153 -0
  17. package/dist/exe-dev/exe-dev.js.map +1 -0
  18. package/dist/exe-dev/grants.d.ts +3 -4
  19. package/dist/exe-dev/grants.d.ts.map +1 -1
  20. package/dist/exe-dev/grants.js +31 -15
  21. package/dist/exe-dev/grants.js.map +1 -1
  22. package/dist/exe-dev/model.d.ts +8 -23
  23. package/dist/exe-dev/model.d.ts.map +1 -1
  24. package/dist/exe-dev/model.js +5 -12
  25. package/dist/exe-dev/model.js.map +1 -1
  26. package/dist/exe-dev/preflight.d.ts +3 -2
  27. package/dist/exe-dev/preflight.d.ts.map +1 -1
  28. package/dist/exe-dev/preflight.js +8 -8
  29. package/dist/exe-dev/preflight.js.map +1 -1
  30. package/dist/exe-dev/shell.d.ts +5 -5
  31. package/dist/exe-dev/shell.d.ts.map +1 -1
  32. package/dist/exe-dev/shell.js +7 -7
  33. package/dist/exe-dev/shell.js.map +1 -1
  34. package/dist/exe-dev/sweep.d.ts +3 -5
  35. package/dist/exe-dev/sweep.d.ts.map +1 -1
  36. package/dist/exe-dev/sweep.js +8 -10
  37. package/dist/exe-dev/sweep.js.map +1 -1
  38. package/dist/executor.d.ts +118 -0
  39. package/dist/executor.d.ts.map +1 -0
  40. package/dist/executor.js +98 -0
  41. package/dist/executor.js.map +1 -0
  42. package/dist/harness-preflight.d.ts +6 -0
  43. package/dist/harness-preflight.d.ts.map +1 -0
  44. package/dist/harness-preflight.js +50 -0
  45. package/dist/harness-preflight.js.map +1 -0
  46. package/dist/invalid-frame.d.ts +1 -1
  47. package/dist/invalid-frame.d.ts.map +1 -1
  48. package/dist/invalid-frame.js +2 -1
  49. package/dist/invalid-frame.js.map +1 -1
  50. package/dist/keyed-lock.d.ts +2 -2
  51. package/dist/keyed-lock.js +2 -2
  52. package/dist/local/local.d.ts +20 -0
  53. package/dist/local/local.d.ts.map +1 -0
  54. package/dist/local/{index.js → local.js} +86 -115
  55. package/dist/local/local.js.map +1 -0
  56. package/dist/prepared-attempt.d.ts +5 -0
  57. package/dist/prepared-attempt.d.ts.map +1 -0
  58. package/dist/prepared-attempt.js +40 -0
  59. package/dist/prepared-attempt.js.map +1 -0
  60. package/dist/provision.d.ts +20 -10
  61. package/dist/provision.d.ts.map +1 -1
  62. package/dist/provision.js +94 -23
  63. package/dist/provision.js.map +1 -1
  64. package/dist/run-host-session.d.ts +12 -8
  65. package/dist/run-host-session.d.ts.map +1 -1
  66. package/dist/run-host-session.js +35 -22
  67. package/dist/run-host-session.js.map +1 -1
  68. package/package.json +11 -11
  69. package/dist/exe-dev/index.d.ts +0 -8
  70. package/dist/exe-dev/index.d.ts.map +0 -1
  71. package/dist/exe-dev/index.js +0 -239
  72. package/dist/exe-dev/index.js.map +0 -1
  73. package/dist/index.d.ts +0 -82
  74. package/dist/index.d.ts.map +0 -1
  75. package/dist/index.js +0 -82
  76. package/dist/index.js.map +0 -1
  77. package/dist/local/index.d.ts +0 -15
  78. package/dist/local/index.d.ts.map +0 -1
  79. package/dist/local/index.js.map +0 -1
@@ -1,16 +1,20 @@
1
- import { Attempt, AttemptChannel, AttemptFailure, Instance, Repository } from "@usine/core";
2
- import { Effect, FileSystem, Layer, Path, Redacted, Ref, Result, Schema, Stream, } from "effect";
1
+ import * as AttemptChannel from "@usine/core/attempt/channel";
2
+ import { RepositoryName } from "@usine/core/repository";
3
+ import { InstanceDirectory } from "@usine/core/instance";
4
+ import { Effect, FileSystem, Layer, Path, Redacted, Result, Schema, Stream, } from "effect";
3
5
  import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process";
4
6
  import { allowlistedEnvironment, collectCommand, requireSuccess } from "../child-command.js";
5
- import { CheckoutRequest, CredentialProvider, Executor, ExecutorError, ExecutorOperationError, logPreflightFailure, WorkerCapabilityError, } from "../index.js";
7
+ 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";
6
10
  import { keyedLockFor } from "../keyed-lock.js";
7
- import { provisionWorktree, safeSegment } from "../provision.js";
11
+ import { cacheDirectoryName, isCacheDirectoryName, provisionWorktree, safeSegment, } from "../provision.js";
8
12
  import { runHostSessionFor } from "../run-host-session.js";
9
13
  const isExecutorError = Schema.is(ExecutorError);
10
14
  /**
11
- * The run host gets a minimal environment, never the orchestrator's: the App
12
- * private key and every other orchestrator secret must not reach the agent
13
- * (ADR 0011's single-repo worker token is the only credential it holds).
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).
14
18
  */
15
19
  const HOST_ENVIRONMENT_ALLOWLIST = [
16
20
  "HOME",
@@ -22,7 +26,7 @@ const HOST_ENVIRONMENT_ALLOWLIST = [
22
26
  "USER",
23
27
  ];
24
28
  const executorError = (operation, message, cause) => new ExecutorOperationError({ operation, message, cause });
25
- /** The credential must never survive into a persisted error message. */
29
+ /** Removes the credential from text before it can reach a persisted error message. */
26
30
  const scrubbed = (text, credential) => text.replaceAll(Redacted.value(credential), "[REDACTED]");
27
31
  const credentialEnvironment = (base, credential) => {
28
32
  const token = Redacted.value(credential);
@@ -41,7 +45,6 @@ const makeLocalExecutor = (options) => Effect.gen(function* () {
41
45
  const path = yield* Path.Path;
42
46
  const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;
43
47
  const fetches = yield* keyedLockFor();
44
- const preparedStates = yield* Ref.make(new Map());
45
48
  const baseEnvironment = yield* allowlistedEnvironment(HOST_ENVIRONMENT_ALLOWLIST);
46
49
  const repositoryUrl = options.repositoryUrl ??
47
50
  ((repository) => `https://github.com/${repository}.git`);
@@ -60,9 +63,9 @@ const makeLocalExecutor = (options) => Effect.gen(function* () {
60
63
  const run = Effect.fn("LocalExecutor.run")(function* (operation, command, args, commandOptions = {}) {
61
64
  yield* executeCommand(operation, command, args, commandOptions);
62
65
  });
63
- // ADR 0006: worktrees never outlive their Attempt. A crashed orchestrator
64
- // leaves both directories and bare-cache registrations behind; the sweep
65
- // reclaims them at the next layer build, before new Attempts start.
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.
66
69
  const sweepAbandonedWorktrees = Effect.fn("LocalExecutor.sweepAbandonedWorktrees")(function* () {
67
70
  if (!(yield* fileSystem.exists(workersRoot)))
68
71
  return;
@@ -83,27 +86,52 @@ const makeLocalExecutor = (options) => Effect.gen(function* () {
83
86
  }
84
87
  const reposRoot = path.join(workersRoot, worker, "repos");
85
88
  if (yield* fileSystem.exists(reposRoot)) {
86
- const caches = yield* fileSystem.readDirectory(reposRoot);
87
- for (const cache of caches) {
88
- yield* run("cleanup", "git", [
89
+ const entries = yield* fileSystem.readDirectory(reposRoot);
90
+ let pruned = 0;
91
+ let skipped = 0;
92
+ let failed = 0;
93
+ for (const entry of entries) {
94
+ if (!isCacheDirectoryName(entry)) {
95
+ yield* Effect.logDebug("Skipping a non-cache entry during the local cache sweep", {
96
+ worker,
97
+ host: "local",
98
+ entry,
99
+ });
100
+ skipped += 1;
101
+ continue;
102
+ }
103
+ const result = yield* run("cleanup", "git", [
89
104
  "--git-dir",
90
- path.join(reposRoot, cache),
105
+ path.join(reposRoot, entry),
91
106
  "worktree",
92
107
  "prune",
93
108
  ]).pipe(Effect.tapError((error) => Effect.logWarning("Could not prune a bare cache during the sweep", {
94
109
  worker,
95
110
  host: "local",
96
- cache,
111
+ cache: entry,
97
112
  message: error.message,
98
- })), Effect.ignore);
113
+ })), Effect.result);
114
+ if (Result.isSuccess(result)) {
115
+ pruned += 1;
116
+ }
117
+ else {
118
+ failed += 1;
119
+ }
99
120
  }
121
+ yield* Effect.logInfo("Local cache sweep completed", {
122
+ worker,
123
+ host: "local",
124
+ pruned,
125
+ skipped,
126
+ failed,
127
+ });
100
128
  }
101
129
  }
102
130
  });
103
131
  yield* sweepAbandonedWorktrees().pipe(Effect.tapError((error) => Effect.logWarning("Abandoned-worktree sweep failed; continuing", {
104
132
  message: String(error),
105
133
  })), Effect.ignore);
106
- const preflight = Effect.fn("LocalExecutor.preflight")(function* (worker) {
134
+ const preflight = Effect.fn("LocalExecutor.preflight")(function* (worker, brains) {
107
135
  yield* Effect.annotateCurrentSpan({ worker, host: "local" });
108
136
  const gitVersion = (yield* executeCommand("preflight", "git", ["--version"])).trim();
109
137
  if (!gitVersion.startsWith("git version ")) {
@@ -126,6 +154,7 @@ const makeLocalExecutor = (options) => Effect.gen(function* () {
126
154
  cause: new Error("run-host protocol mismatch"),
127
155
  });
128
156
  }
157
+ yield* verifyHarnesses(worker, brains, runHost, (command, args) => executeCommand("preflight", command, args));
129
158
  yield* Effect.logInfo("Worker preflight verified", {
130
159
  worker,
131
160
  host: "local",
@@ -140,9 +169,12 @@ const makeLocalExecutor = (options) => Effect.gen(function* () {
140
169
  host: "local",
141
170
  repository: request.repository,
142
171
  });
143
- const credential = yield* credentials.issue(request.repository, request.attemptId);
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 });
144
176
  const workerRoot = path.join(workersRoot, request.worker);
145
- const cache = path.join(workerRoot, "repos", `${safeSegment(request.repository)}.git`);
177
+ const cache = path.join(workerRoot, "repos", cacheDirectoryName(request.repository));
146
178
  const worktree = path.join(workerRoot, "attempts", safeSegment(request.attemptId));
147
179
  const environment = credentialEnvironment(baseEnvironment, credential);
148
180
  const commandOptions = { env: environment, extendEnv: false };
@@ -154,13 +186,22 @@ const makeLocalExecutor = (options) => Effect.gen(function* () {
154
186
  cache,
155
187
  worktree,
156
188
  });
157
- const remove = (target) => fileSystem.remove(target, { recursive: true, force: true });
189
+ const remove = (_operation, target) => fileSystem.remove(target, { recursive: true, force: true });
158
190
  const ops = {
159
191
  ensureRoots: Effect.andThen(fileSystem.makeDirectory(path.dirname(cache), { recursive: true }), fileSystem.makeDirectory(path.dirname(worktree), { recursive: true })),
160
192
  removePath: remove,
161
193
  cacheExists: fileSystem.exists(cache),
162
194
  promoteStaging: fileSystem.rename(`${cache}.cloning`, cache),
163
- git: (args) => executeCommand("prepare", "git", args, commandOptions),
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
+ }),
164
205
  };
165
206
  const prepared = yield* fetches
166
207
  .withLock(request.repository)(provisionWorktree({
@@ -172,131 +213,61 @@ const makeLocalExecutor = (options) => Effect.gen(function* () {
172
213
  }))
173
214
  .pipe(Effect.mapError((error) => isExecutorError(error)
174
215
  ? error
175
- : executorError("prepare", "Attempt workspace preparation failed", error)), Effect.onError(() => Effect.gen(function* () {
176
- yield* fileSystem.remove(worktree, { recursive: true, force: true }).pipe(Effect.tapError((error) => Effect.logWarning("Could not remove a partial local workspace", {
177
- attemptId: request.attemptId,
178
- worker: request.worker,
179
- host: "local",
180
- worktree,
181
- message: String(error),
182
- })), Effect.ignore);
183
- Redacted.wipeUnsafe(credential);
184
- })));
185
- yield* Ref.update(preparedStates, (current) => {
186
- const next = new Map(current);
187
- next.set(request.attemptId, { cache, credential });
188
- return next;
189
- });
216
+ : executorError("prepare", "Attempt workspace preparation failed", error)));
190
217
  yield* Effect.logInfo("Attempt workspace ready", {
191
218
  attemptId: request.attemptId,
192
219
  baseCommit: prepared.spec.baseCommit,
193
220
  worktree,
194
221
  });
195
- return prepared;
196
- });
197
- const spawn = Effect.fn("LocalExecutor.spawnRunHost")(function* (prepared, input) {
222
+ 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) {
198
228
  const attemptId = prepared.spec.attemptId;
199
229
  yield* Effect.annotateCurrentSpan({
200
230
  attemptId,
201
231
  worker: prepared.worker,
202
232
  host: "local",
203
233
  });
204
- const stored = (yield* Ref.get(preparedStates)).get(attemptId);
205
- if (stored === undefined) {
206
- return yield* new AttemptFailure.InfraFailure({
207
- message: `Attempt ${attemptId} has no prepared credential`,
208
- cause: new Error("prepared Attempt state missing"),
209
- });
210
- }
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");
211
240
  yield* Effect.logInfo("Launching the run host", {
212
241
  attemptId,
213
242
  worker: prepared.worker,
214
243
  host: "local",
215
244
  command: runHost.command,
216
245
  worktree: prepared.worktree,
246
+ turboCache,
217
247
  });
218
248
  const handle = yield* spawner.spawn(ChildProcess.make(runHost.command, runHost.args, {
219
249
  cwd: prepared.worktree,
220
- env: credentialEnvironment(baseEnvironment, stored.credential),
250
+ env: {
251
+ ...credentialEnvironment(baseEnvironment, credential),
252
+ TURBO_CACHE_DIR: turboCache,
253
+ },
221
254
  extendEnv: false,
222
255
  stdin: { stream: Stream.fromQueue(input), endOnDone: true },
223
256
  }));
224
257
  return {
225
258
  handle,
226
259
  host: "local",
227
- scrub: (text) => scrubbed(text, stored.credential),
260
+ scrub: (text) => scrubbed(text, credential),
228
261
  };
229
262
  });
230
- const session = yield* runHostSessionFor({ interruptGrace, spawn });
231
- const cleanup = Effect.fn("LocalExecutor.cleanup")(function* (prepared) {
232
- const attemptId = prepared.spec.attemptId;
233
- yield* Effect.annotateCurrentSpan({
234
- attemptId,
235
- worker: prepared.worker,
236
- host: "local",
237
- });
238
- yield* Effect.logInfo("Cleaning Attempt workspace", {
239
- attemptId,
240
- worker: prepared.worker,
241
- host: "local",
242
- worktree: prepared.worktree,
243
- });
244
- const state = (yield* Ref.get(preparedStates)).get(attemptId);
245
- if (state === undefined) {
246
- yield* fileSystem
247
- .remove(prepared.worktree, { recursive: true, force: true })
248
- .pipe(Effect.mapError((cause) => executorError("cleanup", `Could not remove ${prepared.worktree}`, cause)));
249
- return;
250
- }
251
- const finish = Effect.gen(function* () {
252
- const removedFromGit = yield* run("cleanup", "git", [
253
- "--git-dir",
254
- state.cache,
255
- "worktree",
256
- "remove",
257
- "--force",
258
- prepared.worktree,
259
- ]).pipe(Effect.result);
260
- const removedFromDisk = yield* fileSystem
261
- .remove(prepared.worktree, { recursive: true, force: true })
262
- .pipe(Effect.mapError((cause) => executorError("cleanup", `Could not remove ${prepared.worktree}`, cause)), Effect.result);
263
- const pruned = yield* run("cleanup", "git", [
264
- "--git-dir",
265
- state.cache,
266
- "worktree",
267
- "prune",
268
- ]).pipe(Effect.result);
269
- for (const result of [removedFromGit, removedFromDisk, pruned]) {
270
- if (Result.isFailure(result)) {
271
- return yield* result.failure;
272
- }
273
- }
274
- }).pipe(Effect.mapError((cause) => isExecutorError(cause)
275
- ? cause
276
- : executorError("cleanup", `Could not clean Attempt ${attemptId}`, cause)));
277
- yield* finish.pipe(Effect.ensuring(Effect.gen(function* () {
278
- yield* Ref.update(preparedStates, (current) => {
279
- const next = new Map(current);
280
- next.delete(attemptId);
281
- return next;
282
- });
283
- Redacted.wipeUnsafe(state.credential);
284
- })));
285
- yield* Effect.logInfo("Attempt cleanup completed", {
286
- attemptId,
287
- worker: prepared.worker,
288
- host: "local",
289
- });
290
- });
263
+ const session = yield* runHostSessionFor({ interruptGrace });
291
264
  return Executor.of({
292
265
  kind: "local",
293
266
  cancel: session.cancel,
294
- cleanup,
295
- launch: session.launch,
296
267
  preflight,
297
268
  prepare,
298
269
  });
299
270
  });
300
- /** Node-only local executor; the package root remains platform-free. */
271
+ /** Runs Attempts in isolated checkouts on the local machine. Requires Node; worker contracts are platform-free. */
301
272
  export const layer = (options) => Layer.effect(Executor, makeLocalExecutor(options));
302
- //# sourceMappingURL=index.js.map
273
+ //# sourceMappingURL=local.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local.js","sourceRoot":"","sources":["../../src/local/local.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import { Effect, Scope } from "effect";
2
+ import type { CheckoutRequest, ExecutorError, PreparedAttempt } from "./executor.ts";
3
+ /** Owns partial preparation and the run host in one child scope, released at the Attempt's end. */
4
+ export declare const prepareAttempt: (acquire: Effect.Effect<PreparedAttempt, ExecutorError, Scope.Scope>, request: CheckoutRequest) => Effect.Effect<PreparedAttempt, ExecutorError, Scope.Scope>;
5
+ //# sourceMappingURL=prepared-attempt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prepared-attempt.d.ts","sourceRoot":"","sources":["../src/prepared-attempt.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAoB,KAAK,EAAE,MAAM,QAAQ,CAAC;AACzD,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAErF,mGAAmG;AACnG,eAAO,MAAM,cAAc,YAChB,MAAM,CAAC,MAAM,CAAC,eAAe,EAAE,aAAa,EAAE,KAAK,CAAC,KAAK,CAAC,WAC1D,eAAe,KACvB,MAAM,CAAC,MAAM,CAAC,eAAe,EAAE,aAAa,EAAE,KAAK,CAAC,KAAK,CAqDzD,CAAC"}
@@ -0,0 +1,40 @@
1
+ import { InfraFailure } from "@usine/core/attempt/failure";
2
+ import { Effect, Exit, Fiber, Ref, Scope } from "effect";
3
+ /** Owns partial preparation and the run host in one child scope, released at the Attempt's end. */
4
+ export const prepareAttempt = (acquire, request) => Effect.uninterruptibleMask((restore) => Effect.gen(function* () {
5
+ const scope = yield* Scope.fork(yield* Effect.scope);
6
+ // acquireRelease masks acquisition by default in Effect rc.111. Only the
7
+ // ownership transfer is masked here; clone, fetch, and lock waits must stop
8
+ // promptly. Each acquiring implementation registers its own finalizers.
9
+ const prepared = yield* restore(acquire).pipe(Scope.provide(scope), Effect.onError((cause) => Scope.close(scope, Exit.failCause(cause))));
10
+ const unavailable = yield* Ref.make(false);
11
+ yield* Scope.addFinalizer(scope, Ref.set(unavailable, true));
12
+ return {
13
+ workspace: prepared.workspace,
14
+ launch: Effect.fn("PreparedAttempt.launch")(function* (io) {
15
+ const attemptId = prepared.workspace.spec.attemptId;
16
+ yield* Effect.annotateCurrentSpan({ attemptId, worker: prepared.workspace.worker });
17
+ if (yield* Ref.getAndSet(unavailable, true)) {
18
+ yield* Effect.logWarning("Attempt was already launched or released", { attemptId });
19
+ return yield* new InfraFailure({
20
+ message: `Attempt ${attemptId} was already launched or released`,
21
+ cause: new Error("prepared Attempt is no longer available"),
22
+ });
23
+ }
24
+ // Closing the owner's scope interrupts the session before checkout and
25
+ // credential finalizers. Interrupting a caller waiting on join must also
26
+ // stop that scoped fiber, so timeout/cancel completes the handshake first.
27
+ return yield* Effect.acquireUseRelease(Effect.forkIn(prepared.launch(io).pipe(
28
+ // End the timer with the live session. Checkout/grant finalizers run
29
+ // afterward and cannot turn completed agent work into a retry.
30
+ Effect.timeoutOrElse({
31
+ duration: `${request.maxAttemptMinutes} minutes`,
32
+ orElse: () => Effect.fail(new InfraFailure({
33
+ message: `Attempt exceeded the ${request.maxAttemptMinutes}-minute budget`,
34
+ cause: new Error("attempt timeout"),
35
+ })),
36
+ })), scope), Fiber.join, Fiber.interrupt).pipe(Effect.onExit((exit) => Scope.close(scope, exit)));
37
+ }),
38
+ };
39
+ }));
40
+ //# sourceMappingURL=prepared-attempt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prepared-attempt.js","sourceRoot":"","sources":["../src/prepared-attempt.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,17 @@
1
+ import { RepositoryName } from "@usine/core/repository";
1
2
  import { Effect } from "effect";
2
- import { ExecutorOperationError, PreparedAttempt, type CheckoutRequest } from "./index.ts";
3
+ import { ExecutorOperationError, AttemptWorkspace, type CheckoutRequest } from "./executor.ts";
3
4
  export declare const safeSegment: (value: string) => string;
4
- export interface WorkspaceLayout {
5
+ /** The bare cache directory name for a repository under `repos/`, shared by every adapter. */
6
+ export declare const cacheDirectoryName: (repository: RepositoryName) => string;
7
+ /**
8
+ * Whether a `repos/` entry is one of our bare caches, decided by the name we
9
+ * mint rather than by probing contents: a `HEAD` lookup fails with ENOTDIR on
10
+ * a stray file, and a `.cloning` leftover or a tool's scratch directory must
11
+ * never reach `git worktree prune`.
12
+ */
13
+ export declare const isCacheDirectoryName: (entry: string) => boolean;
14
+ interface WorkspaceLayout {
5
15
  readonly cache: string;
6
16
  readonly staging: string;
7
17
  readonly worktree: string;
@@ -9,11 +19,11 @@ export interface WorkspaceLayout {
9
19
  /** The adapter-specific primitives; everything else about provisioning is shared. */
10
20
  export interface WorkspaceOps<E> {
11
21
  readonly ensureRoots: Effect.Effect<void, E>;
12
- readonly removePath: (target: string) => Effect.Effect<void, E>;
22
+ readonly removePath: (operation: "prepare" | "cleanup", target: string) => Effect.Effect<void, E>;
13
23
  readonly cacheExists: Effect.Effect<boolean, E>;
14
24
  /** Atomically promote the finished staging clone to the cache path. */
15
25
  readonly promoteStaging: Effect.Effect<void, E>;
16
- readonly git: (args: ReadonlyArray<string>) => Effect.Effect<string, E>;
26
+ readonly git: (operation: "prepare" | "cleanup", args: ReadonlyArray<string>) => Effect.Effect<string, E>;
17
27
  }
18
28
  export interface ProvisionOptions<E> {
19
29
  readonly request: CheckoutRequest;
@@ -23,11 +33,11 @@ export interface ProvisionOptions<E> {
23
33
  readonly ops: WorkspaceOps<E>;
24
34
  }
25
35
  /**
26
- * One canonical cached-clone-to-worktree choreography shared by every
27
- * Executor: clone into a staging sibling and promote on success (an
28
- * interrupted clone must never leave a half-initialized cache that every
29
- * later fetch for the repository would poison), fetch the requested
30
- * revision, and check out a detached worktree at the resolved commit.
36
+ * The clone-to-worktree sequence every Executor shares: clone into a staging
37
+ * sibling and promote it on success, so an interrupted clone never leaves a
38
+ * half-initialized cache that later fetches would poison; then fetch the
39
+ * requested revision and check out a detached worktree at the resolved commit.
31
40
  */
32
- export declare const provisionWorktree: <E>(options: ProvisionOptions<E>) => Effect.Effect<PreparedAttempt, E | ExecutorOperationError, never>;
41
+ export declare const provisionWorktree: <E>(options: ProvisionOptions<E>) => Effect.Effect<AttemptWorkspace, E | ExecutorOperationError, import("effect/Scope").Scope>;
42
+ export {};
33
43
  //# sourceMappingURL=provision.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"provision.d.ts","sourceRoot":"","sources":["../src/provision.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAU,MAAM,QAAQ,CAAC;AACxC,OAAO,EACL,sBAAsB,EACtB,eAAe,EAEf,KAAK,eAAe,EACrB,MAAM,YAAY,CAAC;AAEpB,eAAO,MAAM,WAAW,UAAW,MAAM,KAAG,MAAoD,CAAC;AAIjG,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,qFAAqF;AACrF,MAAM,WAAW,YAAY,CAAC,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAC7C,QAAQ,CAAC,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAChE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IAChD,uEAAuE;IACvE,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAChD,QAAQ,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,KAAK,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;CACzE;AAED,MAAM,WAAW,gBAAgB,CAAC,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC;IAClC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC;IACjC,QAAQ,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC;CAC/B;AAED;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,GAAsD,CAAC,oGA6EnF,CAAC"}
1
+ {"version":3,"file":"provision.d.ts","sourceRoot":"","sources":["../src/provision.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAa,MAAM,wBAAwB,CAAC;AACnE,OAAO,EAAE,MAAM,EAAU,MAAM,QAAQ,CAAC;AACxC,OAAO,EACL,sBAAsB,EACtB,gBAAgB,EAEhB,KAAK,eAAe,EACrB,MAAM,eAAe,CAAC;AAEvB,eAAO,MAAM,WAAW,UAAW,MAAM,KAAG,MAAoD,CAAC;AAIjG,8FAA8F;AAC9F,eAAO,MAAM,kBAAkB,eAAgB,cAAc,KAAG,MACT,CAAC;AAExD;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,UAAW,MAAM,KAAG,OACmC,CAAC;AAIzF,UAAU,eAAe;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,qFAAqF;AACrF,MAAM,WAAW,YAAY,CAAC,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAC7C,QAAQ,CAAC,UAAU,EAAE,CAAC,SAAS,EAAE,SAAS,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAClG,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IAChD,uEAAuE;IACvE,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAChD,QAAQ,CAAC,GAAG,EAAE,CACZ,SAAS,EAAE,SAAS,GAAG,SAAS,EAChC,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,KACxB,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;CAC/B;AAED,MAAM,WAAW,gBAAgB,CAAC,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC;IAClC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC;IACjC,QAAQ,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC;CAC/B;AAED;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,GAAsD,CAAC,4HAwJnF,CAAC"}
package/dist/provision.js CHANGED
@@ -1,14 +1,24 @@
1
- import { AttemptChannel, Repository } from "@usine/core";
1
+ import * as AttemptChannel from "@usine/core/attempt/channel";
2
+ import { RepositoryName, CommitSha } from "@usine/core/repository";
2
3
  import { Effect, Schema } from "effect";
3
- import { ExecutorOperationError, PreparedAttempt, WorktreePath, } from "./index.js";
4
+ import { ExecutorOperationError, AttemptWorkspace, WorktreePath, } from "./executor.js";
4
5
  export const safeSegment = (value) => value.replaceAll(/[^A-Za-z0-9_.-]/gu, "_");
5
- const decodeCommit = Schema.decodeUnknownEffect(Repository.CommitSha);
6
+ const CACHE_DIRECTORY_SUFFIX = ".git";
7
+ /** The bare cache directory name for a repository under `repos/`, shared by every adapter. */
8
+ export const cacheDirectoryName = (repository) => `${safeSegment(repository)}${CACHE_DIRECTORY_SUFFIX}`;
6
9
  /**
7
- * One canonical cached-clone-to-worktree choreography shared by every
8
- * Executor: clone into a staging sibling and promote on success (an
9
- * interrupted clone must never leave a half-initialized cache that every
10
- * later fetch for the repository would poison), fetch the requested
11
- * revision, and check out a detached worktree at the resolved commit.
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`.
14
+ */
15
+ export const isCacheDirectoryName = (entry) => entry.length > CACHE_DIRECTORY_SUFFIX.length && entry.endsWith(CACHE_DIRECTORY_SUFFIX);
16
+ const decodeCommit = Schema.decodeUnknownEffect(CommitSha);
17
+ /**
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.
12
22
  */
13
23
  export const provisionWorktree = Effect.fn("Executor.provisionWorktree")(function* (options) {
14
24
  const { layout, ops, request } = options;
@@ -18,23 +28,77 @@ export const provisionWorktree = Effect.fn("Executor.provisionWorktree")(functio
18
28
  host: options.host,
19
29
  repository: request.repository,
20
30
  });
21
- yield* ops.ensureRoots;
22
- yield* ops.removePath(layout.worktree);
23
- if (yield* ops.cacheExists) {
24
- yield* ops.git(["--git-dir", layout.cache, "remote", "set-url", "origin", options.url]);
25
- }
26
- else {
27
- yield* ops.removePath(layout.staging);
28
- yield* ops.git(["clone", "--bare", "--filter=blob:none", options.url, layout.staging]).pipe(Effect.onError(() => ops.removePath(layout.staging).pipe(Effect.tapError((error) => Effect.logWarning("Could not remove a partial clone", {
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* () {
42
+ yield* Effect.annotateCurrentSpan({
43
+ attemptId: request.attemptId,
44
+ worker: request.worker,
45
+ repository: request.repository,
46
+ host: options.host,
47
+ });
48
+ yield* Effect.logInfo("Cleaning Attempt workspace", {
29
49
  attemptId: request.attemptId,
30
50
  worker: request.worker,
31
51
  host: options.host,
32
- staging: layout.staging,
52
+ worktree: layout.worktree,
53
+ });
54
+ const cacheExists = yield* ops.cacheExists.pipe(Effect.tapError((error) => Effect.logWarning("Could not inspect cache during cleanup", {
55
+ attemptId: request.attemptId,
33
56
  message: String(error),
34
- })), Effect.ignore)));
35
- yield* ops.promoteStaging;
57
+ })), Effect.orElseSucceed(() => false));
58
+ if (cacheExists) {
59
+ yield* cleanup("git-worktree", ops.git("cleanup", [
60
+ "--git-dir",
61
+ layout.cache,
62
+ "worktree",
63
+ "remove",
64
+ "--force",
65
+ layout.worktree,
66
+ ]));
67
+ }
68
+ yield* cleanup("worktree-directory", ops.removePath("cleanup", layout.worktree));
69
+ if (cacheExists) {
70
+ yield* cleanup("cache-registration", ops.git("cleanup", ["--git-dir", layout.cache, "worktree", "prune"]));
71
+ }
72
+ }));
73
+ yield* ops.ensureRoots;
74
+ yield* ops.removePath("prepare", layout.worktree);
75
+ if (yield* ops.cacheExists) {
76
+ yield* ops.git("prepare", [
77
+ "--git-dir",
78
+ layout.cache,
79
+ "remote",
80
+ "set-url",
81
+ "origin",
82
+ options.url,
83
+ ]);
84
+ }
85
+ else {
86
+ // Staging belongs to this locked clone only. Release it before unlocking,
87
+ // including interruption between clone completion and cache promotion.
88
+ yield* Effect.scoped(Effect.gen(function* () {
89
+ yield* Effect.addFinalizer(() => cleanup("partial-clone", ops.removePath("cleanup", layout.staging)));
90
+ yield* ops.removePath("prepare", layout.staging);
91
+ yield* ops.git("prepare", [
92
+ "clone",
93
+ "--bare",
94
+ "--filter=blob:none",
95
+ options.url,
96
+ layout.staging,
97
+ ]);
98
+ yield* ops.promoteStaging;
99
+ }));
36
100
  }
37
- yield* ops.git([
101
+ yield* ops.git("prepare", [
38
102
  "--git-dir",
39
103
  layout.cache,
40
104
  "fetch",
@@ -43,13 +107,18 @@ export const provisionWorktree = Effect.fn("Executor.provisionWorktree")(functio
43
107
  "origin",
44
108
  request.revision,
45
109
  ]);
46
- const resolved = (yield* ops.git(["--git-dir", layout.cache, "rev-parse", "FETCH_HEAD"])).trim();
110
+ const resolved = (yield* ops.git("prepare", [
111
+ "--git-dir",
112
+ layout.cache,
113
+ "rev-parse",
114
+ "FETCH_HEAD",
115
+ ])).trim();
47
116
  const baseCommit = yield* decodeCommit(resolved).pipe(Effect.mapError((cause) => new ExecutorOperationError({
48
117
  operation: "prepare",
49
118
  message: "git returned an invalid object id",
50
119
  cause,
51
120
  })));
52
- yield* ops.git([
121
+ yield* ops.git("prepare", [
53
122
  "--git-dir",
54
123
  layout.cache,
55
124
  "worktree",
@@ -58,7 +127,7 @@ export const provisionWorktree = Effect.fn("Executor.provisionWorktree")(functio
58
127
  layout.worktree,
59
128
  baseCommit,
60
129
  ]);
61
- return new PreparedAttempt({
130
+ return new AttemptWorkspace({
62
131
  worker: request.worker,
63
132
  spec: new AttemptChannel.RunSpec({
64
133
  attemptId: request.attemptId,
@@ -69,6 +138,8 @@ export const provisionWorktree = Effect.fn("Executor.provisionWorktree")(functio
69
138
  task: request.task,
70
139
  agent: request.agent,
71
140
  parentModel: request.parentModel,
141
+ maxChildren: request.maxChildren,
142
+ parentEffort: request.parentEffort,
72
143
  }),
73
144
  worktree: WorktreePath.make(layout.worktree),
74
145
  });