@adhdev/daemon-standalone 1.0.28-rc.33 → 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 ? "5e05ac37dcef7e88d50d419fe2cf93bfbf77fc88" : void 0) ?? "unknown";
33315
- const commitShort = readInjected(true ? "5e05ac37" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
33316
- const version2 = readInjected(true ? "1.0.28-rc.33" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
33317
- const builtAt = readInjected(true ? "2026-07-31T00:24:14.883Z" : 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);
@@ -43655,6 +43686,23 @@ Next step: ${nextStep}`;
43655
43686
  `).run(leaseDeadlineMs, updatedAt, attemptId);
43656
43687
  this.maybeCheckpointWal();
43657
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
+ }
43658
43706
  // ── TURN-LEDGER (Stage 5): idempotency-keyed causal events ───────────────
43659
43707
  /**
43660
43708
  * Append a causal event. INSERT OR IGNORE on UNIQUE(attempt_id, kind, dedupe_key)
@@ -44879,7 +44927,8 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
44879
44927
  "task_reclaimed",
44880
44928
  "task_approval_needed",
44881
44929
  "task_question_pending",
44882
- "p2p_dispatch_failed"
44930
+ "p2p_dispatch_failed",
44931
+ "dispatch_duplicate_rebound"
44883
44932
  ]);
44884
44933
  LEDGER_DIR_NAME = "mesh-ledger";
44885
44934
  MAX_FILE_SIZE_BYTES = 10 * 1024 * 1024;
@@ -53979,6 +54028,42 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
53979
54028
  ]);
53980
54029
  }
53981
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
+ });
53982
54067
  function localCoordinatorDaemonId() {
53983
54068
  return canonicalDaemonId(readNonEmptyString(loadConfig2().machineId));
53984
54069
  }
@@ -54179,6 +54264,37 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
54179
54264
  }
54180
54265
  }).catch((e) => {
54181
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
+ }
54182
54298
  LOG2.error("MeshQueue", `Failed to dispatch task via ${ctx.transport} to node ${ctx.nodeId}: ${e?.message}`);
54183
54299
  updateSessionDeliveryStatus(delivery.id, "failed", { lastError: e?.message, incrementAttempt: true });
54184
54300
  endTaskDispatchInFlight(ctx.meshId, ctx.task.id);
@@ -55751,6 +55867,7 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
55751
55867
  init_mesh_task_inflight();
55752
55868
  init_model_provider_compat();
55753
55869
  init_mesh_turn_ledger();
55870
+ init_mesh_duplicate_dispatch();
55754
55871
  IDLE_AUTO_FAST_FORWARD_THROTTLE_MS = 30 * 60 * 1e3;
55755
55872
  idleAutoFastForwardLastAttempt = /* @__PURE__ */ new Map();
55756
55873
  CONTINUOUS_AUTO_FAST_FORWARD_SCAN_COOLDOWN_MS = 45 * 1e3;
@@ -70921,6 +71038,7 @@ ${lastSnapshot}`;
70921
71038
  DEFAULT_STATUS_P2P_REPORT_INTERVAL_MS: () => DEFAULT_STATUS_P2P_REPORT_INTERVAL_MS,
70922
71039
  DEFAULT_STATUS_SERVER_REPORT_INTERVAL_MS: () => DEFAULT_STATUS_SERVER_REPORT_INTERVAL_MS,
70923
71040
  DEV_SERVER_PORT: () => DEV_SERVER_PORT,
71041
+ DUPLICATE_MESH_DISPATCH_CODE: () => DUPLICATE_MESH_DISPATCH_CODE,
70924
71042
  DaemonAgentStreamManager: () => DaemonAgentStreamManager,
70925
71043
  DaemonCdpInitializer: () => DaemonCdpInitializer,
70926
71044
  DaemonCdpManager: () => DaemonCdpManager,
@@ -70930,6 +71048,7 @@ ${lastSnapshot}`;
70930
71048
  DaemonCommandRouter: () => DaemonCommandRouter,
70931
71049
  DaemonStatusReporter: () => DaemonStatusReporter,
70932
71050
  DevServer: () => DevServer,
