@adhdev/daemon-standalone 1.0.29-rc.2 → 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 ? "970517bde86bb64ddf4944f4676a0b7aa3e0ecd6" : void 0) ?? "unknown";
33315
- const commitShort = readInjected(true ? "970517bd" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
33316
- const version2 = readInjected(true ? "1.0.29-rc.2" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
33317
- const builtAt = readInjected(true ? "2026-08-01T12:48:29.542Z" : 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
  }
@@ -36155,20 +36155,40 @@ ${error48.message || ""}`;
36155
36155
  let hostDaemonId = readString3(raw?.hostDaemonId);
36156
36156
  let hostNodeId = readString3(raw?.hostNodeId);
36157
36157
  const hostAddress = readString3(raw?.hostAddress);
36158
+ let hostSynthesized = false;
36159
+ const nodes = Array.isArray(meshRecord?.nodes) ? meshRecord.nodes : [];
36160
+ const nodeDaemonIdOf = (node) => {
36161
+ const record2 = readObject(node);
36162
+ return readString3(record2?.daemonId) ?? readString3(record2?.daemon_id);
36163
+ };
36164
+ if (role === "host" && !hostDaemonId) {
36165
+ const declaredHostNode = nodes.find((n) => normalizeMeshDaemonRole(readObject(n)?.role) === "host");
36166
+ if (declaredHostNode) {
36167
+ const declaredDaemonId = nodeDaemonIdOf(declaredHostNode);
36168
+ if (declaredDaemonId) {
36169
+ hostDaemonId = declaredDaemonId;
36170
+ if (!hostNodeId) hostNodeId = readString3(readObject(declaredHostNode)?.id);
36171
+ }
36172
+ }
36173
+ }
36158
36174
  const localDaemonId = readString3(opts?.localDaemonId);
36159
- if (role === "host" && !hostDaemonId && localDaemonId) {
36175
+ const hasForeignDaemonNode = localDaemonId ? nodes.some((n) => {
36176
+ const nodeDaemonId = nodeDaemonIdOf(n);
36177
+ return nodeDaemonId ? !daemonIdsEquivalent(nodeDaemonId, localDaemonId) : false;
36178
+ }) : false;
36179
+ if (role === "host" && !hostDaemonId && !hostNodeId && localDaemonId && !hasForeignDaemonNode) {
36160
36180
  hostDaemonId = localDaemonId;
36161
- if (!hostNodeId && Array.isArray(meshRecord?.nodes)) {
36162
- const selfNode = meshRecord.nodes.find((n) => {
36163
- const nodeDaemonId = readString3(readObject(n)?.daemonId);
36164
- return nodeDaemonId ? daemonIdsEquivalent(nodeDaemonId, localDaemonId) : false;
36165
- });
36166
- const selfNodeId = readString3(readObject(selfNode)?.id);
36167
- if (selfNodeId) hostNodeId = selfNodeId;
36168
- }
36181
+ hostSynthesized = true;
36182
+ const selfNode = nodes.find((n) => {
36183
+ const nodeDaemonId = nodeDaemonIdOf(n);
36184
+ return nodeDaemonId ? daemonIdsEquivalent(nodeDaemonId, localDaemonId) : false;
36185
+ });
36186
+ const selfNodeId = readString3(readObject(selfNode)?.id);
36187
+ if (selfNodeId) hostNodeId = selfNodeId;
36169
36188
  }
36170
36189
  if (hostDaemonId) normalized.hostDaemonId = hostDaemonId;
36171
36190
  if (hostNodeId) normalized.hostNodeId = hostNodeId;
36191
+ if (hostSynthesized) normalized.hostSynthesized = true;
36172
36192
  if (hostAddress) normalized.hostAddress = hostAddress;
36173
36193
  if (pairing) {
36174
36194
  const status = pairing.status === "pairing" || pairing.status === "paired" || pairing.status === "rejected" || pairing.status === "revoked" ? pairing.status : "not_configured";
@@ -36238,6 +36258,7 @@ ${error48.message || ""}`;
36238
36258
  resolveScopedMeshId: () => resolveScopedMeshId,
36239
36259
  setDifficultyBrains: () => setDifficultyBrains,
36240
36260
  setMagiKindPanel: () => setMagiKindPanel,
36261
+ setMeshHostPin: () => setMeshHostPin,
36241
36262
  tokenIdForManualPairing: () => tokenIdForManualPairing,
36242
36263
  updateMesh: () => updateMesh,
36243
36264
  updateNode: () => updateNode
@@ -36404,7 +36425,11 @@ ${error48.message || ""}`;
36404
36425
  defaultBranch: opts.defaultBranch,
36405
36426
  policy: mergeMeshPolicy(void 0, opts.policy),
36406
36427
  coordinator: opts.coordinator || {},
36407
- 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
+ })(),
36408
36433
  nodes: [],
36409
36434
  createdAt: now,
36410
36435
  updatedAt: now
@@ -36590,6 +36615,86 @@ ${error48.message || ""}`;
36590
36615
  saveMeshConfig(config2);
36591
36616
  return { accepted: true, mesh, meshHost: mesh.meshHost, node, tokenId: validation.tokenId };
36592
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
+ }
36593
36698
  function markMeshHostPairingJoined(meshId, opts) {
36594
36699
  const config2 = loadMeshConfig();
36595
36700
  const mesh = config2.meshes.find((m) => m.id === meshId);
@@ -36650,6 +36755,12 @@ ${error48.message || ""}`;
36650
36755
  worktreeBootstrap: opts.worktreeBootstrap,
36651
36756
  role: opts.role
36652
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
+ }
36653
36764
  mesh.nodes.push(node);
36654
36765
  mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
36655
36766
  saveMeshConfig(config2);
@@ -39372,9 +39483,20 @@ Next step: ${nextStep}`;
39372
39483
  }
39373
39484
  continue;
39374
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
+ }
39375
39496
  if (validated.intendedFor && identityDeliversTo(validated.intendedFor, drainer)) {
39376
39497
  ctx.batchSeen.add(eventId);
39377
39498
  bump("v2Delivered");
39499
+ LOG2.debug("MeshEventsV2", `unicast ${event.event} (mesh ${event.meshId}, eventId ${eventId}) delivered to ${coordinatorIdentityKey(drainer)}; intendedFor=${coordinatorIdentityKey(validated.intendedFor)}`);
39378
39500
  kept.push(event);
39379
39501
  continue;
39380
39502
  }
