@adhdev/daemon-core 0.9.82-rc.387 → 0.9.82-rc.389

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.mjs CHANGED
@@ -378,10 +378,10 @@ function readInjected(value) {
378
378
  }
379
379
  function getDaemonBuildInfo() {
380
380
  if (cached) return cached;
381
- const commit = readInjected(true ? "057d5def5d55af124dfe910ee9accdf244576c14" : void 0) ?? "unknown";
382
- const commitShort = readInjected(true ? "057d5def" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
383
- const version = readInjected(true ? "0.9.82-rc.387" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
384
- const builtAt = readInjected(true ? "2026-06-26T02:21:27.575Z" : void 0);
381
+ const commit = readInjected(true ? "f82b4b4cdb13171d2666cc959054b788af4f2ea5" : void 0) ?? "unknown";
382
+ const commitShort = readInjected(true ? "f82b4b4c" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
383
+ const version = readInjected(true ? "0.9.82-rc.389" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
384
+ const builtAt = readInjected(true ? "2026-06-26T06:17:18.789Z" : void 0);
385
385
  cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
386
386
  return cached;
387
387
  }
@@ -4549,9 +4549,16 @@ function isInsideQuotedSpan(text, matchStart, matchEnd) {
4549
4549
  }
4550
4550
  return false;
4551
4551
  }
4552
+ function isGluedToLetterSuffix(text, matchStart, matchEnd) {
4553
+ const letterOrMark = /[\p{L}\p{M}]/u;
4554
+ const next = matchEnd < text.length ? text[matchEnd] : "";
4555
+ const prev = matchStart > 0 ? text[matchStart - 1] : "";
4556
+ return letterOrMark.test(next) || letterOrMark.test(prev);
4557
+ }
4552
4558
  function isRealMutationMatch(text, matchStart, matchEnd) {
4553
4559
  if (hasNegationBefore(text, matchStart)) return false;
4554
4560
  if (hasTrailingNegation(text, matchEnd)) return false;
4561
+ if (isGluedToLetterSuffix(text, matchStart, matchEnd)) return false;
4555
4562
  if (isInsidePathSegment(text, matchStart, matchEnd)) return false;
4556
4563
  if (isInsideQuotedSpan(text, matchStart, matchEnd)) return false;
4557
4564
  return isMutationKeywordInCommandContext(text, matchStart, matchEnd);
@@ -5257,10 +5264,20 @@ var init_mesh_runtime_store = __esm({
5257
5264
  CREATE INDEX IF NOT EXISTS idx_mesh_queue_assignment
5258
5265
  ON mesh_queue(mesh_id, assigned_node_id, assigned_session_id, status);
5259
5266
 
5267
+ -- mesh_id is DB-level isolation (defense-in-depth). The fingerprint STRING
5268
+ -- also carries meshId as its first '::'-joined segment (see
5269
+ -- buildMeshCompletionFingerprint) \u2014 that string-prefix defense is kept; this
5270
+ -- column makes cross-mesh suppression impossible even if the string format
5271
+ -- drifts or two meshes ever collide on a fingerprint body.
5260
5272
  CREATE TABLE IF NOT EXISTS mesh_completion_fingerprints (
5261
5273
  fingerprint TEXT PRIMARY KEY,
5262
- expires_at INTEGER NOT NULL
5274
+ expires_at INTEGER NOT NULL,
5275
+ mesh_id TEXT NOT NULL DEFAULT ''
5263
5276
  );
5277
+ -- NOTE: the (mesh_id, fingerprint) index is created in migrateMeshIsolationColumns,
5278
+ -- NOT here. A pre-isolation DB still has the legacy table (CREATE IF NOT EXISTS is a
5279
+ -- no-op), so referencing mesh_id in an index before the ALTER ADD COLUMN runs would
5280
+ -- fail with "no such column". The migration adds the column then the index.
5264
5281
 
5265
5282
  CREATE TABLE IF NOT EXISTS mesh_direct_dispatches (
5266
5283
  task_id TEXT PRIMARY KEY,
@@ -5280,13 +5297,18 @@ var init_mesh_runtime_store = __esm({
5280
5297
  CREATE INDEX IF NOT EXISTS idx_direct_dispatches_mesh_session
5281
5298
  ON mesh_direct_dispatches(mesh_id, session_id, status);
5282
5299
 
5300
+ -- MESH-ISOLATION-LEAK: mesh_id is part of the PK so a nodeId shared across two
5301
+ -- meshes (same machine in multiple repos) keeps a separate idle-session row per
5302
+ -- mesh, and getRemoteIdleSessions(meshId) can never surface another mesh's
5303
+ -- session for a queue claim.
5283
5304
  CREATE TABLE IF NOT EXISTS remote_idle_sessions (
5305
+ mesh_id TEXT NOT NULL,
5284
5306
  node_id TEXT NOT NULL,
5285
5307
  session_id TEXT NOT NULL,
5286
5308
  provider_type TEXT NOT NULL,
5287
5309
  expires_at INTEGER NOT NULL,
5288
5310
  metadata TEXT,
5289
- PRIMARY KEY (node_id, session_id)
5311
+ PRIMARY KEY (mesh_id, node_id, session_id)
5290
5312
  );
5291
5313
 
5292
5314
  CREATE TABLE IF NOT EXISTS mesh_session_delivery (
@@ -5410,19 +5432,67 @@ var init_mesh_runtime_store = __esm({
5410
5432
  cursor INTEGER NOT NULL DEFAULT 0
5411
5433
  );
5412
5434
  `);
5435
+ this.migrateMeshIsolationColumns();
5413
5436
  }
5414
- hasCompletionFingerprint(fingerprint) {
5437
+ tableColumns(table) {
5438
+ const rows = this.db.prepare(`PRAGMA table_info(${table})`).all();
5439
+ return new Set(rows.map((r) => r.name));
5440
+ }
5441
+ /**
5442
+ * MESH-ISOLATION-LEAK migration. Two tables historically lacked a `mesh_id` column,
5443
+ * letting one machine that belongs to multiple meshes (multiple repos) leak rows
5444
+ * across meshes. Both migrations are idempotent and run on every boot — the column
5445
+ * check short-circuits once the new schema is in place.
5446
+ */
5447
+ migrateMeshIsolationColumns() {
5448
+ try {
5449
+ const fpCols = this.tableColumns("mesh_completion_fingerprints");
5450
+ if (!fpCols.has("mesh_id")) {
5451
+ this.db.exec(`ALTER TABLE mesh_completion_fingerprints ADD COLUMN mesh_id TEXT NOT NULL DEFAULT ''`);
5452
+ this.db.exec(`
5453
+ UPDATE mesh_completion_fingerprints
5454
+ SET mesh_id = substr(fingerprint, 1, instr(fingerprint, '::') - 1)
5455
+ WHERE instr(fingerprint, '::') > 0 AND mesh_id = ''
5456
+ `);
5457
+ }
5458
+ this.db.exec(`
5459
+ CREATE INDEX IF NOT EXISTS idx_mesh_completion_fingerprints_mesh
5460
+ ON mesh_completion_fingerprints(mesh_id, fingerprint)
5461
+ `);
5462
+ const idleCols = this.tableColumns("remote_idle_sessions");
5463
+ if (!idleCols.has("mesh_id")) {
5464
+ this.db.exec(`
5465
+ DROP TABLE IF EXISTS remote_idle_sessions;
5466
+ CREATE TABLE remote_idle_sessions (
5467
+ mesh_id TEXT NOT NULL,
5468
+ node_id TEXT NOT NULL,
5469
+ session_id TEXT NOT NULL,
5470
+ provider_type TEXT NOT NULL,
5471
+ expires_at INTEGER NOT NULL,
5472
+ metadata TEXT,
5473
+ PRIMARY KEY (mesh_id, node_id, session_id)
5474
+ );
5475
+ `);
5476
+ }
5477
+ } catch (err) {
5478
+ if (!loggedMigrationFailure) {
5479
+ loggedMigrationFailure = true;
5480
+ LOG.warn("MeshRuntimeStore", `mesh-isolation column migration failed: ${err?.message || err}`);
5481
+ }
5482
+ }
5483
+ }
5484
+ hasCompletionFingerprint(meshId, fingerprint) {
5415
5485
  const now = Date.now();
5416
- const row = this.db.prepare("SELECT 1 FROM mesh_completion_fingerprints WHERE fingerprint = ? AND expires_at > ?").get(fingerprint, now);
5486
+ const row = this.db.prepare("SELECT 1 FROM mesh_completion_fingerprints WHERE mesh_id = ? AND fingerprint = ? AND expires_at > ?").get(meshId, fingerprint, now);
5417
5487
  if (++this.fingerprintSweepCounter >= 100) {
5418
5488
  this.fingerprintSweepCounter = 0;
5419
5489
  this.sweepExpiredFingerprints();
5420
5490
  }
5421
5491
  return row !== void 0;
5422
5492
  }
5423
- recordCompletionFingerprint(fingerprint, ttlMs) {
5493
+ recordCompletionFingerprint(meshId, fingerprint, ttlMs) {
5424
5494
  const expiresAt = Date.now() + ttlMs;
5425
- this.db.prepare("INSERT OR REPLACE INTO mesh_completion_fingerprints (fingerprint, expires_at) VALUES (?, ?)").run(fingerprint, expiresAt);
5495
+ this.db.prepare("INSERT OR REPLACE INTO mesh_completion_fingerprints (fingerprint, expires_at, mesh_id) VALUES (?, ?, ?)").run(fingerprint, expiresAt, meshId);
5426
5496
  this.maybeCheckpointWal();
5427
5497
  }
5428
5498
  sweepExpiredFingerprints() {
@@ -5931,14 +6001,14 @@ var init_mesh_runtime_store = __esm({
5931
6001
  `).run(now, meshId, cutoff);
5932
6002
  }
5933
6003
  // ── Remote Idle Sessions ─────────────────────────────────────────────────
5934
- setRemoteIdleSession(nodeId, sessionId, providerType, expiresAt, metadata) {
6004
+ setRemoteIdleSession(meshId, nodeId, sessionId, providerType, expiresAt, metadata) {
5935
6005
  this.db.prepare(`
5936
- INSERT OR REPLACE INTO remote_idle_sessions (node_id, session_id, provider_type, expires_at, metadata)
5937
- VALUES (?, ?, ?, ?, ?)
5938
- `).run(nodeId, sessionId, providerType, expiresAt, metadata ? JSON.stringify(metadata) : null);
6006
+ INSERT OR REPLACE INTO remote_idle_sessions (mesh_id, node_id, session_id, provider_type, expires_at, metadata)
6007
+ VALUES (?, ?, ?, ?, ?, ?)
6008
+ `).run(meshId, nodeId, sessionId, providerType, expiresAt, metadata ? JSON.stringify(metadata) : null);
5939
6009
  }
5940
- getRemoteIdleSessions() {
5941
- const rows = this.db.prepare("SELECT node_id, session_id, provider_type, expires_at, metadata FROM remote_idle_sessions").all();
6010
+ getRemoteIdleSessions(meshId) {
6011
+ const rows = this.db.prepare("SELECT node_id, session_id, provider_type, expires_at, metadata FROM remote_idle_sessions WHERE mesh_id = ?").all(meshId);
5942
6012
  return rows.map((r) => ({
5943
6013
  nodeId: r.node_id,
5944
6014
  sessionId: r.session_id,
@@ -5947,8 +6017,8 @@ var init_mesh_runtime_store = __esm({
5947
6017
  metadata: r.metadata ? JSON.parse(r.metadata) : void 0
5948
6018
  }));
5949
6019
  }
5950
- deleteRemoteIdleSession(nodeId, sessionId) {
5951
- this.db.prepare("DELETE FROM remote_idle_sessions WHERE node_id = ? AND session_id = ?").run(nodeId, sessionId);
6020
+ deleteRemoteIdleSession(meshId, nodeId, sessionId) {
6021
+ this.db.prepare("DELETE FROM remote_idle_sessions WHERE mesh_id = ? AND node_id = ? AND session_id = ?").run(meshId, nodeId, sessionId);
5952
6022
  }
5953
6023
  pruneExpiredRemoteIdleSessions() {
5954
6024
  this.db.prepare("DELETE FROM remote_idle_sessions WHERE expires_at <= ?").run(Date.now());
@@ -11319,7 +11389,7 @@ async function triggerMeshQueue(components, meshId) {
11319
11389
  }
11320
11390
  let remoteSessions = [];
11321
11391
  try {
11322
- remoteSessions = MeshRuntimeStore.getInstance().getRemoteIdleSessions();
11392
+ remoteSessions = MeshRuntimeStore.getInstance().getRemoteIdleSessions(meshId);
11323
11393
  } catch {
11324
11394
  }
11325
11395
  const remoteCandidates = [];
@@ -11334,7 +11404,7 @@ async function triggerMeshQueue(components, meshId) {
11334
11404
  const assigned = tryAssignQueueTask(components, meshId, candidate.nodeId, candidate.sessionId, candidate.providerType);
11335
11405
  if (assigned && candidate.origin === "remote") {
11336
11406
  try {
11337
- MeshRuntimeStore.getInstance().deleteRemoteIdleSession(candidate.nodeId, candidate.sessionId);
11407
+ MeshRuntimeStore.getInstance().deleteRemoteIdleSession(meshId, candidate.nodeId, candidate.sessionId);
11338
11408
  } catch {
11339
11409
  }
11340
11410
  }
@@ -14088,17 +14158,17 @@ function shouldSuppressIntentionalCleanupStop(args) {
14088
14158
  if (isIntentionalCleanupStopMetadata(args.metadataEvent)) return true;
14089
14159
  return hasRecentIntentionalCleanupStop(args.meshId, args.sessionId, args.nodeId);
14090
14160
  }
14091
- function hasFingerprintSeen(fingerprint) {
14161
+ function hasFingerprintSeen(meshId, fingerprint) {
14092
14162
  try {
14093
- return MeshRuntimeStore.getInstance().hasCompletionFingerprint(fingerprint);
14163
+ return MeshRuntimeStore.getInstance().hasCompletionFingerprint(meshId, fingerprint);
14094
14164
  } catch {
14095
14165
  return false;
14096
14166
  }
14097
14167
  }
14098
- function recordFingerprintSeen(fingerprint) {
14168
+ function recordFingerprintSeen(meshId, fingerprint) {
14099
14169
  try {
14100
14170
  const db = MeshRuntimeStore.getInstance();
14101
- db.recordCompletionFingerprint(fingerprint, RECENT_COMPLETION_FINGERPRINT_TTL_MS);
14171
+ db.recordCompletionFingerprint(meshId, fingerprint, RECENT_COMPLETION_FINGERPRINT_TTL_MS);
14102
14172
  db.sweepExpiredFingerprints();
14103
14173
  } catch {
14104
14174
  }
@@ -14128,7 +14198,7 @@ function buildMeshCompletionFingerprint(args) {
14128
14198
  function isDuplicateMeshCompletionEvent(args) {
14129
14199
  const fingerprint = buildMeshCompletionFingerprint(args);
14130
14200
  if (!fingerprint) return false;
14131
- if (hasFingerprintSeen(fingerprint)) {
14201
+ if (hasFingerprintSeen(args.meshId, fingerprint)) {
14132
14202
  if (args.taskId) {
14133
14203
  recordCompletionConflict({
14134
14204
  meshId: args.meshId,
@@ -14140,7 +14210,7 @@ function isDuplicateMeshCompletionEvent(args) {
14140
14210
  }
14141
14211
  return true;
14142
14212
  }
14143
- recordFingerprintSeen(fingerprint);
14213
+ recordFingerprintSeen(args.meshId, fingerprint);
14144
14214
  return false;
14145
14215
  }
14146
14216
  function isDuplicateMeshApprovalEvent(args) {
@@ -14154,16 +14224,16 @@ function isDuplicateMeshApprovalEvent(args) {
14154
14224
  args.providerType || "",
14155
14225
  approvalIdentity
14156
14226
  ].join("::");
14157
- if (hasFingerprintSeen(fingerprint)) return true;
14158
- recordFingerprintSeen(fingerprint);
14227
+ if (hasFingerprintSeen(args.meshId, fingerprint)) return true;
14228
+ recordFingerprintSeen(args.meshId, fingerprint);
14159
14229
  return false;
14160
14230
  }
14161
14231
  function isDuplicateRefineTerminalEvent(meshId, eventName, metadataEvent) {
14162
14232
  const jobId = readRefineJobId({ metadataEvent });
14163
14233
  const fingerprint = jobId && (/* @__PURE__ */ new Set(["refine:completed", "refine:failed"])).has(eventName) ? `${meshId}::${eventName}::${jobId}` : "";
14164
14234
  if (!fingerprint) return false;
14165
- if (hasFingerprintSeen(fingerprint)) return true;
14166
- recordFingerprintSeen(fingerprint);
14235
+ if (hasFingerprintSeen(meshId, fingerprint)) return true;
14236
+ recordFingerprintSeen(meshId, fingerprint);
14167
14237
  return false;
14168
14238
  }
14169
14239
  function isSynthesizedReconciledTerminal(terminalPayload) {
@@ -14217,7 +14287,7 @@ function evaluateMeshEventSuppression(args, ctx) {
14217
14287
  if (intentionalCleanupStop) {
14218
14288
  if (eventSessionId && eventNodeId) {
14219
14289
  try {
14220
- MeshRuntimeStore.getInstance().deleteRemoteIdleSession(eventNodeId, eventSessionId);
14290
+ MeshRuntimeStore.getInstance().deleteRemoteIdleSession(args.meshId, eventNodeId, eventSessionId);
14221
14291
  } catch {
14222
14292
  }
14223
14293
  }
@@ -14290,7 +14360,7 @@ function evaluateMeshEventSuppression(args, ctx) {
14290
14360
  terminalTaskId,
14291
14361
  eventTaskId
14292
14362
  });
14293
- const supersedesSynthesizedTerminal = isSynthesizedReconciledTerminal(terminal.payload) && isRealProviderCompletionEvent(args.metadataEvent) && isGenuineCompletionEvidence(args.metadataEvent);
14363
+ const supersedesSynthesizedTerminal = isSynthesizedReconciledTerminal(terminal.payload) && isRealProviderCompletionEvent(args.metadataEvent) && !isFalseIdleCompletion(args.metadataEvent);
14294
14364
  if (!newDispatchAfterTerminal && !supersedesWeakTerminal && !distinctTaskCompletion && !supersedesTruncatedTerminal && !supersedesSynthesizedTerminal) {
14295
14365
  const terminalProviderSessionId = readNonEmptyString2(terminal.payload.providerSessionId);
14296
14366
  const terminalFinalSummary = readNonEmptyString2(terminal.payload.finalSummary);
@@ -14433,7 +14503,25 @@ function injectMeshSystemMessage(components, args) {
14433
14503
  const isFalseIdle = isFalseIdleCompletion(args.metadataEvent);
14434
14504
  completedTaskForLedger = markSessionTerminal(sessionId, "completed", eventTimestamp, { tentativeIfDirect: isFalseIdle });
14435
14505
  if (nodeId && providerType) {
14436
- runIdleMaintenanceThenAssignQueue(components, { meshId: args.meshId, nodeId, sessionId, providerType });
14506
+ if (!isFalseIdle) {
14507
+ sweepExpiredRemoteIdleSessions();
14508
+ try {
14509
+ MeshRuntimeStore.getInstance().setRemoteIdleSession(args.meshId, nodeId, sessionId, providerType, Date.now() + REMOTE_IDLE_SESSION_TTL_MS);
14510
+ } catch {
14511
+ }
14512
+ setImmediate(() => {
14513
+ maybeAutoFastForwardIdleNode(components, { meshId: args.meshId, nodeId, sessionId, providerType }).finally(() => {
14514
+ try {
14515
+ const assigned = tryAssignQueueTask(components, args.meshId, nodeId, sessionId, providerType);
14516
+ if (assigned) MeshRuntimeStore.getInstance().deleteRemoteIdleSession(args.meshId, nodeId, sessionId);
14517
+ } catch (e) {
14518
+ LOG.warn("MeshQueue", `Failed to assign idle queue task after completion for ${nodeId}: ${e?.message || e}`);
14519
+ }
14520
+ });
14521
+ });
14522
+ } else {
14523
+ runIdleMaintenanceThenAssignQueue(components, { meshId: args.meshId, nodeId, sessionId, providerType });
14524
+ }
14437
14525
  }
14438
14526
  const completedTaskId = completedTaskForLedger?.id;
14439
14527
  if (completedTaskId && hasPendingDependents(args.meshId, completedTaskId)) {
@@ -14488,14 +14576,14 @@ function injectMeshSystemMessage(components, args) {
14488
14576
  if (sessionId && nodeId && providerType) {
14489
14577
  sweepExpiredRemoteIdleSessions();
14490
14578
  try {
14491
- MeshRuntimeStore.getInstance().setRemoteIdleSession(nodeId, sessionId, providerType, Date.now() + REMOTE_IDLE_SESSION_TTL_MS);
14579
+ MeshRuntimeStore.getInstance().setRemoteIdleSession(args.meshId, nodeId, sessionId, providerType, Date.now() + REMOTE_IDLE_SESSION_TTL_MS);
14492
14580
  } catch {
14493
14581
  }
14494
14582
  setImmediate(() => {
14495
14583
  maybeAutoFastForwardIdleNode(components, { meshId: args.meshId, nodeId, sessionId, providerType }).finally(() => {
14496
14584
  try {
14497
14585
  const assigned = tryAssignQueueTask(components, args.meshId, nodeId, sessionId, providerType);
14498
- if (assigned) MeshRuntimeStore.getInstance().deleteRemoteIdleSession(nodeId, sessionId);
14586
+ if (assigned) MeshRuntimeStore.getInstance().deleteRemoteIdleSession(args.meshId, nodeId, sessionId);
14499
14587
  } catch (e) {
14500
14588
  LOG.warn("MeshQueue", `Failed to assign idle queue task after maintenance for ${nodeId}: ${e?.message || e}`);
14501
14589
  }
@@ -14507,7 +14595,7 @@ function injectMeshSystemMessage(components, args) {
14507
14595
  const nodeId = readNonEmptyString2(args.nodeId) || readNonEmptyString2(args.metadataEvent.meshNodeId);
14508
14596
  if (sessionId && nodeId) {
14509
14597
  try {
14510
- MeshRuntimeStore.getInstance().deleteRemoteIdleSession(nodeId, sessionId);
14598
+ MeshRuntimeStore.getInstance().deleteRemoteIdleSession(args.meshId, nodeId, sessionId);
14511
14599
  } catch {
14512
14600
  }
14513
14601
  }
@@ -14544,7 +14632,7 @@ function injectMeshSystemMessage(components, args) {
14544
14632
  const nodeId = readNonEmptyString2(args.nodeId) || readNonEmptyString2(args.metadataEvent.meshNodeId);
14545
14633
  if (sessionId && nodeId) {
14546
14634
  try {
14547
- MeshRuntimeStore.getInstance().deleteRemoteIdleSession(nodeId, sessionId);
14635
+ MeshRuntimeStore.getInstance().deleteRemoteIdleSession(args.meshId, nodeId, sessionId);
14548
14636
  } catch {
14549
14637
  }
14550
14638
  }
@@ -15022,6 +15110,9 @@ function resolveReconcileIntervalMs() {
15022
15110
  }
15023
15111
  return DEFAULT_RECONCILE_INTERVAL_MS;
15024
15112
  }
15113
+ function inFlightSynthKey(meshId, taskId) {
15114
+ return `${meshId}::${taskId}`;
15115
+ }
15025
15116
  function resolveCoordinatorDaemonIds(components) {
15026
15117
  const statusInstanceId = readNonEmptyString2(components.statusInstanceId);
15027
15118
  const machineId = readNonEmptyString2(loadConfig().machineId);
@@ -15586,6 +15677,14 @@ function readChatPayloadStatus(payload) {
15586
15677
  async function reconcileUnterminatedDirectDispatches(components, mesh, selfIds, localDaemonId) {
15587
15678
  const dispatches = getActiveDirectDispatches(mesh.id);
15588
15679
  if (dispatches.length === 0) return;
15680
+ const activeTaskKeys = new Set(
15681
+ dispatches.map((d) => readNonEmptyString2(d.taskId)).filter(Boolean).map((taskId) => inFlightSynthKey(mesh.id, taskId))
15682
+ );
15683
+ for (const key of inFlightIdleObservationCounts.keys()) {
15684
+ if (key.startsWith(`${mesh.id}::`) && !activeTaskKeys.has(key)) {
15685
+ inFlightIdleObservationCounts.delete(key);
15686
+ }
15687
+ }
15589
15688
  const dispatchMeshCommand = components.dispatchMeshCommand;
15590
15689
  const nodeById = new Map(mesh.nodes.map((n) => [n.id, n]));
15591
15690
  for (const dispatch of dispatches) {
@@ -15621,7 +15720,19 @@ async function reconcileUnterminatedDirectDispatches(components, mesh, selfIds,
15621
15720
  continue;
15622
15721
  }
15623
15722
  if (!payload) continue;
15624
- if (readChatPayloadStatus(payload) !== "idle") continue;
15723
+ const synthKey = inFlightSynthKey(mesh.id, taskId);
15724
+ if (readChatPayloadStatus(payload) !== "idle") {
15725
+ inFlightIdleObservationCounts.delete(synthKey);
15726
+ continue;
15727
+ }
15728
+ if (dispatch.status === "acked") {
15729
+ const idleStreak = (inFlightIdleObservationCounts.get(synthKey) ?? 0) + 1;
15730
+ inFlightIdleObservationCounts.set(synthKey, idleStreak);
15731
+ if (idleStreak < REQUIRED_CONSECUTIVE_IDLE_TICKS_FOR_INFLIGHT_SYNTH) {
15732
+ LOG.info("MeshReconcile", `In-flight synth hold: task ${taskId} on node ${nodeId} (mesh ${mesh.id}) read idle ${idleStreak}/${REQUIRED_CONSECUTIVE_IDLE_TICKS_FOR_INFLIGHT_SYNTH} consecutive tick(s) after generating_started \u2014 deferring completion synth until the idle settle is confirmed (guards against a mid-turn idle flicker pre-empting the real completion)`);
15733
+ continue;
15734
+ }
15735
+ }
15625
15736
  const messages = Array.isArray(payload.messages) ? payload.messages : [];
15626
15737
  const evidence = extractFinalAssistantSummaryEvidence(messages);
15627
15738
  if (!evidence.finalSummary) continue;
@@ -15776,7 +15887,7 @@ function setupMeshReconcileLoop(components) {
15776
15887
  }
15777
15888
  };
15778
15889
  }
15779
- var DEFAULT_RECONCILE_INTERVAL_MS, DEFAULT_AUTO_PRUNE_MIN_AGE_MS, coordinatorModalParkState, heldEventLedgerRecorded, ASSIGNED_STRANDED_DEADLINE_MS, STRICT_SESSION_MATCH_TTL_MS, unresolvedForwardRejectionCounts, MAX_FORWARD_REJECTIONS;
15890
+ var DEFAULT_RECONCILE_INTERVAL_MS, DEFAULT_AUTO_PRUNE_MIN_AGE_MS, REQUIRED_CONSECUTIVE_IDLE_TICKS_FOR_INFLIGHT_SYNTH, inFlightIdleObservationCounts, coordinatorModalParkState, heldEventLedgerRecorded, ASSIGNED_STRANDED_DEADLINE_MS, STRICT_SESSION_MATCH_TTL_MS, unresolvedForwardRejectionCounts, MAX_FORWARD_REJECTIONS;
15780
15891
  var init_mesh_reconcile_loop = __esm({
15781
15892
  "src/mesh/mesh-reconcile-loop.ts"() {
15782
15893
  "use strict";
@@ -15798,6 +15909,8 @@ var init_mesh_reconcile_loop = __esm({
15798
15909
  init_chat_message_normalization();
15799
15910
  DEFAULT_RECONCILE_INTERVAL_MS = 4e3;
15800
15911
  DEFAULT_AUTO_PRUNE_MIN_AGE_MS = 24 * 60 * 6e4;
15912
+ REQUIRED_CONSECUTIVE_IDLE_TICKS_FOR_INFLIGHT_SYNTH = 2;
15913
+ inFlightIdleObservationCounts = /* @__PURE__ */ new Map();
15801
15914
  coordinatorModalParkState = /* @__PURE__ */ new Map();
15802
15915
  heldEventLedgerRecorded = /* @__PURE__ */ new Set();
15803
15916
  ASSIGNED_STRANDED_DEADLINE_MS = 5 * 6e4;