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
@@ -88,7 +88,6 @@ interface LiveAuthorityBaseV3 {
88
88
  nativeSessionId: string;
89
89
  adapter: Adapter;
90
90
  observationId?: string;
91
- expectedGenerationId?: `gen_${string}`;
92
91
  }
93
92
 
94
93
  /**
@@ -649,13 +648,6 @@ function recordLiveAuthority<S extends CoordinationAuthoritySignalV3>(
649
648
  platform: livePlatformV3(),
650
649
  expected_prior_state_digest: coordinationAuthorityStateDigestV3(expected),
651
650
  desired_state_digest: coordinationAuthorityStateDigestV3(desired),
652
- expected_generation_id:
653
- input.expectedGenerationId ??
654
- ((subject === input.owner
655
- ? expected.v3_generation_id
656
- : readLiveCoordinationRow(input.coordRoot, input.owner)?.v3_generation_id) as
657
- | `gen_${string}`
658
- | undefined),
659
651
  reconciler: {
660
652
  readStateDigest: () => {
661
653
  const heartbeat = readHeartbeat(input.coordRoot, subject);
@@ -689,12 +681,6 @@ export function liveCoordinationWriteModeV3(coordRoot: string): EventV3WriteMode
689
681
  }
690
682
 
691
683
  function requireHeartbeat(input: LiveAuthorityBaseV3, owner: string): Heartbeat {
692
- if (
693
- input.expectedGenerationId &&
694
- readLiveCoordinationRow(input.coordRoot, owner)?.v3_generation_id !== input.expectedGenerationId
695
- ) {
696
- throw new LiveCoordinationAuthorityV3Error("expected_generation_changed");
697
- }
698
684
  const heartbeat = ensureLiveCoordinationHeartbeat(
699
685
  input.coordRoot,
700
686
  owner,
@@ -702,9 +688,6 @@ function requireHeartbeat(input: LiveAuthorityBaseV3, owner: string): Heartbeat
702
688
  input.adapter,
703
689
  );
704
690
  if (!heartbeat) throw new LiveCoordinationAuthorityV3Error(`heartbeat_missing:${owner}`);
705
- if (input.expectedGenerationId && heartbeat.v3_generation_id !== input.expectedGenerationId) {
706
- throw new LiveCoordinationAuthorityV3Error("expected_generation_changed");
707
- }
708
691
  return heartbeat;
709
692
  }
710
693
 
@@ -5,7 +5,6 @@ import { normalizeNativeIdV3 } from "../events/v3/canonical.ts";
5
5
  import type { EventV3 } from "../events/v3/contract.ts";
6
6
  import { readEventV3ControlState } from "../events/v3/control.ts";
7
7
  import { fingerprintContextV3 } from "../events/v3/fingerprint-keys.ts";
8
- import { withGenerationCustodyV3 } from "../events/v3/generation-custody.ts";
9
8
  import {
10
9
  liveInstanceIdV3,
11
10
  livePlatformV3,
@@ -26,34 +25,17 @@ interface LiveLifecycleObservationBaseV3 {
26
25
  observedAt?: string;
27
26
  }
28
27
 
29
- interface LiveSweepObservationV3Input extends LiveLifecycleObservationBaseV3 {
30
- expectedGenerationId: `gen_${string}` | null;
31
- observation: "stale_heartbeat" | "killed" | "unparseable_heartbeat" | "missing_timestamp";
32
- ageMs: number;
33
- }
34
-
35
28
  export function recordLiveSweepObservationV3(
36
- input: LiveSweepObservationV3Input,
29
+ input: LiveLifecycleObservationBaseV3 & {
30
+ observation: "stale_heartbeat" | "killed" | "unparseable_heartbeat" | "missing_timestamp";
31
+ ageMs: number;
32
+ },
37
33
  ): LiveLifecycleObservationV3Result {
38
- input = { ...input };
39
- // Reject stale observations before preparing durable custody state. The
40
- // in-custody checks cover replacement while acquiring custody and reentry.
41
- requireSweepHookState(input);
42
- return withGenerationCustodyV3(input.coordRoot, [liveInstanceIdV3(input.owner)], () => {
43
- requireSweepHookState(input);
44
- return recordObservation(
45
- input,
46
- "lifecycle.sweep_observed",
47
- {
48
- subject_instance_id: liveInstanceIdV3(input.owner),
49
- observation: input.observation,
50
- provisional: true,
51
- age_ms: Math.max(0, Math.floor(input.ageMs)),
52
- },
53
- () => {
54
- requireSweepHookState(input);
55
- },
56
- );
34
+ return recordObservation(input, "lifecycle.sweep_observed", {
35
+ subject_instance_id: liveInstanceIdV3(input.owner),
36
+ observation: input.observation,
37
+ provisional: true,
38
+ age_ms: Math.max(0, Math.floor(input.ageMs)),
57
39
  });
58
40
  }
59
41
 
@@ -62,16 +44,11 @@ export function recordLiveResumeObservationV3(
62
44
  ): LiveLifecycleObservationV3Result {
63
45
  const normalized = withAttestedAdapter(input);
64
46
  const hook = requireHookState(normalized);
65
- return recordObservation(
66
- normalized,
67
- "session.resumed",
68
- {
69
- prior_generation_id: hook.generation_id,
70
- continuity: "native",
71
- evidence_reference: "heartbeat_recreated",
72
- },
73
- () => {},
74
- );
47
+ return recordObservation(normalized, "session.resumed", {
48
+ prior_generation_id: hook.generation_id,
49
+ continuity: "native",
50
+ evidence_reference: "heartbeat_recreated",
51
+ });
75
52
  }
76
53
 
77
54
  function recordObservation<T extends "lifecycle.sweep_observed" | "session.resumed">(
@@ -89,7 +66,6 @@ function recordObservation<T extends "lifecycle.sweep_observed" | "session.resum
89
66
  continuity: "native";
90
67
  evidence_reference: string;
91
68
  },
92
- beforeWrite: () => void,
93
69
  ): LiveLifecycleObservationV3Result {
94
70
  const route = resolveLiveEventLedgerRouteV3(input.coordRoot);
95
71
  if (route.state === "blocked") throw new LiveCoordinationAuthorityV3Error(route.reason);
@@ -145,7 +121,6 @@ function recordObservation<T extends "lifecycle.sweep_observed" | "session.resum
145
121
  monotonic_ns: process.hrtime.bigint().toString(),
146
122
  };
147
123
  const event = buildEventV3(eventType, { ...common, payload } as never) as EventV3;
148
- beforeWrite();
149
124
  const durability = writeEventV3(input.coordRoot, event, {
150
125
  expectedGenesisId: control.genesis.event.payload.genesis_id as `gex_${string}`,
151
126
  });
@@ -155,19 +130,6 @@ function recordObservation<T extends "lifecycle.sweep_observed" | "session.resum
155
130
  return { state: "recorded", event };
156
131
  }
157
132
 
158
- function requireSweepHookState(input: LiveSweepObservationV3Input): void {
159
- if (
160
- typeof input.expectedGenerationId !== "string" ||
161
- !/^gen_[a-zA-Z0-9._-]+$/.test(input.expectedGenerationId)
162
- ) {
163
- throw new LiveCoordinationAuthorityV3Error("hook_generation_not_joinable");
164
- }
165
- const hook = requireHookState(withAttestedAdapter(input));
166
- if (hook.generation_id !== input.expectedGenerationId) {
167
- throw new LiveCoordinationAuthorityV3Error("expected_generation_changed");
168
- }
169
- }
170
-
171
133
  function withAttestedAdapter<T extends LiveLifecycleObservationBaseV3>(input: T): T {
172
134
  const adapter = liveCoordinationAdapterV3(input.coordRoot, input.owner);
173
135
  if (!adapter) return input;
@@ -24,11 +24,6 @@ import {
24
24
  writeFileSync,
25
25
  } from "node:fs";
26
26
  import { dirname, join } from "node:path";
27
- import {
28
- assertCurrentGenerationV3,
29
- withGenerationCustodyV3,
30
- } from "../../events/v3/generation-custody.ts";
31
- import { liveInstanceIdV3 } from "../../events/v3/live-routing.ts";
32
27
  import { canonicalClaimPath } from "../claim-path.ts";
33
28
  import { type Heartbeat, heartbeatPath, readHeartbeat } from "./heartbeat-reader.ts";
34
29
  import type { TaskState } from "./session-state.ts";
@@ -68,15 +63,12 @@ function mutate(
68
63
  instanceId: string,
69
64
  fn: (hb: Heartbeat) => Heartbeat,
70
65
  ): Heartbeat | null {
71
- return withGenerationCustodyV3(coordRoot, [liveInstanceIdV3(instanceId)], () => {
72
- const hb = readHeartbeat(coordRoot, instanceId);
73
- if (!hb) return null;
74
- const next = fn(hb);
75
- next.last_heartbeat = nowIsoSeconds();
76
- assertCurrentGenerationV3(coordRoot, liveInstanceIdV3(instanceId), hb.v3_generation_id);
77
- atomicWrite(heartbeatPath(coordRoot, instanceId), JSON.stringify(next, null, 2));
78
- return next;
79
- });
66
+ const hb = readHeartbeat(coordRoot, instanceId);
67
+ if (!hb) return null;
68
+ const next = fn(hb);
69
+ next.last_heartbeat = nowIsoSeconds();
70
+ atomicWrite(heartbeatPath(coordRoot, instanceId), JSON.stringify(next, null, 2));
71
+ return next;
80
72
  }
81
73
 
82
74
  export function setTask(coordRoot: string, instanceId: string, task: string): Heartbeat | null {
@@ -108,15 +100,12 @@ export function setIdentityCache(
108
100
  name: string,
109
101
  agentId: string,
110
102
  ): Heartbeat | null {
111
- return withGenerationCustodyV3(coordRoot, [liveInstanceIdV3(instanceId)], () => {
112
- const heartbeat = readHeartbeat(coordRoot, instanceId);
113
- if (!heartbeat) return null;
114
- heartbeat.name = name;
115
- heartbeat.agent_id = agentId;
116
- assertCurrentGenerationV3(coordRoot, liveInstanceIdV3(instanceId), heartbeat.v3_generation_id);
117
- atomicWrite(heartbeatPath(coordRoot, instanceId), JSON.stringify(heartbeat, null, 2));
118
- return heartbeat;
119
- });
103
+ const heartbeat = readHeartbeat(coordRoot, instanceId);
104
+ if (!heartbeat) return null;
105
+ heartbeat.name = name;
106
+ heartbeat.agent_id = agentId;
107
+ atomicWrite(heartbeatPath(coordRoot, instanceId), JSON.stringify(heartbeat, null, 2));
108
+ return heartbeat;
120
109
  }
121
110
 
122
111
  /** Restore the pool-assigned display name on a generation that was
@@ -339,12 +328,6 @@ export function clearCoordinationCache(coordRoot: string, instanceId: string): b
339
328
  }
340
329
 
341
330
  export function healPidmap(coordRoot: string, instanceId: string, pid: number): void {
342
- withGenerationCustodyV3(coordRoot, [liveInstanceIdV3(instanceId)], () =>
343
- healPidmapUnderCustody(coordRoot, instanceId, pid),
344
- );
345
- }
346
-
347
- function healPidmapUnderCustody(coordRoot: string, instanceId: string, pid: number): void {
348
331
  const dir = join(coordRoot, ".harnery", "pid-map");
349
332
  mkdirSync(dir, { recursive: true });
350
333
  const hb = readHeartbeat(coordRoot, instanceId);
@@ -5,10 +5,6 @@ import {
5
5
  readCoordinationViewV3,
6
6
  requireAuthoritySafeCoordinationViewV3,
7
7
  } from "../../events/v3/coordination-view.ts";
8
- import {
9
- assertCurrentGenerationV3,
10
- withGenerationCustodyV3,
11
- } from "../../events/v3/generation-custody.ts";
12
8
  import { liveInstanceIdV3, resolveLiveEventLedgerRouteV3 } from "../../events/v3/live-routing.ts";
13
9
  import { type Heartbeat, readHeartbeat } from "./heartbeat-reader.ts";
14
10
  import {
@@ -68,26 +64,6 @@ function materializeLiveCoordinationHeartbeat(
68
64
  _adapter: Adapter,
69
65
  model: string | undefined,
70
66
  force: boolean,
71
- ): Heartbeat | null {
72
- return withGenerationCustodyV3(coordRoot, [liveInstanceIdV3(nativeInstanceId)], () =>
73
- materializeHeartbeatUnderCustody(
74
- coordRoot,
75
- nativeInstanceId,
76
- nativeSessionId,
77
- _adapter,
78
- model,
79
- force,
80
- ),
81
- );
82
- }
83
-
84
- function materializeHeartbeatUnderCustody(
85
- coordRoot: string,
86
- nativeInstanceId: string,
87
- nativeSessionId: string,
88
- _adapter: Adapter,
89
- model: string | undefined,
90
- force: boolean,
91
67
  ): Heartbeat | null {
92
68
  const route = resolveLiveEventLedgerRouteV3(coordRoot);
93
69
  if (route.state === "blocked") throw new Error(`event_v3_coordination_view:${route.reason}`);
@@ -157,11 +133,6 @@ function materializeHeartbeatUnderCustody(
157
133
  v3_projection_event_id: generation.last_event_id,
158
134
  v3_task_state: generation.task_state === "set" ? "set" : "cleared",
159
135
  };
160
- assertCurrentGenerationV3(
161
- coordRoot,
162
- liveInstanceIdV3(nativeInstanceId),
163
- generation.generation_id,
164
- );
165
136
  writeHeartbeatCache(coordRoot, nativeInstanceId, materialized);
166
137
  return materialized;
167
138
  }
@@ -24,8 +24,6 @@ import {
24
24
  writeFileSync,
25
25
  } from "node:fs";
26
26
  import { dirname, join } from "node:path";
27
- import { withGenerationCustodyV3 } from "../../events/v3/generation-custody.ts";
28
- import { liveInstanceIdV3 } from "../../events/v3/live-routing.ts";
29
27
  import { checkPidToken, processStartToken } from "./proc-start.ts";
30
28
 
31
29
  /**
@@ -128,17 +126,6 @@ export function writePidmapRow(
128
126
  pid: number,
129
127
  instanceId: string,
130
128
  platform: string,
131
- ): void {
132
- withGenerationCustodyV3(coordRoot, [liveInstanceIdV3(instanceId)], () =>
133
- writePidmapRowUnderCustody(coordRoot, pid, instanceId, platform),
134
- );
135
- }
136
-
137
- function writePidmapRowUnderCustody(
138
- coordRoot: string,
139
- pid: number,
140
- instanceId: string,
141
- platform: string,
142
129
  ): void {
143
130
  const dir = join(coordRoot, ".harnery", "pid-map");
144
131
  const path = join(dir, String(pid));