@adhdev/daemon-standalone 1.0.29-rc.3 → 1.0.29-rc.4

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 ? "8ee046ce7156a829d1038a65cb48221ca9bedb64" : void 0) ?? "unknown";
33315
- const commitShort = readInjected(true ? "8ee046ce" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
33316
- const version2 = readInjected(true ? "1.0.29-rc.3" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
33317
- const builtAt = readInjected(true ? "2026-08-01T13:27:48.513Z" : void 0);
33314
+ const commit = readInjected(true ? "df91f2d3a3bded96267f00003d1ee8e27dda0512" : void 0) ?? "unknown";
33315
+ const commitShort = readInjected(true ? "df91f2d3" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
33316
+ const version2 = readInjected(true ? "1.0.29-rc.4" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
33317
+ const builtAt = readInjected(true ? "2026-08-02T00:25:39.936Z" : void 0);
33318
33318
  cached2 = builtAt ? { commit, commitShort, version: version2, builtAt } : { commit, commitShort, version: version2 };
33319
33319
  return cached2;
33320
33320
  }
@@ -36258,6 +36258,7 @@ ${error48.message || ""}`;
36258
36258
  resolveScopedMeshId: () => resolveScopedMeshId,
36259
36259
  setDifficultyBrains: () => setDifficultyBrains,
36260
36260
  setMagiKindPanel: () => setMagiKindPanel,
36261
+ setMeshHostPin: () => setMeshHostPin,
36261
36262
  tokenIdForManualPairing: () => tokenIdForManualPairing,
36262
36263
  updateMesh: () => updateMesh,
36263
36264
  updateNode: () => updateNode
@@ -36424,7 +36425,11 @@ ${error48.message || ""}`;
36424
36425
  defaultBranch: opts.defaultBranch,
36425
36426
  policy: mergeMeshPolicy(void 0, opts.policy),
36426
36427
  coordinator: opts.coordinator || {},
36427
- meshHost: opts.meshHost || createDefaultMeshHostMetadata(),
36428
+ meshHost: opts.meshHost || (() => {
36429
+ const base = createDefaultMeshHostMetadata();
36430
+ const creatingDaemonId = typeof opts.hostDaemonId === "string" ? opts.hostDaemonId.trim() : "";
36431
+ return creatingDaemonId ? { ...base, hostDaemonId: creatingDaemonId } : base;
36432
+ })(),
36428
36433
  nodes: [],
36429
36434
  createdAt: now,
36430
36435
  updatedAt: now
@@ -36610,6 +36615,86 @@ ${error48.message || ""}`;
36610
36615
  saveMeshConfig(config2);
36611
36616
  return { accepted: true, mesh, meshHost: mesh.meshHost, node, tokenId: validation.tokenId };
36612
36617
  }
36618
+ function setMeshHostPin(meshId, opts) {
36619
+ const config2 = loadMeshConfig();
36620
+ const mesh = config2.meshes.find((m) => m.id === meshId);
36621
+ if (!mesh) return void 0;
36622
+ const hostDaemonId = typeof opts.hostDaemonId === "string" ? opts.hostDaemonId.trim() : "";
36623
+ const hostNodeId = typeof opts.hostNodeId === "string" ? opts.hostNodeId.trim() : "";
36624
+ const previous = mesh.meshHost || createDefaultMeshHostMetadata();
36625
+ if (!hostDaemonId && !hostNodeId) {
36626
+ return {
36627
+ mesh,
36628
+ meshHost: previous,
36629
+ applied: false,
36630
+ reason: "invalid_host_daemon_id",
36631
+ ...previous.hostDaemonId ? { hostDaemonId: previous.hostDaemonId } : {},
36632
+ ...previous.hostNodeId ? { hostNodeId: previous.hostNodeId } : {}
36633
+ };
36634
+ }
36635
+ if (previous.role === "member") {
36636
+ return {
36637
+ mesh,
36638
+ meshHost: previous,
36639
+ applied: false,
36640
+ reason: "not_host_role",
36641
+ ...previous.hostDaemonId ? { hostDaemonId: previous.hostDaemonId } : {},
36642
+ ...previous.hostNodeId ? { hostNodeId: previous.hostNodeId } : {}
36643
+ };
36644
+ }
36645
+ const existingDaemonId = typeof previous.hostDaemonId === "string" ? previous.hostDaemonId.trim() : "";
36646
+ if (existingDaemonId && !opts.force) {
36647
+ const sameHost = hostDaemonId ? daemonIdsEquivalent(existingDaemonId, hostDaemonId) : true;
36648
+ if (!sameHost) {
36649
+ return {
36650
+ mesh,
36651
+ meshHost: previous,
36652
+ applied: false,
36653
+ reason: "host_already_pinned",
36654
+ hostDaemonId: existingDaemonId,
36655
+ ...previous.hostNodeId ? { hostNodeId: previous.hostNodeId } : {}
36656
+ };
36657
+ }
36658
+ const existingNodeId = typeof previous.hostNodeId === "string" ? previous.hostNodeId.trim() : "";
36659
+ if (!hostNodeId || hostNodeId === existingNodeId) {
36660
+ return {
36661
+ mesh,
36662
+ meshHost: previous,
36663
+ applied: false,
36664
+ reason: "already_pinned_same",
36665
+ hostDaemonId: existingDaemonId,
36666
+ ...existingNodeId ? { hostNodeId: existingNodeId } : {}
36667
+ };
36668
+ }
36669
+ }
36670
+ const now = opts.now || (/* @__PURE__ */ new Date()).toISOString();
36671
+ const effectiveDaemonId = hostDaemonId || existingDaemonId;
36672
+ mesh.meshHost = {
36673
+ ...previous,
36674
+ role: "host",
36675
+ ...effectiveDaemonId ? { hostDaemonId: effectiveDaemonId } : {},
36676
+ ...hostNodeId ? { hostNodeId } : previous.hostNodeId ? { hostNodeId: previous.hostNodeId } : {},
36677
+ ...opts.hostAddress?.trim() ? { hostAddress: opts.hostAddress.trim() } : {}
36678
+ };
36679
+ const hostNode = hostNodeId ? mesh.nodes.find((n) => n.id === hostNodeId) : effectiveDaemonId ? mesh.nodes.find((n) => n.daemonId && daemonIdsEquivalent(n.daemonId, effectiveDaemonId)) : void 0;
36680
+ if (hostNode) {
36681
+ for (const node of mesh.nodes) {
36682
+ if (node.role === "host" && node !== hostNode) node.role = void 0;
36683
+ }
36684
+ hostNode.role = "host";
36685
+ if (!mesh.meshHost.hostNodeId) mesh.meshHost.hostNodeId = hostNode.id;
36686
+ }
36687
+ mesh.updatedAt = now;
36688
+ saveMeshConfig(config2);
36689
+ return {
36690
+ mesh,
36691
+ meshHost: mesh.meshHost,
36692
+ applied: true,
36693
+ reason: "pinned",
36694
+ ...mesh.meshHost.hostDaemonId ? { hostDaemonId: mesh.meshHost.hostDaemonId } : {},
36695
+ ...mesh.meshHost.hostNodeId ? { hostNodeId: mesh.meshHost.hostNodeId } : {}
36696
+ };
36697
+ }
36613
36698
  function markMeshHostPairingJoined(meshId, opts) {
36614
36699
  const config2 = loadMeshConfig();
36615
36700
  const mesh = config2.meshes.find((m) => m.id === meshId);
@@ -36670,6 +36755,12 @@ ${error48.message || ""}`;
36670
36755
  worktreeBootstrap: opts.worktreeBootstrap,
36671
36756
  role: opts.role
36672
36757
  };
36758
+ const pinnedHostDaemonId = typeof mesh.meshHost?.hostDaemonId === "string" ? mesh.meshHost.hostDaemonId.trim() : "";
36759
+ const anchorMissing = !(typeof mesh.meshHost?.hostNodeId === "string" && mesh.meshHost.hostNodeId.trim());
36760
+ if (!node.role && anchorMissing && pinnedHostDaemonId && mesh.meshHost?.role !== "member" && node.daemonId && daemonIdsEquivalent(node.daemonId, pinnedHostDaemonId) && !mesh.nodes.some((n) => n.role === "host")) {
36761
+ node.role = "host";
36762
+ mesh.meshHost = { ...mesh.meshHost || createDefaultMeshHostMetadata(), hostNodeId: node.id };
36763
+ }
36673
36764
  mesh.nodes.push(node);
36674
36765
  mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
36675
36766
  saveMeshConfig(config2);
@@ -39392,9 +39483,20 @@ Next step: ${nextStep}`;
39392
39483
  }
39393
39484
  continue;
39394
39485
  }
39486
+ if (validated.intendedFor && !validated.intendedFor.sessionId && daemonIdsEquivalent(validated.intendedFor.daemonId, drainer.daemonId)) {
39487
+ const liveSessions = ctx.countLiveCoordinatorSessions?.(validated.intendedFor.daemonId) ?? 0;
39488
+ if (liveSessions > 1) {
39489
+ warnV2Once(
39490
+ `${event.meshId}::${eventId}::ambiguous-unicast`,
39491
+ `v2 unicast ${event.event} on mesh ${event.meshId} carries NO coordinator session but ${liveSessions} coordinator sessions are live on ${validated.intendedFor.daemonId} \u2014 delivery is first-come-first-served and may reach the wrong coordinator. Delivered to ${coordinatorIdentityKey(drainer)}. The EMITTING path must stamp targetCoordinatorSessionId.`
39492
+ );
39493
+ bump("v2AmbiguousUnicastDelivered");
39494
+ }
39495
+ }
39395
39496
  if (validated.intendedFor && identityDeliversTo(validated.intendedFor, drainer)) {
39396
39497
  ctx.batchSeen.add(eventId);
39397
39498
  bump("v2Delivered");
39499
+ LOG2.debug("MeshEventsV2", `unicast ${event.event} (mesh ${event.meshId}, eventId ${eventId}) delivered to ${coordinatorIdentityKey(drainer)}; intendedFor=${coordinatorIdentityKey(validated.intendedFor)}`);
39398
39500
  kept.push(event);
39399
39501
  continue;
39400
39502
  }
@@ -39409,6 +39511,7 @@ Next step: ${nextStep}`;
39409
39511
  kept.push(event);
39410
39512
  continue;
39411
39513
  }
39514
+ LOG2.debug("MeshEventsV2", `unicast ${event.event} (mesh ${event.meshId}, eventId ${eventId}) NOT delivered to ${coordinatorIdentityKey(drainer)}; intendedFor=${validated.intendedFor ? coordinatorIdentityKey(validated.intendedFor) : "none"} \u2014 left for its own drainer`);
39412
39515
  bump("v2RoutedAway");
39413
39516
  }
