harnery 0.31.1 → 0.31.3

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.
@@ -150,6 +150,45 @@ async function handleProject(root, rest) {
150
150
  }
151
151
  return 0;
152
152
  }
153
+ function adapterFromPlatform(platform) {
154
+ if (platform === "cursor")
155
+ return "cursor";
156
+ if (platform === "codex")
157
+ return "codex";
158
+ return "claude-code";
159
+ }
160
+ /**
161
+ * Append a canonical `health.heartbeat_swept` event after an operator kill.
162
+ * Same envelope stale-sweep emits, so the projector's terminal / ended_at
163
+ * guards treat kill and sweep identically. Soft-fails: the unlink already
164
+ * happened.
165
+ */
166
+ async function emitHeartbeatSwept(root, owner, hb) {
167
+ try {
168
+ const { emit } = await import("./events/emit.js");
169
+ let ageSecs;
170
+ if (hb.last_heartbeat) {
171
+ const ts = Date.parse(hb.last_heartbeat);
172
+ if (Number.isFinite(ts)) {
173
+ ageSecs = Math.max(0, Math.floor((Date.now() - ts) / 1000));
174
+ }
175
+ }
176
+ emit(root, {
177
+ event_type: "health.heartbeat_swept",
178
+ instance_id: owner,
179
+ session_id: hb.session_id ?? owner,
180
+ adapter: adapterFromPlatform(hb.platform),
181
+ source: "agent-coord",
182
+ data: {
183
+ reason: "killed",
184
+ ...(ageSecs !== undefined ? { age_secs: ageSecs } : {}),
185
+ },
186
+ });
187
+ }
188
+ catch {
189
+ /* soft-fail: never break the caller */
190
+ }
191
+ }
153
192
  /**
154
193
  * Append a canonical `claim.release` event for a path dropped from an owner's
155
194
  * files_touched. The path is canonicalized to repo-relative (matching the
@@ -161,13 +200,11 @@ async function emitClaimRelease(root, owner, hb, path, reason) {
161
200
  try {
162
201
  const { emit } = await import("./events/emit.js");
163
202
  const canonical = path.startsWith(`${root}/`) ? path.slice(root.length + 1) : path;
164
- const platform = hb.platform;
165
- const adapter = platform === "cursor" ? "cursor" : platform === "codex" ? "codex" : "claude-code";
166
203
  emit(root, {
167
204
  event_type: "claim.release",
168
205
  instance_id: owner,
169
206
  session_id: hb.session_id ?? owner,
170
- adapter,
207
+ adapter: adapterFromPlatform(hb.platform),
171
208
  source: "agent-coord",
172
209
  data: { path: canonical, reason },
173
210
  });
@@ -240,9 +277,17 @@ async function handleStateAction(root, action, rest) {
240
277
  // killing only the file leaves the claims resurrectable from the
241
278
  // permanent Edit/Write events on the next full replay (observed: a
242
279
  // 6-day-dead agent's claims returning after its heartbeat was killed).
280
+ //
281
+ // Also emit health.heartbeat_swept so the stream records a terminal
282
+ // marker. Without it, a later drain that replays [session.start …
283
+ // tools … claim.release] treats the owner as still in-flight and
284
+ // re-creates the file (kill→resurrect loop observed 2026-08-03: 21
285
+ // killed zombies back within a minute via claim.release seeding +
286
+ // historical replay).
243
287
  const before = writer.readHeartbeat(root, owner);
244
288
  const ok = writer.killHeartbeat(root, owner);
245
289
  if (ok && before) {
290
+ await emitHeartbeatSwept(root, owner, before);
246
291
  for (const held of before.files_touched ?? []) {
247
292
  await emitClaimRelease(root, owner, before, held, "heal");
248
293
  }
@@ -1 +1 @@
1
- {"version":3,"file":"heartbeat-projector.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/state/heartbeat-projector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,SAAS,GAAG,UAAU,GAAG,WAAW,CAAC;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,kFAAkF;IAClF,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,4BAA4B,CAAC,EAAE,OAAO,CAAC;IACvC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,yEAAyE;IACzE,aAAa,EAAE,MAAM,CAAC;IACtB,+EAA+E;IAC/E,cAAc,EAAE,MAAM,CAAC;IACvB,oCAAoC;IACpC,OAAO,EAAE;QACP,cAAc,EAAE,CAAC,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;QACnB,cAAc,EAAE,MAAM,CAAC;KACxB,CAAC;CACH;AAED,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,SAAS,cAAc,EAAE,GAChC;IAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;CAAE,CAoD9D;AA4XD,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAE3E"}
1
+ {"version":3,"file":"heartbeat-projector.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/state/heartbeat-projector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,SAAS,GAAG,UAAU,GAAG,WAAW,CAAC;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,kFAAkF;IAClF,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,4BAA4B,CAAC,EAAE,OAAO,CAAC;IACvC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,yEAAyE;IACzE,aAAa,EAAE,MAAM,CAAC;IACtB,+EAA+E;IAC/E,cAAc,EAAE,MAAM,CAAC;IACvB,oCAAoC;IACpC,OAAO,EAAE;QACP,cAAc,EAAE,CAAC,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;QACnB,cAAc,EAAE,MAAM,CAAC;KACxB,CAAC;CACH;AAED,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,SAAS,cAAc,EAAE,GAChC;IAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;CAAE,CAoD9D;AA6YD,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAE3E"}
@@ -12,29 +12,29 @@ import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "
12
12
  import { dirname, join } from "node:path";
13
13
  export function projectHeartbeats(coordRoot, events) {
14
14
  const perOwner = {};
15
- // Terminal events for an owner we've never seen must NOT seed a new heartbeat:
16
- // that resurrects a dead agent as a nameless, started_at-less zombie (the
17
- // `agent-unknown (20608d ago)` ghost). It happens when a subagent.stop /
18
- // session.end drains without (or after) its matching start: seed() then
19
- // apply(stop) writes a bare tombstone the sweep+readers then choke on. If
20
- // there's no existing heartbeat and the first event we see for an owner is
21
- // terminal, skip it entirely.
15
+ // Events that must NOT seed a heartbeat for an owner with no live file.
16
+ // Terminal lifecycle events (session.end / subagent.stop /
17
+ // health.heartbeat_swept) used to be the whole set — a stop without a
18
+ // matching start resurrected a nameless `agent-unknown` tombstone, and a
19
+ // lone health.heartbeat_swept re-created the file stale-sweep had just
20
+ // deleted (self-perpetuating zombie loop, same instance swept 18×).
22
21
  //
23
- // `health.heartbeat_swept` is terminal for the same reason, and was the
24
- // sharper bug: stale-sweep deletes a dead heartbeat then emits this event,
25
- // which the projector replayed to RE-CREATE the very file the sweep just
26
- // removed (minus files_touched, since no start event ever ran for it). The
27
- // reader then flagged it "missing required fields", and the resurrected file,
28
- // carrying a fresh last_heartbeat = the swept-event ts, survived one
29
- // freshness window before the next sweep deleted-and-resurrected it again. A
30
- // self-perpetuating zombie loop (same instance swept 18×). A swept event must
31
- // never seed a heartbeat.
32
- const TERMINAL = new Set(["session.end", "subagent.stop", "health.heartbeat_swept"]);
22
+ // `claim.release` joins them: kill-heartbeat unlinks the file THEN emits
23
+ // claim.release for each held path so replay honors the drop. Projecting
24
+ // those releases alone used to seed a fresh heartbeat (name recovered from
25
+ // .name-history, last_heartbeat = release ts), undoing the kill. Side-effect
26
+ // events must never birth an owner.
27
+ const NEVER_SEED = new Set([
28
+ "session.end",
29
+ "subagent.stop",
30
+ "health.heartbeat_swept",
31
+ "claim.release",
32
+ ]);
33
33
  // Seed from any existing v2 files so a partial replay doesn't reset state.
34
34
  for (const ev of events) {
35
35
  if (!perOwner[ev.instance_id]) {
36
36
  const existing = readExisting(coordRoot, ev.instance_id);
37
- if (!existing && TERMINAL.has(ev.event_type))
37
+ if (!existing && NEVER_SEED.has(ev.event_type))
38
38
  continue;
39
39
  perOwner[ev.instance_id] = existing ?? seed(ev, coordRoot);
40
40
  }
@@ -102,7 +102,21 @@ function seed(ev, coordRoot) {
102
102
  return hb;
103
103
  }
104
104
  function apply(hb, ev, coordRoot) {
105
- hb.last_heartbeat = ev.ts;
105
+ // Sweep telemetry must not refresh liveness. apply() used to stamp
106
+ // last_heartbeat = ev.ts for every event, so a drain that replayed
107
+ // [session.start … tools … health.heartbeat_swept] wrote a heartbeat whose
108
+ // last_heartbeat was the swept ts — looking freshly alive for another
109
+ // freshness window, which the next sweep deleted-and-re-emitted. Record the
110
+ // event for audit (last_event_id / events_applied) but keep the prior
111
+ // liveness stamp; also set ended_at so the mid-batch write guard skips
112
+ // re-creating a file the sweep/kill already removed.
113
+ const isSweepTelemetry = ev.event_type === "health.heartbeat_swept";
114
+ if (!isSweepTelemetry) {
115
+ hb.last_heartbeat = ev.ts;
116
+ }
117
+ else if (!hb.last_heartbeat) {
118
+ hb.last_heartbeat = ev.ts;
119
+ }
106
120
  hb.last_event_id = ev.event_id;
107
121
  hb.events_applied += 1;
108
122
  hb.v2_meta.last_projected = new Date().toISOString();
@@ -152,6 +166,9 @@ function apply(hb, ev, coordRoot) {
152
166
  hb.ended_at = pickStr(d, "ended_at") ?? ev.ts;
153
167
  hb.clean_exit = pickBool(d, "clean_exit");
154
168
  break;
169
+ case "health.heartbeat_swept":
170
+ hb.ended_at = ev.ts;
171
+ break;
155
172
  case "subagent.start": {
156
173
  const name = pickStr(d, "name");
157
174
  if (name)
@@ -1,8 +1,10 @@
1
1
  import type { Adapter } from "../events/schema.js";
2
2
  /**
3
3
  * Resolve the adapter firing the hook. The dispatcher binary is always
4
- * invoked with `--adapter <name>` per the wiring in each adapter's settings
5
- * file (Phase 1). Returns null when the flag is missing; caller falls
4
+ * invoked with `--adapter <name>` per the current wiring in each adapter's
5
+ * settings file. `--harness` remains an accepted alias because settings files
6
+ * written by older releases survive a package upgrade until the consumer
7
+ * re-runs `harn init`. Returns null when neither flag is present; caller falls
6
8
  * through to the env-based fallback or skips emission.
7
9
  */