@@ -39389,6 +39511,7 @@ Next step: ${nextStep}`;
39389
39511
  kept.push(event);
39390
39512
  continue;
39391
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`);
39392
39515
  bump("v2RoutedAway");
39393
39516
  }
39394
39517
  return kept;
@@ -39841,7 +39964,12 @@ Next step: ${nextStep}`;
39841
39964
  try {
39842
39965
  const store = MeshRuntimeStore.getInstance();
39843
39966
  if (store.pendingEventCount(meshId) > 0) {
39844
- 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
+ )) {
39845
39973
  const event = row.payload;
39846
39974
  if (event) pushUnique(event);
39847
39975
  }
@@ -39880,7 +40008,8 @@ Next step: ${nextStep}`;
39880
40008
  const routed = routeV2EventsForDrainer(merged, drainer, {
39881
40009
  alreadyDrained: (eventId) => priorDrainedEventIds.has(eventId),
39882
40010
  batchSeen: /* @__PURE__ */ new Set(),
39883
- countMetrics: true
40011
+ countMetrics: true,
40012
+ ...opts?.countLiveCoordinatorSessions ? { countLiveCoordinatorSessions: opts.countLiveCoordinatorSessions } : {}
39884
40013
  });
39885
40014
  return reconcilePendingMeshCoordinatorEvents(meshId, routed);
39886
40015
  }