39414
39517
  return kept;
@@ -39861,7 +39964,12 @@ Next step: ${nextStep}`;
39861
39964
  try {
39862
39965
  const store = MeshRuntimeStore.getInstance();
39863
39966
  if (store.pendingEventCount(meshId) > 0) {
39864
- for (const row of store.drainPendingEvents(meshId, daemonIds.length > 0 ? daemonIds : void 0, onlyEvents ? { onlyEvents } : void 0)) {
39967
+ const drainedBy = drainer ? JSON.stringify(drainer) : null;
39968
+ for (const row of store.drainPendingEvents(
39969
+ meshId,
39970
+ daemonIds.length > 0 ? daemonIds : void 0,
39971
+ { ...onlyEvents ? { onlyEvents } : {}, drainedBy }
39972
+ )) {
39865
39973
  const event = row.payload;
39866
39974
  if (event) pushUnique(event);
39867
39975
  }
@@ -39900,7 +40008,8 @@ Next step: ${nextStep}`;
39900
40008
  const routed = routeV2EventsForDrainer(merged, drainer, {
39901
40009
  alreadyDrained: (eventId) => priorDrainedEventIds.has(eventId),
39902
40010
  batchSeen: /* @__PURE__ */ new Set(),
39903
- countMetrics: true
40011
+ countMetrics: true,
40012
+ ...opts?.countLiveCoordinatorSessions ? { countLiveCoordinatorSessions: opts.countLiveCoordinatorSessions } : {}
39904
40013
  });
