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
@@ -38,7 +38,6 @@ interface LiveAuthorityBaseV3 {
38
38
  nativeSessionId: string;
39
39
  adapter: Adapter;
40
40
  observationId?: string;
41
- expectedGenerationId?: `gen_${string}`;
42
41
  }
43
42
  /**
44
43
  * Establish the missing generation authority for one adapter-native session,
@@ -1 +1 @@
1
- {"version":3,"file":"live-authority-v3.d.ts","sourceRoot":"","sources":["../../../src/core/agents/live-authority-v3.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"live-authority-v3.d.ts","sourceRoot":"","sources":["../../../src/core/agents/live-authority-v3.ts"],"names":[],"mappings":"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"}
@@ -419,10 +419,6 @@ function recordLiveAuthority(input, signal, observation, expected, desired, appl
419
419
  platform: livePlatformV3(),
420
420
  expected_prior_state_digest: coordinationAuthorityStateDigestV3(expected),
421
421
  desired_state_digest: coordinationAuthorityStateDigestV3(desired),
422
- expected_generation_id: input.expectedGenerationId ??
423
- (subject === input.owner
424
- ? expected.v3_generation_id
425
- : readLiveCoordinationRow(input.coordRoot, input.owner)?.v3_generation_id),
426
422
  reconciler: {
427
423
  readStateDigest: () => {
428
424
  const heartbeat = readHeartbeat(input.coordRoot, subject);
@@ -452,16 +448,9 @@ export function liveCoordinationWriteModeV3(coordRoot) {
452
448
  return route.mode;
453
449
  }
454
450
  function requireHeartbeat(input, owner) {
455
- if (input.expectedGenerationId &&
456
- readLiveCoordinationRow(input.coordRoot, owner)?.v3_generation_id !== input.expectedGenerationId) {
457
- throw new LiveCoordinationAuthorityV3Error("expected_generation_changed");
458
- }
459
451
  const heartbeat = ensureLiveCoordinationHeartbeat(input.coordRoot, owner, owner === input.owner ? input.nativeSessionId : owner, input.adapter);
460
452
  if (!heartbeat)
461
453
  throw new LiveCoordinationAuthorityV3Error(`heartbeat_missing:${owner}`);
462
- if (input.expectedGenerationId && heartbeat.v3_generation_id !== input.expectedGenerationId) {
463
- throw new LiveCoordinationAuthorityV3Error("expected_generation_changed");
464
- }
465
454
  return heartbeat;
466
455
  }
467
456
  export function coordinationAuthorityStateDigestV3(heartbeat) {
@@ -11,12 +11,10 @@ interface LiveLifecycleObservationBaseV3 {
11
11
  adapter: EventAdapterIdV3;
12
12
  observedAt?: string;
13
13
  }
14
- interface LiveSweepObservationV3Input extends LiveLifecycleObservationBaseV3 {
15
- expectedGenerationId: `gen_${string}` | null;
14
+ export declare function recordLiveSweepObservationV3(input: LiveLifecycleObservationBaseV3 & {
16
15
  observation: "stale_heartbeat" | "killed" | "unparseable_heartbeat" | "missing_timestamp";
17
16
  ageMs: number;
18
- }
19
- export declare function recordLiveSweepObservationV3(input: LiveSweepObservationV3Input): LiveLifecycleObservationV3Result;
17
+ }): LiveLifecycleObservationV3Result;
20
18
  export declare function recordLiveResumeObservationV3(input: LiveLifecycleObservationBaseV3): LiveLifecycleObservationV3Result;
21
19
  export {};
22
20
  //# sourceMappingURL=live-lifecycle-v3.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"live-lifecycle-v3.d.ts","sourceRoot":"","sources":["../../../src/core/agents/live-lifecycle-v3.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAGnE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAcxD,MAAM,MAAM,gCAAgC,GAAG;IAAE,KAAK,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAC;AAErF,UAAU,8BAA8B;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,gBAAgB,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,UAAU,2BAA4B,SAAQ,8BAA8B;IAC1E,oBAAoB,EAAE,OAAO,MAAM,EAAE,GAAG,IAAI,CAAC;IAC7C,WAAW,EAAE,iBAAiB,GAAG,QAAQ,GAAG,uBAAuB,GAAG,mBAAmB,CAAC;IAC1F,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,2BAA2B,GACjC,gCAAgC,CAqBlC;AAED,wBAAgB,6BAA6B,CAC3C,KAAK,EAAE,8BAA8B,GACpC,gCAAgC,CAalC"}
1
+ {"version":3,"file":"live-lifecycle-v3.d.ts","sourceRoot":"","sources":["../../../src/core/agents/live-lifecycle-v3.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAGnE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAaxD,MAAM,MAAM,gCAAgC,GAAG;IAAE,KAAK,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAC;AAErF,UAAU,8BAA8B;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,gBAAgB,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,8BAA8B,GAAG;IACtC,WAAW,EAAE,iBAAiB,GAAG,QAAQ,GAAG,uBAAuB,GAAG,mBAAmB,CAAC;IAC1F,KAAK,EAAE,MAAM,CAAC;CACf,GACA,gCAAgC,CAOlC;AAED,wBAAgB,6BAA6B,CAC3C,KAAK,EAAE,8BAA8B,GACpC,gCAAgC,CAQlC"}
@@ -3,27 +3,17 @@ import { buildEventV3 } from "../events/v3/builder.js";
3
3
  import { normalizeNativeIdV3 } from "../events/v3/canonical.js";
4
4
  import { readEventV3ControlState } from "../events/v3/control.js";
5
5
  import { fingerprintContextV3 } from "../events/v3/fingerprint-keys.js";
6
- import { withGenerationCustodyV3 } from "../events/v3/generation-custody.js";
7
6
  import { liveInstanceIdV3, livePlatformV3, resolveLiveEventLedgerRouteV3, } from "../events/v3/live-routing.js";
8
7
  import { readJoinableHookProducerStateV3 } from "../events/v3/producers/recorder.js";
9
8
  import { writeEventV3 } from "../events/v3/writer.js";
10
9
  import { LiveCoordinationAuthorityV3Error } from "./live-authority-v3.js";
11
10
  import { liveCoordinationAdapterV3 } from "./state/live-coordination-view.js";
12
11
  export function recordLiveSweepObservationV3(input) {
13
- input = { ...input };
14
- // Reject stale observations before preparing durable custody state. The
15
- // in-custody checks cover replacement while acquiring custody and reentry.
16
- requireSweepHookState(input);
17
- return withGenerationCustodyV3(input.coordRoot, [liveInstanceIdV3(input.owner)], () => {
18
- requireSweepHookState(input);
19
- return recordObservation(input, "lifecycle.sweep_observed", {
20
- subject_instance_id: liveInstanceIdV3(input.owner),
21
- observation: input.observation,
22
- provisional: true,
23
- age_ms: Math.max(0, Math.floor(input.ageMs)),
24
- }, () => {
25
- requireSweepHookState(input);
26
- });
12
+ return recordObservation(input, "lifecycle.sweep_observed", {
13
+ subject_instance_id: liveInstanceIdV3(input.owner),
14
+ observation: input.observation,
15
+ provisional: true,
16
+ age_ms: Math.max(0, Math.floor(input.ageMs)),
27
17
  });
28
18
  }
29
19
  export function recordLiveResumeObservationV3(input) {
@@ -33,9 +23,9 @@ export function recordLiveResumeObservationV3(input) {
33
23
  prior_generation_id: hook.generation_id,
34
24
  continuity: "native",
35
25
  evidence_reference: "heartbeat_recreated",
36
- }, () => { });
26
+ });
37
27
  }
38
- function recordObservation(input, eventType, payload, beforeWrite) {
28
+ function recordObservation(input, eventType, payload) {
39
29
  const route = resolveLiveEventLedgerRouteV3(input.coordRoot);
40
30
  if (route.state === "blocked")
41
31
  throw new LiveCoordinationAuthorityV3Error(route.reason);
@@ -83,7 +73,6 @@ function recordObservation(input, eventType, payload, beforeWrite) {
83
73
  monotonic_ns: process.hrtime.bigint().toString(),
84
74
  };
85
75
  const event = buildEventV3(eventType, { ...common, payload });
86
- beforeWrite();
87
76
  const durability = writeEventV3(input.coordRoot, event, {
88
77
  expectedGenesisId: control.genesis.event.payload.genesis_id,
89
78
  });
@@ -92,16 +81,6 @@ function recordObservation(input, eventType, payload, beforeWrite) {
92
81
  }
93
82
  return { state: "recorded", event };
94
83
  }
95
- function requireSweepHookState(input) {
96
- if (typeof input.expectedGenerationId !== "string" ||
97
- !/^gen_[a-zA-Z0-9._-]+$/.test(input.expectedGenerationId)) {
98
- throw new LiveCoordinationAuthorityV3Error("hook_generation_not_joinable");
99
- }
100
- const hook = requireHookState(withAttestedAdapter(input));
101
- if (hook.generation_id !== input.expectedGenerationId) {
102
- throw new LiveCoordinationAuthorityV3Error("expected_generation_changed");
103
- }
104
- }
105
84
  function withAttestedAdapter(input) {
106
85
  const adapter = liveCoordinationAdapterV3(input.coordRoot, input.owner);
107
86
  if (!adapter)
@@ -1 +1 @@
1
- {"version":3,"file":"heartbeat-writer.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/state/heartbeat-writer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAkBH,OAAO,EAAE,KAAK,SAAS,EAAgC,MAAM,uBAAuB,CAAC;AACrF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAEpD,OAAO,EAAE,KAAK,SAAS,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAatE,kFAAkF;AAClF,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,SAAS,EAChB,MAAM,CAAC,EAAE,MAAM,EACf,oBAAoB,CAAC,EAAE,MAAM,GAC5B,SAAS,GAAG,IAAI,CAQlB;AAkBD,wBAAgB,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAoB7F;AAED,6EAA6E;AAC7E,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,GACd,SAAS,GAAG,IAAI,CAUlB;AAED;;;;6BAI6B;AAC7B,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE,SAAS,GAAG,UAAU,GAAG,WAAuB,GACrD,SAAS,GAAG,IAAI,CAelB;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,MAAM,EAAE,GACzB;IAAE,aAAa,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAKvD;AAED,2EAA2E;AAC3E,wBAAgB,2BAA2B,CACzC,kBAAkB,EAAE,MAAM,GAAG,SAAS,EACtC,KAAK,EAAE,SAAS,GACf,MAAM,GAAG,IAAI,CAOf;AAED;;;;4EAI4E;AAC5E,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,IAAI,CAAC,EAAE,MAAM,GACZ,SAAS,GAAG,IAAI,CAMlB;AAED;;;;;;;;;GASG;AACH,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,GACX,SAAS,GAAG,IAAI,CAOlB;AAED;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,GACX,SAAS,GAAG,IAAI,CAOlB;AAED,wBAAgB,YAAY,CAC1B,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,GACX,SAAS,GAAG,IAAI,CAQlB;AAED,oFAAoF;AACpF,wBAAgB,YAAY,CAC1B,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,GACX,SAAS,GAAG,IAAI,CAWlB;AAED,uEAAuE;AACvE,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,eAAe,CAC7B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,GACX,eAAe,EAAE,CA6BnB;AAED,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CASrF;AAED,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAInF"}
1
+ {"version":3,"file":"heartbeat-writer.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/state/heartbeat-writer.ts"],"names":[],"mappings":"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"}
@@ -15,8 +15,6 @@
15
15
  */
