harnery 0.45.0 → 0.45.1

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 (128) hide show
  1. package/dist/commander.js +0 -1
  2. package/dist/commands/files.d.ts +2 -2
  3. package/dist/commands/files.d.ts.map +1 -1
  4. package/dist/commands/files.js +4 -7
  5. package/dist/commands/servers.d.ts.map +1 -1
  6. package/dist/commands/servers.js +17 -11
  7. package/dist/commands/tunnel.d.ts +0 -15
  8. package/dist/commands/tunnel.d.ts.map +1 -1
  9. package/dist/commands/tunnel.js +153 -453
  10. package/dist/core/agents/live-authority-v3.d.ts +0 -1
  11. package/dist/core/agents/live-authority-v3.d.ts.map +1 -1
  12. package/dist/core/agents/live-authority-v3.js +0 -11
  13. package/dist/core/agents/live-lifecycle-v3.d.ts +2 -4
  14. package/dist/core/agents/live-lifecycle-v3.d.ts.map +1 -1
  15. package/dist/core/agents/live-lifecycle-v3.js +7 -28
  16. package/dist/core/agents/state/heartbeat-writer.d.ts.map +1 -1
  17. package/dist/core/agents/state/heartbeat-writer.js +14 -25
  18. package/dist/core/agents/state/live-coordination-writer.d.ts.map +1 -1
  19. package/dist/core/agents/state/live-coordination-writer.js +0 -5
  20. package/dist/core/agents/state/pidmap.d.ts.map +1 -1
  21. package/dist/core/agents/state/pidmap.js +0 -5
  22. package/dist/core/agents/state/stale-sweep.d.ts.map +1 -1
  23. package/dist/core/agents/state/stale-sweep.js +70 -180
  24. package/dist/core/artifacts/activity.d.ts +4 -1
  25. package/dist/core/artifacts/activity.d.ts.map +1 -1
  26. package/dist/core/artifacts/activity.js +8 -2
  27. package/dist/core/artifacts/delivery-card.d.ts.map +1 -1
  28. package/dist/core/artifacts/delivery-card.js +1 -2
  29. package/dist/core/artifacts/index.d.ts.map +1 -1
  30. package/dist/core/artifacts/index.js +38 -12
  31. package/dist/core/events/v3/authority-outbox.d.ts.map +1 -1
  32. package/dist/core/events/v3/authority-outbox.js +0 -29
  33. package/dist/core/events/v3/producers/coordination-recorder.d.ts +0 -1
  34. package/dist/core/events/v3/producers/coordination-recorder.d.ts.map +1 -1
  35. package/dist/core/events/v3/producers/coordination-recorder.js +0 -7
  36. package/dist/core/events/v3/producers/recorder.d.ts.map +1 -1
  37. package/dist/core/events/v3/producers/recorder.js +64 -77
  38. package/dist/core/hooks/cli.js +78 -48
  39. package/dist/core/servers/index.d.ts +13 -10
  40. package/dist/core/servers/index.d.ts.map +1 -1
  41. package/dist/core/servers/index.js +97 -192
  42. package/dist/core/servers/tunnels.d.ts +3 -5
  43. package/dist/core/servers/tunnels.d.ts.map +1 -1
  44. package/dist/core/servers/tunnels.js +2 -45
  45. package/dist/core/storage/durable-history.js +56 -22
  46. package/dist/core/storage/segments.d.ts.map +1 -1
  47. package/dist/core/storage/segments.js +73 -17
  48. package/dist/core/work/state.js +7 -7
  49. package/dist/core/workflow/engine.d.ts.map +1 -1
  50. package/dist/core/workflow/engine.js +21 -65
  51. package/dist/core/workflow/live-session-v3.d.ts +0 -6
  52. package/dist/core/workflow/live-session-v3.d.ts.map +1 -1
  53. package/dist/core/workflow/live-session-v3.js +5 -126
  54. package/dist/core/workflow/proof.d.ts +4 -4
  55. package/dist/core/workflow/proof.d.ts.map +1 -1
  56. package/dist/core/workflow/proof.js +4 -12
  57. package/dist/core/workflow/spawn-claude.d.ts.map +1 -1
  58. package/dist/core/workflow/spawn-claude.js +0 -19
  59. package/dist/core/workflow/spawn-codex.d.ts.map +1 -1
  60. package/dist/core/workflow/spawn-codex.js +0 -13
  61. package/dist/core/workflow/spawn-cursor.d.ts.map +1 -1
  62. package/dist/core/workflow/spawn-cursor.js +0 -19
  63. package/dist/core/workflow/spawn-opencode.d.ts.map +1 -1
  64. package/dist/core/workflow/spawn-opencode.js +0 -14
  65. package/dist/core/workflow/types.d.ts +11 -54
  66. package/dist/core/workflow/types.d.ts.map +1 -1
  67. package/dist/lib/identities/assume.d.ts.map +1 -1
  68. package/dist/lib/identities/assume.js +0 -4
  69. package/dist/lib/tunnel/state.d.ts +6 -13
  70. package/dist/lib/tunnel/state.d.ts.map +1 -1
  71. package/dist/lib/tunnel/state.js +12 -58
  72. package/package.json +1 -6
  73. package/src/commander.ts +0 -10
  74. package/src/commands/files.ts +5 -13
  75. package/src/commands/servers.ts +23 -12
  76. package/src/commands/tunnel.ts +166 -533
  77. package/src/core/agents/live-authority-v3.ts +0 -17
  78. package/src/core/agents/live-lifecycle-v3.ts +14 -52
  79. package/src/core/agents/state/heartbeat-writer.ts +12 -29
  80. package/src/core/agents/state/live-coordination-writer.ts +0 -29
  81. package/src/core/agents/state/pidmap.ts +0 -13
  82. package/src/core/agents/state/stale-sweep.ts +82 -247
  83. package/src/core/artifacts/activity.ts +9 -2
  84. package/src/core/artifacts/delivery-card.ts +1 -7
  85. package/src/core/artifacts/index.ts +45 -12
  86. package/src/core/events/v3/authority-outbox.ts +0 -56
  87. package/src/core/events/v3/producers/coordination-recorder.ts +0 -15
  88. package/src/core/events/v3/producers/recorder.ts +68 -94
  89. package/src/core/hooks/cli.ts +85 -47
  90. package/src/core/servers/index.ts +106 -228
  91. package/src/core/servers/tunnels.ts +3 -55
  92. package/src/core/storage/durable-history.ts +52 -20
  93. package/src/core/storage/segments.ts +79 -17
  94. package/src/core/work/state.ts +7 -7
  95. package/src/core/workflow/engine.ts +21 -73
  96. package/src/core/workflow/live-session-v3.ts +5 -146
  97. package/src/core/workflow/proof.ts +5 -21
  98. package/src/core/workflow/spawn-claude.ts +0 -18
  99. package/src/core/workflow/spawn-codex.ts +0 -13
  100. package/src/core/workflow/spawn-cursor.ts +0 -18
  101. package/src/core/workflow/spawn-opencode.ts +0 -14
  102. package/src/core/workflow/types.ts +11 -41
  103. package/src/lib/identities/assume.ts +0 -4
  104. package/src/lib/tunnel/state.ts +15 -70
  105. package/dist/commands/turn-rollback.d.ts +0 -5
  106. package/dist/commands/turn-rollback.d.ts.map +0 -1
  107. package/dist/commands/turn-rollback.js +0 -76
  108. package/dist/core/agents/state/unchanged-file.d.ts +0 -44
  109. package/dist/core/agents/state/unchanged-file.d.ts.map +0 -1
  110. package/dist/core/agents/state/unchanged-file.js +0 -390
  111. package/dist/core/events/v3/generation-custody.d.ts +0 -5
  112. package/dist/core/events/v3/generation-custody.d.ts.map +0 -1
  113. package/dist/core/events/v3/generation-custody.js +0 -50
  114. package/dist/core/turn-rollback/content.d.ts +0 -53
  115. package/dist/core/turn-rollback/content.d.ts.map +0 -1
  116. package/dist/core/turn-rollback/content.js +0 -396
  117. package/dist/core/turn-rollback/index.d.ts +0 -72
  118. package/dist/core/turn-rollback/index.d.ts.map +0 -1
  119. package/dist/core/turn-rollback/index.js +0 -443
  120. package/dist/core/workflow/failure-evidence.d.ts +0 -16
  121. package/dist/core/workflow/failure-evidence.d.ts.map +0 -1
  122. package/dist/core/workflow/failure-evidence.js +0 -114
  123. package/src/commands/turn-rollback.ts +0 -111
  124. package/src/core/agents/state/unchanged-file.ts +0 -456
  125. package/src/core/events/v3/generation-custody.ts +0 -59
  126. package/src/core/turn-rollback/content.ts +0 -499
  127. package/src/core/turn-rollback/index.ts +0 -580
  128. package/src/core/workflow/failure-evidence.ts +0 -141
