@adhdev/daemon-core 0.9.82-rc.458 → 0.9.82-rc.459

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
@@ -409,10 +409,10 @@ function readInjected(value) {
409
409
  }
410
410
  function getDaemonBuildInfo() {
411
411
  if (cached) return cached;
412
- const commit = readInjected(true ? "690e14cc1bdb099a0c52d7fffef41329cc5b15b5" : void 0) ?? "unknown";
413
- const commitShort = readInjected(true ? "690e14cc" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
414
- const version = readInjected(true ? "0.9.82-rc.458" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
415
- const builtAt = readInjected(true ? "2026-07-04T09:53:14.279Z" : void 0);
412
+ const commit = readInjected(true ? "7f95d1c8a5f682abdc7de49343d5bee688a9f16f" : void 0) ?? "unknown";
413
+ const commitShort = readInjected(true ? "7f95d1c8" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
414
+ const version = readInjected(true ? "0.9.82-rc.459" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
415
+ const builtAt = readInjected(true ? "2026-07-04T13:20:51.551Z" : void 0);
416
416
  cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
417
417
  return cached;
418
418
  }
@@ -11543,7 +11543,154 @@ var init_mesh_events_pending = __esm({
11543
11543
  }
11544
11544
  });
11545
11545
 
11546
+ // src/logging/debug-config.ts
11547
+ function isAlwaysOnTraceCategory(category) {
11548
+ return !!category && ALWAYS_ON_TRACE_CATEGORIES.includes(category);
11549
+ }
11550
+ function normalizeCategories(categories) {
11551
+ if (!Array.isArray(categories)) return [];
11552
+ return categories.map((category) => String(category || "").trim()).filter(Boolean);
11553
+ }
11554
+ function resolveDebugRuntimeConfig(options = {}) {
11555
+ const dev = options.dev === true;
11556
+ return {
11557
+ logLevel: options.logLevel || (dev ? "debug" : DEFAULT_CONFIG2.logLevel),
11558
+ collectDebugTrace: typeof options.trace === "boolean" ? options.trace : dev,
11559
+ traceContent: options.traceContent === true,
11560
+ traceBufferSize: Number.isFinite(options.traceBufferSize) ? Math.max(10, Math.floor(options.traceBufferSize)) : dev ? DEV_TRACE_BUFFER_SIZE : DEFAULT_CONFIG2.traceBufferSize,
11561
+ traceCategories: normalizeCategories(options.traceCategories)
11562
+ };
11563
+ }
11564
+ function setDebugRuntimeConfig(config) {
11565
+ currentConfig = {
11566
+ ...config,
11567
+ traceCategories: normalizeCategories(config.traceCategories),
11568
+ traceBufferSize: Math.max(10, Math.floor(config.traceBufferSize || DEFAULT_CONFIG2.traceBufferSize))
11569
+ };
11570
+ }
11571
+ function getDebugRuntimeConfig() {
11572
+ return { ...currentConfig, traceCategories: [...currentConfig.traceCategories] };
11573
+ }
11574
+ function resetDebugRuntimeConfig() {
11575
+ currentConfig = { ...DEFAULT_CONFIG2 };
11576
+ }
11577
+ function shouldCollectTraceCategory(category) {
11578
+ const config = currentConfig;
11579
+ if (isAlwaysOnTraceCategory(category)) return true;
11580
+ if (!config.collectDebugTrace) return false;
11581
+ if (!category) return true;
11582
+ if (config.traceCategories.length === 0) return true;
11583
+ return config.traceCategories.includes(category);
11584
+ }
11585
+ var NORMAL_TRACE_BUFFER_SIZE, DEV_TRACE_BUFFER_SIZE, ALWAYS_ON_TRACE_CATEGORIES, DEFAULT_CONFIG2, currentConfig;
11586
+ var init_debug_config = __esm({
11587
+ "src/logging/debug-config.ts"() {
11588
+ "use strict";
11589
+ NORMAL_TRACE_BUFFER_SIZE = 200;
11590
+ DEV_TRACE_BUFFER_SIZE = 1e3;
11591
+ ALWAYS_ON_TRACE_CATEGORIES = ["completion-gate", "fsm-transition"];
11592
+ DEFAULT_CONFIG2 = {
11593
+ logLevel: "info",
11594
+ collectDebugTrace: false,
11595
+ traceContent: false,
11596
+ traceBufferSize: NORMAL_TRACE_BUFFER_SIZE,
11597
+ traceCategories: []
11598
+ };
11599
+ currentConfig = { ...DEFAULT_CONFIG2 };
11600
+ }
11601
+ });
11602
+
11603
+ // src/logging/debug-trace.ts
11604
+ function summarizeString(value) {
11605
+ return `[${value.length} chars]`;
11606
+ }
11607
+ function sanitizeTraceValue(value, traceContent) {
11608
+ if (traceContent) {
11609
+ if (Array.isArray(value)) return value.map((entry) => sanitizeTraceValue(entry, traceContent));
11610
+ if (value && typeof value === "object") {
11611
+ return Object.fromEntries(
11612
+ Object.entries(value).map(([key2, nested]) => [key2, sanitizeTraceValue(nested, traceContent)])
11613
+ );
11614
+ }
11615
+ return value;
11616
+ }
11617
+ if (typeof value === "string") return summarizeString(value);
11618
+ if (Array.isArray(value)) return value.map((entry) => sanitizeTraceValue(entry, traceContent));
11619
+ if (value && typeof value === "object") {
11620
+ return Object.fromEntries(
11621
+ Object.entries(value).map(([key2, nested]) => [key2, sanitizeTraceValue(nested, traceContent)])
11622
+ );
11623
+ }
11624
+ return value;
11625
+ }
11626
+ function sanitizeTracePayload(payload) {
11627
+ if (!payload) return {};
11628
+ const { traceContent } = getDebugRuntimeConfig();
11629
+ return sanitizeTraceValue(payload, traceContent);
11630
+ }
11631
+ function createEntry(event) {
11632
+ return {
11633
+ id: `trace_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`,
11634
+ ts: Date.now(),
11635
+ ...event,
11636
+ payload: sanitizeTracePayload(event.payload)
11637
+ };
11638
+ }
11639
+ function createDebugTraceStore(options) {
11640
+ const entries = [];
11641
+ const capacity = Math.max(1, Math.floor(options.capacity || 100));
11642
+ return {
11643
+ record(event) {
11644
+ if (!options.enabled && !isAlwaysOnTraceCategory(event.category)) return null;
11645
+ const entry = createEntry(event);
11646
+ entries.push(entry);
11647
+ if (entries.length > capacity) {
11648
+ entries.splice(0, entries.length - capacity);
11649
+ }
11650
+ return entry;
11651
+ },
11652
+ list(query = {}) {
11653
+ const limit = Math.max(1, Math.floor(query.limit || 100));
11654
+ return entries.filter((entry) => !query.interactionId || entry.interactionId === query.interactionId).filter((entry) => !query.category || entry.category === query.category).slice(-limit).map((entry) => ({ ...entry, payload: entry.payload ? { ...entry.payload } : {} }));
11655
+ },
11656
+ clear() {
11657
+ entries.splice(0, entries.length);
11658
+ }
11659
+ };
11660
+ }
11661
+ function configureDebugTraceStore() {
11662
+ const config = getDebugRuntimeConfig();
11663
+ globalStore = createDebugTraceStore({
11664
+ enabled: config.collectDebugTrace,
11665
+ capacity: config.traceBufferSize
11666
+ });
11667
+ }
11668
+ function recordDebugTrace(event) {
11669
+ if (!shouldCollectTraceCategory(event.category)) return null;
11670
+ return globalStore.record(event);
11671
+ }
11672
+ function getRecentDebugTrace(query = {}) {
11673
+ return globalStore.list(query);
11674
+ }
11675
+ function clearDebugTrace() {
11676
+ globalStore.clear();
11677
+ }
11678
+ function createInteractionId(prefix = "ix") {
11679
+ return `${prefix}_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;
11680
+ }
11681
+ var globalStore;
11682
+ var init_debug_trace = __esm({
11683
+ "src/logging/debug-trace.ts"() {
11684
+ "use strict";
11685
+ init_debug_config();
11686
+ globalStore = createDebugTraceStore({ enabled: false, capacity: getDebugRuntimeConfig().traceBufferSize });
11687
+ }
11688
+ });
11689
+
11546
11690
  // src/mesh/mesh-events-stale.ts
11691
+ function recordSynthCompletionGateTrace(stage, payload) {
11692
+ recordDebugTrace({ category: "completion-gate", stage, level: "debug", payload });
11693
+ }
11547
11694
  function findRecentTerminalLedgerEvidence(args) {
11548
11695
  if (!args.sessionId && !args.nodeId) return null;
11549
11696
  const entries = readLedgerEntries(args.meshId, { tail: 200 });
@@ -11677,6 +11824,7 @@ function reconcileDirectDispatchCompletionFromTranscript(args) {
11677
11824
  completedAt
11678
11825
  });
11679
11826
  const workerResult = evidence.workerResult;
11827
+ const selfAttributing = workerResult.source === "final_summary_json";
11680
11828
  const dispatchTime = dispatch?.timestamp ? new Date(dispatch.timestamp).getTime() : Number.NaN;
11681
11829
  const transcriptTime = args.transcriptMessageAt ? new Date(args.transcriptMessageAt).getTime() : Number.NaN;
11682
11830
  const transcriptAfterDispatch = Number.isFinite(dispatchTime) && Number.isFinite(transcriptTime) && transcriptTime >= dispatchTime;
@@ -11709,7 +11857,9 @@ function reconcileDirectDispatchCompletionFromTranscript(args) {
11709
11857
  dispatchEntryId: dispatch?.id,
11710
11858
  dispatchTimestamp: dispatch?.timestamp,
11711
11859
  transcriptMessageAt: readNonEmptyString2(args.transcriptMessageAt),
11712
- transcriptFinalAssistantPresent: true
11860
+ // Honestly reflect self-attribution: a plain-text tail did NOT prove a turn-final
11861
+ // assistant message (only a self-attributing final_summary_json did).
11862
+ transcriptFinalAssistantPresent: selfAttributing
11713
11863
  },
11714
11864
  evidence
11715
11865
  }
@@ -11726,6 +11876,11 @@ function reconcileDirectDispatchCompletionFromTranscript(args) {
11726
11876
  finalSummary,
11727
11877
  taskId: args.taskId,
11728
11878
  workerResult,
11879
+ // EARLYNOTIFY-GATEBYPASS (c): mark a non-self-attributing synth WEAK so its pending
11880
+ // fingerprint is `…::weak` (isWeakCompletionMetadata reads evidenceLevel), never claiming
11881
+ // the genuine dedup slot. evidenceLevel:'weak' is deliberately NOT a false-idle marker
11882
+ // (the transcript tail existed) — it keeps the completion superseable, not suppressed.
11883
+ ...selfAttributing ? {} : { evidenceLevel: "weak" },
11729
11884
  completionDiagnostic: {
11730
11885
  reason: "direct_task_transcript_reconciliation",
11731
11886
  terminalLedgerKind: kind,
@@ -11744,6 +11899,14 @@ function reconcileDirectDispatchCompletionFromTranscript(args) {
11744
11899
  ...readNonEmptyString2(args.targetCoordinatorDaemonId) ? { targetCoordinatorDaemonId: readNonEmptyString2(args.targetCoordinatorDaemonId) } : {},
11745
11900
  ...targetCoordinatorSessionId ? { targetCoordinatorSessionId } : {}
11746
11901
  });
11902
+ recordSynthCompletionGateTrace("synth-fire", {
11903
+ producer: "transcript_reconcile",
11904
+ source: args.source || "direct_task_transcript_reconciliation",
11905
+ taskId: args.taskId,
11906
+ kind,
11907
+ selfAttributing,
11908
+ evidenceLevel: selfAttributing ? "sufficient" : "weak"
11909
+ });
11747
11910
  return { reconciled: true, kind, workerResult, ledgerEntryId: entry.id };
11748
11911
  }
11749
11912
  function buildNoProgressCompletionReconciliation(args) {
@@ -11755,10 +11918,20 @@ function buildNoProgressCompletionReconciliation(args) {
11755
11918
  const completionDiagnostic = readRecord5(args.metadataEvent.completionDiagnostic);
11756
11919
  const finalSummary = readNonEmptyString2(args.metadataEvent.finalSummary);
11757
11920
  const status = readNonEmptyString2(args.metadataEvent.status).toLowerCase();
11921
+ const noProgressSelfAttributing = Boolean(
11922
+ finalSummary || workerResult || completionDiagnostic?.finalAssistantPresent === true
11923
+ );
11758
11924
  const explicitCompletionEvidence = Boolean(
11759
- finalSummary || workerResult || completionDiagnostic?.finalAssistantPresent === true || status === "idle" || status === "ready" || status === "completed"
11925
+ noProgressSelfAttributing || status === "idle" || status === "ready" || status === "completed"
11760
11926
  );
11761
11927
  if (explicitCompletionEvidence) {
11928
+ recordSynthCompletionGateTrace("synth-fire", {
11929
+ producer: "no_progress_reconcile",
11930
+ source: "no_progress_reconciliation",
11931
+ taskId: readNonEmptyString2(args.metadataEvent.taskId),
11932
+ selfAttributing: noProgressSelfAttributing,
11933
+ evidenceLevel: noProgressSelfAttributing ? "sufficient" : "weak"
11934
+ });
11762
11935
  return {
11763
11936
  ...args.metadataEvent,
11764
11937
  targetSessionId: sessionId,
@@ -11768,6 +11941,7 @@ function buildNoProgressCompletionReconciliation(args) {
11768
11941
  source: "no_progress_reconciliation",
11769
11942
  reconciledFromEvent: "monitor:no_progress",
11770
11943
  timestamp: args.metadataEvent.timestamp ?? Date.now(),
11944
+ ...noProgressSelfAttributing ? {} : { evidenceLevel: "weak" },
11771
11945
  completionDiagnostic: {
11772
11946
  ...completionDiagnostic || {},
11773
11947
  reconciliationReason: "provider_completion_evidence"
@@ -11796,6 +11970,7 @@ var init_mesh_events_stale = __esm({
11796
11970
  init_mesh_delivery_policy();
11797
11971
  init_mesh_events_pending();
11798
11972
  init_mesh_events_utils();
11973
+ init_debug_trace();
11799
11974
  init_dist();
11800
11975
  DIRECT_DISPATCH_RECONCILE_GRACE_MS = 6e4;
11801
11976
  DIRECT_DISPATCH_IDLE_SESSION_RECONCILE_GRACE_MS = 12e4;
@@ -12842,6 +13017,32 @@ function tryAssignQueueTask(components, meshId, nodeId, sessionId, providerType)
12842
13017
  );
12843
13018
  return true;
12844
13019
  }
13020
+ function awaitClaimWindowMs(cycles) {
13021
+ return AUTO_LAUNCH_AWAIT_CLAIM_MS * Math.pow(2, Math.min(cycles, AUTO_LAUNCH_AWAIT_CLAIM_BACKOFF_CAP_CYCLES));
13022
+ }
13023
+ function remoteSessionAppearsLive(meshId, sessionId) {
13024
+ if (!sessionId) return false;
13025
+ try {
13026
+ return MeshRuntimeStore.getInstance().getRemoteIdleSessions(meshId).some((s2) => sessionIdsEquivalent(s2.sessionId, sessionId));
13027
+ } catch {
13028
+ return false;
13029
+ }
13030
+ }
13031
+ function inWindowAutoLaunchSessionIdsForNode(meshId, nodeId) {
13032
+ const nowMs = Date.now();
13033
+ const out = [];
13034
+ for (const task of getQueue(meshId, { status: ["pending"] })) {
13035
+ const al = task.autoLaunch;
13036
+ const sid = al ? readNonEmptyString2(al.sessionId) : "";
13037
+ if (!al || al.status !== "started" && al.status !== "completed" || !sid) continue;
13038
+ if (!daemonIdsEquivalent(al.nodeId, nodeId)) continue;
13039
+ const launchedAtMs = Date.parse(al.updatedAt);
13040
+ const inBaseWindow = Number.isFinite(launchedAtMs) && nowMs - launchedAtMs < AUTO_LAUNCH_AWAIT_CLAIM_MS;
13041
+ const inBackoff = autoLaunchAwaitClaimBackoff.has(`${meshId}::${task.id}`);
13042
+ if (inBaseWindow || inBackoff) out.push(sid);
13043
+ }
13044
+ return out;
13045
+ }
12845
13046
  function isActionableSkipReason(reason) {
12846
13047
  if (!reason) return false;
12847
13048
  return ACTIONABLE_SKIP_REASON_PREFIXES.some((prefix) => reason === prefix || reason.startsWith(prefix));
@@ -13081,8 +13282,24 @@ function isSessionActivelyGenerating(components, sessionId) {
13081
13282
  if (!state) return false;
13082
13283
  return sessionStateLooksActive(state);
13083
13284
  }
13285
+ function resolveSessionBusyVerdict(components, sessionId) {
13286
+ if (!sessionId) return "UNKNOWN";
13287
+ try {
13288
+ const instances = components.instanceManager?.getByCategory?.("cli") || [];
13289
+ const inst = instances.find((i) => {
13290
+ const sid = readNonEmptyString2(i?.getState?.().instanceId);
13291
+ return sid && sessionIdsEquivalent(sid, sessionId);
13292
+ });
13293
+ if (!inst) return "UNKNOWN";
13294
+ const state = inst.getState?.();
13295
+ if (!state) return "UNKNOWN";
13296
+ return sessionStateLooksActive(state) ? "GENERATING" : "IDLE_CONFIRMED";
13297
+ } catch {
13298
+ return "UNKNOWN";
13299
+ }
13300
+ }
13084
13301
  function liveSessionCountForNode(components, meshId, nodeId) {
13085
- return components.instanceManager.getByCategory("cli").filter((inst) => {
13302
+ const localInstances = components.instanceManager.getByCategory("cli").filter((inst) => {
13086
13303
  const state = inst.getState();
13087
13304
  const settings = state.settings || {};
13088
13305
  if (readNonEmptyString2(settings.meshNodeFor) !== meshId) return false;
@@ -13090,9 +13307,16 @@ function liveSessionCountForNode(components, meshId, nodeId) {
13090
13307
  if (!daemonIdsEquivalent(instNodeId, nodeId)) return false;
13091
13308
  const status = readNonEmptyString2(state.status).toLowerCase();
13092
13309
  return !isTerminalSessionStatus(status);
13093
- }).length;
13310
+ });
13311
+ let count = localInstances.length;
13312
+ const localSessionIds = localInstances.map((inst) => readNonEmptyString2(inst.getState().instanceId)).filter(Boolean);
13313
+ for (const sid of inWindowAutoLaunchSessionIdsForNode(meshId, nodeId)) {
13314
+ if (!localSessionIds.some((local) => sessionIdsEquivalent(local, sid))) count += 1;
13315
+ }
13316
+ return count;
13094
13317
  }
13095
13318
  function nodeHasLiveSessionPendingClaim(components, meshId, nodeId) {
13319
+ if (inWindowAutoLaunchSessionIdsForNode(meshId, nodeId).length > 0) return true;
13096
13320
  const busySessionIds = new Set(
13097
13321
  getQueue(meshId, { status: ["assigned"] }).filter((task) => daemonIdsEquivalent(task.assignedNodeId, nodeId)).map((task) => readNonEmptyString2(task.assignedSessionId)).filter(Boolean)
13098
13322
  );
@@ -13203,10 +13427,54 @@ async function resolveUsableProvider(components, nodeId, node, requiredTags) {
13203
13427
  function readMeshNodeId(node) {
13204
13428
  return normalizeMeshNodeId(node) ?? "";
13205
13429
  }
13430
+ function driveExpiredAwaitClaim(components, meshId, task, ctx) {
13431
+ const { sessionId, nodeId, providerType } = ctx;
13432
+ const backoffKey = `${meshId}::${task.id}`;
13433
+ const nowMs = Date.now();
13434
+ const state = autoLaunchAwaitClaimBackoff.get(backoffKey) || { cycles: 0, nextAttemptAtMs: 0 };
13435
+ if (state.nextAttemptAtMs && nowMs < state.nextAttemptAtMs) return "backoff";
13436
+ const atCap = state.cycles >= AUTO_LAUNCH_AWAIT_CLAIM_BACKOFF_CAP_CYCLES;
13437
+ const live = remoteSessionAppearsLive(meshId, sessionId);
13438
+ if ((live || atCap) && nodeId && providerType) {
13439
+ try {
13440
+ MeshRuntimeStore.getInstance().setRemoteIdleSession(meshId, nodeId, sessionId, providerType, nowMs + AUTO_LAUNCH_REMOTE_IDLE_TTL_MS);
13441
+ } catch {
13442
+ }
13443
+ const assigned = tryAssignQueueTask(components, meshId, nodeId, sessionId, providerType);
13444
+ if (assigned) {
13445
+ autoLaunchAwaitClaimBackoff.delete(backoffKey);
13446
+ const isFallback = atCap && !live;
13447
+ recordAutoLaunchEvent(meshId, {
13448
+ phase: "completed",
13449
+ taskId: task.id,
13450
+ reason: isFallback ? "await_claim_direct_dispatch_fallback" : "await_claim_redriven",
13451
+ nodeId,
13452
+ sessionId
13453
+ });
13454
+ LOG.info("MeshQueue", `Auto-launch await-claim ${isFallback ? "direct-dispatch fallback" : "re-drive"} claimed task ${task.id} into existing session ${sessionId} on node ${nodeId} (mesh ${meshId})`);
13455
+ return isFallback ? "fallback" : "claimed";
13456
+ }
13457
+ if (atCap) {
13458
+ autoLaunchAwaitClaimBackoff.delete(backoffKey);
13459
+ return "respawn";
13460
+ }
13461
+ }
13462
+ const cycles = Math.min(state.cycles + 1, AUTO_LAUNCH_AWAIT_CLAIM_BACKOFF_CAP_CYCLES);
13463
+ autoLaunchAwaitClaimBackoff.set(backoffKey, { cycles, nextAttemptAtMs: nowMs + awaitClaimWindowMs(cycles) });
13464
+ recordAutoLaunchEvent(meshId, { phase: "skipped", taskId: task.id, reason: "awaiting_launched_session_claim_backoff", nodeId, sessionId });
13465
+ return "backoff";
13466
+ }
13206
13467
  async function maybeAutoLaunchOneQueueSession(components, meshId, mesh) {
13207
13468
  const queue = getQueue(meshId);
13208
13469
  const statusById = new Map(queue.map((task) => [task.id, task.status]));
13209
13470
  const pending = queue.filter((task) => task.status === "pending");
13471
+ {
13472
+ const pendingIds = new Set(pending.map((t) => t.id));
13473
+ const prefix = `${meshId}::`;
13474
+ for (const key2 of [...autoLaunchAwaitClaimBackoff.keys()]) {
13475
+ if (key2.startsWith(prefix) && !pendingIds.has(key2.slice(prefix.length))) autoLaunchAwaitClaimBackoff.delete(key2);
13476
+ }
13477
+ }
13210
13478
  if (!pending.length) return false;
13211
13479
  const maxParallelTasks = resolveMaxParallelTasks(mesh?.policy?.maxParallelTasks);
13212
13480
  const maxReadonlyParallelTasks = resolveMaxReadonlyParallelTasks(maxParallelTasks);
@@ -13231,10 +13499,18 @@ async function maybeAutoLaunchOneQueueSession(components, meshId, mesh) {
13231
13499
  }
13232
13500
  if (task.autoLaunch?.status === "completed" && task.autoLaunch.sessionId) {
13233
13501
  const launchedAtMs = Date.parse(task.autoLaunch.updatedAt);
13502
+ const alSessionId = readNonEmptyString2(task.autoLaunch.sessionId);
13503
+ const alNodeId = readNonEmptyString2(task.autoLaunch.nodeId);
13504
+ const alProvider = readNonEmptyString2(task.autoLaunch.providerType);
13234
13505
  if (Number.isFinite(launchedAtMs) && Date.now() - launchedAtMs < AUTO_LAUNCH_AWAIT_CLAIM_MS) {
13235
- recordAutoLaunchEvent(meshId, { phase: "skipped", taskId: task.id, reason: "awaiting_launched_session_claim", nodeId: task.autoLaunch.nodeId, sessionId: task.autoLaunch.sessionId });
13506
+ recordAutoLaunchEvent(meshId, { phase: "skipped", taskId: task.id, reason: "awaiting_launched_session_claim", nodeId: alNodeId, sessionId: alSessionId });
13236
13507
  continue;
13237
13508
  }
13509
+ if (Number.isFinite(launchedAtMs) && alSessionId && alNodeId) {
13510
+ const outcome = driveExpiredAwaitClaim(components, meshId, task, { sessionId: alSessionId, nodeId: alNodeId, providerType: alProvider });
13511
+ if (outcome === "claimed" || outcome === "fallback") return true;
13512
+ if (outcome === "backoff") continue;
13513
+ }
13238
13514
  }
13239
13515
  const candidateNodes = Array.isArray(mesh?.nodes) ? mesh.nodes.filter((node) => {
13240
13516
  if (task.targetNodeId && !meshNodeIdMatches(node, task.targetNodeId)) return false;
@@ -13620,7 +13896,7 @@ function runIdleMaintenanceThenAssignQueue(components, args) {
13620
13896
  });
13621
13897
  });
13622
13898
  }
13623
- var import_fs13, IDLE_AUTO_FAST_FORWARD_THROTTLE_MS, idleAutoFastForwardLastAttempt, DISPATCH_CONFIRM_TIMEOUT_MS, DISPATCH_CONNECT_TIMEOUT_MS, dispatchWarmupGetterMissingWarned, LOCAL_LAUNCH_READY_TIMEOUT_MS, LOCAL_LAUNCH_READY_POLL_MS, autoLaunchInProgress, autoLaunchCooldownUntil, AUTO_LAUNCH_COOLDOWN_MS, AUTO_LAUNCH_AWAIT_CLAIM_MS, lastAutoLaunchLedgerKey, AUTO_LAUNCH_LEDGER_DEDUP_MAX, ACTIONABLE_SKIP_REASON_PREFIXES, TRANSIENT_TARGET_NODE_BOOTSTRAP_PENDING_REASON, lastActionableSkipNotified;
13899
+ var import_fs13, IDLE_AUTO_FAST_FORWARD_THROTTLE_MS, idleAutoFastForwardLastAttempt, DISPATCH_CONFIRM_TIMEOUT_MS, DISPATCH_CONNECT_TIMEOUT_MS, dispatchWarmupGetterMissingWarned, LOCAL_LAUNCH_READY_TIMEOUT_MS, LOCAL_LAUNCH_READY_POLL_MS, autoLaunchInProgress, autoLaunchCooldownUntil, AUTO_LAUNCH_COOLDOWN_MS, AUTO_LAUNCH_AWAIT_CLAIM_MS, AUTO_LAUNCH_AWAIT_CLAIM_BACKOFF_CAP_CYCLES, AUTO_LAUNCH_REMOTE_IDLE_TTL_MS, autoLaunchAwaitClaimBackoff, lastAutoLaunchLedgerKey, AUTO_LAUNCH_LEDGER_DEDUP_MAX, ACTIONABLE_SKIP_REASON_PREFIXES, TRANSIENT_TARGET_NODE_BOOTSTRAP_PENDING_REASON, lastActionableSkipNotified;
13624
13900
  var init_mesh_queue_assignment = __esm({
13625
13901
  "src/mesh/mesh-queue-assignment.ts"() {
13626
13902
  "use strict";
@@ -13656,6 +13932,9 @@ var init_mesh_queue_assignment = __esm({
13656
13932
  autoLaunchCooldownUntil = /* @__PURE__ */ new Map();
13657
13933
  AUTO_LAUNCH_COOLDOWN_MS = 5e3;
13658
13934
  AUTO_LAUNCH_AWAIT_CLAIM_MS = 9e4;
13935
+ AUTO_LAUNCH_AWAIT_CLAIM_BACKOFF_CAP_CYCLES = 2;
13936
+ AUTO_LAUNCH_REMOTE_IDLE_TTL_MS = 5 * 60 * 1e3;
13937
+ autoLaunchAwaitClaimBackoff = /* @__PURE__ */ new Map();
13659
13938
  lastAutoLaunchLedgerKey = /* @__PURE__ */ new Map();
13660
13939
  AUTO_LAUNCH_LEDGER_DEDUP_MAX = 2e3;
13661
13940
  ACTIONABLE_SKIP_REASON_PREFIXES = [
@@ -14683,22 +14962,26 @@ function extractFinalSummaryFromMessagesAfter(messages, minTimestampMs, maxChars
14683
14962
  return "";
14684
14963
  }
14685
14964
  function extractFinalAssistantSummaryEvidence(messages, maxChars = DEFAULT_FINAL_SUMMARY_MAX_CHARS) {
14686
- if (!Array.isArray(messages) || messages.length === 0) return { finalSummary: "" };
14965
+ const turnEnd = selectFinalAssistantTurnEndMessage(messages);
14966
+ if (!turnEnd) return { finalSummary: "" };
14967
+ return {
14968
+ finalSummary: flattenContent(turnEnd.content).trim().slice(0, maxChars),
14969
+ transcriptMessageAt: readChatMessageTimestampIso(turnEnd)
14970
+ };
14971
+ }
14972
+ function selectFinalAssistantTurnEndMessage(messages) {
14973
+ if (!Array.isArray(messages) || messages.length === 0) return null;
14687
14974
  for (let i = messages.length - 1; i >= 0; i--) {
14688
14975
  const msg = messages[i];
14689
14976
  if (!msg) continue;
14690
14977
  const classification = classifyChatMessageVisibility(msg);
14691
- if (classification.isUserFacing && (msg.role === "assistant" || msg.role === "model")) {
14692
- const text = flattenContent(msg.content).trim();
14693
- if (text) {
14694
- return {
14695
- finalSummary: text.slice(0, maxChars),
14696
- transcriptMessageAt: readChatMessageTimestampIso(msg)
14697
- };
14698
- }
14978
+ if (!classification.isUserFacing) continue;
14979
+ if (msg.role === "assistant" || msg.role === "model") {
14980
+ return flattenContent(msg.content).trim() ? msg : null;
14699
14981
  }
14982
+ return null;
14700
14983
  }
14701
- return { finalSummary: "" };
14984
+ return null;
14702
14985
  }
14703
14986
  function canonicalizeKindHint(value) {
14704
14987
  return value.trim().toLowerCase().replace(/[\s-]+/g, "_");
@@ -17692,6 +17975,11 @@ function recoverStrandedAssignedDispatches(components, meshId, store) {
17692
17975
  const assigned = getQueue(meshId, { status: ["assigned"] });
17693
17976
  if (!assigned.length) return;
17694
17977
  const nowMs = Date.now();
17978
+ const assignedKeys = new Set(assigned.map((r) => `${meshId}::${r.id}`));
17979
+ const meshKeyPrefix = `${meshId}::`;
17980
+ for (const key2 of [...deliveredNoTurnUnknownStreak.keys()]) {
17981
+ if (key2.startsWith(meshKeyPrefix) && !assignedKeys.has(key2)) deliveredNoTurnUnknownStreak.delete(key2);
17982
+ }
17695
17983
  for (const row of assigned) {
17696
17984
  const dispatchedAtMs = Date.parse(row.dispatchTimestamp ?? "");
17697
17985
  if (!Number.isFinite(dispatchedAtMs)) continue;
@@ -17715,20 +18003,45 @@ function recoverStrandedAssignedDispatches(components, meshId, store) {
17715
18003
  }
17716
18004
  if (store.taskHasConfirmedDelivery(meshId, row.id)) {
17717
18005
  if (nowMs - dispatchedAtMs < DELIVERED_NO_TURN_DEADLINE_MS) continue;
17718
- if (row.assignedSessionId && isSessionActivelyGenerating(components, row.assignedSessionId)) continue;
18006
+ const streakKey = `${meshId}::${row.id}`;
18007
+ const verdict = row.assignedSessionId ? resolveSessionBusyVerdict(components, row.assignedSessionId) : "IDLE_CONFIRMED";
18008
+ if (verdict === "GENERATING") {
18009
+ deliveredNoTurnUnknownStreak.delete(streakKey);
18010
+ continue;
18011
+ }
18012
+ let reclaimReason;
18013
+ if (verdict === "IDLE_CONFIRMED") {
18014
+ deliveredNoTurnUnknownStreak.delete(streakKey);
18015
+ reclaimReason = "delivered_no_turn_deadline";
18016
+ } else {
18017
+ const streak = (deliveredNoTurnUnknownStreak.get(streakKey) ?? 0) + 1;
18018
+ deliveredNoTurnUnknownStreak.set(streakKey, streak);
18019
+ if (streak < RECLAIM_UNKNOWN_GRACE_TICKS) {
18020
+ traceMeshEventDrop("reclaim_deferred_unknown_verdict", {
18021
+ taskId: row.id,
18022
+ sessionId: row.assignedSessionId,
18023
+ nodeId: row.assignedNodeId,
18024
+ meshId,
18025
+ event: "agent:generating_completed"
18026
+ }, `unknown ${streak}/${RECLAIM_UNKNOWN_GRACE_TICKS}`);
18027
+ continue;
18028
+ }
18029
+ reclaimReason = "reclaim_after_unknown_grace";
18030
+ }
17719
18031
  const reclaimedLost = reclaimStrandedAssignedTask(meshId, row.id, {
17720
- reason: "delivered_no_turn_deadline",
18032
+ reason: reclaimReason,
17721
18033
  ageMs: nowMs - dispatchedAtMs
17722
18034
  });
17723
18035
  if (reclaimedLost) {
17724
- LOG.warn("MeshReconcile", `Reclaimed delivered-but-lost task ${row.id} on mesh ${meshId} (node=${row.assignedNodeId ?? "?"} session=${row.assignedSessionId ?? "?"}, delivered but no completion in ${Math.round((nowMs - dispatchedAtMs) / 1e3)}s, session non-generating \u2192 ${reclaimedLost.status})`);
18036
+ deliveredNoTurnUnknownStreak.delete(streakKey);
18037
+ LOG.warn("MeshReconcile", `Reclaimed delivered-but-lost task ${row.id} on mesh ${meshId} (node=${row.assignedNodeId ?? "?"} session=${row.assignedSessionId ?? "?"}, delivered but no completion in ${Math.round((nowMs - dispatchedAtMs) / 1e3)}s, verdict ${verdict} \u2192 ${reclaimReason} \u2192 ${reclaimedLost.status})`);
17725
18038
  traceMeshEventDrop("assigned_stranded_delivered_no_turn", {
17726
18039
  taskId: row.id,
17727
18040
  sessionId: row.assignedSessionId,
17728
18041
  nodeId: row.assignedNodeId,
17729
18042
  meshId,
17730
18043
  event: "agent:generating_completed"
17731
- }, `delivered ${Math.round((nowMs - dispatchedAtMs) / 1e3)}s \u2192 ${reclaimedLost.status}`);
18044
+ }, `delivered ${Math.round((nowMs - dispatchedAtMs) / 1e3)}s ${reclaimReason} \u2192 ${reclaimedLost.status}`);
17732
18045
  }
17733
18046
  continue;
17734
18047
  }
@@ -18431,7 +18744,7 @@ function setupMeshReconcileLoop(components) {
18431
18744
  }
18432
18745
  };
18433
18746
  }
18434
- var DEFAULT_RECONCILE_INTERVAL_MS, DEFAULT_AUTO_PRUNE_MIN_AGE_MS, DEFAULT_PENDING_HELD_DRAIN_ESCALATE_MS, ACKED_DEATH_CONSECUTIVE_READ_FAILURES, inFlightAckedHoldState, coordinatorModalParkState, heldEventLedgerRecorded, ASSIGNED_STRANDED_DEADLINE_MS, DELIVERED_NO_TURN_DEADLINE_MS, STRICT_SESSION_MATCH_TTL_MS, unresolvedForwardRejectionCounts, MAX_FORWARD_REJECTIONS;
18747
+ var DEFAULT_RECONCILE_INTERVAL_MS, DEFAULT_AUTO_PRUNE_MIN_AGE_MS, DEFAULT_PENDING_HELD_DRAIN_ESCALATE_MS, ACKED_DEATH_CONSECUTIVE_READ_FAILURES, inFlightAckedHoldState, coordinatorModalParkState, heldEventLedgerRecorded, ASSIGNED_STRANDED_DEADLINE_MS, DELIVERED_NO_TURN_DEADLINE_MS, RECLAIM_UNKNOWN_GRACE_TICKS, deliveredNoTurnUnknownStreak, STRICT_SESSION_MATCH_TTL_MS, unresolvedForwardRejectionCounts, MAX_FORWARD_REJECTIONS;
18435
18748
  var init_mesh_reconcile_loop = __esm({
18436
18749
  "src/mesh/mesh-reconcile-loop.ts"() {
18437
18750
  "use strict";
@@ -18462,6 +18775,8 @@ var init_mesh_reconcile_loop = __esm({
18462
18775
  heldEventLedgerRecorded = /* @__PURE__ */ new Set();
18463
18776
  ASSIGNED_STRANDED_DEADLINE_MS = 5 * 6e4;
18464
18777
  DELIVERED_NO_TURN_DEADLINE_MS = 15 * 6e4;
18778
+ RECLAIM_UNKNOWN_GRACE_TICKS = 3;
18779
+ deliveredNoTurnUnknownStreak = /* @__PURE__ */ new Map();
18465
18780
  STRICT_SESSION_MATCH_TTL_MS = 6e4;
18466
18781
  unresolvedForwardRejectionCounts = /* @__PURE__ */ new Map();
18467
18782
  MAX_FORWARD_REJECTIONS = 5;
@@ -18591,63 +18906,6 @@ var init_approval_utils = __esm({
18591
18906
  }
18592
18907
  });
18593
18908
 
18594
- // src/logging/debug-config.ts
18595
- function isAlwaysOnTraceCategory(category) {
18596
- return !!category && ALWAYS_ON_TRACE_CATEGORIES.includes(category);
18597
- }
18598
- function normalizeCategories(categories) {
18599
- if (!Array.isArray(categories)) return [];
18600
- return categories.map((category) => String(category || "").trim()).filter(Boolean);
18601
- }
18602
- function resolveDebugRuntimeConfig(options = {}) {
18603
- const dev = options.dev === true;
18604
- return {
18605
- logLevel: options.logLevel || (dev ? "debug" : DEFAULT_CONFIG2.logLevel),
18606
- collectDebugTrace: typeof options.trace === "boolean" ? options.trace : dev,
18607
- traceContent: options.traceContent === true,
18608
- traceBufferSize: Number.isFinite(options.traceBufferSize) ? Math.max(10, Math.floor(options.traceBufferSize)) : dev ? DEV_TRACE_BUFFER_SIZE : DEFAULT_CONFIG2.traceBufferSize,
18609
- traceCategories: normalizeCategories(options.traceCategories)
18610
- };
18611
- }
18612
- function setDebugRuntimeConfig(config) {
18613
- currentConfig = {
18614
- ...config,
18615
- traceCategories: normalizeCategories(config.traceCategories),
18616
- traceBufferSize: Math.max(10, Math.floor(config.traceBufferSize || DEFAULT_CONFIG2.traceBufferSize))
18617
- };
18618
- }
18619
- function getDebugRuntimeConfig() {
18620
- return { ...currentConfig, traceCategories: [...currentConfig.traceCategories] };
18621
- }
18622
- function resetDebugRuntimeConfig() {
18623
- currentConfig = { ...DEFAULT_CONFIG2 };
18624
- }
18625
- function shouldCollectTraceCategory(category) {
18626
- const config = currentConfig;
18627
- if (isAlwaysOnTraceCategory(category)) return true;
18628
- if (!config.collectDebugTrace) return false;
18629
- if (!category) return true;
18630
- if (config.traceCategories.length === 0) return true;
18631
- return config.traceCategories.includes(category);
18632
- }
18633
- var NORMAL_TRACE_BUFFER_SIZE, DEV_TRACE_BUFFER_SIZE, ALWAYS_ON_TRACE_CATEGORIES, DEFAULT_CONFIG2, currentConfig;
18634
- var init_debug_config = __esm({
18635
- "src/logging/debug-config.ts"() {
18636
- "use strict";
18637
- NORMAL_TRACE_BUFFER_SIZE = 200;
18638
- DEV_TRACE_BUFFER_SIZE = 1e3;
18639
- ALWAYS_ON_TRACE_CATEGORIES = ["completion-gate", "fsm-transition"];
18640
- DEFAULT_CONFIG2 = {
18641
- logLevel: "info",
18642
- collectDebugTrace: false,
18643
- traceContent: false,
18644
- traceBufferSize: NORMAL_TRACE_BUFFER_SIZE,
18645
- traceCategories: []
18646
- };
18647
- currentConfig = { ...DEFAULT_CONFIG2 };
18648
- }
18649
- });
18650
-
18651
18909
  // src/providers/sdk/v1/schemas/cli/provider.schema.json
18652
18910
  var provider_schema_default;
18653
18911
  var init_provider_schema = __esm({
@@ -31089,93 +31347,14 @@ var os10 = __toESM(require("os"));
31089
31347
  var path17 = __toESM(require("path"));
31090
31348
  var import_node_crypto3 = require("crypto");
31091
31349
  init_logger();
31092
-
31093
- // src/logging/debug-trace.ts
31094
- init_debug_config();
31095
- function summarizeString(value) {
31096
- return `[${value.length} chars]`;
31097
- }
31098
- function sanitizeTraceValue(value, traceContent) {
31099
- if (traceContent) {
31100
- if (Array.isArray(value)) return value.map((entry) => sanitizeTraceValue(entry, traceContent));
31101
- if (value && typeof value === "object") {
31102
- return Object.fromEntries(
31103
- Object.entries(value).map(([key2, nested]) => [key2, sanitizeTraceValue(nested, traceContent)])
31104
- );
31105
- }
31106
- return value;
31107
- }
31108
- if (typeof value === "string") return summarizeString(value);
31109
- if (Array.isArray(value)) return value.map((entry) => sanitizeTraceValue(entry, traceContent));
31110
- if (value && typeof value === "object") {
31111
- return Object.fromEntries(
31112
- Object.entries(value).map(([key2, nested]) => [key2, sanitizeTraceValue(nested, traceContent)])
31113
- );
31114
- }
31115
- return value;
31116
- }
31117
- function sanitizeTracePayload(payload) {
31118
- if (!payload) return {};
31119
- const { traceContent } = getDebugRuntimeConfig();
31120
- return sanitizeTraceValue(payload, traceContent);
31121
- }
31122
- function createEntry(event) {
31123
- return {
31124
- id: `trace_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`,
31125
- ts: Date.now(),
31126
- ...event,
31127
- payload: sanitizeTracePayload(event.payload)
31128
- };
31129
- }
31130
- function createDebugTraceStore(options) {
31131
- const entries = [];
31132
- const capacity = Math.max(1, Math.floor(options.capacity || 100));
31133
- return {
31134
- record(event) {
31135
- if (!options.enabled && !isAlwaysOnTraceCategory(event.category)) return null;
31136
- const entry = createEntry(event);
31137
- entries.push(entry);
31138
- if (entries.length > capacity) {
31139
- entries.splice(0, entries.length - capacity);
31140
- }
31141
- return entry;
31142
- },
31143
- list(query = {}) {
31144
- const limit = Math.max(1, Math.floor(query.limit || 100));
31145
- return entries.filter((entry) => !query.interactionId || entry.interactionId === query.interactionId).filter((entry) => !query.category || entry.category === query.category).slice(-limit).map((entry) => ({ ...entry, payload: entry.payload ? { ...entry.payload } : {} }));
31146
- },
31147
- clear() {
31148
- entries.splice(0, entries.length);
31149
- }
31150
- };
31151
- }
31152
- var globalStore = createDebugTraceStore({ enabled: false, capacity: getDebugRuntimeConfig().traceBufferSize });
31153
- function configureDebugTraceStore() {
31154
- const config = getDebugRuntimeConfig();
31155
- globalStore = createDebugTraceStore({
31156
- enabled: config.collectDebugTrace,
31157
- capacity: config.traceBufferSize
31158
- });
31159
- }
31160
- function recordDebugTrace(event) {
31161
- if (!shouldCollectTraceCategory(event.category)) return null;
31162
- return globalStore.record(event);
31163
- }
31164
- function getRecentDebugTrace(query = {}) {
31165
- return globalStore.list(query);
31166
- }
31167
- function clearDebugTrace() {
31168
- globalStore.clear();
31169
- }
31170
- function createInteractionId(prefix = "ix") {
31171
- return `${prefix}_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;
31172
- }
31350
+ init_debug_trace();
31173
31351
 
31174
31352
  // src/commands/chat-commands-read.ts
31175
31353
  var path16 = __toESM(require("path"));
31176
31354
  init_contracts();
31177
31355
  init_coordinator_registry();
31178
31356
  init_logger();
31357
+ init_debug_trace();
31179
31358
 
31180
31359
  // src/chat/source-machine.ts
31181
31360
  var INITIAL_CHAT_SOURCE_STATE = Object.freeze({
@@ -36410,6 +36589,7 @@ ${formatManifestValidationIssues2(validation.issues)}`,
36410
36589
  };
36411
36590
 
36412
36591
  // src/commands/low-family/session-host.ts
36592
+ init_debug_trace();
36413
36593
  function toHostedCliRuntimeDescriptor(record) {
36414
36594
  if (!record || typeof record !== "object") return null;
36415
36595
  const runtimeId = typeof record.sessionId === "string" ? record.sessionId : "";
@@ -36902,6 +37082,7 @@ var refineConfigHandlers = {
36902
37082
  // src/commands/low-family/diagnostics.ts
36903
37083
  var fs11 = __toESM(require("fs"));
36904
37084
  init_logger();
37085
+ init_debug_trace();
36905
37086
  var diagnosticsHandlers = {
36906
37087
  get_logs: async (_ctx, args) => {
36907
37088
  const count = parseInt(args?.count) || parseInt(args?.lines) || 100;
@@ -38413,6 +38594,7 @@ function applyPreLaunchTrust(trust, workingDir) {
38413
38594
 
38414
38595
  // src/providers/spec/fsm-driver.ts
38415
38596
  init_logger();
38597
+ init_debug_trace();
38416
38598
  init_debug_config();
38417
38599
  init_pty_write_chunking();
38418
38600
  function countNewlines(s2) {
@@ -41268,6 +41450,7 @@ function createCliAdapter(provider, workingDir, cliArgs, extraEnv, transportFact
41268
41450
 
41269
41451
  // src/providers/cli-provider-instance.ts
41270
41452
  init_logger();
41453
+ init_debug_trace();
41271
41454
  init_debug_config();
41272
41455
  init_mesh_event_trace();
41273
41456
  init_control_effects();
@@ -41291,6 +41474,46 @@ function normalizeProviderSessionId(provider, providerSessionId) {
41291
41474
  return normalizedId;
41292
41475
  }
41293
41476
 
41477
+ // src/providers/native-history/antigravity-claim-registry.ts
41478
+ var claimsByUuid = /* @__PURE__ */ new Map();
41479
+ var CLAIM_STALE_MS = 10 * 60 * 1e3;
41480
+ function normalizeUuid(uuid) {
41481
+ return String(uuid || "").trim().toLowerCase();
41482
+ }
41483
+ function antigravityOwnerToken(workspace, sessionStartedAtMs, instanceId) {
41484
+ const iid = typeof instanceId === "string" ? instanceId.trim() : "";
41485
+ if (iid) return `iid:${iid}`;
41486
+ if (typeof sessionStartedAtMs === "number" && sessionStartedAtMs > 0) {
41487
+ const ws = String(workspace || "").trim().toLowerCase();
41488
+ return `spawn:${ws}:${sessionStartedAtMs}`;
41489
+ }
41490
+ return "";
41491
+ }
41492
+ function claimAntigravityConversation(uuid, owner, now = Date.now()) {
41493
+ const key2 = normalizeUuid(uuid);
41494
+ if (!key2 || !owner) return false;
41495
+ const existing = claimsByUuid.get(key2);
41496
+ if (existing && existing.owner !== owner && now - existing.refreshedAtMs < CLAIM_STALE_MS) {
41497
+ return false;
41498
+ }
41499
+ claimsByUuid.set(key2, { owner, refreshedAtMs: now });
41500
+ return true;
41501
+ }
41502
+ function isAntigravityConversationClaimedByOther(uuid, owner, now = Date.now()) {
41503
+ const key2 = normalizeUuid(uuid);
41504
+ if (!key2) return false;
41505
+ const existing = claimsByUuid.get(key2);
41506
+ if (!existing) return false;
41507
+ if (existing.owner === owner) return false;
41508
+ return now - existing.refreshedAtMs < CLAIM_STALE_MS;
41509
+ }
41510
+ function releaseAntigravityOwner(owner) {
41511
+ if (!owner) return;
41512
+ for (const [key2, claim] of claimsByUuid) {
41513
+ if (claim.owner === owner) claimsByUuid.delete(key2);
41514
+ }
41515
+ }
41516
+
41294
41517
  // src/providers/cli-provider-instance.ts
41295
41518
  init_chat_message_normalization();
41296
41519
 
@@ -42223,7 +42446,20 @@ var CliProviderInstance = class _CliProviderInstance {
42223
42446
  if (now - at > USER_INPUT_ACK_DEDUP_WINDOW_MS) this.recentUserInputAcks.delete(key2);
42224
42447
  }
42225
42448
  }
42449
+ /**
42450
+ * Owner token for this session in the antigravity conversation-claim
42451
+ * registry. Derived identically to the dispatcher's read-side token
42452
+ * (workspace + spawn time) so the claims the dispatcher records under this
42453
+ * session are the ones dispose() releases.
42454
+ */
42455
+ antigravityClaimOwner() {
42456
+ return antigravityOwnerToken(this.workingDir, this.startedAt);
42457
+ }
42226
42458
  dispose() {
42459
+ if (this.type === "antigravity-cli") {
42460
+ const owner = this.antigravityClaimOwner();
42461
+ if (owner) releaseAntigravityOwner(owner);
42462
+ }
42227
42463
  this.adapter.shutdown();
42228
42464
  this.monitor.reset();
42229
42465
  if (this.autoApproveSettleTimer) {
@@ -42978,12 +43214,21 @@ var CliProviderInstance = class _CliProviderInstance {
42978
43214
  if (this.isMeshWorkerSession()) {
42979
43215
  traceMeshEventStage("fired", this.meshTraceCtx(), `${reason} (source=${fcEvidenceSource})`);
42980
43216
  }
43217
+ if (this.completionTraceOn()) this.recordCompletionGateTrace("synth-fire", {
43218
+ path: "startup_grace_fast_collapse",
43219
+ reason,
43220
+ evidenceSource: fcEvidenceSource,
43221
+ hadFinalSummary: !!fcFinalSummary,
43222
+ missingEvidence,
43223
+ evidenceLevel: "weak"
43224
+ });
42981
43225
  this.pushEvent({
42982
43226
  event: "agent:generating_completed",
42983
43227
  chatTitle,
42984
43228
  duration: 0,
42985
43229
  timestamp: now,
42986
43230
  finalSummary: fcFinalSummary,
43231
+ evidenceLevel: "weak",
42987
43232
  completionDiagnostic: {
42988
43233
  reason,
42989
43234
  finalAssistantEvidenceSource: fcEvidenceSource,
@@ -43710,6 +43955,10 @@ ${effect.notification.body || ""}`.trim();
43710
43955
  const previousHistorySessionId = this.providerSessionId || this.instanceId;
43711
43956
  const previousProviderSessionId = this.providerSessionId;
43712
43957
  this.providerSessionId = nextSessionId;
43958
+ if (this.type === "antigravity-cli") {
43959
+ const owner = this.antigravityClaimOwner();
43960
+ if (owner) claimAntigravityConversation(nextSessionId, owner);
43961
+ }
43713
43962
  this.historyWriter.promoteHistorySession(this.type, previousHistorySessionId, nextSessionId);
43714
43963
  this.historyWriter.writeSessionStart(this.type, nextSessionId, this.workingDir, this.instanceId);
43715
43964
  if (this.shouldHydrateExistingProviderHistory()) {
@@ -47581,6 +47830,51 @@ function extractUserPrompt(payload) {
47581
47830
  if (!text) return "";
47582
47831
  return extractUserRequestContent(text);
47583
47832
  }
47833
+ function extractModelReasoning(payload) {
47834
+ const inner = firstLenField(payload, 20);
47835
+ if (!inner) return "";
47836
+ const reasoning = firstLenField(inner, 3);
47837
+ if (!reasoning || !looksLikeText(reasoning)) return "";
47838
+ return reasoning.toString("utf-8").trim();
47839
+ }
47840
+ function topLevelFieldNumbers(payload) {
47841
+ return decodeProtoFields(payload).map((f) => f.field);
47842
+ }
47843
+ var MIN_RECOVERED_MESSAGE_CHARS = 12;
47844
+ function extractUtf8TextRuns(buf) {
47845
+ if (buf.length === 0) return [];
47846
+ const decoded = buf.toString("utf-8");
47847
+ const parts = decoded.split(/[\u0000-\u0008\u000B\u000C\u000E-\u001F\u007F\uFFFD]+/);
47848
+ const runs = [];
47849
+ for (const part of parts) {
47850
+ const trimmed = part.trim();
47851
+ if (trimmed.length >= MIN_PRINTABLE_RUN) runs.push(trimmed);
47852
+ }
47853
+ return runs;
47854
+ }
47855
+ function isPlausibleMessageText(s2) {
47856
+ if (s2.length < MIN_RECOVERED_MESSAGE_CHARS) return false;
47857
+ if (!/[A-Za-zÀ-￿]/.test(s2)) return false;
47858
+ if (/^(file:\/\/|[A-Za-z]:[\\/]|\/[A-Za-z0-9._-]+\/)/.test(s2)) return false;
47859
+ if ((s2.match(/ /g) ?? []).length < 2) return false;
47860
+ if (/[[{]\s*"/.test(s2)) return false;
47861
+ const structural = (s2.match(/[{}[\]":\\]/g) ?? []).length;
47862
+ if (structural / s2.length > 0.12) return false;
47863
+ return true;
47864
+ }
47865
+ function recoverMessageText(payload, excludeTexts) {
47866
+ const exclusions = excludeTexts.map((t) => t.trim()).filter(Boolean);
47867
+ let best = "";
47868
+ for (const run of extractUtf8TextRuns(payload)) {
47869
+ const candidate = stripAnswerMarker(run).trim();
47870
+ if (!isPlausibleMessageText(candidate)) continue;
47871
+ if (exclusions.some((e) => e === candidate || e.includes(candidate) || candidate.includes(e))) {
47872
+ continue;
47873
+ }
47874
+ if (candidate.length > best.length) best = candidate;
47875
+ }
47876
+ return best;
47877
+ }
47584
47878
  function isSqliteBusyError(err) {
47585
47879
  if (!err) return false;
47586
47880
  const code = err.code;
@@ -47659,8 +47953,23 @@ function parseConversationDb(filePath, sessionId, workspace) {
47659
47953
  if (!payload || !Buffer.isBuffer(payload) || payload.length === 0) continue;
47660
47954
  const receivedAt = baseTs + messages.length;
47661
47955
  if (row.step_type === AGY_STEP_TYPE_USER) {
47662
- const content = extractUserPrompt(payload);
47663
- if (!content) continue;
47956
+ let content = extractUserPrompt(payload);
47957
+ if (!content) {
47958
+ const recovered = extractUserRequestContent(recoverMessageText(payload, []));
47959
+ if (recovered) {
47960
+ content = recovered;
47961
+ LOG.debug(
47962
+ "NativeHistory",
47963
+ `antigravity .db ${path31.basename(filePath)} step ${row.idx} (type ${row.step_type}): user prompt absent at field 19; recovered ${content.length} chars via printable-run fallback \u2014 possible step_payload schema drift`
47964
+ );
47965
+ } else {
47966
+ LOG.debug(
47967
+ "NativeHistory",
47968
+ `antigravity .db ${path31.basename(filePath)} step ${row.idx} (type ${row.step_type}) dropped: no user prompt text (payload ${payload.length}B, top-level fields [${topLevelFieldNumbers(payload).join(",")}])`
47969
+ );
47970
+ continue;
47971
+ }
47972
+ }
47664
47973
  const msg = {
47665
47974
  ts: new Date(receivedAt).toISOString(),
47666
47975
  receivedAt,
@@ -47673,8 +47982,24 @@ function parseConversationDb(filePath, sessionId, workspace) {
47673
47982
  if (normalizedWorkspace) msg.workspace = normalizedWorkspace;
47674
47983
  messages.push(msg);
47675
47984
  } else if (row.step_type === AGY_STEP_TYPE_MODEL) {
47676
- const content = extractModelAnswer(payload);
47677
- if (!content) continue;
47985
+ let content = extractModelAnswer(payload);
47986
+ if (!content) {
47987
+ const reasoning = extractModelReasoning(payload);
47988
+ const recovered = recoverMessageText(payload, reasoning ? [reasoning] : []);
47989
+ if (recovered) {
47990
+ content = recovered;
47991
+ LOG.debug(
47992
+ "NativeHistory",
47993
+ `antigravity .db ${path31.basename(filePath)} step ${row.idx} (type ${row.step_type}): answer absent at field 20; recovered ${content.length} chars via printable-run fallback \u2014 possible step_payload schema drift`
47994
+ );
47995
+ } else {
47996
+ LOG.debug(
47997
+ "NativeHistory",
47998
+ `antigravity .db ${path31.basename(filePath)} step ${row.idx} (type ${row.step_type}) dropped: no answer text (payload ${payload.length}B, top-level fields [${topLevelFieldNumbers(payload).join(",")}], reasoningOnly=${reasoning ? "yes" : "no"})`
47999
+ );
48000
+ continue;
48001
+ }
48002
+ }
47678
48003
  const msg = {
47679
48004
  ts: new Date(receivedAt).toISOString(),
47680
48005
  receivedAt,
@@ -47920,7 +48245,8 @@ function createNativeHistoryDispatcher(reader) {
47920
48245
  const sessionId = input.sessionId || input.historySessionId || "";
47921
48246
  const requestedProviderSid = input.providerSessionId || "";
47922
48247
  const sessionStartedAtMs = typeof input.sessionStartedAtMs === "number" ? input.sessionStartedAtMs : typeof input.args?.sessionStartedAtMs === "number" ? input.args.sessionStartedAtMs : 0;
47923
- const sourcePath = resolveSourcePath(reader, workspace, sessionId, sessionStartedAtMs);
48248
+ const instanceId = typeof input.instanceId === "string" ? input.instanceId : typeof input.args?.instanceId === "string" ? input.args.instanceId : "";
48249
+ const sourcePath = resolveSourcePath(reader, workspace, sessionId, sessionStartedAtMs, instanceId);
47924
48250
  if (!sourcePath) return null;
47925
48251
  if (input.forceRefresh === true || input.args?.forceRefresh === true) {
47926
48252
  try {
@@ -47948,14 +48274,14 @@ function createNativeHistoryDispatcher(reader) {
47948
48274
  };
47949
48275
  };
47950
48276
  }
47951
- function resolveSourcePath(reader, workspace, sessionId, sessionStartedAtMs) {
48277
+ function resolveSourcePath(reader, workspace, sessionId, sessionStartedAtMs, instanceId) {
47952
48278
  switch (reader) {
47953
48279
  case "claude-cli":
47954
48280
  return resolveClaudePath(workspace, sessionId);
47955
48281
  case "codex-cli":
47956
48282
  return resolveCodexPath(workspace, sessionId, sessionStartedAtMs);
47957
48283
  case "antigravity-cli":
47958
- return resolveAntigravityPath(workspace, sessionId);
48284
+ return resolveAntigravityPath(workspace, sessionId, sessionStartedAtMs, instanceId);
47959
48285
  case "hermes-cli":
47960
48286
  return resolveHermesPath(workspace, sessionId);
47961
48287
  }
@@ -48070,27 +48396,73 @@ function resolveRealPath(value) {
48070
48396
  return value;
48071
48397
  }
48072
48398
  }
48073
- function resolveAntigravityPath(workspace, sessionId) {
48074
- void workspace;
48399
+ var AGY_SPAWN_CLAIM_GRACE_MS = 2e3;
48400
+ function resolveAntigravityPath(workspace, sessionId, sessionStartedAtMs, instanceId) {
48075
48401
  const agyRoot = path33.join(os24.homedir(), ".gemini", "antigravity-cli");
48402
+ const owner = antigravityOwnerToken(workspace, sessionStartedAtMs, instanceId);
48076
48403
  if (sessionId && isUuidLikeSessionId2(sessionId)) {
48077
48404
  const dbPath = path33.join(agyRoot, "conversations", `${sessionId}.db`);
48078
- if (fs24.existsSync(dbPath)) return dbPath;
48405
+ if (fs24.existsSync(dbPath)) {
48406
+ if (owner) claimAntigravityConversation(sessionId, owner);
48407
+ return dbPath;
48408
+ }
48079
48409
  }
48080
48410
  const brainRoot2 = path33.join(agyRoot, "brain");
48081
48411
  if (fs24.existsSync(brainRoot2)) {
48082
- const cutoff = Date.now() - RECENT_WINDOW_MS;
48083
- const entries = fs24.readdirSync(brainRoot2, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => ({ p: path33.join(brainRoot2, e.name), mtime: safeMtime(path33.join(brainRoot2, e.name)) })).filter((e) => e.mtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
48412
+ const cutoff = spawnAwareCutoff(sessionStartedAtMs);
48413
+ const entries = fs24.readdirSync(brainRoot2, { withFileTypes: true }).filter((e) => e.isDirectory() && isUuidLikeSessionId2(e.name)).filter((e) => !isAntigravityConversationClaimedByOther(e.name, owner)).map((e) => ({ uuid: e.name, p: path33.join(brainRoot2, e.name), mtime: safeMtime(path33.join(brainRoot2, e.name)) })).filter((e) => e.mtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
48084
48414
  for (const e of entries) {
48085
48415
  const t = path33.join(e.p, ".system_generated", "logs", "transcript.jsonl");
48086
- if (fs24.existsSync(t) && safeSize(t) > 0) return t;
48416
+ if (fs24.existsSync(t) && safeSize(t) > 0) {
48417
+ if (owner) claimAntigravityConversation(e.uuid, owner);
48418
+ return t;
48419
+ }
48087
48420
  }
48088
48421
  }
48089
48422
  const convRoot = path33.join(agyRoot, "conversations");
48090
- const newestDb = newestRecentFile2(convRoot, /^[0-9a-f-]+\.db$/i);
48091
- if (newestDb) return newestDb;
48423
+ const picked = pickUnboundConversationDb(convRoot, sessionStartedAtMs, owner);
48424
+ if (picked) {
48425
+ if (owner) claimAntigravityConversation(picked.uuid, owner);
48426
+ return picked.path;
48427
+ }
48092
48428
  return null;
48093
48429
  }
48430
+ function pickUnboundConversationDb(convRoot, sessionFloorMs, owner) {
48431
+ let entries = [];
48432
+ try {
48433
+ entries = fs24.readdirSync(convRoot, { withFileTypes: true });
48434
+ } catch {
48435
+ return null;
48436
+ }
48437
+ const recencyCutoff = Date.now() - RECENT_WINDOW_MS;
48438
+ const candidates = [];
48439
+ for (const entry of entries) {
48440
+ if (!entry.isFile()) continue;
48441
+ const match = /^([0-9a-f-]+)\.db$/i.exec(entry.name);
48442
+ if (!match || !isUuidLikeSessionId2(match[1])) continue;
48443
+ const uuid = match[1];
48444
+ if (isAntigravityConversationClaimedByOther(uuid, owner)) continue;
48445
+ const p = path33.join(convRoot, entry.name);
48446
+ const mtime = safeMtime(p);
48447
+ if (mtime < recencyCutoff) continue;
48448
+ candidates.push({ path: p, uuid, mtime, birth: safeBirthtime(p) });
48449
+ }
48450
+ if (candidates.length === 0) return null;
48451
+ if (sessionFloorMs > 0) {
48452
+ const floor = sessionFloorMs - AGY_SPAWN_CLAIM_GRACE_MS;
48453
+ const own = candidates.filter((c) => (c.birth > 0 ? c.birth : c.mtime) >= floor);
48454
+ if (own.length === 0) return null;
48455
+ own.sort((a, b) => (a.birth || a.mtime) - (b.birth || b.mtime));
48456
+ return { path: own[0].path, uuid: own[0].uuid };
48457
+ }
48458
+ candidates.sort((a, b) => b.mtime - a.mtime);
48459
+ return { path: candidates[0].path, uuid: candidates[0].uuid };
48460
+ }
48461
+ function spawnAwareCutoff(sessionStartedAtMs) {
48462
+ const recency = Date.now() - RECENT_WINDOW_MS;
48463
+ if (sessionStartedAtMs > 0) return Math.max(recency, sessionStartedAtMs - AGY_SPAWN_CLAIM_GRACE_MS);
48464
+ return recency;
48465
+ }
48094
48466
  function resolveHermesPath(workspace, sessionId) {
48095
48467
  void workspace;
48096
48468
  void sessionId;
@@ -48147,6 +48519,15 @@ function safeMtime(p) {
48147
48519
  return 0;
48148
48520
  }
48149
48521
  }
48522
+ function safeBirthtime(p) {
48523
+ try {
48524
+ const st = fs24.statSync(p);
48525
+ const birth = Math.floor(st.birthtimeMs);
48526
+ return birth > 0 ? birth : Math.floor(st.mtimeMs);
48527
+ } catch {
48528
+ return 0;
48529
+ }
48530
+ }
48150
48531
  function safeSize(p) {
48151
48532
  try {
48152
48533
  return fs24.statSync(p).size;
@@ -53682,6 +54063,7 @@ function getRecentCommands(count = 50) {
53682
54063
  cleanOldFiles();
53683
54064
 
53684
54065
  // src/commands/router.ts
54066
+ init_debug_trace();
53685
54067
  init_mesh_host_ownership();
53686
54068
  init_mesh_work_queue();
53687
54069
  var fs33 = __toESM(require("fs"));
@@ -54975,6 +55357,7 @@ async function resolveProviderTypeFromPriority(args) {
54975
55357
  // src/commands/router-refine.ts
54976
55358
  var import_node_child_process7 = require("child_process");
54977
55359
  init_logger();
55360
+ init_debug_trace();
54978
55361
  init_dist();
54979
55362
  init_mesh_events();
54980
55363
 
@@ -59200,6 +59583,7 @@ init_build_info();
59200
59583
  init_normalize();
59201
59584
  init_logger();
59202
59585
  init_debug_config();
59586
+ init_debug_trace();
59203
59587
 
59204
59588
  // src/ipc-protocol.ts
59205
59589
  var DEFAULT_DAEMON_PORT = 19222;