@@ -40100,6 +40229,11 @@ Next step: ${nextStep}`;
40100
40229
  /** unicast events re-attributed to the drainer via daemon-core match (a
40101
40230
  * coordinatorRunId change orphaned them). */
40102
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,
40103
40237
  /** v1 (unversioned) events passed through as broadcast (rollout baseline). */
40104
40238
  v1BroadcastAccepted: 0,
40105
40239
  /** T6 enforce: v2 events that FAILED validation and were QUARANTINED (held back
@@ -41858,7 +41992,15 @@ Next step: ${nextStep}`;
41858
41992
  event_id TEXT,
41859
41993
  scope TEXT,
41860
41994
  dispatched_by TEXT,
41861
- 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
41862
42004
  );
41863
42005
 
41864
42006
  CREATE INDEX IF NOT EXISTS idx_mesh_pending_events_mesh_drained
@@ -42104,7 +42246,7 @@ Next step: ${nextStep}`;
42104
42246
  this.db.exec(`ALTER TABLE mesh_missions ADD COLUMN close_candidate_emitted_at TEXT`);
42105
42247
  }
42106
42248
  const pendingCols = this.tableColumns("mesh_pending_events");
42107
- 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"]) {
42108
42250
  if (!pendingCols.has(col)) {
42109
42251
  this.db.exec(`ALTER TABLE mesh_pending_events ADD COLUMN ${col} TEXT`);
42110
42252
  }
@@ -43373,8 +43515,8 @@ Next step: ${nextStep}`;
43373
43515
  const ids = rows.map((r) => r.id);
43374
43516
  const now = Date.now();