@@ -1 +1 @@
1
- {"version":3,"file":"tunnels.d.ts","sourceRoot":"","sources":["../../../src/core/servers/tunnels.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAEL,KAAK,uBAAuB,EAC5B,KAAK,WAAW,EACjB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,KAAK,mBAAmB,EAExB,KAAK,aAAa,EAGnB,MAAM,YAAY,CAAC;AAEpB,uEAAuE;AACvE,wBAAgB,6BAA6B,CAAC,OAAO,EAAE,aAAa,GAAG,uBAAuB,CAiC7F;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED,6EAA6E;AAC7E,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,GAAG,mBAAmB,CAmB5F"}
1
+ {"version":3,"file":"tunnels.d.ts","sourceRoot":"","sources":["../../../src/core/servers/tunnels.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAe,KAAK,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAC1E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEtD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED,6EAA6E;AAC7E,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,GAAG,mBAAmB,CAc5F"}
@@ -2,57 +2,15 @@
2
2
  * Tunnels as registry services.
3
3
  *
4
4
  * `tunnel up` and `tunnel reload` register the new gate; `tunnel down` removes
5
- * its record. Missing original witnesses remain unknown and cannot authorize actions.
5
+ * its record. Older tunnels need an explicit adoption of an observed listener.
6
6
  */
7
- import { hostname } from "node:os";
8
7
  import { resolve } from "node:path";
9
- import { gateLogFile, } from "../../lib/tunnel/state.js";
10
- import { readServer, verifyProcessGeneration, withServerRegistrationCustody, } from "./index.js";
11
- /** Verify only witnesses saved by the original tunnel registration. */
12
- export function createTunnelReadinessVerifier(options) {
13
- return {
14
- observeProcess(pid, originalToken) {
15
- try {
16
- process.kill(pid, 0);
17
- }
18
- catch (error) {
19
- const code = error.code;
20
- if (code === "ESRCH")
21
- return "absent";
22
- return "unknown";
23
- }
24
- return verifyProcessGeneration(pid, originalToken);
25
- },
26
- withRegistration(state, inspect) {
27
- try {
28
- const original = readServer(tunnelServerId(state.name), options);
29
- if (!original ||
30
- original.host !== hostname() ||
31
- original.kind !== "service" ||
32
- original.type !== "tunnel" ||
33
- original.registration_id !== state.registration_id ||
34
- original.pid !== state.gate_pid ||
35
- original.start_token !== state.gate_start_token ||
36
- original.port !== state.gate_port ||
37
- original.url !== state.url)
38
- return "unknown";
39
- return withServerRegistrationCustody(original, options, inspect);
40
- }
41
- catch {
42
- return "unknown";
43
- }
44
- },
45
- };
46
- }
8
+ import { gateLogFile } from "../../lib/tunnel/state.js";
47
9
  export function tunnelServerId(name) {
48
10
  return `tunnel-${name.toLowerCase().replace(/[^a-z0-9._-]+/g, "-")}`;
49
11
  }
50
12
  /** Register the new gate; saved helper PIDs have no generation witnesses. */
51
13
  export function tunnelServerInput(state, coordRoot) {
52
- if (Object.hasOwn(state, "provider_pid") || Object.hasOwn(state, "provider_start_token"))
53
- throw new Error("obsolete tunnel provider authority is unknown; state retained");
54
- if (!state.gate_start_token)
55
- throw new Error("tunnel gate generation witness is unavailable; state retained");
56
14
  return {
57
15
  id: tunnelServerId(state.name),
58
16
  kind: "service",
@@ -61,7 +19,6 @@ export function tunnelServerInput(state, coordRoot) {
61
19
  url: state.url,
62
20
  port: state.gate_port,
63
21
  pid: state.gate_pid,
64
- start_token: state.gate_start_token,
65
22
  log: resolve(coordRoot, ".cache", "tunnel", gateLogFile(state.name)),
66
23
  cwd: coordRoot,
67
24
  started_at: state.started_at,
@@ -394,31 +394,55 @@ function acquireLease(lease) {
394
394
  pid: process.pid,
395
395
  acquired_at: new Date().toISOString(),
396
396
  };
397
- let claimed;
398
- try {
399
- mkdirSync(lease, { mode: stateDirMode() });
400
- assertDirectoryWithinParent(lease, parent);
401
- claimed = captureDirectoryIdentity(lease);
402
- writeOwner(join(lease, "owner.json"), owner);
403
- syncDirectory(claimed);
397
+ if (claimLease(lease, parent, owner))
404
398
  return owner;
399
+ if (recoverStaleLease(lease, DURABLE_HISTORY_LEASE_STALE_MS))
400
+ continue;
401
+ throw new Error(`durable history lease busy: ${lease}`);
402
+ }
403
+ throw new Error(`durable history lease busy: ${lease}`);
404
+ }
405
+ /**
406
+ * Publish a complete lease in one rename. The owner record is written and synced
407
+ * in a private claim directory first, so a writer stopped at any point leaves
408
+ * either no lease or one with an owner. A held lease always has an owner record,
409
+ * here and in the earlier create-then-write protocol, so a rename that replaces
410
+ * an empty lease directory never takes a held lease. A lease with any entry makes
411
+ * the rename fail and the caller reports it busy.
412
+ */
413
+ function claimLease(lease, parent, owner) {
414
+ const claim = `${lease}.claim-${process.pid}-${owner.owner_id}`;
415
+ try {
416
+ mkdirSync(claim, { mode: stateDirMode() });
417
+ assertDirectoryWithinParent(claim, parent);
418
+ const claimed = captureDirectoryIdentity(claim);
419
+ writeOwner(join(claim, "owner.json"), owner);
420
+ syncDirectory(claimed);
421
+ renameSync(claim, lease);
422
+ }
423
+ catch {
424
+ return false;
425
+ }
426
+ finally {
427
+ try {
428
+ rmSync(claim, { recursive: true, force: true });
405
429
  }
406
430
  catch {
407
- if (claimed) {
408
- try {
409
- assertDirectoryIdentity(claimed);
410
- rmSync(lease, { recursive: true, force: false });
411
- }
412
- catch {
413
- // Never remove a lease after its directory identity changes.
414
- }
415
- }
416
- if (recoverStaleLease(lease, DURABLE_HISTORY_LEASE_STALE_MS))
417
- continue;
418
- throw new Error(`durable history lease busy: ${lease}`);
431
+ // A leftover claim directory never blocks a lease.
419
432
  }
420
433
  }
421
- throw new Error(`durable history lease busy: ${lease}`);
434
+ try {
435
+ assertDirectoryWithinParent(lease, parent);
436
+ const current = JSON.parse(completeJsonl(join(lease, "owner.json")));
437
+ if (current.owner_id !== owner.owner_id)
438
+ return false;
439
+ syncDirectory(parent);
440
+ return true;
441
+ }
442
+ catch {
443
+ releaseOwnedLease(lease, owner);
444
+ return false;
445
+ }
422
446
  }
423
447
  function writeOwner(path, owner) {
424
448
  const parent = captureDirectoryIdentity(dirname(path));
@@ -468,7 +492,7 @@ function recoverStaleLease(lease, staleMs) {
468
492
  assertDirectoryIdentity(leaseIdentity);
469
493
  if (completeJsonl(ownerPath) !== raw)
470
494
  return false;
471
- rmSync(lease, { recursive: true, force: false });
495
+ retireLease(lease, randomUUID());
472
496
  return true;
473
497
  }
474
498
  catch {
@@ -480,12 +504,22 @@ function releaseOwnedLease(lease, owner) {
480
504
  const current = JSON.parse(completeJsonl(join(lease, "owner.json")));
481
505
  if (current.owner_id !== owner.owner_id)
482
506
  return;
483
- rmSync(lease, { recursive: true, force: false });
507
+ retireLease(lease, owner.owner_id);
484
508
  }
485
509
  catch {
486
510
  // A missing or replaced lease does not belong to this operation.
487
511
  }
488
512
  }
513
+ /**
514
+ * Move a lease aside before deleting it. Its path goes from held to absent in
515
+ * one rename and is never an empty directory that a concurrent claim could
516
+ * replace while a recursive removal is still running.
517
+ */
518
+ function retireLease(lease, tag) {
519
+ const retired = `${lease}.retired-${process.pid}-${tag}`;
520
+ renameSync(lease, retired);
521
+ rmSync(retired, { recursive: true, force: true });
522
+ }
489
523
  function processIsAlive(pid) {
490
524
  try {
491
525
  process.kill(pid, 0);
@@ -1 +1 @@
1
- {"version":3,"file":"segments.d.ts","sourceRoot":"","sources":["../../../src/core/storage/segments.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"segments.d.ts","sourceRoot":"","sources":["../../../src/core/storage/segments.ts"],"names":[],"mappings":"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"}
@@ -191,25 +191,19 @@ export async function withFamilyLease(directory, policy, operation) {
191
191
  let owner;
192
192
  while (true) {
193
193
  try {
194
- mkdirSync(lease, { mode: stateDirMode() });
195
- const leaseIdentity = captureDirectoryIdentity(lease);
196
- owner = {
197
- owner_id: randomUUID(),
198
- pid: process.pid,
199
- acquired_at: new Date().toISOString(),
200
- };
201
- writeNewFile(join(lease, "owner.json"), Buffer.from(`${JSON.stringify(owner)}\n`));
202
- assertDirectoryIdentity(leaseIdentity);
194
+ owner = claimLease(lease);
203
195
  break;
204
196
  }
205
197
  catch (error) {
206
- if (pathExists(lease) && !safeLeaseDirectory(lease)) {
198
+ if (leaseHasWrongType(lease)) {
207
199
  throw new HarneryLogLeaseError("wrong_type", `log lease is not a directory: ${lease}`);
208
200
  }
209
201
  if (recoverStaleLease(lease, policy.lease_stale_ms))
210
202
  continue;
211
203
  if (Date.now() - started >= policy.lease_timeout_ms) {
212
- throw new HarneryLogLeaseError("timeout", `timed out acquiring log lease: ${lease}`);
204
+ throw new HarneryLogLeaseError("timeout", leaseHasValidOwner(lease)
205
+ ? `timed out acquiring log lease: ${lease}`
206
+ : `timed out acquiring log lease with no valid owner; an interrupted writer left it, and it is never recovered automatically: ${lease}`);
213
207
  }
214
208
  await new Promise((resolve) => setTimeout(resolve, policy.lease_retry_ms));
215
209
  void error;
@@ -223,6 +217,42 @@ export async function withFamilyLease(directory, policy, operation) {
223
217
  releaseOwnedLease(lease, owner);
224
218
  }
225
219
  }
220
+ /**
221
+ * Publish a complete lease in one rename. The owner record is written and synced
222
+ * in a private claim directory first, so a writer stopped at any point leaves
223
+ * either no lease or one with an owner. A held lease always has an owner record,
224
+ * here and in the earlier create-then-write protocol, so a rename that replaces
225
+ * an empty lease directory never takes a held lease. A lease with any entry makes
226
+ * the rename fail, and the caller waits or recovers as before.
227
+ */
228
+ function claimLease(lease) {
229
+ const owner = {
230
+ owner_id: randomUUID(),
231
+ pid: process.pid,
232
+ acquired_at: new Date().toISOString(),
233
+ };
234
+ const content = `${JSON.stringify(owner)}\n`;
235
+ const claim = `${lease}.claim-${process.pid}-${owner.owner_id}`;
236
+ try {
237
+ mkdirSync(claim, { mode: stateDirMode() });
238
+ writeNewFile(join(claim, "owner.json"), Buffer.from(content));
239
+ renameSync(claim, lease);
240
+ }
241
+ finally {
242
+ rmSync(claim, { recursive: true, force: true });
243
+ }
244
+ try {
245
+ captureDirectoryIdentity(lease);
246
+ if (readRegularFile(join(lease, "owner.json"), 4_096).toString("utf8") !== content) {
247
+ throw new Error(`log lease owner changed during claim: ${lease}`);
248
+ }
249
+ }
250
+ catch (error) {
251
+ releaseOwnedLease(lease, owner);
252
+ throw error;
253
+ }
254
+ return owner;
255
+ }
226
256
  function shouldRotate(active, incoming, options, now) {
227
257
  const stat = regularFileStat(active);
228
258
  const incomingBytes = incoming.reduce((sum, record) => sum + record.byteLength, 0);
@@ -315,6 +345,18 @@ function atomicJson(path, value) {
315
345
  renameSync(temporary, path);
316
346
  assertRegularPath(path, captureDirectoryIdentity(dirname(path)));
317
347
  }
348
+ function leaseHasValidOwner(lease) {
349
+ try {
350
+ const owner = JSON.parse(readRegularFile(join(lease, "owner.json"), 4_096).toString("utf8"));
351
+ return (typeof owner?.owner_id === "string" &&
352
+ owner.owner_id.length > 0 &&
353
+ Number.isSafeInteger(owner.pid) &&
354
+ Number.isFinite(Date.parse(owner.acquired_at)));
355
+ }
356
+ catch {
357
+ return false;
358
+ }
359
+ }
318
360
  function recoverStaleLease(lease, maximumAgeMs) {
319
361
  let identity;
320
362
  let raw;
@@ -344,7 +386,7 @@ function recoverStaleLease(lease, maximumAgeMs) {
344
386
  assertDirectoryIdentity(identity);
345
387
  if (readRegularFile(join(lease, "owner.json"), 4_096).toString("utf8") !== raw)
346
388
  return false;
347
- rmSync(lease, { recursive: true, force: false });
389
+ retireLease(lease, randomUUID());
348
390
  return true;
349
391
  }
350
392
  catch {
@@ -356,12 +398,22 @@ function releaseOwnedLease(lease, owner) {
356
398
  const current = JSON.parse(readRegularFile(join(lease, "owner.json"), 4_096).toString("utf8"));
357
399
  if (current.owner_id !== owner.owner_id)
358
400
  return;
359
- rmSync(lease, { recursive: true, force: false });
401
+ retireLease(lease, owner.owner_id);
360
402
  }
361
403
  catch {
362
404
  // A missing or replaced lease does not belong to this operation.
363
405
  }
364
406
  }
407
+ /**
408
+ * Move a lease aside before deleting it. Its path goes from held to absent in
409
+ * one rename and is never an empty directory that a concurrent claim could
410
+ * replace while a recursive removal is still running.
411
+ */
412
+ function retireLease(lease, tag) {
413
+ const retired = `${lease}.retired-${process.pid}-${tag}`;
414
+ renameSync(lease, retired);
415
+ rmSync(retired, { recursive: true, force: true });
416
+ }
365
417
  function processIsAlive(pid) {
366
418
  try {
367
419
  process.kill(pid, 0);
@@ -519,12 +571,16 @@ function writeAllSync(fd, buffer, writer) {
519
571
  function nativeWriteSync(fd, buffer, offset, length) {
520
572
  return writeSync(fd, buffer, offset, length);
521
573
  }
522
- function safeLeaseDirectory(path) {
574
+ /** One lstat, so a lease released between checks reads as absent, not as a wrong type. */
575
+ function leaseHasWrongType(path) {
523
576
  try {
524
- return !lstatSync(path).isSymbolicLink() && lstatSync(path).isDirectory();
577
+ const stat = lstatSync(path);
578
+ return stat.isSymbolicLink() || !stat.isDirectory();
525
579
  }
526
- catch {
527
- return false;
580
+ catch (error) {
581
+ if (error.code === "ENOENT")
582
+ return false;
583
+ throw error;
528
584
  }
529
585
  }
530
586
  function pathExists(path) {
@@ -6,7 +6,7 @@ import { appendSegmentedJsonlFile, readSegmentedJsonlFileSync, } from "../storag
6
6
  import { stateDirMode, stateFileMode } from "../storage/modes.js";
7
7
  import { readWorkflowApproval } from "../workflow/approvals.js";
8
8
  import { stableDigest } from "../workflow/durable-record.js";
9
- import { deriveRunFailureClass, readWorkflowProof } from "../workflow/proof.js";
9
+ import { readWorkflowProof } from "../workflow/proof.js";
10
10
  import { readWorkflowRunManifest, workflowScriptDigest } from "../workflow/run-state.js";
11
11
  import { WORKFLOW_TRANSCRIPT_EVENT_BYTES, workflowTranscriptPath } from "../workflow/transcript.js";
12
12
  import { isWorkspaceBoundExecutionEvidence } from "../workflow/workspaces/validate.js";
@@ -464,13 +464,13 @@ function inspectAttempt(coordRoot, event, intent, priorRunId) {
464
464
  proof.acceptance.summary.unknown === 0
465
465
  ? "succeeded"
466
466
  : "failed";
467
- // Re-derive no-effect eligibility from every participant rather than
468
- // trusting a persisted transport class. Missing evidence stays charged.
469
- // The script's explicit decision authority remains a separate path.
467
+ // A failed attempt the run classified as uninformative about the work is
468
+ // uncharged (ADR 0046). Absent class ⇒ charged, as before. Read only for a
469
+ // failed attempt: a succeeded run never carries a class.
470
470
  if (attempt.status === "failed" &&
471
- (proof.run.class === "decision" ||
472
- ((proof.run.class === "environment" || proof.run.class === "upstream") &&
473
- deriveRunFailureClass(proof.run.status, proof.agents) === proof.run.class))) {
471
+ (proof.run.class === "environment" ||
472
+ proof.run.class === "upstream" ||
473
+ proof.run.class === "decision")) {
474
474
  attempt.uncharged = proof.run.class;
475
475
  if (proof.run.class === "decision" && typeof proof.run.decision_id === "string") {
476
476
  attempt.blocked_on = proof.run.decision_id;
@@ -1 +1 @@
1
- {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../../src/core/workflow/engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AA0DH,OAAO,KAAK,EAIV,UAAU,EAGV,SAAS,EAeV,MAAM,YAAY,CAAC;AAuDpB,qBAAa,gBAAiB,SAAQ,KAAK;IACzC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;gBAEf,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAM/E;AAED,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;gBAEpB,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM;CAOvF;AAED;;;;6EAI6E;AAC7E,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;gBAEjB,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM;CAUhD;AAED,wBAAsB,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,CA6E1F"}
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../../src/core/workflow/engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAiDH,OAAO,KAAK,EAIV,UAAU,EAGV,SAAS,EAeV,MAAM,YAAY,CAAC;AAuDpB,qBAAa,gBAAiB,SAAQ,KAAK;IACzC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;gBAEf,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAM/E;AAED,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;gBAEpB,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM;CAOvF;AAED;;;;6EAI6E;AAC7E,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;gBAEjB,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM;CAUhD;AAED,wBAAsB,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,CA6E1F"}
@@ -37,8 +37,7 @@ import { freezeWorkflowAttemptContext } from "./attempt-context.js";
37
37
  import { probeBilling } from "./billing.js";
38
38
  import { stableDigest } from "./durable-record.js";
39
39
  import { evidencePreflightError } from "./evidence-preflight.js";
40
- import { canRetryFailedSpawn, observeSpawnFailure, resolveFailureEvidence, } from "./failure-evidence.js";
41
- import { endWorkflowChildSessionV3, recordWorkflowChildTerminalFailureV3, startWorkflowChildSessionV3, } from "./live-session-v3.js";
40
+ import { endWorkflowChildSessionV3, startWorkflowChildSessionV3 } from "./live-session-v3.js";
42
41
  import { buildWorkflowProof, createEvidenceRecord, digestResult, normalizeWorkflowMeta, writeWorkflowProof, } from "./proof.js";
43
42
  import { acquireWorkflowResumeLease, assertWorkflowRunResumable, assertWorkflowScriptUnchanged, WORKFLOW_RUN_MANIFEST_SCHEMA_VERSION, workflowScriptDigest, writeWorkflowRunManifest, } from "./run-state.js";
44
43
  import { assertProjectionWithinWorkspace, resolveGitGrantRoots } from "./sandbox-projection.js";
@@ -865,40 +864,23 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
865
864
  },
866
865
  });
867
866
  agentProof.access = access;
868
- let childGenerationId;
869
867
  let recordAgentEnd;
870
868
  const finalizeChild = () => {
871
869
  try {
872
- if (childGenerationId)
873
- endWorkflowChildSessionV3({
874
- coordRoot: opts.coordRoot,
875
- instanceId: childInstanceId(runId, id),
876
- runId,
877
- agentId: id,
878
- adapter,
879
- cleanExit: agentProof.status === "succeeded",
880
- expectedGenerationId: childGenerationId,
881
- });
882
- // Result publication is the resume-cache boundary, after canonical custody.
870
+ // Record the canonical terminal first. agent.end is the resume-cache
871
+ // boundary, so a child whose end was not recorded never reports success.
872
+ endWorkflowChildSessionV3({
873
+ coordRoot: opts.coordRoot,
874
+ instanceId: childInstanceId(runId, id),
875
+ runId,
876
+ agentId: id,
877
+ adapter,
878
+ cleanExit: agentProof.status === "succeeded",
879
+ });
883
880
  recordAgentEnd?.();
884
881
  }
885
882
  catch (error) {
886
- let reason = `V3 terminal recording failed: ${error.message}`;
887
- try {
888
- if (childGenerationId)
889
- recordWorkflowChildTerminalFailureV3({
890
- coordRoot: opts.coordRoot,
891
- instanceId: childInstanceId(runId, id),
892
- runId,
893
- agentId: id,
894
- adapter,
895
- expectedGenerationId: childGenerationId,
896
- reason,
897
- });
898
- }
899
- catch (visibilityError) {
900
- reason += `; blocked lifecycle recording failed: ${visibilityError.message}`;
901
- }
883
+ const reason = `V3 terminal recording failed: ${error.message}`;
902
884
  const failure = new Error(agentProof.error ? `${agentProof.error}; ${reason}` : reason, {
903
885
  cause: error,
904
886
  });
@@ -930,7 +912,7 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
930
912
  // Headless children do not reliably fire adapter hooks. The engine owns
931
913
  // their canonical V3 start so every dispatched child has an auditable
932
914
  // generation before it begins work.
933
- const child = startWorkflowChildSessionV3({
915
+ startWorkflowChildSessionV3({
934
916
  coordRoot: opts.coordRoot,
935
917
  instanceId: childInstanceId(runId, id),
936
918
  runId,
@@ -939,13 +921,9 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
939
921
  label,
940
922
  model: agentOpts.model,
941
923
  });
942
- if (!child.v3_generation_id)
943
- throw new Error("workflow_child_v3_generation_missing");
944
- childGenerationId = child.v3_generation_id;
945
924
  let attemptPrompt = dispatchPrompt;
946
925
  let last = null;
947
926
  let agentCostUsd = 0;
948
- let informativeAttempt;
949
927
  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
950
928
  last = await spawner({
951
929
  prompt: attemptPrompt,
@@ -967,29 +945,15 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
967
945
  agentCostUsd += last.costUsd ?? 0;
968
946
  costUsd += last.costUsd ?? 0;
969
947
  if (!last.ok) {
970
- const observed = last.failureEvidence === undefined
971
- ? observeSpawnFailure({}, last.text, "final_message")
972
- : resolveFailureEvidence(last.failureEvidence);
973
- agentProof.failure_evidence = informativeAttempt
974
- ? {
975
- ...observed,
976
- effect: { state: "unknown" },
977
- partial_output: informativeAttempt.partial_output,
978
- }
979
- : observed;
980
- transcript("agent.attempt_failed", {
981
- id,
982
- attempt,
983
- error: last.error,
984
- failure_evidence: observed,
985
- result_digest: digestResult(last.text, "text"),
986
- text: last.text,
987
- });
988
- if (!canRetryFailedSpawn({ ...last, failureEvidence: agentProof.failure_evidence }))
948
+ transcript("agent.attempt_failed", { id, attempt, error: last.error });
949
+ // ADR 0046: an environment failure (the binary was absent) cannot be
950
+ // helped by retrying an unchanged environment, so stop the in-agent
951
+ // retry too — not just the outer attempt/replan budget. An upstream
952
+ // refusal keeps retrying here: the vendor may recover mid-loop.
953
+ if (last.class === "environment")
989
954
  break;
990
- continue;
955
+ continue; // spawn-level failure: retry with the original prompt
991
956
  }
992
- informativeAttempt = observeSpawnFailure({}, last.text, "final_message");
993
957
  if (!agentOpts.schema) {
994
958
  agentProof.status = "succeeded";
995
959
  agentProof.cost_usd =
@@ -1030,14 +994,7 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
1030
994
  }, "json", parsed.value);
1031
995
  return parsed.value;
1032
996
  }
1033
- agentProof.failure_evidence = informativeAttempt;
1034
- transcript("agent.schema_retry", {
1035
- id,
1036
- attempt,
1037
- problems,
1038
- rejected_text: last.text,
1039
- result_digest: digestResult(last.text, "text"),
1040
- });
997
+ transcript("agent.schema_retry", { id, attempt, problems });
1041
998
  // Keep the original cache identity while making the actual output
1042
999
  // contract explicit. A full bounded copy of the rejected value lets the
1043
1000
  // child repair omissions instead of reconstructing an unseen object.
@@ -1076,7 +1033,6 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
1076
1033
  finalizeChild();
1077
1034
  }
1078
1035
  finally {
1079
- // A slot is disposable; unresolved custody remains visible and failed.
1080
1036
  release();
1081
1037
  }
1082
1038
  }
@@ -14,12 +14,6 @@ export declare function startWorkflowChildSessionV3(input: WorkflowChildSessionV
14
14
  /** Record the authoritative terminal before removing the disposable coordination cache. */
15
15
  export declare function endWorkflowChildSessionV3(input: WorkflowChildSessionV3Input & {
16
16
  cleanExit: boolean;
17
- expectedGenerationId: string;
18
- }): void;
19
- /** Persist unresolved terminal custody only for the generation this dispatch owns. */
20
- export declare function recordWorkflowChildTerminalFailureV3(input: WorkflowChildSessionV3Input & {
21
- expectedGenerationId: string;
22
- reason: string;
23
17
  }): void;
24
18
  export { stableScopeId } from "./scope-id.js";
25
19
  //# sourceMappingURL=live-session-v3.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"live-session-v3.d.ts","sourceRoot":"","sources":["../../../src/core/workflow/live-session-v3.ts"],"names":[],"mappings":"AAUA,OAAO,EACL,KAAK,SAAS,EAGf,MAAM,qCAAqC,CAAC;AAoB7C,MAAM,WAAW,2BAA2B;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,8FAA8F;AAC9F,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,2BAA2B,GAAG,SAAS,CAqDzF;AAED,2FAA2F;AAC3F,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,2BAA2B,GAAG;IAAE,SAAS,EAAE,OAAO,CAAC;IAAC,oBAAoB,EAAE,MAAM,CAAA;CAAE,GACxF,IAAI,CAIN;AA0CD,sFAAsF;AACtF,wBAAgB,oCAAoC,CAClD,KAAK,EAAE,2BAA2B,GAAG;IAAE,oBAAoB,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACpF,IAAI,CAcN;AA8FD,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"live-session-v3.d.ts","sourceRoot":"","sources":["../../../src/core/workflow/live-session-v3.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,SAAS,EAEf,MAAM,qCAAqC,CAAC;AAY7C,MAAM,WAAW,2BAA2B;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,8FAA8F;AAC9F,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,2BAA2B,GAAG,SAAS,CAiDzF;AAED,2FAA2F;AAC3F,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,2BAA2B,GAAG;IAAE,SAAS,EAAE,OAAO,CAAA;CAAE,GAC1D,IAAI,CAmBN;AAgBD,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC"}