@adhdev/daemon-standalone 1.0.28-rc.32 → 1.0.28-rc.34

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.
package/dist/index.js CHANGED
@@ -33311,10 +33311,10 @@ var require_dist3 = __commonJS({
33311
33311
  }
33312
33312
  function getDaemonBuildInfo() {
33313
33313
  if (cached2) return cached2;
33314
- const commit = readInjected(true ? "9d291b6668878c1d0e3c210fad52ff57cf9ec1f8" : void 0) ?? "unknown";
33315
- const commitShort = readInjected(true ? "9d291b66" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
33316
- const version2 = readInjected(true ? "1.0.28-rc.32" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
33317
- const builtAt = readInjected(true ? "2026-07-30T17:15:53.842Z" : void 0);
33314
+ const commit = readInjected(true ? "fcccd1309a13173048d54bcfb1edbf698ee22ee3" : void 0) ?? "unknown";
33315
+ const commitShort = readInjected(true ? "fcccd130" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
33316
+ const version2 = readInjected(true ? "1.0.28-rc.34" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
33317
+ const builtAt = readInjected(true ? "2026-07-31T01:14:11.973Z" : void 0);
33318
33318
  cached2 = builtAt ? { commit, commitShort, version: version2, builtAt } : { commit, commitShort, version: version2 };
33319
33319
  return cached2;
33320
33320
  }
@@ -38307,6 +38307,37 @@ Next step: ${nextStep}`;
38307
38307
  nowMs: args.nowMs
38308
38308
  });
38309
38309
  }
38310
+ function rebindAttemptToLiveHolder(args) {
38311
+ const holder = typeof args.holderSessionId === "string" ? args.holderSessionId.trim() : "";
38312
+ if (!holder) return { rebound: false, reason: "no_holder" };
38313
+ const store = MeshRuntimeStore.getInstance();
38314
+ const attempt = store.getCurrentTurnAttempt(args.meshId, args.taskId);
38315
+ if (!attempt) return { rebound: false, reason: "no_attempt" };
38316
+ if (attempt.terminalOutcome) return { rebound: false, reason: "attempt_terminal", attemptId: attempt.attemptId };
38317
+ if (attempt.sessionId && sessionIdsEquivalent(attempt.sessionId, holder)) {
38318
+ return { rebound: false, reason: "same_session", attemptId: attempt.attemptId };
38319
+ }
38320
+ const nowMs = args.nowMs ?? Date.now();
38321
+ const nowIso = new Date(nowMs).toISOString();
38322
+ const ok = store.rebindTurnAttemptSession(attempt.attemptId, holder, nowIso);
38323
+ if (!ok) return { rebound: false, reason: "store_rejected", attemptId: attempt.attemptId };
38324
+ try {
38325
+ store.insertTurnEvent({
38326
+ eventId: (0, import_crypto5.randomUUID)(),
38327
+ meshId: args.meshId,
38328
+ attemptId: attempt.attemptId,
38329
+ taskId: args.taskId,
38330
+ kind: "session_rebound",
38331
+ dedupeKey: holder,
38332
+ payload: safeEvidenceJson({ fromSessionId: attempt.sessionId ?? null, toSessionId: holder, reason: "duplicate_dispatch_refused" }),
38333
+ occurredAtMs: nowMs,
38334
+ recordedAt: nowIso
38335
+ });
38336
+ } catch {
38337
+ }
38338
+ LOG2.info("TurnLedger", `Rebound attempt ${attempt.attemptId} (task ${args.taskId}) from session ${attempt.sessionId ?? "none"} to live holder ${holder} after a duplicate-dispatch refusal`);
38339
+ return { rebound: true, attemptId: attempt.attemptId, fromSessionId: attempt.sessionId ?? void 0, toSessionId: holder };
38340
+ }
38310
38341
  function evaluateRedrive(meshId, taskId, nowMs = Date.now()) {
38311
38342
  const store = MeshRuntimeStore.getInstance();
38312
38343
  const attempt = store.getCurrentTurnAttempt(meshId, taskId);
@@ -39597,6 +39628,32 @@ Next step: ${nextStep}`;
39597
39628
  return false;
39598
39629
  }
39599
39630
  }
39631
+ function requeueDrainedPendingMeshCoordinatorEvent(event) {
39632
+ const fingerprint = buildPendingEventFingerprint(event);
39633
+ if (!fingerprint.trim()) return false;
39634
+ let requeued = false;
39635
+ try {
39636
+ requeued = MeshRuntimeStore.getInstance().requeueDrainedPendingEventByFingerprint(event.meshId, fingerprint);
39637
+ } catch (e) {
39638
+ LOG2.warn("MeshEvents", `SQLite re-queue of held ${event.event} failed for mesh ${event.meshId}: ${e?.message || e}`);
39639
+ }
39640
+ try {
39641
+ const path50 = getPendingEventsPath(event.meshId, event.targetCoordinatorDaemonId);
39642
+ const alreadyOnDisk = readPendingMeshCoordinatorEventsFromDisk(event.meshId, event.targetCoordinatorDaemonId).some((pending) => buildPendingEventFingerprint(pending) === fingerprint);
39643
+ if (!alreadyOnDisk) {
39644
+ trimPendingEventsIfNeeded(path50);
39645
+ (0, import_fs5.appendFileSync)(path50, JSON.stringify(event) + "\n", "utf-8");
39646
+ requeued = true;
39647
+ }
39648
+ } catch (e) {
39649
+ if (!requeued) {
39650
+ LOG2.warn("MeshEvents", `Failed to durably re-queue held ${event.event} for mesh ${event.meshId}: ${e?.message || e}`);
39651
+ return false;
39652
+ }
39653
+ LOG2.warn("MeshEvents", `JSONL re-queue append failed for mesh ${event.meshId}; SQLite holds the event: ${e?.message || e}`);
39654
+ }
39655
+ return requeued;
39656
+ }
39600
39657
  function atomicDrainFile(path50) {
39601
39658
  const tmpPath = `${path50}.draining`;
39602
39659
  try {
@@ -43395,6 +43452,49 @@ Next step: ${nextStep}`;
43395
43452
  `UPDATE mesh_pending_events SET drained = 1, drained_at = ? WHERE drained = 0 AND id IN (${idList.map(() => "?").join(",")})`
43396
43453
  ).run(now, ...idList).changes;
43397
43454
  }
43455
+ /**
43456
+ * STRICT-ROUTE-HOLD-DURABILITY: return an ALREADY-DRAINED row to the queue
43457
+ * (drained=1 → drained=0), in place, by fingerprint.
43458
+ *
43459
+ * Why this exists (the rc.33 defect): a strict-routed completion whose originating
43460
+ * coordinator session is not currently live is "held" by re-queuing it. That
43461
+ * re-queue used to call the normal insert path, which CANNOT work for a held
43462
+ * event — three independent suppressors reject it:
43463
+ *
43464
+ * 1. `idx_mesh_pending_events_fingerprint` is UNIQUE on (mesh_id, fingerprint)
43465
+ * with NO `drained` qualifier, and insertPendingEvent uses INSERT OR IGNORE.
43466
+ * The just-drained row still occupies that fingerprint, so the "fresh
43467
+ * undrained copy" is silently ignored — changes = 0, no row added.
43468
+ * 2. hasPendingCoordinatorEventDuplicate → hasPendingEventFingerprint queries
43469
+ * `drained = 0`, so it does NOT see the drained original and reports no
43470
+ * duplicate — the caller believes the re-queue succeeded.
43471
+ * 3. Even if a copy did land, the v2 eventId is already in
43472
+ * drainedEventIdsForMesh(), so routeV2EventsForDrainer would skip it as
43473
+ * already-delivered on the next drain.
43474
+ *
43475
+ * The pre-restart hold only ever worked because the in-memory reconcile loop
43476
+ * re-read the event; nothing durable was written. A restart inside the 60s TTL
43477
+ * therefore lost the completion permanently (observed: task ec6c901a — exactly
43478
+ * one row, drained=1, and zero lines in the JSONL mirror).
43479
+ *
43480
+ * Flipping the EXISTING row back to drained=0 is the only correct move: it keeps
43481
+ * the unique fingerprint (no duplicate row can ever be created), removes the
43482
+ * eventId from the drained-baseline so the v2 idempotency filter stops swallowing
43483
+ * it, and makes the hold survive a process restart. queued_at is deliberately
43484
+ * PRESERVED so the strict TTL keeps measuring the event's true age across holds
43485
+ * and cannot be refreshed into an immortal row.
43486
+ *
43487
+ * Returns true when a drained row was found and returned to the queue.
43488
+ */
43489
+ requeueDrainedPendingEventByFingerprint(meshId, fingerprint) {
43490
+ if (!fingerprint) return false;
43491
+ const changes = this.db.prepare(
43492
+ `UPDATE mesh_pending_events SET drained = 0, drained_at = NULL
43493
+ WHERE mesh_id = ? AND fingerprint = ? AND drained = 1`
43494
+ ).run(meshId, fingerprint).changes;
43495
+ if (changes > 0) this.maybeCheckpointWal();
43496
+ return changes > 0;
43497
+ }
43398
43498
  /**
43399
43499
  * Hard-delete pending-event rows by id (including the dedup fingerprint history).
43400
43500
  * Used to expire an unresolved-delegate outbox entry that has exhausted its retry
@@ -43586,6 +43686,23 @@ Next step: ${nextStep}`;
43586
43686
  `).run(leaseDeadlineMs, updatedAt, attemptId);
43587
43687
  this.maybeCheckpointWal();
43588
43688
  }
43689
+ /**
43690
+ * DUP-CLAIM-REBIND: point a still-open attempt at the session that is ACTUALLY
43691
+ * working it. Used when a node refuses a duplicate dispatch and names the live
43692
+ * holder — the attempt was opened against the session we tried to dispatch to,
43693
+ * but the work is running on the holder, so the binding (not the attempt) is what
43694
+ * is wrong. Conditional on `terminal_outcome IS NULL` so a settled attempt is
43695
+ * never rewritten; returns whether the rebind landed.
43696
+ */
43697
+ rebindTurnAttemptSession(attemptId, sessionId, updatedAt) {
43698
+ const res = this.db.prepare(`
43699
+ UPDATE mesh_turn_attempts
43700
+ SET session_id = ?, updated_at = ?
43701
+ WHERE attempt_id = ? AND terminal_outcome IS NULL
43702
+ `).run(sessionId, updatedAt, attemptId);
43703
+ this.maybeCheckpointWal();
43704
+ return res.changes > 0;
43705
+ }
43589
43706
  // ── TURN-LEDGER (Stage 5): idempotency-keyed causal events ───────────────
43590
43707
  /**
43591
43708
  * Append a causal event. INSERT OR IGNORE on UNIQUE(attempt_id, kind, dedupe_key)
@@ -44810,7 +44927,8 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
44810
44927
  "task_reclaimed",
44811
44928
  "task_approval_needed",
44812
44929
  "task_question_pending",
44813
- "p2p_dispatch_failed"
44930
+ "p2p_dispatch_failed",
44931
+ "dispatch_duplicate_rebound"
44814
44932
  ]);
44815
44933
  LEDGER_DIR_NAME = "mesh-ledger";
44816
44934
  MAX_FILE_SIZE_BYTES = 10 * 1024 * 1024;
@@ -53910,6 +54028,42 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
53910
54028
  ]);
53911
54029
  }
53912
54030
  });
54031
+ function encodeDuplicateMeshDispatchCode(holderSessionId) {
54032
+ const holder = typeof holderSessionId === "string" ? holderSessionId.trim() : "";
54033
+ return holder ? `${DUPLICATE_MESH_DISPATCH_CODE}:${holder}` : DUPLICATE_MESH_DISPATCH_CODE;
54034
+ }
54035
+ function classifyDuplicateMeshDispatch(err) {
54036
+ if (!err || typeof err !== "object") return null;
54037
+ const e = err;
54038
+ if (e.code === DUPLICATE_MESH_DISPATCH_CODE) {
54039
+ const holder = typeof e.holderSessionId === "string" ? e.holderSessionId.trim() : "";
54040
+ return holder ? { holderSessionId: holder } : {};
54041
+ }
54042
+ for (const raw of [e.meshCode, e.code]) {
54043
+ if (typeof raw !== "string") continue;
54044
+ if (raw !== DUPLICATE_MESH_DISPATCH_CODE && !raw.startsWith(`${DUPLICATE_MESH_DISPATCH_CODE}:`)) continue;
54045
+ const holder = raw.slice(DUPLICATE_MESH_DISPATCH_CODE.length + 1).trim();
54046
+ return holder ? { holderSessionId: holder } : {};
54047
+ }
54048
+ return null;
54049
+ }
54050
+ var DUPLICATE_MESH_DISPATCH_CODE;
54051
+ var DuplicateMeshDispatchError;
54052
+ var init_mesh_duplicate_dispatch = __esm2({
54053
+ "src/mesh/mesh-duplicate-dispatch.ts"() {
54054
+ "use strict";
54055
+ DUPLICATE_MESH_DISPATCH_CODE = "DUPLICATE_MESH_DISPATCH";
54056
+ DuplicateMeshDispatchError = class extends Error {
54057
+ code = DUPLICATE_MESH_DISPATCH_CODE;
54058
+ holderSessionId;
54059
+ constructor(message, info = {}) {
54060
+ super(message);
54061
+ this.name = "DuplicateMeshDispatchError";
54062
+ this.holderSessionId = info.holderSessionId;
54063
+ }
54064
+ };
54065
+ }
54066
+ });
53913
54067
  function localCoordinatorDaemonId() {
53914
54068
  return canonicalDaemonId(readNonEmptyString(loadConfig2().machineId));
53915
54069
  }
@@ -54110,6 +54264,37 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
54110
54264
  }
54111
54265
  }).catch((e) => {
54112
54266
  if (timer) clearTimeout(timer);
54267
+ const duplicate = classifyDuplicateMeshDispatch(e);
54268
+ if (duplicate?.holderSessionId) {
54269
+ const rebind = rebindAttemptToLiveHolder({
54270
+ meshId: ctx.meshId,
54271
+ taskId: ctx.task.id,
54272
+ holderSessionId: duplicate.holderSessionId
54273
+ });
54274
+ if (rebind.rebound || rebind.reason === "same_session") {
54275
+ LOG2.info("MeshQueue", `Duplicate dispatch of task ${ctx.task.id} refused by node ${ctx.nodeId}: it is already being worked by live session ${duplicate.holderSessionId}. Task stays assigned; turn attempt ${rebind.attemptId ?? "n/a"} ${rebind.rebound ? "rebound to that session" : "was already bound to it"}.`);
54276
+ updateSessionDeliveryStatus(delivery.id, "delivered");
54277
+ try {
54278
+ appendLedgerEntry(ctx.meshId, {
54279
+ kind: "dispatch_duplicate_rebound",
54280
+ nodeId: ctx.nodeId,
54281
+ sessionId: duplicate.holderSessionId,
54282
+ payload: {
54283
+ taskId: ctx.task.id,
54284
+ deliveryId: delivery.id,
54285
+ transport: ctx.transport,
54286
+ attemptedSessionId: ctx.sessionId,
54287
+ holderSessionId: duplicate.holderSessionId,
54288
+ ...rebind.attemptId ? { attemptId: rebind.attemptId } : {},
54289
+ rebound: rebind.rebound
54290
+ }
54291
+ });
54292
+ } catch {
54293
+ }
54294
+ return;
54295
+ }
54296
+ LOG2.warn("MeshQueue", `Duplicate dispatch of task ${ctx.task.id} refused by node ${ctx.nodeId} (holder ${duplicate.holderSessionId}), but the turn attempt could not be rebound (${rebind.reason}) \u2014 falling back to the requeue path.`);
54297
+ }
54113
54298
  LOG2.error("MeshQueue", `Failed to dispatch task via ${ctx.transport} to node ${ctx.nodeId}: ${e?.message}`);
54114
54299
  updateSessionDeliveryStatus(delivery.id, "failed", { lastError: e?.message, incrementAttempt: true });
54115
54300
  endTaskDispatchInFlight(ctx.meshId, ctx.task.id);
@@ -55682,6 +55867,7 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
55682
55867
  init_mesh_task_inflight();
55683
55868
  init_model_provider_compat();
55684
55869
  init_mesh_turn_ledger();
55870
+ init_mesh_duplicate_dispatch();
55685
55871
  IDLE_AUTO_FAST_FORWARD_THROTTLE_MS = 30 * 60 * 1e3;
55686
55872
  idleAutoFastForwardLastAttempt = /* @__PURE__ */ new Map();
55687
55873
  CONTINUOUS_AUTO_FAST_FORWARD_SCAN_COOLDOWN_MS = 45 * 1e3;
@@ -60859,23 +61045,51 @@ ${cleanBody}`;
60859
61045
  async function pollAssignedTaskTerminalEvidence(components, mesh, row, opts) {
60860
61046
  const sessionId = readNonEmptyString(row.assignedSessionId);
60861
61047
  const nodeId = readNonEmptyString(row.assignedNodeId);
60862
- if (!sessionId || !nodeId) return null;
61048
+ const traceCtx = {
61049
+ taskId: row.id,
61050
+ ...sessionId ? { sessionId } : {},
61051
+ ...nodeId ? { nodeId } : {},
61052
+ meshId: mesh.id,
61053
+ event: "agent:generating_completed"
61054
+ };
61055
+ const declined = (reason, detail) => {
61056
+ traceMeshEventDrop(`poll_terminal_evidence_${reason}`, traceCtx, detail);
61057
+ return null;
61058
+ };
61059
+ if (!sessionId || !nodeId) {
61060
+ return declined("no_assigned_worker", `sessionId=${sessionId ?? "none"} nodeId=${nodeId ?? "none"}`);
61061
+ }
60863
61062
  const providerType = readNonEmptyString(row.assignedProviderType);
60864
61063
  const payload = await runSessionEvidenceCollection(sessionId, () => fetchAssignedTaskChatTail(components, mesh, row));
60865
- if (!payload) return null;
60866
- if (readChatPayloadStatus(payload) !== "idle") return null;
61064
+ if (!payload) return declined("chat_tail_unreadable", "worker transcript read returned no payload (offline/unreachable?)");
61065
+ const payloadStatus = readChatPayloadStatus(payload);
61066
+ if (payloadStatus !== "idle") return declined("session_not_idle", `status=${payloadStatus ?? "unknown"} \u2014 mid-turn, not a turn-end`);
60867
61067
  const messages = Array.isArray(payload.messages) ? payload.messages : [];
60868
61068
  const evidence = extractFinalAssistantSummaryEvidence(messages);
60869
- if (!evidence.finalSummary) return null;
60870
- if (hasTrailingToolActivityAfterFinalAssistant(messages)) return null;
61069
+ if (!evidence.finalSummary) return declined("no_final_assistant_summary", `idle with ${messages.length} message(s) but no assistant result`);
61070
+ if (hasTrailingToolActivityAfterFinalAssistant(messages)) {
61071
+ return declined("trailing_tool_activity", "tool/terminal bubble trails the final assistant \u2014 worker is mid-turn");
61072
+ }
60871
61073
  const dispatchedAtMs = Date.parse(readNonEmptyString(row.dispatchTimestamp));
60872
61074
  const transcriptAtMs = Date.parse(evidence.transcriptMessageAt ?? "");
60873
61075
  if (!(Number.isFinite(dispatchedAtMs) && Number.isFinite(transcriptAtMs) && transcriptAtMs >= dispatchedAtMs)) {
60874
- return null;
61076
+ const unusable = !Number.isFinite(dispatchedAtMs) || !Number.isFinite(transcriptAtMs);
61077
+ return declined(
61078
+ unusable ? "timestamp_unusable" : "summary_predates_dispatch",
61079
+ `dispatchTimestamp=${row.dispatchTimestamp ?? "none"} transcriptMessageAt=${evidence.transcriptMessageAt ?? "none"}`
61080
+ );
60875
61081
  }
60876
61082
  if (typeof opts?.minFinalAssistantAgeMs === "number" && opts.minFinalAssistantAgeMs > 0 && Date.now() - transcriptAtMs < opts.minFinalAssistantAgeMs) {
60877
- return null;
61083
+ return declined(
61084
+ "final_assistant_not_settled",
61085
+ `age=${Date.now() - transcriptAtMs}ms < minFinalAssistantAgeMs=${opts.minFinalAssistantAgeMs} \u2014 treated as in-flight narration`
61086
+ );
60878
61087
  }
61088
+ traceMeshEventStage(
61089
+ "poll_terminal_evidence_completed",
61090
+ traceCtx,
61091
+ `idle with final assistant after dispatch \u2014 task is completed, re-drive prevented`
61092
+ );
60879
61093
  return {
60880
61094
  outcome: "completed",
60881
61095
  finalSummary: evidence.finalSummary,
@@ -61002,7 +61216,7 @@ ${cleanBody}`;
61002
61216
  ...force ? { force: true } : {}
61003
61217
  });
61004
61218
  }
61005
- function recordHeldTerminalEventsToLedger(meshId, drainDaemonIds, reason, heldForCoordinatorCount) {
61219
+ function recordHeldTerminalEventsToLedger(meshId, drainDaemonIds, reason, heldForCoordinatorCount, strictRoutedFingerprints) {
61006
61220
  let pending;
61007
61221
  try {
61008
61222
  pending = getPendingMeshCoordinatorEvents(meshId, drainDaemonIds.length > 0 ? drainDaemonIds : void 0);
@@ -61010,6 +61224,7 @@ ${cleanBody}`;
61010
61224
  return;
61011
61225
  }
61012
61226
  for (const event of pending) {
61227
+ if (strictRoutedFingerprints?.has(buildPendingEventFingerprint(event))) continue;
61013
61228
  if (!shouldForceInjectMeshEvent(event.event)) continue;
61014
61229
  const fingerprint = buildPendingEventFingerprint(event);
61015
61230
  const key2 = `${meshId}::${fingerprint || `${event.event}::${event.nodeId || ""}::${event.queuedAt}`}`;
@@ -62089,6 +62304,7 @@ ${cleanBody}`;
62089
62304
  meshCoordinators.map((c) => readNonEmptyString(c.sessionId)).filter(Boolean)
62090
62305
  );
62091
62306
  let orphanEscaped = 0;
62307
+ const strictRoutedFingerprints = /* @__PURE__ */ new Set();
62092
62308
  const hasPendingForOrphanPeek = !store || (() => {
62093
62309
  try {
62094
62310
  return store.pendingEventCount(meshId) > 0;
@@ -62123,10 +62339,11 @@ ${cleanBody}`;
62123
62339
  for (const pending of drained) {
62124
62340
  if (isOrphan(pending)) {
62125
62341
  holdOrExpireStrictUnmatchedEvent(pending, readNonEmptyString(pending.targetCoordinatorSessionId), meshId);
62342
+ strictRoutedFingerprints.add(buildPendingEventFingerprint(pending));
62126
62343
  orphanEscaped++;
62127
62344
  } else {
62128
62345
  try {
62129
- queuePendingMeshCoordinatorEvent(pending);
62346
+ requeueDrainedPendingMeshCoordinatorEvent(pending);
62130
62347
  } catch {
62131
62348
  }
62132
62349
  }
@@ -62149,7 +62366,8 @@ ${cleanBody}`;
62149
62366
  meshId,
62150
62367
  drainDaemonIds.length > 0 ? drainDaemonIds : localDaemonId ? [localDaemonId] : [],
62151
62368
  "modal_parked",
62152
- modalParkedCoordinators.length
62369
+ modalParkedCoordinators.length,
62370
+ strictRoutedFingerprints
62153
62371
  );
62154
62372
  }
62155
62373
  } else if (generatingCoordinators.length > 0) {
@@ -62208,15 +62426,15 @@ ${cleanBody}`;
62208
62426
  const queuedAt = typeof pending.queuedAt === "number" ? pending.queuedAt : Date.now();
62209
62427
  if (Date.now() - queuedAt <= STRICT_SESSION_MATCH_TTL_MS) {
62210
62428
  try {
62211
- queuePendingMeshCoordinatorEvent(pending);
62212
- LOG2.info("MeshReconcile", `Strict route hold: coordinator session ${wantSession} not live on mesh ${meshId} \u2014 re-queued (${pending.event})`);
62429
+ const requeued = requeueDrainedPendingMeshCoordinatorEvent(pending);
62430
+ LOG2.info("MeshReconcile", `Strict route hold: coordinator session ${wantSession} not live on mesh ${meshId} \u2014 re-queued (${pending.event})${requeued ? "" : " [WARN: not durably re-queued]"}`);
62213
62431
  traceMeshEventDrop("strict_route_hold", {
62214
62432
  taskId: pending.metadataEvent?.taskId,
62215
62433
  sessionId: pending.metadataEvent?.targetSessionId ?? wantSession,
62216
62434
  nodeId: pending.nodeId,
62217
62435
  meshId,
62218
62436
  event: pending.event
62219
- }, `coordinatorSession=${wantSession} not live`);
62437
+ }, `coordinatorSession=${wantSession} not live durable=${requeued}`);
62220
62438
  } catch (e) {
62221
62439
  LOG2.warn("MeshReconcile", `Strict route re-queue failed for ${pending.event} on mesh ${meshId}: ${e?.message || e}`);
62222
62440
  }
@@ -70820,6 +71038,7 @@ ${lastSnapshot}`;
70820
71038
  DEFAULT_STATUS_P2P_REPORT_INTERVAL_MS: () => DEFAULT_STATUS_P2P_REPORT_INTERVAL_MS,
70821
71039
  DEFAULT_STATUS_SERVER_REPORT_INTERVAL_MS: () => DEFAULT_STATUS_SERVER_REPORT_INTERVAL_MS,
70822
71040
  DEV_SERVER_PORT: () => DEV_SERVER_PORT,
71041
+ DUPLICATE_MESH_DISPATCH_CODE: () => DUPLICATE_MESH_DISPATCH_CODE,
70823
71042
  DaemonAgentStreamManager: () => DaemonAgentStreamManager,
70824
71043
  DaemonCdpInitializer: () => DaemonCdpInitializer,
70825
71044
  DaemonCdpManager: () => DaemonCdpManager,
@@ -70829,6 +71048,7 @@ ${lastSnapshot}`;
70829
71048
  DaemonCommandRouter: () => DaemonCommandRouter,
70830
71049
  DaemonStatusReporter: () => DaemonStatusReporter,
70831
71050
  DevServer: () => DevServer,
71051
+ DuplicateMeshDispatchError: () => DuplicateMeshDispatchError,
70832
71052
  FsmDriver: () => FsmDriver,
70833
71053
  GOAL_PREVIEW_MAX: () => GOAL_PREVIEW_MAX,
70834
71054
  GitCommandError: () => GitCommandError,
@@ -70938,6 +71158,7 @@ ${lastSnapshot}`;
70938
71158
  canonicalDaemonId: () => canonicalDaemonId,
70939
71159
  claimNextTask: () => claimNextTask,
70940
71160
  classifyChatMessageVisibility: () => classifyChatMessageVisibility,
71161
+ classifyDuplicateMeshDispatch: () => classifyDuplicateMeshDispatch,
70941
71162
  classifyHotChatSessionsForSubscriptionFlush: () => classifyHotChatSessionsForSubscriptionFlush2,
70942
71163
  classifyP2pRelayFailure: () => classifyP2pRelayFailure,
70943
71164
  classifyShadowDivergence: () => classifyShadowDivergence,
@@ -70980,6 +71201,7 @@ ${lastSnapshot}`;
70980
71201
  detectIDEs: () => detectIDEs,
70981
71202
  detectNewlySettledCompletedSessions: () => detectNewlySettledCompletedSessions2,
70982
71203
  drainPendingMeshCoordinatorEvents: () => drainPendingMeshCoordinatorEvents,
71204
+ encodeDuplicateMeshDispatchCode: () => encodeDuplicateMeshDispatchCode,
70983
71205
  enqueueTask: () => enqueueTask,
70984
71206
  ensureSessionHostReady: () => ensureSessionHostReady2,
70985
71207
  evaluateFsm: () => evaluateFsm,
@@ -73540,6 +73762,7 @@ ${lastSnapshot}`;
73540
73762
  this.authEpoch = context.authEpoch;
73541
73763
  }
73542
73764
  };
73765
+ init_mesh_duplicate_dispatch();
73543
73766
  init_state_store();
73544
73767
  var import_child_process5 = require("child_process");
73545
73768
  var import_util22 = require("util");
@@ -85232,6 +85455,7 @@ ${body}
85232
85455
  init_recent_activity();
85233
85456
  init_hash();
85234
85457
  init_coordinator_registry();
85458
+ init_mesh_duplicate_dispatch();
85235
85459
  init_summary_metadata();
85236
85460
  var os19 = __toESM2(require("os"));
85237
85461
  var crypto5 = __toESM2(require("crypto"));
@@ -94745,7 +94969,10 @@ Run 'adhdev doctor' for detailed diagnostics.`
94745
94969
  } catch {
94746
94970
  }
94747
94971
  if (stampResult && stampResult.stamped === false && stampResult.reason === "task_already_stamped_on_live_instance") {
94748
- throw new Error(`Refusing duplicate mesh dispatch: task ${meshContext.taskId} is already being worked by a live session on this daemon`);
94972
+ throw new DuplicateMeshDispatchError(
94973
+ `Refusing duplicate mesh dispatch: task ${meshContext.taskId} is already being worked by a live session on this daemon`,
94974
+ { holderSessionId: stampResult.holderSessionId }
94975
+ );
94749
94976
  }
94750
94977
  if (meshContext.silentIdlePush === true) {
94751
94978
  try {
@@ -110513,7 +110740,13 @@ ${e?.stderr || ""}`;
110513
110740
  * marker in state.settings). Returns `{ stamped: true }` when the stamp was
110514
110741
  * applied, or `{ stamped: false, reason }` when it was refused — the instance
110515
110742
  * was missing / has no attach method, or the DOUBLE-DISPATCH idempotence guard
110516
- * fired (the same task is already running on another live session here). */
110743
+ * fired (the same task is already running on another live session here).
110744
+ *
110745
+ * DUP-CLAIM-REBIND: when the guard fires, the id of the live session that already
110746
+ * holds the task is returned as `holderSessionId`. The coordinator needs it to
110747
+ * REBIND its turn-ledger attempt onto the real worker instead of cancelling the
110748
+ * attempt — the guard already resolved that instance, so surfacing it here keeps
110749
+ * the caller from having to parse it back out of an error string. */
110517
110750
  attachMeshAssignmentToInstance(instanceId, assignment) {
110518
110751
  const inst = this.instances.get(instanceId);
110519
110752
  if (!inst || typeof inst.attachMeshAssignment !== "function") {
@@ -110524,7 +110757,7 @@ ${e?.stderr || ""}`;
110524
110757
  const conflict = this.findLiveWorkingTaskHolder(assignment.meshId, assignment.taskId, instanceId);
110525
110758
  if (conflict) {
110526
110759
  LOG2.warn("MeshDispatch", `attachMeshAssignment refused: task ${assignment.taskId} (mesh ${assignment.meshId}) is already being worked by live session ${conflict} \u2014 skipping duplicate stamp on ${instanceId}`);
110527
- return { stamped: false, reason: "task_already_stamped_on_live_instance" };
110760
+ return { stamped: false, reason: "task_already_stamped_on_live_instance", holderSessionId: conflict };
110528
110761
  }
110529
110762
  }
110530
110763
  inst.attachMeshAssignment(assignment);