16
16
  import { existsSync, mkdirSync, readdirSync, readFileSync, renameSync, unlinkSync, writeFileSync, } from "node:fs";
17
17
  import { dirname, join } from "node:path";
18
- import { assertCurrentGenerationV3, withGenerationCustodyV3, } from "../../events/v3/generation-custody.js";
19
- import { liveInstanceIdV3 } from "../../events/v3/live-routing.js";
20
18
  import { canonicalClaimPath } from "../claim-path.js";
21
19
  import { heartbeatPath, readHeartbeat } from "./heartbeat-reader.js";
22
20
  export { readHeartbeat } from "./heartbeat-reader.js";
@@ -40,16 +38,13 @@ export function setLifecycleCache(coordRoot, instanceId, state, reason, suggeste
40
38
  }));
41
39
  }
42
40
  function mutate(coordRoot, instanceId, fn) {
43
- return withGenerationCustodyV3(coordRoot, [liveInstanceIdV3(instanceId)], () => {
44
- const hb = readHeartbeat(coordRoot, instanceId);
45
- if (!hb)
46
- return null;
47
- const next = fn(hb);
48
- next.last_heartbeat = nowIsoSeconds();
49
- assertCurrentGenerationV3(coordRoot, liveInstanceIdV3(instanceId), hb.v3_generation_id);
50
- atomicWrite(heartbeatPath(coordRoot, instanceId), JSON.stringify(next, null, 2));
51
- return next;
52
- });
41
+ const hb = readHeartbeat(coordRoot, instanceId);
42
+ if (!hb)
43
+ return null;
44
+ const next = fn(hb);
45
+ next.last_heartbeat = nowIsoSeconds();
46
+ atomicWrite(heartbeatPath(coordRoot, instanceId), JSON.stringify(next, null, 2));
47
+ return next;
53
48
  }