8
10
  export declare function detectAdapter(argv: readonly string[]): Adapter | null;
@@ -1 +1 @@
1
- {"version":3,"file":"detect.d.ts","sourceRoot":"","sources":["../../../../src/core/hooks/adapter/detect.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAEnD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,GAAG,IAAI,CAWrE"}
1
+ {"version":3,"file":"detect.d.ts","sourceRoot":"","sources":["../../../../src/core/hooks/adapter/detect.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAEnD;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,GAAG,IAAI,CAcrE"}
@@ -1,21 +1,26 @@
1
1
  import { coordEnv } from "../../../lib/env.js";
2
2
  /**
3
3
  * Resolve the adapter firing the hook. The dispatcher binary is always
4
- * invoked with `--adapter <name>` per the wiring in each adapter's settings
5
- * file (Phase 1). Returns null when the flag is missing; caller falls
4
+ * invoked with `--adapter <name>` per the current wiring in each adapter's
5
+ * settings file. `--harness` remains an accepted alias because settings files
6
+ * written by older releases survive a package upgrade until the consumer
7
+ * re-runs `harn init`. Returns null when neither flag is present; caller falls
6
8
  * through to the env-based fallback or skips emission.
7
9
  */
8
10
  export function detectAdapter(argv) {
9
11
  for (let i = 0; i < argv.length; i++) {
10
12
  const a = argv[i];
11
- if (a === "--adapter") {
13
+ if (a === "--adapter" || a === "--harness") {
12
14
  return validate(argv[i + 1]);
13
15
  }
14
16
  if (a.startsWith("--adapter=")) {
15
17
  return validate(a.slice("--adapter=".length));
16
18
  }
19
+ if (a.startsWith("--harness=")) {
20
+ return validate(a.slice("--harness=".length));
21
+ }
17
22
  }
18
- return validate(coordEnv("AGENT_COORD_ADAPTER"));
23
+ return validate(coordEnv("AGENT_COORD_ADAPTER") ?? coordEnv("AGENT_COORD_HARNESS"));
19
24
  }
20
25
  function validate(v) {
21
26
  if (v === "claude-code" || v === "cursor" || v === "codex")
@@ -44,11 +44,11 @@ function parseArgv(argv) {
44
44
  const out = { eventName: null, extra: [] };
45
45
  for (let i = 0; i < argv.length; i++) {
46
46
  const arg = argv[i];
47
- if (arg === "--adapter") {
47
+ if (arg === "--adapter" || arg === "--harness") {
48
48
  i++; // detectAdapter will re-parse; just consume the value here.
49
49
  continue;
50
50
  }
51
- if (arg.startsWith("--adapter="))
51
+ if (arg.startsWith("--adapter=") || arg.startsWith("--harness="))
52
52
  continue;
53
53
  if (!out.eventName && !arg.startsWith("--")) {
54
54
  out.eventName = arg;
@@ -246,16 +246,17 @@ export type HealthPidmapHeal = EventEnvelope<"health.pidmap_heal", {
246
246
  reason: string;
247
247
  }>;
248
248
  /**
249
- * A heartbeat file was removed by stale-sweep. Symmetric with
250
- * `health.heartbeat_heal` so the full lifecycle (created → healed → swept) is
251
- * auditable from the event stream alone. Sweeps were silent before, which
252
- * made "why did this agent vanish?" un-answerable without guesswork.
249
+ * A heartbeat file was removed by stale-sweep or an operator kill. Symmetric
250
+ * with `health.heartbeat_heal` so the full lifecycle (created → healed →
251
+ * swept) is auditable from the event stream alone. Sweeps were silent before,
252
+ * which made "why did this agent vanish?" un-answerable without guesswork.
253
253
  * `reason`: "stale" (last_heartbeat past the freshness cutoff) | "unparseable"
254
254
  * (JSON.parse failed AND mtime was old) | "missing_ts" (no last_heartbeat AND
255
- * mtime was old). Fresh-mtime files are never swept regardless of content.
255
+ * mtime was old) | "killed" (operator `kill-heartbeat` / `agents heal --kind
256
+ * kill`). Fresh-mtime files are never auto-swept regardless of content.
256
257
  */
257
258
  export type HealthHeartbeatSwept = EventEnvelope<"health.heartbeat_swept", {
258
- reason: "stale" | "unparseable" | "missing_ts";
259
+ reason: "stale" | "unparseable" | "missing_ts" | "killed";
259
260
  age_secs?: number;
260
261
  }>;
261
262
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../../src/core/hooks/events/schema.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../../src/core/hooks/events/schema.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "harnery",
3
- "version": "0.31.1",
3
+ "version": "0.31.3",
4
4
  "description": "Multi-agent coordination for AI coding agents - Claude Code, Cursor, and Codex.",
5
5
  "license": "MIT",
6
6
  "author": "Ryan Kelly",
@@ -164,6 +164,48 @@ async function handleProject(root: string, rest: string[]): Promise<number> {
164
164
  return 0;
165
165
  }
166
166
 
167
+ function adapterFromPlatform(platform: unknown): "claude-code" | "cursor" | "codex" {
168
+ if (platform === "cursor") return "cursor";
169
+ if (platform === "codex") return "codex";
170
+ return "claude-code";
171
+ }
172
+
173
+ /**
174
+ * Append a canonical `health.heartbeat_swept` event after an operator kill.
175
+ * Same envelope stale-sweep emits, so the projector's terminal / ended_at
176
+ * guards treat kill and sweep identically. Soft-fails: the unlink already
177
+ * happened.
178
+ */
179
+ async function emitHeartbeatSwept(
180
+ root: string,
181
+ owner: string,
182
+ hb: { session_id?: string; platform?: string; last_heartbeat?: string },
183
+ ): Promise<void> {
184
+ try {
185
+ const { emit } = await import("./events/emit.ts");
186
+ let ageSecs: number | undefined;
187
+ if (hb.last_heartbeat) {
188
+ const ts = Date.parse(hb.last_heartbeat);
189
+ if (Number.isFinite(ts)) {
190
+ ageSecs = Math.max(0, Math.floor((Date.now() - ts) / 1000));
191
+ }
192
+ }
193
+ emit(root, {
194
+ event_type: "health.heartbeat_swept",
195
+ instance_id: owner,
196
+ session_id: hb.session_id ?? owner,
197
+ adapter: adapterFromPlatform(hb.platform),
198
+ source: "agent-coord",
199
+ data: {
200
+ reason: "killed",
201
+ ...(ageSecs !== undefined ? { age_secs: ageSecs } : {}),
202
+ },
203
+ });
204
+ } catch {
205
+ /* soft-fail: never break the caller */
206
+ }
207
+ }
208
+
167
209
  /**
168
210
  * Append a canonical `claim.release` event for a path dropped from an owner's
169
211
  * files_touched. The path is canonicalized to repo-relative (matching the
@@ -181,14 +223,11 @@ async function emitClaimRelease(
181
223
  try {
182
224
  const { emit } = await import("./events/emit.ts");
183
225
  const canonical = path.startsWith(`${root}/`) ? path.slice(root.length + 1) : path;
184
- const platform = hb.platform;
185
- const adapter =
186
- platform === "cursor" ? "cursor" : platform === "codex" ? "codex" : "claude-code";
187
226
  emit(root, {
188
227
  event_type: "claim.release",
189
228
  instance_id: owner,
190
229
  session_id: hb.session_id ?? owner,
191
- adapter,
230
+ adapter: adapterFromPlatform(hb.platform),
192
231
  source: "agent-coord",
193
232
  data: { path: canonical, reason },
194
233
  });
@@ -269,9 +308,17 @@ async function handleStateAction(root: string, action: string, rest: string[]):
269
308
  // killing only the file leaves the claims resurrectable from the
270
309
  // permanent Edit/Write events on the next full replay (observed: a
271
310
  // 6-day-dead agent's claims returning after its heartbeat was killed).
311
+ //
312
+ // Also emit health.heartbeat_swept so the stream records a terminal
313
+ // marker. Without it, a later drain that replays [session.start …
314
+ // tools … claim.release] treats the owner as still in-flight and
315
+ // re-creates the file (kill→resurrect loop observed 2026-08-03: 21
316
+ // killed zombies back within a minute via claim.release seeding +
317
+ // historical replay).
272
318
  const before = writer.readHeartbeat(root, owner);
273
319
  const ok = writer.killHeartbeat(root, owner);
274
320
  if (ok && before) {
321
+ await emitHeartbeatSwept(root, owner, before);
275
322
  for (const held of before.files_touched ?? []) {
276
323
  await emitClaimRelease(root, owner, before, held, "heal");
277
324
  }
@@ -65,30 +65,30 @@ export function projectHeartbeats(
65
65
  ): { written: string[]; perOwner: Record<string, V2Heartbeat> } {
66
66
  const perOwner: Record<string, V2Heartbeat> = {};
67
67
 
68
- // Terminal events for an owner we've never seen must NOT seed a new heartbeat:
69
- // that resurrects a dead agent as a nameless, started_at-less zombie (the
70
- // `agent-unknown (20608d ago)` ghost). It happens when a subagent.stop /
71
- // session.end drains without (or after) its matching start: seed() then
72
- // apply(stop) writes a bare tombstone the sweep+readers then choke on. If
73
- // there's no existing heartbeat and the first event we see for an owner is
74
- // terminal, skip it entirely.
68
+ // Events that must NOT seed a heartbeat for an owner with no live file.
69
+ // Terminal lifecycle events (session.end / subagent.stop /
70
+ // health.heartbeat_swept) used to be the whole set — a stop without a
71
+ // matching start resurrected a nameless `agent-unknown` tombstone, and a
72
+ // lone health.heartbeat_swept re-created the file stale-sweep had just
73
+ // deleted (self-perpetuating zombie loop, same instance swept 18×).
75
74
  //
76
- // `health.heartbeat_swept` is terminal for the same reason, and was the
77
- // sharper bug: stale-sweep deletes a dead heartbeat then emits this event,
78
- // which the projector replayed to RE-CREATE the very file the sweep just
79
- // removed (minus files_touched, since no start event ever ran for it). The
80
- // reader then flagged it "missing required fields", and the resurrected file,
81
- // carrying a fresh last_heartbeat = the swept-event ts, survived one
82
- // freshness window before the next sweep deleted-and-resurrected it again. A
83
- // self-perpetuating zombie loop (same instance swept 18×). A swept event must
84
- // never seed a heartbeat.
85
- const TERMINAL = new Set(["session.end", "subagent.stop", "health.heartbeat_swept"]);
75
+ // `claim.release` joins them: kill-heartbeat unlinks the file THEN emits
76
+ // claim.release for each held path so replay honors the drop. Projecting
77
+ // those releases alone used to seed a fresh heartbeat (name recovered from
78
+ // .name-history, last_heartbeat = release ts), undoing the kill. Side-effect
79
+ // events must never birth an owner.
80
+ const NEVER_SEED = new Set([
81
+ "session.end",
82
+ "subagent.stop",
83
+ "health.heartbeat_swept",
84
+ "claim.release",
85
+ ]);
86
86
 
87
87
  // Seed from any existing v2 files so a partial replay doesn't reset state.
88
88
  for (const ev of events) {
89
89
  if (!perOwner[ev.instance_id]) {
90
90
  const existing = readExisting(coordRoot, ev.instance_id);
91
- if (!existing && TERMINAL.has(ev.event_type)) continue;
91
+ if (!existing && NEVER_SEED.has(ev.event_type)) continue;
92
92
  perOwner[ev.instance_id] = existing ?? seed(ev, coordRoot);
93
93
  }
94
94
  apply(perOwner[ev.instance_id]!, ev, coordRoot);
@@ -158,7 +158,20 @@ function seed(ev: CanonicalEvent, coordRoot: string): V2Heartbeat {
158
158
  }
159
159
 
160
160
  function apply(hb: V2Heartbeat, ev: CanonicalEvent, coordRoot: string): void {
161
- hb.last_heartbeat = ev.ts;
161
+ // Sweep telemetry must not refresh liveness. apply() used to stamp
162
+ // last_heartbeat = ev.ts for every event, so a drain that replayed
163
+ // [session.start … tools … health.heartbeat_swept] wrote a heartbeat whose
164
+ // last_heartbeat was the swept ts — looking freshly alive for another
165
+ // freshness window, which the next sweep deleted-and-re-emitted. Record the
166
+ // event for audit (last_event_id / events_applied) but keep the prior
167
+ // liveness stamp; also set ended_at so the mid-batch write guard skips
168
+ // re-creating a file the sweep/kill already removed.
169
+ const isSweepTelemetry = ev.event_type === "health.heartbeat_swept";
170
+ if (!isSweepTelemetry) {
171
+ hb.last_heartbeat = ev.ts;
172
+ } else if (!hb.last_heartbeat) {
173
+ hb.last_heartbeat = ev.ts;
174
+ }
162
175
  hb.last_event_id = ev.event_id;
163
176
  hb.events_applied += 1;
164
177
  hb.v2_meta.last_projected = new Date().toISOString();
@@ -201,6 +214,10 @@ function apply(hb: V2Heartbeat, ev: CanonicalEvent, coordRoot: string): void {
201
214
  hb.clean_exit = pickBool(d, "clean_exit");
202
215
  break;
203
216
 
217
+ case "health.heartbeat_swept":
218
+ hb.ended_at = ev.ts;
219
+ break;
220
+
204
221
  case "subagent.start": {
205
222
  const name = pickStr(d, "name");
206
223
  if (name) hb.name = name;
@@ -3,21 +3,26 @@ import type { Adapter } from "../events/schema.ts";
3
3
 
4
4
  /**
5
5
  * Resolve the adapter firing the hook. The dispatcher binary is always
6
- * invoked with `--adapter <name>` per the wiring in each adapter's settings
7
- * file (Phase 1). Returns null when the flag is missing; caller falls
6
+ * invoked with `--adapter <name>` per the current wiring in each adapter's
7
+ * settings file. `--harness` remains an accepted alias because settings files
8
+ * written by older releases survive a package upgrade until the consumer
9
+ * re-runs `harn init`. Returns null when neither flag is present; caller falls
8
10
  * through to the env-based fallback or skips emission.
9
11
  */
10
12
  export function detectAdapter(argv: readonly string[]): Adapter | null {
11
13
  for (let i = 0; i < argv.length; i++) {
12
14
  const a = argv[i]!;
13
- if (a === "--adapter") {
15
+ if (a === "--adapter" || a === "--harness") {
14
16
  return validate(argv[i + 1]);
15
17
  }
16
18
  if (a.startsWith("--adapter=")) {
17
19
  return validate(a.slice("--adapter=".length));
18
20
  }
21
+ if (a.startsWith("--harness=")) {
22
+ return validate(a.slice("--harness=".length));
23
+ }
19
24
  }
20
- return validate(coordEnv("AGENT_COORD_ADAPTER"));
25
+ return validate(coordEnv("AGENT_COORD_ADAPTER") ?? coordEnv("AGENT_COORD_HARNESS"));
21
26
  }
22
27
 
23
28
  function validate(v: string | undefined): Adapter | null {
@@ -80,11 +80,11 @@ function parseArgv(argv: string[]): Argv {
80
80
  const out: Argv = { eventName: null, extra: [] };
81
81
  for (let i = 0; i < argv.length; i++) {
82
82
  const arg = argv[i]!;
83
- if (arg === "--adapter") {
83
+ if (arg === "--adapter" || arg === "--harness") {
84
84
  i++; // detectAdapter will re-parse; just consume the value here.
85
85
  continue;
86
86
  }
87
- if (arg.startsWith("--adapter=")) continue;
87
+ if (arg.startsWith("--adapter=") || arg.startsWith("--harness=")) continue;
88
88
  if (!out.eventName && !arg.startsWith("--")) {
89
89
  out.eventName = arg;
90
90
  } else {
@@ -419,18 +419,19 @@ export type HealthPidmapHeal = EventEnvelope<
419
419
  >;
420
420
 
421
421
  /**
422
- * A heartbeat file was removed by stale-sweep. Symmetric with
423
- * `health.heartbeat_heal` so the full lifecycle (created → healed → swept) is
424
- * auditable from the event stream alone. Sweeps were silent before, which
425
- * made "why did this agent vanish?" un-answerable without guesswork.
422
+ * A heartbeat file was removed by stale-sweep or an operator kill. Symmetric
423
+ * with `health.heartbeat_heal` so the full lifecycle (created → healed →
424
+ * swept) is auditable from the event stream alone. Sweeps were silent before,
425
+ * which made "why did this agent vanish?" un-answerable without guesswork.
426
426
  * `reason`: "stale" (last_heartbeat past the freshness cutoff) | "unparseable"
427
427
  * (JSON.parse failed AND mtime was old) | "missing_ts" (no last_heartbeat AND
428
- * mtime was old). Fresh-mtime files are never swept regardless of content.
428
+ * mtime was old) | "killed" (operator `kill-heartbeat` / `agents heal --kind
429
+ * kill`). Fresh-mtime files are never auto-swept regardless of content.
429
430
  */
430
431
  export type HealthHeartbeatSwept = EventEnvelope<
431
432
  "health.heartbeat_swept",
432
433
  {
433
- reason: "stale" | "unparseable" | "missing_ts";
434
+ reason: "stale" | "unparseable" | "missing_ts" | "killed";
434
435
  age_secs?: number;
435
436
  }
436
437
  >;