39905
40014
  return reconcilePendingMeshCoordinatorEvents(meshId, routed);
39906
40015
  }
@@ -40120,6 +40229,11 @@ Next step: ${nextStep}`;
40120
40229
  /** unicast events re-attributed to the drainer via daemon-core match (a
40121
40230
  * coordinatorRunId change orphaned them). */
40122
40231
  v2ReattributedToDrainer: 0,
40232
+ /** REFINE-EVENT-SESSION-SCOPED-UNICAST: unicast events delivered while addressed only
40233
+ * at DAEMON granularity (no sessionId in intendedFor) even though >1 coordinator
40234
+ * session was live on that daemon — i.e. delivered by race, not by address. Non-zero
40235
+ * here names an emit path that still fails to stamp targetCoordinatorSessionId. */
40236
+ v2AmbiguousUnicastDelivered: 0,
40123
40237
  /** v1 (unversioned) events passed through as broadcast (rollout baseline). */
40124
40238
  v1BroadcastAccepted: 0,
40125
40239
  /** T6 enforce: v2 events that FAILED validation and were QUARANTINED (held back
@@ -41878,7 +41992,15 @@ Next step: ${nextStep}`;
41878
41992
  event_id TEXT,
41879
41993
  scope TEXT,
41880
41994
  dispatched_by TEXT,
41881
- intended_for TEXT
41995
+ intended_for TEXT,
41996
+ -- REFINE-EVENT-SESSION-SCOPED-UNICAST: WHO consumed this row. The ledger
41997
+ -- previously recorded only THAT an event was drained, never by which
41998
+ -- coordinator identity \u2014 so a mis-delivered unicast (a sibling session
41999
+ -- consuming another coordinator's event) left no evidence and had to be
42000
+ -- inferred. Written at drain time as the JSON-serialized drainer
42001
+ -- CoordinatorIdentity. NULL on rows drained before this column existed
42002
+ -- and on any drain whose caller passed no identity (daemon-level drain).
42003
+ drained_by TEXT
41882
42004
  );
41883
42005
 
41884
42006
  CREATE INDEX IF NOT EXISTS idx_mesh_pending_events_mesh_drained