54
49
  export function setTask(coordRoot, instanceId, task) {
55
50
  return mutate(coordRoot, instanceId, (hb) => {
@@ -73,16 +68,13 @@ export function setTask(coordRoot, instanceId, task) {
73
68
  }
74
69
  /** Update the disposable identity cache after a canonical V3 attestation. */
75
70
  export function setIdentityCache(coordRoot, instanceId, name, agentId) {
76
- return withGenerationCustodyV3(coordRoot, [liveInstanceIdV3(instanceId)], () => {
77
- const heartbeat = readHeartbeat(coordRoot, instanceId);
78
- if (!heartbeat)
79
- return null;
80
- heartbeat.name = name;
81
- heartbeat.agent_id = agentId;
82
- assertCurrentGenerationV3(coordRoot, liveInstanceIdV3(instanceId), heartbeat.v3_generation_id);
83
- atomicWrite(heartbeatPath(coordRoot, instanceId), JSON.stringify(heartbeat, null, 2));
84
- return heartbeat;
85
- });
71
+ const heartbeat = readHeartbeat(coordRoot, instanceId);
72
+ if (!heartbeat)
73
+ return null;
74
+ heartbeat.name = name;
75
+ heartbeat.agent_id = agentId;
76
+ atomicWrite(heartbeatPath(coordRoot, instanceId), JSON.stringify(heartbeat, null, 2));
77
+ return heartbeat;
86
78
  }
87
79
  /** Restore the pool-assigned display name on a generation that was
88
80
  * materialized before the adapter's normal SessionStart naming path ran.
@@ -256,9 +248,6 @@ export function clearCoordinationCache(coordRoot, instanceId) {
256
248
  }
257
249
  }
258
250
  export function healPidmap(coordRoot, instanceId, pid) {
259
- withGenerationCustodyV3(coordRoot, [liveInstanceIdV3(instanceId)], () => healPidmapUnderCustody(coordRoot, instanceId, pid));
260
- }
261
- function healPidmapUnderCustody(coordRoot, instanceId, pid) {
262
251
  const dir = join(coordRoot, ".harnery", "pid-map");
263
252
  mkdirSync(dir, { recursive: true });
264
253
  const hb = readHeartbeat(coordRoot, instanceId);
@@ -1 +1 @@
1
- {"version":3,"file":"live-coordination-writer.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/state/live-coordination-writer.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAUhD,OAAO,EAAE,KAAK,SAAS,EAAiB,MAAM,uBAAuB,CAAC;AAUtE;;;;;GAKG;AACH,wBAAgB,+BAA+B,CAC7C,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,MAAM,EACxB,eAAe,EAAE,MAAM,EACvB,QAAQ,EAAE,OAAO,EACjB,KAAK,CAAC,EAAE,MAAM,GACb,SAAS,GAAG,IAAI,CASlB;AAED,wFAAwF;AACxF,wBAAgB,+BAA+B,CAC7C,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,MAAM,EACxB,eAAe,EAAE,MAAM,EACvB,OAAO,EAAE,OAAO,EAChB,KAAK,CAAC,EAAE,MAAM,GACb,SAAS,GAAG,IAAI,CASlB"}
1
+ {"version":3,"file":"live-coordination-writer.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/state/live-coordination-writer.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAMhD,OAAO,EAAE,KAAK,SAAS,EAAiB,MAAM,uBAAuB,CAAC;AAUtE;;;;;GAKG;AACH,wBAAgB,+BAA+B,CAC7C,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,MAAM,EACxB,eAAe,EAAE,MAAM,EACvB,QAAQ,EAAE,OAAO,EACjB,KAAK,CAAC,EAAE,MAAM,GACb,SAAS,GAAG,IAAI,CASlB;AAED,wFAAwF;AACxF,wBAAgB,+BAA+B,CAC7C,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,MAAM,EACxB,eAAe,EAAE,MAAM,EACvB,OAAO,EAAE,OAAO,EAChB,KAAK,CAAC,EAAE,MAAM,GACb,SAAS,GAAG,IAAI,CASlB"}
@@ -1,7 +1,6 @@
1
1
  import { mkdirSync, renameSync, writeFileSync } from "node:fs";
2
2
  import { dirname, join } from "node:path";
3
3
  import { readCoordinationViewV3, requireAuthoritySafeCoordinationViewV3, } from "../../events/v3/coordination-view.js";
4
- import { assertCurrentGenerationV3, withGenerationCustodyV3, } from "../../events/v3/generation-custody.js";
5
4
  import { liveInstanceIdV3, resolveLiveEventLedgerRouteV3 } from "../../events/v3/live-routing.js";
6
5
  import { readHeartbeat } from "./heartbeat-reader.js";
7
6
  import { isAdapterV3, isCurrentV3HeartbeatCache, observedAdapterV3, projectHeartbeatV3, } from "./live-coordination-view.js";
@@ -20,9 +19,6 @@ export function repairLiveCoordinationHeartbeat(coordRoot, nativeInstanceId, nat
20
19
  return materializeLiveCoordinationHeartbeat(coordRoot, nativeInstanceId, nativeSessionId, adapter, model, true);
21
20
  }
22
21
  function materializeLiveCoordinationHeartbeat(coordRoot, nativeInstanceId, nativeSessionId, _adapter, model, force) {
23
- return withGenerationCustodyV3(coordRoot, [liveInstanceIdV3(nativeInstanceId)], () => materializeHeartbeatUnderCustody(coordRoot, nativeInstanceId, nativeSessionId, _adapter, model, force));
24
- }
25
- function materializeHeartbeatUnderCustody(coordRoot, nativeInstanceId, nativeSessionId, _adapter, model, force) {
26
22
  const route = resolveLiveEventLedgerRouteV3(coordRoot);
27
23
  if (route.state === "blocked")
28
24
  throw new Error(`event_v3_coordination_view:${route.reason}`);
@@ -89,7 +85,6 @@ function materializeHeartbeatUnderCustody(coordRoot, nativeInstanceId, nativeSes
89
85
  v3_projection_event_id: generation.last_event_id,
90
86
  v3_task_state: generation.task_state === "set" ? "set" : "cleared",
91
87
  };
92
- assertCurrentGenerationV3(coordRoot, liveInstanceIdV3(nativeInstanceId), generation.generation_id);
93
88
  writeHeartbeatCache(coordRoot, nativeInstanceId, materialized);
94
89
  return materialized;
95
90
  }
@@ -1 +1 @@
1
- {"version":3,"file":"pidmap.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/state/pidmap.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AA2BH,6EAA6E;AAC7E,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG;IAC3C,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;CAChC,CAGA;AAwCD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CA8B7D;AAED,wBAAgB,cAAc,CAC5B,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,GACf,IAAI,CAIN;AAsCD;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAmBjF;AAED,yFAAyF;AACzF,wBAAgB,2BAA2B,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAoBzF"}
1
+ {"version":3,"file":"pidmap.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/state/pidmap.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAyBH,6EAA6E;AAC7E,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG;IAC3C,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;CAChC,CAGA;AAwCD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CA8B7D;AAED,wBAAgB,cAAc,CAC5B,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,GACf,IAAI,CA6BN;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAmBjF;AAED,yFAAyF;AACzF,wBAAgB,2BAA2B,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAoBzF"}
@@ -15,8 +15,6 @@
15
15
  */
16
16
  import { existsSync, mkdirSync, readdirSync, readFileSync, renameSync, unlinkSync, writeFileSync, } from "node:fs";
17
17
  import { dirname, join } from "node:path";
18
- import { withGenerationCustodyV3 } from "../../events/v3/generation-custody.js";
19
- import { liveInstanceIdV3 } from "../../events/v3/live-routing.js";
20
18
  import { checkPidToken, processStartToken } from "./proc-start.js";
21
19
  /**
22
20
  * Row count that triggers a dead-row sweep on the next write.
@@ -112,9 +110,6 @@ export function prunePidmapDeadRows(coordRoot) {
112
110
  return removed;
113
111
  }
114
112
  export function writePidmapRow(coordRoot, pid, instanceId, platform) {
115
- withGenerationCustodyV3(coordRoot, [liveInstanceIdV3(instanceId)], () => writePidmapRowUnderCustody(coordRoot, pid, instanceId, platform));
116
- }
117
- function writePidmapRowUnderCustody(coordRoot, pid, instanceId, platform) {
118
113
  const dir = join(coordRoot, ".harnery", "pid-map");
119
114
  const path = join(dir, String(pid));
120
115
  // Stamped at write time, when the pid provably belongs to the process we
@@ -1 +1 @@
1
- {"version":3,"file":"stale-sweep.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/state/stale-sweep.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAyIH,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG;IAC7C,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,qBAAqB,EAAE,MAAM,CAAC;CAC/B,CAuPA"}
1
+ {"version":3,"file":"stale-sweep.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/state/stale-sweep.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAkEH,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG;IAC7C,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,qBAAqB,EAAE,MAAM,CAAC;CAC/B,CAyJA"}
@@ -9,15 +9,12 @@
9
9
  * HARNERY_AGENT_COORD_FRESHNESS env var or `.harnery/config.jsonc`
10
10
  * `coord.freshness_seconds` (see `coordFreshnessSeconds`).
11
11
  */
12
- import { existsSync, lstatSync, readdirSync } from "node:fs";
13
- import { basename, dirname, join, resolve } from "node:path";
12
+ import { existsSync, readdirSync, readFileSync, statSync, unlinkSync } from "node:fs";
13
+ import { join } from "node:path";
14
14
  import { coordFreshnessSeconds } from "../../config.js";
15
15
  import { eventAdapterIdV3FromPlatform } from "../../events/v3/adapter-id.js";
16
- import { withGenerationCustodyV3 } from "../../events/v3/generation-custody.js";
17
- import { liveInstanceIdV3 } from "../../events/v3/live-routing.js";
18
16
  import { writeProducerDiagnosticV3 } from "../../events/v3/producers/intake.js";
19
17
  import { recordLiveSweepObservationV3 } from "../live-lifecycle-v3.js";
20
- import { captureFileRevision, deleteFileIfUnchanged, recoverInterruptedFileDeletions, } from "./unchanged-file.js";
21
18
  /** platform → adapter, for the swept-event envelope (mirrors heartbeat-writer's adapterOf). */
22
19
  /**
23
20
  * Record the sweep before deleting disposable cache state.
@@ -28,14 +25,13 @@ import { captureFileRevision, deleteFileIfUnchanged, recoverInterruptedFileDelet
28
25
  * diagnostics spool instead. If neither durable record can be written, fail
29
26
  * closed and keep the file.
30
27
  */
31
- function emitSwept(coordRoot, instanceId, adapter, sessionId, expectedGenerationId, reason, ageSecs) {
28
+ function emitSwept(coordRoot, instanceId, adapter, sessionId, reason, ageSecs) {
32
29
  try {
33
30
  recordLiveSweepObservationV3({
34
31
  coordRoot,
35
32
  owner: instanceId,
36
33
  nativeSessionId: sessionId,
37
34
  adapter,
38
- expectedGenerationId,
39
35
  observation: reason === "stale"
40
36
  ? "stale_heartbeat"
41
37
  : reason === "unparseable"
@@ -57,58 +53,14 @@ function emitSwept(coordRoot, instanceId, adapter, sessionId, expectedGeneration
57
53
  }));
58
54
  }
59
55
  }
60
- /** Any retained or unreadable owner row prevents dependent cache deletion. */
61
- function retainsHeartbeat(coordRoot, activeDir, owner, uncertainOwners) {
62
- if (uncertainOwners.has("*") || uncertainOwners.has(owner))
63
- return true;
64
- if (!/^[A-Za-z0-9_-]{1,128}$/.test(owner))
65
- return true;
66
- const heartbeat = join(activeDir, `${owner}.json`);
56
+ /** File mtime in epoch-seconds, or +Infinity if it can't be read (treat as fresh → don't reap). */
57
+ function mtimeSecs(path) {
67
58
  try {
68
- lstatSync(heartbeat);
69
- return true;
70
- }
71
- catch (error) {
72
- if (error.code !== "ENOENT")
73
- return true;
74
- }
75
- try {
76
- if (!lstatSync(activeDir).isDirectory())
77
- return true;
78
- }
79
- catch (error) {
80
- return error.code !== "ENOENT";
81
- }
82
- // Callers hold this owner's custody. A sweeper that died after the initial
83
- // directory scan may have left its heartbeat hidden under a private pin.
84
- for (const recovery of recoverInterruptedFileDeletions(activeDir, (source) => source === heartbeat)) {
85
- if (recovery.sourcePath && recovery.sourcePath !== heartbeat)
86
- continue;
87
- if (recovery.state !== "restored") {
88
- uncertainOwners.add(recovery.sourcePath ? owner : "*");
89
- recordCleanupFailure(coordRoot, recovery.sourcePath ?? activeDir, recovery);
90
- }
91
- return true;
92
- }
93
- return false;
94
- }
95
- function recordCleanupFailure(coordRoot, sourcePath, result) {
96
- if (result.state !== "error" &&
97
- result.state !== "recovery-required" &&
98
- result.state !== "retained") {
99
- return;
59
+ return Math.floor(statSync(path).mtimeMs / 1000);
100
60
  }
101
- writeProducerDiagnosticV3(coordRoot, "heartbeat_sweep_unrecorded", {
102
- signal: "cache.cleanup",
103
- state: "cache_cleanup_pending",
104
- reason: `${result.state}:${result.error ?? "file_cleanup_pending"}; source=${sourcePath}; recovery=${result.recoveryPath ?? "unavailable"}`,
105
- });
106
- }
107
- function recordHeartbeatCleanupResult(coordRoot, sourcePath, owner, result, uncertainOwners) {
108
- if (result.state === "recovery-required" || result.state === "error") {
109
- uncertainOwners.add(owner);
61
+ catch {
62
+ return Number.POSITIVE_INFINITY;
110
63
  }
111
- recordCleanupFailure(coordRoot, sourcePath, result);
112
64
  }
113
65
  export function staleSweep(coordRoot) {
114
66
  const heartbeatsRemoved = [];
@@ -134,129 +86,81 @@ export function staleSweep(coordRoot) {
134
86
  // lifecycle.sweep_observed; a terminal or unavailable generation gets a
135
87
  // heartbeat_sweep_unrecorded producer diagnostic without being resurrected.
136
88
  const liveInstanceIds = new Set();
137
- const uncertainOwners = new Set();
138
- const d = resolve(coordRoot, ".harnery", "active");
139
- for (const recovery of existsSync(d)
140
- ? recoverInterruptedFileDeletions(d, (source) => dirname(source) === d && /^[A-Za-z0-9_-]{1,128}\.json$/.test(basename(source)))
141
- : []) {
142
- if (recovery.state !== "restored") {
143
- uncertainOwners.add(recovery.sourcePath ? basename(recovery.sourcePath, ".json") : "*");
144
- recordCleanupFailure(coordRoot, recovery.sourcePath ?? d, recovery);
145
- }
146
- }
89
+ const d = join(coordRoot, ".harnery", "active");
147
90
  if (existsSync(d)) {
148
91
  for (const f of readdirSync(d)) {
149
92
  if (!f.endsWith(".json"))
150
93
  continue;
151
94
  const path = join(d, f);
152
95
  const idFromFile = f.replace(/\.json$/, "");
153
- if (!/^[A-Za-z0-9_-]{1,128}$/.test(idFromFile))
154
- continue;
96
+ let parsed = null;
155
97
  try {
156
- withGenerationCustodyV3(coordRoot, [liveInstanceIdV3(idFromFile)], () => {
157
- const revision = captureFileRevision(path);
158
- if (!revision)
159
- return;
160
- const mtimeSecs = Number(revision.mtimeNs / 1000000000n);
161
- let parsed = null;
98
+ parsed = JSON.parse(readFileSync(path, "utf8"));
99
+ }
100
+ catch {
101
+ parsed = null;
102
+ }
103
+ if (parsed === null) {
104
+ // Unparseable: only reap if the file itself is mtime-old.
105
+ if (mtimeSecs(path) < cutoff) {
162
106
  try {
163
- const value = JSON.parse(revision.bytes.toString("utf8"));
164
- if (value && typeof value === "object" && !Array.isArray(value))
165
- parsed = value;
166
- }
167
- catch {
168
- parsed = null;
169
- }
170
- if (parsed === null) {
171
- // Unparseable: only reap if the file itself is mtime-old.
172
- if (mtimeSecs < cutoff) {
173
- const result = deleteFileIfUnchanged(path, revision, () => emitSwept(coordRoot, idFromFile, "claude-code", idFromFile, null, "unparseable", nowSec - mtimeSecs));
174
- recordHeartbeatCleanupResult(coordRoot, path, idFromFile, result, uncertainOwners);
175
- if (result.state === "deleted") {
176
- heartbeatsRemoved.push(f);
177
- }
107
+ const ageSecs = nowSec - mtimeSecs(path);
108
+ if (!emitSwept(coordRoot, idFromFile, "claude-code", idFromFile, "unparseable", ageSecs)) {
109
+ continue;
178
110
  }
179
- return;
111
+ unlinkSync(path);
112
+ heartbeatsRemoved.push(f);
180
113
  }
181
- // The filename selects the writer's custody scope. A conflicting content
182
- // identity cannot authorize an audit or deletion for a different owner.
183
- if (parsed.instance_id !== undefined && parsed.instance_id !== idFromFile)
184
- return;
185
- const instanceId = parsed.instance_id ?? idFromFile;
186
- const adapter = eventAdapterIdV3FromPlatform(parsed.platform, { context: "stale-sweep" });
187
- const sessionId = parsed.session_id ?? instanceId;
188
- const generationId = typeof parsed.v3_generation_id === "string" &&
189
- /^gen_[A-Za-z0-9._-]+$/.test(parsed.v3_generation_id)
190
- ? parsed.v3_generation_id
191
- : null;
192
- const ts = parsed.last_heartbeat
193
- ? Math.floor(Date.parse(parsed.last_heartbeat) / 1000)
194
- : Number.NaN;
195
- if (!parsed.last_heartbeat || !Number.isFinite(ts)) {
196
- // No / NaN last_heartbeat: can't trust content; gate on mtime.
197
- if (mtimeSecs < cutoff) {
198
- const result = deleteFileIfUnchanged(path, revision, () => emitSwept(coordRoot, instanceId, adapter, sessionId, generationId, "missing_ts", nowSec - mtimeSecs));
199
- recordHeartbeatCleanupResult(coordRoot, path, idFromFile, result, uncertainOwners);
200
- if (result.state === "deleted") {
201
- heartbeatsRemoved.push(f);
202
- }
203
- }
204
- else if (parsed.instance_id) {
205
- liveInstanceIds.add(parsed.instance_id);
206
- }
207
- return;
114
+ catch {
115
+ /* swallow */
208
116
  }
209
- if (ts < cutoff) {
210
- // Legitimate stale prune (valid timestamp, past the freshness cutoff).
211
- const result = deleteFileIfUnchanged(path, revision, () => emitSwept(coordRoot, instanceId, adapter, sessionId, generationId, "stale", nowSec - ts));
212
- recordHeartbeatCleanupResult(coordRoot, path, idFromFile, result, uncertainOwners);
213
- if (result.state === "deleted") {
214
- heartbeatsRemoved.push(f);
215
- }
216
- return;
117
+ }
118
+ continue;
119
+ }
120
+ const instanceId = parsed.instance_id ?? idFromFile;
121
+ const adapter = eventAdapterIdV3FromPlatform(parsed.platform, { context: "stale-sweep" });
122
+ const sessionId = parsed.session_id ?? instanceId;
123
+ const ts = parsed.last_heartbeat
124
+ ? Math.floor(Date.parse(parsed.last_heartbeat) / 1000)
125
+ : Number.NaN;
126
+ if (!parsed.last_heartbeat || !Number.isFinite(ts)) {
127
+ // No / NaN last_heartbeat: can't trust content; gate on mtime.
128
+ if (mtimeSecs(path) < cutoff) {
129
+ if (!emitSwept(coordRoot, instanceId, adapter, sessionId, "missing_ts", nowSec - mtimeSecs(path))) {
130
+ continue;
217
131
  }
218
- if (parsed.instance_id)
219
- liveInstanceIds.add(parsed.instance_id);
220
- });
132
+ unlinkSync(path);
133
+ heartbeatsRemoved.push(f);
134
+ }
135
+ else if (parsed.instance_id) {
136
+ liveInstanceIds.add(parsed.instance_id);
137
+ }
138
+ continue;
221
139
  }
222
- catch {
223
- // Busy or unknown custody retains the cache and its dependent files.
224
- uncertainOwners.add(idFromFile);
140
+ if (ts < cutoff) {
141
+ // Legitimate stale prune (valid timestamp, past the freshness cutoff).
142
+ if (!emitSwept(coordRoot, instanceId, adapter, sessionId, "stale", nowSec - ts)) {
143
+ continue;
144
+ }
145
+ unlinkSync(path);
146
+ heartbeatsRemoved.push(f);
147
+ continue;
225
148
  }
149
+ if (parsed.instance_id)
150
+ liveInstanceIds.add(parsed.instance_id);
226
151
  }
227
152
  }
228
153
  // 2. Prune pid-map entries whose instance has no live heartbeat.
229
- const pidmapDir = resolve(coordRoot, ".harnery", "pid-map");
230
- for (const recovery of existsSync(pidmapDir)
231
- ? recoverInterruptedFileDeletions(pidmapDir, (source) => dirname(source) === pidmapDir && /^\d+$/.test(basename(source)))
232
- : [])
233
- recordCleanupFailure(coordRoot, recovery.sourcePath ?? pidmapDir, recovery);
154
+ const pidmapDir = join(coordRoot, ".harnery", "pid-map");
234
155
  if (existsSync(pidmapDir)) {
235
156
  for (const f of readdirSync(pidmapDir)) {
236
- if (f.startsWith(".harnery-delete-"))
237
- continue;
238
157
  const path = join(pidmapDir, f);
239
158
  try {
240
- const revision = captureFileRevision(path);
241
- if (!revision)
242
- continue;
243
- const row = revision.bytes.toString("utf8").trim();
159
+ const row = readFileSync(path, "utf8").trim();
244
160
  const ownerId = row.split("\t")[0]?.trim() ?? "";
245
- const prune = () => {
246
- if (!ownerId ||
247
- (!liveInstanceIds.has(ownerId) &&
248
- !retainsHeartbeat(coordRoot, d, ownerId, uncertainOwners))) {
249
- const result = deleteFileIfUnchanged(path, revision, () => !ownerId || !retainsHeartbeat(coordRoot, d, ownerId, uncertainOwners));
250
- recordCleanupFailure(coordRoot, path, result);
251
- if (result.state === "deleted")
252
- pidmapsRemoved += 1;
253
- }
254
- };
255
- if (/^[A-Za-z0-9_-]{1,128}$/.test(ownerId)) {
256
- withGenerationCustodyV3(coordRoot, [liveInstanceIdV3(ownerId)], prune);
257
- }
258
- else if (!ownerId) {
259
- prune();
161
+ if (!ownerId || !liveInstanceIds.has(ownerId)) {
162
+ unlinkSync(path);
163
+ pidmapsRemoved += 1;
260
164
  }
261
165
  }
262
166
  catch {
@@ -266,12 +170,7 @@ export function staleSweep(coordRoot) {
266
170
  }
267
171
  // 3. Prune prompt hashes for dead owners. Resource hashes retain their own
268
172
  // count so existing peer-hash telemetry keeps its original meaning.
269
- const agentsDir = resolve(coordRoot, ".harnery");
270
- for (const recovery of existsSync(agentsDir)
271
- ? recoverInterruptedFileDeletions(agentsDir, (source) => dirname(source) === agentsDir &&
272
- /^\.last-(?:resource|peer)-hash\.[A-Za-z0-9_-]{1,128}$/.test(basename(source)))
273
- : [])
274
- recordCleanupFailure(coordRoot, recovery.sourcePath ?? agentsDir, recovery);
173
+ const agentsDir = join(coordRoot, ".harnery");
275
174
  if (existsSync(agentsDir)) {
276
175
  for (const f of readdirSync(agentsDir)) {
277
176
  const resourceHash = f.startsWith(".last-resource-hash.");
@@ -284,25 +183,16 @@ export function staleSweep(coordRoot) {
284
183
  // retained heartbeat's liveness could not be determined safely.
285
184
  if (!/^[A-Za-z0-9_-]{1,128}$/.test(owner))
286
185
  continue;
186
+ if (existsSync(join(d, `${owner}.json`)))
187
+ continue;
287
188
  }
288
- if (!liveInstanceIds.has(owner) && /^[A-Za-z0-9_-]{1,128}$/.test(owner)) {
189
+ if (!liveInstanceIds.has(owner)) {
289
190
  try {
290
- withGenerationCustodyV3(coordRoot, [liveInstanceIdV3(owner)], () => {
291
- if (retainsHeartbeat(coordRoot, d, owner, uncertainOwners))
292
- return;
293
- const path = join(agentsDir, f);
294
- const revision = captureFileRevision(path);
295
- if (!revision)
296
- return;
297
- const result = deleteFileIfUnchanged(path, revision, () => !retainsHeartbeat(coordRoot, d, owner, uncertainOwners));
298
- recordCleanupFailure(coordRoot, path, result);
299
- if (result.state === "deleted") {
300
- if (resourceHash)
301
- resourceHashesRemoved += 1;
302
- else
303
- peerHashesRemoved += 1;
304
- }
305
- });
191
+ unlinkSync(join(agentsDir, f));
192
+ if (resourceHash)
193
+ resourceHashesRemoved += 1;
194
+ else
195
+ peerHashesRemoved += 1;
306
196
  }
307
197
  catch {
308
198
  /* swallow */
@@ -1,3 +1,4 @@
1
+ import { type Stats } from "node:fs";
1
2
  /** A checkpoint taken before an internal manifest write, never an expiry override. */
2
3
  export interface ArtifactActivity {
3
4
  last_changed_at: string;
@@ -9,6 +10,8 @@ export declare function artifactRootEntries(path: string): string;
9
10
  * Keep the prior root activity while its payload entries match the checkpoint.
10
11
  * A root deletion or rename changes that fingerprint; nested changes retain
11
12
  * their ordinary filesystem timestamps. Symlinks are inspected, never followed.
13
+ * `visit` sees every entry's lstat exactly once, including a root manifest the
14
+ * activity rules skip, so a caller can size the tree in the same walk.
12
15
  */
13
- export declare function readArtifactActivity(path: string, now: Date, previous?: ArtifactActivity): ArtifactActivity;
16
+ export declare function readArtifactActivity(path: string, now: Date, previous?: ArtifactActivity, visit?: (entry: string, stat: Stats) => void): ArtifactActivity;
14
17
  //# sourceMappingURL=activity.d.ts.map