43375
43517
  this.db.prepare(
43376
- `UPDATE mesh_pending_events SET drained = 1, drained_at = ? WHERE id IN (${ids.map(() => "?").join(",")})`
43377
- ).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);
43378
43520
  return rows.map((r) => ({
43379
43521
  id: r.id,
43380
43522
  event: r.event,
@@ -43408,6 +43550,30 @@ Next step: ${nextStep}`;
43408
43550
  })()
43409
43551
  }));
43410
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
+ }
43411
43577
  hasPendingEventFingerprint(meshId, fingerprint) {
43412
43578
  const row = this.db.prepare(
43413
43579
  "SELECT 1 FROM mesh_pending_events WHERE mesh_id = ? AND fingerprint = ? AND drained = 0 LIMIT 1"
@@ -43582,7 +43748,7 @@ Next step: ${nextStep}`;
43582
43748
  requeueDrainedPendingEventByFingerprint(meshId, fingerprint) {
43583
43749
  if (!fingerprint) return false;
43584
43750
  const changes = this.db.prepare(
43585
- `UPDATE mesh_pending_events SET drained = 0, drained_at = NULL
43751
+ `UPDATE mesh_pending_events SET drained = 0, drained_at = NULL, drained_by = NULL
43586
43752
  WHERE mesh_id = ? AND fingerprint = ? AND drained = 1`
43587
43753
  ).run(meshId, fingerprint).changes;
43588
43754
  if (changes > 0) this.maybeCheckpointWal();
@@ -61494,7 +61660,15 @@ ${cleanBody}`;
61494
61660
  try {
61495
61661
  pendingEvents = drainPendingMeshCoordinatorEvents(
61496
61662
  meshId,
61497
- 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
+ }
61498
61672
  );
61499
61673
  } catch (e) {
61500
61674
  LOG2.warn("MeshReconcile", `Drain failed for mesh ${meshId}: ${e?.message || e}`);
@@ -101123,7 +101297,7 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
101123
101297
  }
101124
101298
  return { success: true, mesh: meshRecord.mesh, sourceOfTruth };
101125
101299
  },
101126
- create_mesh: async (_ctx, args) => {
101300
+ create_mesh: async (ctx, args) => {
101127
101301
  const name = typeof args?.name === "string" ? args.name.trim() : "";
101128
101302
  const repoIdentity = typeof args?.repoIdentity === "string" ? args.repoIdentity.trim() : "";
101129
101303
  const repoRemoteUrl = typeof args?.repoRemoteUrl === "string" ? args.repoRemoteUrl.trim() : void 0;
@@ -101132,12 +101306,71 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
101132
101306
  try {
101133
101307
  const { createMesh: createMesh2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
101134
101308
  const meshHost = args?.meshHost && typeof args.meshHost === "object" && !Array.isArray(args.meshHost) ? args.meshHost : void 0;
101135
- 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
+ });
101136
101319
  return { success: true, mesh };
101137
101320
  } catch (e) {
101138
101321
  return { success: false, error: e.message };
101139
101322
  }
101140
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
+ },
101141
101374
  update_mesh: async (ctx, args) => {
101142
101375
  const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
101143
101376
  if (!meshId) return { success: false, error: "meshId required" };
@@ -103082,6 +103315,26 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
103082
103315
  init_mesh_coordinator();
103083
103316
  init_dist();
103084
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
+ }
103085
103338
  var meshCoordinatorLaunchHandlers = {
103086
103339
  launch_mesh_coordinator: async (ctx, args) => {
103087
103340
  const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
@@ -103441,6 +103694,12 @@ ${ptyResult.output.slice(-2e3)}`);
103441
103694
  });
103442
103695
  } catch {
103443
103696
  }
103697
+ await backfillMeshHostPinAfterLaunch({
103698
+ meshId,
103699
+ mesh,
103700
+ coordinatorNode,
103701
+ localDaemonId: ctx.deps.statusInstanceId
103702
+ });
103444
103703
  return {
103445
103704
  success: true,
103446
103705
  meshId,
@@ -103639,6 +103898,12 @@ ${ptyResult.output.slice(-2e3)}`);
103639
103898
  });
103640
103899
  } catch {
103641
103900
  }
103901
+ await backfillMeshHostPinAfterLaunch({
103902
+ meshId,
103903
+ mesh,
103904
+ coordinatorNode,
103905
+ localDaemonId: ctx.deps.statusInstanceId
103906
+ });
103642
103907
  return {
103643
103908
  success: true,
103644
103909
  meshId,
@@ -106041,6 +106306,7 @@ ${mergeTreeErr?.stderr || ""}`;
106041
106306
  ...args.completedAt ? { completedAt: args.completedAt } : {},
106042
106307
  ...args.retryOfJobId ? { retryOfJobId: args.retryOfJobId } : {},
106043
106308
  ...args.coordinatorDaemonId ? { targetCoordinatorDaemonId: args.coordinatorDaemonId } : {},
106309
+ ...args.coordinatorSessionId ? { targetCoordinatorSessionId: args.coordinatorSessionId } : {},
106044
106310
  eventDelivery: { pendingEvents: true, ledger: true },
106045
106311
  evidence: {
106046
106312
  pendingEventsCommand: "get_pending_mesh_events",
@@ -106139,9 +106405,23 @@ ${mergeTreeErr?.stderr || ""}`;
106139
106405
  nodeLabel: handle.targetNodeId,
106140
106406
  nodeId: handle.targetNodeId,
106141
106407
  workspace: handle.workspace,
106142
- 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
+ },
106143
106417
  queuedAt: Date.now(),
106144
- ...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 } : {}
106145
106425
  };