@@ -42124,7 +42246,7 @@ Next step: ${nextStep}`;
42124
42246
  this.db.exec(`ALTER TABLE mesh_missions ADD COLUMN close_candidate_emitted_at TEXT`);
42125
42247
  }
42126
42248
  const pendingCols = this.tableColumns("mesh_pending_events");
42127
- for (const col of ["protocol_version", "event_id", "scope", "dispatched_by", "intended_for"]) {
42249
+ for (const col of ["protocol_version", "event_id", "scope", "dispatched_by", "intended_for", "drained_by"]) {
42128
42250
  if (!pendingCols.has(col)) {
42129
42251
  this.db.exec(`ALTER TABLE mesh_pending_events ADD COLUMN ${col} TEXT`);
42130
42252
  }
@@ -43393,8 +43515,8 @@ Next step: ${nextStep}`;
43393
43515
  const ids = rows.map((r) => r.id);
43394
43516
  const now = Date.now();
43395
43517
  this.db.prepare(
43396
- `UPDATE mesh_pending_events SET drained = 1, drained_at = ? WHERE id IN (${ids.map(() => "?").join(",")})`
43397
- ).run(now, ...ids);
43518
+ `UPDATE mesh_pending_events SET drained = 1, drained_at = ?, drained_by = ? WHERE id IN (${ids.map(() => "?").join(",")})`
43519
+ ).run(now, opts?.drainedBy ?? null, ...ids);
43398
43520
  return rows.map((r) => ({
43399
43521
  id: r.id,
43400
43522
  event: r.event,
@@ -43428,6 +43550,30 @@ Next step: ${nextStep}`;
43428
43550
  })()
43429
43551
  }));
43430
43552
  }
43553
+ /**
43554
+ * REFINE-EVENT-SESSION-SCOPED-UNICAST — drain attribution audit. Returns the most
43555
+ * recent pending-event rows for a mesh with WHO drained each one, so a suspected
43556
+ * mis-delivery ("my refine result went to another coordinator session") is answered
43557
+ * from the ledger instead of inferred from timing. `drainedBy` is the serialized
43558
+ * drainer CoordinatorIdentity, or null when the row is still queued, was drained
43559
+ * before this column existed, or was drained by a caller that passed no identity.
43560
+ */
43561
+ recentDrainedPendingEvents(meshId, limit = 100) {
43562
+ const rows = this.db.prepare(
43563
+ `SELECT id, event, scope, intended_for, drained_by, drained, queued_at, drained_at
43564
+ FROM mesh_pending_events WHERE mesh_id = ? ORDER BY queued_at DESC LIMIT ?`
43565
+ ).all(meshId, Math.max(1, limit));
43566
+ return rows.map((r) => ({
43567
+ id: r.id,
43568
+ event: r.event,
43569
+ scope: r.scope ?? null,
43570
+ intendedFor: r.intended_for ?? null,
43571
+ drainedBy: r.drained_by ?? null,
43572
+ drained: r.drained === 1,
43573
+ queuedAt: r.queued_at,
43574
+ drainedAt: r.drained_at ?? null
43575
+ }));
43576
+ }
43431
43577
  hasPendingEventFingerprint(meshId, fingerprint) {
43432
43578
  const row = this.db.prepare(
43433
43579
  "SELECT 1 FROM mesh_pending_events WHERE mesh_id = ? AND fingerprint = ? AND drained = 0 LIMIT 1"
@@ -43602,7 +43748,7 @@ Next step: ${nextStep}`;
43602
43748
  requeueDrainedPendingEventByFingerprint(meshId, fingerprint) {
43603
43749
  if (!fingerprint) return false;
43604
43750
  const changes = this.db.prepare(
43605
- `UPDATE mesh_pending_events SET drained = 0, drained_at = NULL
43751
+ `UPDATE mesh_pending_events SET drained = 0, drained_at = NULL, drained_by = NULL
43606
43752
  WHERE mesh_id = ? AND fingerprint = ? AND drained = 1`
43607
43753
  ).run(meshId, fingerprint).changes;
43608
43754
  if (changes > 0) this.maybeCheckpointWal();
@@ -61514,7 +61660,15 @@ ${cleanBody}`;
61514
61660
  try {
61515
61661
  pendingEvents = drainPendingMeshCoordinatorEvents(
61516
61662
  meshId,
61517
- drainDaemonIds.length > 0 ? drainDaemonIds : localDaemonId
61663
+ drainDaemonIds.length > 0 ? drainDaemonIds : localDaemonId,
61664
+ {
61665
+ // AMBIGUOUS-UNICAST guard (REFINE-EVENT-SESSION-SCOPED-UNICAST): observability
61666
+ // only — it warns when a session-less unicast event is delivered while several
61667
+ // coordinator sessions are live and racing for it. Never changes delivery, so
61668
+ // an event can't be stranded by it. targetCoordinators is this daemon's live
61669
+ // coordinator set for the mesh, which is exactly the racing population.
61670
+ countLiveCoordinatorSessions: () => new Set(targetCoordinators.map((c) => c.sessionId).filter(Boolean)).size
61671
+ }
61518
61672
  );
61519
61673
  } catch (e) {
61520
61674
  LOG2.warn("MeshReconcile", `Drain failed for mesh ${meshId}: ${e?.message || e}`);
@@ -101143,7 +101297,7 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
101143
101297
  }
101144
101298
  return { success: true, mesh: meshRecord.mesh, sourceOfTruth };
101145
101299
  },
101146
- create_mesh: async (_ctx, args) => {
101300
+ create_mesh: async (ctx, args) => {
101147
101301
  const name = typeof args?.name === "string" ? args.name.trim() : "";
101148
101302
  const repoIdentity = typeof args?.repoIdentity === "string" ? args.repoIdentity.trim() : "";
101149
101303
  const repoRemoteUrl = typeof args?.repoRemoteUrl === "string" ? args.repoRemoteUrl.trim() : void 0;
@@ -101152,12 +101306,71 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
101152
101306
  try {
101153
101307
  const { createMesh: createMesh2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
101154
101308
  const meshHost = args?.meshHost && typeof args.meshHost === "object" && !Array.isArray(args.meshHost) ? args.meshHost : void 0;
101155
- const mesh = createMesh2({ name, repoIdentity, repoRemoteUrl, defaultBranch, policy: args?.policy, meshHost });
101309
+ const requestedHostDaemonId = typeof args?.hostDaemonId === "string" && args.hostDaemonId.trim() ? args.hostDaemonId.trim() : ctx.deps.statusInstanceId || "";
101310
+ const mesh = createMesh2({
101311
+ name,
101312
+ repoIdentity,
101313
+ repoRemoteUrl,
101314
+ defaultBranch,
101315
+ policy: args?.policy,
101316
+ meshHost,
101317
+ ...requestedHostDaemonId ? { hostDaemonId: requestedHostDaemonId } : {}
101318
+ });
101156
101319
  return { success: true, mesh };
101157
101320
  } catch (e) {
101158
101321
  return { success: false, error: e.message };
101159
101322
  }
101160
101323
  },
101324
+ // HOST-PIN-WRITER — establish this mesh's host daemon as a DELIBERATE operator act.
101325
+ //
101326
+ // The dashboard's first-setup flow lets the operator pick which connected daemon
101327
+ // becomes the host; this is the command that actually persists that choice. It is a
101328
+ // separate surface from coordinator launch on purpose: the pin is effectively
101329
+ // permanent ("Fixed when the mesh is created — it cannot be reassigned here"), so it
101330
+ // must not be an incidental side effect of a button whose stated job is launching a
101331
+ // session. A mis-click must not permanently re-home a mesh.
101332
+ //
101333
+ // Reassignment to a DIFFERENT daemon is refused unless the caller passes
101334
+ // force:true — the mutator returns code 'host_already_pinned' and changes nothing.
101335
+ // Re-pinning the same daemon is a no-op, so retries/races are safe.
101336
+ set_mesh_host: async (ctx, args) => {
101337
+ const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
101338
+ const hostDaemonId = typeof args?.hostDaemonId === "string" ? args.hostDaemonId.trim() : "";
101339
+ const hostNodeId = typeof args?.hostNodeId === "string" ? args.hostNodeId.trim() : "";
101340
+ if (!meshId) return { success: false, error: "meshId required" };
101341
+ if (!hostDaemonId && !hostNodeId) return { success: false, error: "hostDaemonId or hostNodeId required" };
101342
+ try {
101343
+ const { setMeshHostPin: setMeshHostPin2, getMesh: getMesh2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
101344
+ const result = setMeshHostPin2(meshId, {
101345
+ ...hostDaemonId ? { hostDaemonId } : {},
101346
+ ...hostNodeId ? { hostNodeId } : {},
101347
+ force: args?.force === true
101348
+ });
101349
+ if (!result) return { success: false, error: "Mesh not found" };
101350
+ if (!result.applied && result.reason !== "already_pinned_same") {
101351
+ return {
101352
+ success: false,
101353
+ code: result.reason,
101354
+ error: result.reason === "host_already_pinned" ? `Mesh host is already pinned to ${result.hostDaemonId}. Pass force:true to reassign it.` : result.reason === "not_host_role" ? "This daemon joined the mesh as a member; its host lives on the daemon it paired with." : "hostDaemonId or hostNodeId required",
101355
+ meshId,
101356
+ meshHost: resolveMeshHostStatus(result.mesh)
101357
+ };
101358
+ }
101359
+ const fresh = getMesh2(meshId) || result.mesh;
101360
+ if (ctx.getCachedInlineMesh(meshId)) ctx.inlineMeshCache.set(meshId, fresh);
101361
+ ctx.invalidateAggregateMeshStatus(meshId);
101362
+ return {
101363
+ success: true,
101364
+ code: result.reason,
101365
+ meshId,
101366
+ applied: result.applied,
101367
+ meshHost: resolveMeshHostStatus(fresh),
101368
+ mesh: fresh
101369
+ };
101370
+ } catch (e) {
101371
+ return { success: false, error: e.message };
101372
+ }
101373
+ },
101161
101374
  update_mesh: async (ctx, args) => {
101162
101375
  const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
101163
101376
  if (!meshId) return { success: false, error: "meshId required" };
@@ -103102,6 +103315,26 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
103102
103315
  init_mesh_coordinator();
103103
103316
  init_dist();
103104
103317
  init_repo_mesh_types();
103318
+ async function backfillMeshHostPinAfterLaunch(opts) {
103319
+ try {
103320
+ const existingPin = typeof opts.mesh?.meshHost?.hostDaemonId === "string" ? opts.mesh.meshHost.hostDaemonId.trim() : "";
103321
+ if (existingPin) return;
103322
+ const { getMesh: getMesh2, setMeshHostPin: setMeshHostPin2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
103323
+ if (!getMesh2(opts.meshId)) return;
103324
+ const nodeDaemonId = typeof opts.coordinatorNode?.daemonId === "string" && opts.coordinatorNode.daemonId.trim() ? opts.coordinatorNode.daemonId.trim() : typeof opts.coordinatorNode?.daemon_id === "string" && opts.coordinatorNode.daemon_id.trim() ? opts.coordinatorNode.daemon_id.trim() : opts.localDaemonId || "";
103325
+ const nodeId = String(normalizeMeshNodeId(opts.coordinatorNode) || "");
103326
+ if (!nodeDaemonId && !nodeId) return;
103327
+ const result = setMeshHostPin2(opts.meshId, {
103328
+ ...nodeDaemonId ? { hostDaemonId: nodeDaemonId } : {},
103329
+ ...nodeId ? { hostNodeId: nodeId } : {}
103330
+ });
103331
+ if (result?.applied) {
103332
+ LOG2.info("MeshCoordinator", `Pinned mesh ${opts.meshId} host to ${result.hostDaemonId || nodeDaemonId} (node ${result.hostNodeId || nodeId}) after coordinator launch`);
103333
+ }
103334
+ } catch (error48) {
103335
+ LOG2.warn("MeshCoordinator", `Host pin backfill skipped for mesh ${opts.meshId}: ${error48?.message || String(error48)}`);
103336
+ }
103337
+ }
103105
103338
  var meshCoordinatorLaunchHandlers = {
103106
103339
  launch_mesh_coordinator: async (ctx, args) => {
103107
103340
  const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
@@ -103461,6 +103694,12 @@ ${ptyResult.output.slice(-2e3)}`);
103461
103694
  });
103462
103695
  } catch {
103463
103696
  }
103697
+ await backfillMeshHostPinAfterLaunch({
103698
+ meshId,
103699
+ mesh,
103700
+ coordinatorNode,
103701
+ localDaemonId: ctx.deps.statusInstanceId
103702
+ });
103464
103703
  return {
103465
103704
  success: true,
103466
103705
  meshId,
@@ -103659,6 +103898,12 @@ ${ptyResult.output.slice(-2e3)}`);
103659
103898
  });
103660
103899
  } catch {
103661
103900
  }
103901
+ await backfillMeshHostPinAfterLaunch({
103902
+ meshId,
103903
+ mesh,
103904
+ coordinatorNode,
103905
+ localDaemonId: ctx.deps.statusInstanceId
103906
+ });
103662
103907
  return {
103663
103908
  success: true,
103664
103909
  meshId,
@@ -106061,6 +106306,7 @@ ${mergeTreeErr?.stderr || ""}`;
106061
106306
  ...args.completedAt ? { completedAt: args.completedAt } : {},
106062
106307
  ...args.retryOfJobId ? { retryOfJobId: args.retryOfJobId } : {},
106063
106308
  ...args.coordinatorDaemonId ? { targetCoordinatorDaemonId: args.coordinatorDaemonId } : {},
106309
+ ...args.coordinatorSessionId ? { targetCoordinatorSessionId: args.coordinatorSessionId } : {},
106064
106310
  eventDelivery: { pendingEvents: true, ledger: true },
106065
106311
  evidence: {
106066
106312
  pendingEventsCommand: "get_pending_mesh_events",
@@ -106159,9 +106405,23 @@ ${mergeTreeErr?.stderr || ""}`;
106159
106405
  nodeLabel: handle.targetNodeId,
106160
106406
  nodeId: handle.targetNodeId,
106161
106407
  workspace: handle.workspace,
106162
- metadataEvent,
106408
+ metadataEvent: {
106409
+ ...metadataEvent,
106410
+ // REFINE-EVENT-SESSION-SCOPED-UNICAST: mirror the session INSIDE
106411
+ // metadataEvent too. handleMeshForwardEvent reads the coordinator session
106412
+ // anchor from `metadataEvent.meshCoordinatorSessionId` (a top-level field
106413
+ // alone is dropped when the event crosses a machine boundary), so this is
106414
+ // what survives the P2P relay for a remote-executing refine.
106415
+ ...handle.targetCoordinatorSessionId ? { meshCoordinatorSessionId: handle.targetCoordinatorSessionId } : {}
106416
+ },
106163
106417
  queuedAt: Date.now(),
106164
- ...handle.targetCoordinatorDaemonId ? { targetCoordinatorDaemonId: handle.targetCoordinatorDaemonId } : {}
106418
+ ...handle.targetCoordinatorDaemonId ? { targetCoordinatorDaemonId: handle.targetCoordinatorDaemonId } : {},
106419
+ // THE FIX: address the terminal event to the requesting coordinator SESSION,
106420
+ // not just its daemon. stampPendingEventV2 folds this into the v2 unicast
106421
+ // `intendedFor`, so identityDeliversTo's both-sides-session branch excludes a
106422
+ // sibling coordinator session on the same daemon. Absent (legacy requester) →
106423
+ // session-less intendedFor → daemon-level delivery exactly as before.
106424
+ ...handle.targetCoordinatorSessionId ? { targetCoordinatorSessionId: handle.targetCoordinatorSessionId } : {}
106165
106425
  };
106166
106426
  if (typeof self.deps.instanceManager?.getByCategory === "function") {
106167
106427
  const forwarded = handleMeshForwardEvent(
@@ -106185,6 +106445,14 @@ ${mergeTreeErr?.stderr || ""}`;
106185
106445
  // re-queued event self-fallbacks to THIS (the executing/worker)
106186
106446
  // daemon and the real coordinator's drain excludes it.
106187
106447
  ...handle.targetCoordinatorDaemonId ? { targetCoordinatorDaemonId: handle.targetCoordinatorDaemonId } : {},
106448
+ // REFINE-EVENT-SESSION-SCOPED-UNICAST: carry the SESSION half of the
106449
+ // return address across the relay as well. buildRelayMetadataEvent
106450
+ // reads meshCoordinatorSessionId (falling back to
106451
+ // targetCoordinatorSessionId), so both spellings are supplied.
106452
+ ...handle.targetCoordinatorSessionId ? {
106453
+ targetCoordinatorSessionId: handle.targetCoordinatorSessionId,
106454
+ meshCoordinatorSessionId: handle.targetCoordinatorSessionId
106455
+ } : {},
106188
106456
  ...slimResult ? { result: slimResult } : {}
106189
106457
  }
106190
106458
  );
@@ -107609,6 +107877,7 @@ ${e?.stderr || ""}`;
107609
107877
  startedAt: args.startedAt || (/* @__PURE__ */ new Date()).toISOString(),
107610
107878
  ...args.completedAt ? { completedAt: args.completedAt } : {},
107611
107879
  ...args.coordinatorDaemonId ? { targetCoordinatorDaemonId: args.coordinatorDaemonId } : {},
107880
+ ...args.coordinatorSessionId ? { targetCoordinatorSessionId: args.coordinatorSessionId } : {},
107612
107881
  eventDelivery: { pendingEvents: true, ledger: true },
107613
107882
  evidence: {
107614
107883
  pendingEventsCommand: "get_pending_mesh_events",
@@ -107638,9 +107907,16 @@ ${e?.stderr || ""}`;
107638
107907
  meshId: handle.meshId,
107639
107908
  nodeLabel: handle.batchLabel,
107640
107909
  nodeId: handle.batchLabel,
107641
- metadataEvent,
107910
+ metadataEvent: {
107911
+ ...metadataEvent,
107912
+ // REFINE-EVENT-SESSION-SCOPED-UNICAST — see queueRefineJobEvent.
107913
+ ...handle.targetCoordinatorSessionId ? { meshCoordinatorSessionId: handle.targetCoordinatorSessionId } : {}
107914
+ },
107642
107915
  queuedAt: Date.now(),
107643
- ...handle.targetCoordinatorDaemonId ? { targetCoordinatorDaemonId: handle.targetCoordinatorDaemonId } : {}
107916
+ ...handle.targetCoordinatorDaemonId ? { targetCoordinatorDaemonId: handle.targetCoordinatorDaemonId } : {},
107917
+ // THE FIX (batch half) — address the batch terminal event to the requesting
107918
+ // coordinator SESSION so a sibling session cannot consume it.
107919
+ ...handle.targetCoordinatorSessionId ? { targetCoordinatorSessionId: handle.targetCoordinatorSessionId } : {}
107644
107920
  };
107645
107921
  if (typeof self.deps.instanceManager?.getByCategory === "function") {
107646
107922
  const forwarded = handleMeshForwardEvent(
@@ -107658,6 +107934,12 @@ ${e?.stderr || ""}`;
107658
107934
  // the sessionless batch job's terminal event must stay targeted
107659
107935
  // at the originating coordinator, not self-fallback to this daemon.
107660
107936
  ...handle.targetCoordinatorDaemonId ? { targetCoordinatorDaemonId: handle.targetCoordinatorDaemonId } : {},
107937
+ // REFINE-EVENT-SESSION-SCOPED-UNICAST — session half of the return
107938
+ // address, both spellings (see queueRefineJobEvent).
107939
+ ...handle.targetCoordinatorSessionId ? {
107940
+ targetCoordinatorSessionId: handle.targetCoordinatorSessionId,
107941
+ meshCoordinatorSessionId: handle.targetCoordinatorSessionId
107942
+ } : {},
107661
107943
  ...result ? { result } : {}
107662
107944
  }
107663
107945
  );
@@ -107730,7 +108012,10 @@ ${e?.stderr || ""}`;
107730
108012
  completedAt,
107731
108013
  jobId: handle.jobId,
107732
108014
  interactionId: handle.interactionId,
107733
- coordinatorDaemonId: handle.targetCoordinatorDaemonId
108015
+ coordinatorDaemonId: handle.targetCoordinatorDaemonId,
108016
+ // REFINE-EVENT-SESSION-SCOPED-UNICAST — carry the requester's session onto the
108017
+ // terminal batch handle (see the single-node path).
108018
+ coordinatorSessionId: handle.targetCoordinatorSessionId
107734
108019
  });
107735
108020
  const terminal = { ...terminalHandle, result: normalizedResult };
107736
108021
  self.terminalRefineBatchJobs.set(key2, terminal);
@@ -107764,7 +108049,8 @@ ${e?.stderr || ""}`;
107764
108049
  rationale: planRecord.orderingRationale
107765
108050
  };
107766
108051
  const coordinatorDaemonId = typeof args?.coordinatorDaemonId === "string" && args.coordinatorDaemonId.trim() ? args.coordinatorDaemonId.trim() : self.deps.statusInstanceId || void 0;
107767
- const handle = buildRefineBatchJobHandle(self, { meshId, nodeIds, order, coordinatorDaemonId });
108052
+ const coordinatorSessionId = typeof args?.coordinatorSessionId === "string" && args.coordinatorSessionId.trim() ? args.coordinatorSessionId.trim() : void 0;
108053
+ const handle = buildRefineBatchJobHandle(self, { meshId, nodeIds, order, coordinatorDaemonId, coordinatorSessionId });
107768
108054
  self.runningRefineBatchJobs.set(key2, handle);
107769
108055
  await appendRefineBatchJobLedger(self, "task_dispatched", handle);
107770
108056
  queueRefineBatchJobEvent(self, "refine:accepted", handle);
@@ -107855,7 +108141,12 @@ ${e?.stderr || ""}`;
107855
108141
  interactionId: handle.interactionId,
107856
108142
  retryOfJobId: handle.retryOfJobId,
107857
108143
  node: { daemonId: handle.targetDaemonId, workspace: handle.workspace },
107858
- coordinatorDaemonId: handle.targetCoordinatorDaemonId
108144
+ coordinatorDaemonId: handle.targetCoordinatorDaemonId,
108145
+ // REFINE-EVENT-SESSION-SCOPED-UNICAST: carry the requester's session from the
108146
+ // accepted handle onto the TERMINAL handle. Dropping it here would leave the
108147
+ // completed/failed event — the one the coordinator actually waits on — back at
108148
+ // daemon-level addressing, i.e. the original defect.
108149
+ coordinatorSessionId: handle.targetCoordinatorSessionId
107859
108150
  });
107860
108151
  const terminal = { ...terminalHandle, result: normalizedResult };
107861
108152
  self.terminalRefineJobs.set(key2, terminal);
@@ -107875,7 +108166,8 @@ ${e?.stderr || ""}`;
107875
108166
  if (!node) return { success: false, error: `Node '${nodeId}' not found in mesh` };
107876
108167
  if (!node.isLocalWorktree || !node.workspace) return { success: false, error: `Refinery requires a local worktree node` };
107877
108168
  const coordinatorDaemonId = typeof args?.coordinatorDaemonId === "string" && args.coordinatorDaemonId.trim() ? args.coordinatorDaemonId.trim() : self.deps.statusInstanceId || void 0;
107878
- const handle = buildRefineJobHandle(self, { meshId, nodeId, node, retryOfJobId: terminal?.jobId, coordinatorDaemonId });
108169
+ const coordinatorSessionId = typeof args?.coordinatorSessionId === "string" && args.coordinatorSessionId.trim() ? args.coordinatorSessionId.trim() : void 0;
108170
+ const handle = buildRefineJobHandle(self, { meshId, nodeId, node, retryOfJobId: terminal?.jobId, coordinatorDaemonId, coordinatorSessionId });
107879
108171
  self.runningRefineJobs.set(key2, handle);
107880
108172
  await appendRefineJobLedger(self, "task_dispatched", handle);
107881
108173
  queueRefineJobEvent(self, "refine:accepted", handle);