71051
+ DuplicateMeshDispatchError: () => DuplicateMeshDispatchError,
70933
71052
  FsmDriver: () => FsmDriver,
70934
71053
  GOAL_PREVIEW_MAX: () => GOAL_PREVIEW_MAX,
70935
71054
  GitCommandError: () => GitCommandError,
@@ -71039,6 +71158,7 @@ ${lastSnapshot}`;
71039
71158
  canonicalDaemonId: () => canonicalDaemonId,
71040
71159
  claimNextTask: () => claimNextTask,
71041
71160
  classifyChatMessageVisibility: () => classifyChatMessageVisibility,
71161
+ classifyDuplicateMeshDispatch: () => classifyDuplicateMeshDispatch,
71042
71162
  classifyHotChatSessionsForSubscriptionFlush: () => classifyHotChatSessionsForSubscriptionFlush2,
71043
71163
  classifyP2pRelayFailure: () => classifyP2pRelayFailure,
71044
71164
  classifyShadowDivergence: () => classifyShadowDivergence,
@@ -71081,6 +71201,7 @@ ${lastSnapshot}`;
71081
71201
  detectIDEs: () => detectIDEs,
71082
71202
  detectNewlySettledCompletedSessions: () => detectNewlySettledCompletedSessions2,
71083
71203
  drainPendingMeshCoordinatorEvents: () => drainPendingMeshCoordinatorEvents,
71204
+ encodeDuplicateMeshDispatchCode: () => encodeDuplicateMeshDispatchCode,
71084
71205
  enqueueTask: () => enqueueTask,
71085
71206
  ensureSessionHostReady: () => ensureSessionHostReady2,
71086
71207
  evaluateFsm: () => evaluateFsm,
@@ -73641,6 +73762,7 @@ ${lastSnapshot}`;
73641
73762
  this.authEpoch = context.authEpoch;
73642
73763
  }
73643
73764
  };
73765
+ init_mesh_duplicate_dispatch();
73644
73766
  init_state_store();
73645
73767
  var import_child_process5 = require("child_process");
73646
73768
  var import_util22 = require("util");
@@ -85333,6 +85455,7 @@ ${body}
85333
85455
  init_recent_activity();
85334
85456
  init_hash();
85335
85457
  init_coordinator_registry();
85458
+ init_mesh_duplicate_dispatch();
85336
85459
  init_summary_metadata();
85337
85460
  var os19 = __toESM2(require("os"));
85338
85461
  var crypto5 = __toESM2(require("crypto"));
@@ -94846,7 +94969,10 @@ Run 'adhdev doctor' for detailed diagnostics.`
94846
94969
  } catch {
94847
94970
  }
94848
94971
  if (stampResult && stampResult.stamped === false && stampResult.reason === "task_already_stamped_on_live_instance") {
94849
- 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
+ );
94850
94976
  }
94851
94977
  if (meshContext.silentIdlePush === true) {
94852
94978
  try {
@@ -110614,7 +110740,13 @@ ${e?.stderr || ""}`;
110614
110740
  * marker in state.settings). Returns `{ stamped: true }` when the stamp was
110615
110741
  * applied, or `{ stamped: false, reason }` when it was refused — the instance
110616
110742
  * was missing / has no attach method, or the DOUBLE-DISPATCH idempotence guard
110617
- * 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. */
110618
110750
  attachMeshAssignmentToInstance(instanceId, assignment) {
110619
110751
  const inst = this.instances.get(instanceId);
110620
110752
  if (!inst || typeof inst.attachMeshAssignment !== "function") {
@@ -110625,7 +110757,7 @@ ${e?.stderr || ""}`;
110625
110757
  const conflict = this.findLiveWorkingTaskHolder(assignment.meshId, assignment.taskId, instanceId);
110626
110758
  if (conflict) {
110627
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}`);
110628
- return { stamped: false, reason: "task_already_stamped_on_live_instance" };
110760
+ return { stamped: false, reason: "task_already_stamped_on_live_instance", holderSessionId: conflict };
110629
110761
  }
110630
110762
  }
110631
110763
  inst.attachMeshAssignment(assignment);