106146
106426
  if (typeof self.deps.instanceManager?.getByCategory === "function") {
106147
106427
  const forwarded = handleMeshForwardEvent(
@@ -106165,6 +106445,14 @@ ${mergeTreeErr?.stderr || ""}`;
106165
106445
  // re-queued event self-fallbacks to THIS (the executing/worker)
106166
106446
  // daemon and the real coordinator's drain excludes it.
106167
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
+ } : {},
106168
106456
  ...slimResult ? { result: slimResult } : {}
106169
106457
  }
106170
106458
  );
@@ -107589,6 +107877,7 @@ ${e?.stderr || ""}`;
107589
107877
  startedAt: args.startedAt || (/* @__PURE__ */ new Date()).toISOString(),
107590
107878
  ...args.completedAt ? { completedAt: args.completedAt } : {},
107591
107879
  ...args.coordinatorDaemonId ? { targetCoordinatorDaemonId: args.coordinatorDaemonId } : {},
107880
+ ...args.coordinatorSessionId ? { targetCoordinatorSessionId: args.coordinatorSessionId } : {},
107592
107881
  eventDelivery: { pendingEvents: true, ledger: true },
107593
107882
  evidence: {
107594
107883
  pendingEventsCommand: "get_pending_mesh_events",
@@ -107618,9 +107907,16 @@ ${e?.stderr || ""}`;
107618
107907
  meshId: handle.meshId,
107619
107908
  nodeLabel: handle.batchLabel,
107620
107909
  nodeId: handle.batchLabel,
107621
- metadataEvent,
107910
+ metadataEvent: {
107911
+ ...metadataEvent,
107912
+ // REFINE-EVENT-SESSION-SCOPED-UNICAST — see queueRefineJobEvent.
107913
+ ...handle.targetCoordinatorSessionId ? { meshCoordinatorSessionId: handle.targetCoordinatorSessionId } : {}
107914
+ },
107622
107915
  queuedAt: Date.now(),
107623
- ...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 } : {}
107624
107920
  };
107625
107921
  if (typeof self.deps.instanceManager?.getByCategory === "function") {
107626
107922
  const forwarded = handleMeshForwardEvent(
@@ -107638,6 +107934,12 @@ ${e?.stderr || ""}`;
107638
107934
  // the sessionless batch job's terminal event must stay targeted
107639
107935
  // at the originating coordinator, not self-fallback to this daemon.
107640
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
+ } : {},
107641
107943
  ...result ? { result } : {}
107642
107944
  }
107643
107945
  );
@@ -107710,7 +108012,10 @@ ${e?.stderr || ""}`;
107710
108012
  completedAt,
107711
108013
  jobId: handle.jobId,
107712
108014
  interactionId: handle.interactionId,
107713
- 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
107714
108019
  });
107715
108020
  const terminal = { ...terminalHandle, result: normalizedResult };
107716
108021
  self.terminalRefineBatchJobs.set(key2, terminal);
@@ -107744,7 +108049,8 @@ ${e?.stderr || ""}`;
107744
108049
  rationale: planRecord.orderingRationale
107745
108050
  };
107746
108051
  const coordinatorDaemonId = typeof args?.coordinatorDaemonId === "string" && args.coordinatorDaemonId.trim() ? args.coordinatorDaemonId.trim() : self.deps.statusInstanceId || void 0;
107747
- 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 });
107748
108054
  self.runningRefineBatchJobs.set(key2, handle);
107749
108055
  await appendRefineBatchJobLedger(self, "task_dispatched", handle);
107750
108056
  queueRefineBatchJobEvent(self, "refine:accepted", handle);
@@ -107835,7 +108141,12 @@ ${e?.stderr || ""}`;
107835
108141
  interactionId: handle.interactionId,
107836
108142
  retryOfJobId: handle.retryOfJobId,
107837
108143
  node: { daemonId: handle.targetDaemonId, workspace: handle.workspace },
107838
- 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
107839
108150
  });
107840
108151
  const terminal = { ...terminalHandle, result: normalizedResult };
107841
108152
  self.terminalRefineJobs.set(key2, terminal);
@@ -107855,7 +108166,8 @@ ${e?.stderr || ""}`;
107855
108166
  if (!node) return { success: false, error: `Node '${nodeId}' not found in mesh` };
107856
108167
  if (!node.isLocalWorktree || !node.workspace) return { success: false, error: `Refinery requires a local worktree node` };
107857
108168
  const coordinatorDaemonId = typeof args?.coordinatorDaemonId === "string" && args.coordinatorDaemonId.trim() ? args.coordinatorDaemonId.trim() : self.deps.statusInstanceId || void 0;
107858
- 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 });
107859
108171
  self.runningRefineJobs.set(key2, handle);
107860
108172
  await appendRefineJobLedger(self, "task_dispatched", handle);
107861
108173
  queueRefineJobEvent(self, "refine:accepted", handle);