@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.mjs CHANGED
@@ -404,10 +404,10 @@ function readInjected(value) {
404
404
  }
405
405
  function getDaemonBuildInfo() {
406
406
  if (cached) return cached;
407
- const commit = readInjected(true ? "690e14cc1bdb099a0c52d7fffef41329cc5b15b5" : void 0) ?? "unknown";
408
- const commitShort = readInjected(true ? "690e14cc" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
409
- const version = readInjected(true ? "0.9.82-rc.458" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
410
- const builtAt = readInjected(true ? "2026-07-04T09:53:14.279Z" : void 0);
407
+ const commit = readInjected(true ? "7f95d1c8a5f682abdc7de49343d5bee688a9f16f" : void 0) ?? "unknown";
408
+ const commitShort = readInjected(true ? "7f95d1c8" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
409
+ const version = readInjected(true ? "0.9.82-rc.459" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
410
+ const builtAt = readInjected(true ? "2026-07-04T13:20:51.551Z" : void 0);
411
411
  cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
412
412
  return cached;
413
413
  }
@@ -11536,7 +11536,154 @@ var init_mesh_events_pending = __esm({
11536
11536
  }
11537
11537
  });
11538
11538
 
11539
+ // src/logging/debug-config.ts
11540
+ function isAlwaysOnTraceCategory(category) {
11541
+ return !!category && ALWAYS_ON_TRACE_CATEGORIES.includes(category);
11542
+ }
11543
+ function normalizeCategories(categories) {
11544
+ if (!Array.isArray(categories)) return [];
11545
+ return categories.map((category) => String(category || "").trim()).filter(Boolean);
11546
+ }
11547
+ function resolveDebugRuntimeConfig(options = {}) {
11548
+ const dev = options.dev === true;
11549
+ return {
11550
+ logLevel: options.logLevel || (dev ? "debug" : DEFAULT_CONFIG2.logLevel),
11551
+ collectDebugTrace: typeof options.trace === "boolean" ? options.trace : dev,
11552
+ traceContent: options.traceContent === true,
11553
+ traceBufferSize: Number.isFinite(options.traceBufferSize) ? Math.max(10, Math.floor(options.traceBufferSize)) : dev ? DEV_TRACE_BUFFER_SIZE : DEFAULT_CONFIG2.traceBufferSize,
11554
+ traceCategories: normalizeCategories(options.traceCategories)
11555
+ };
11556
+ }
11557
+ function setDebugRuntimeConfig(config) {
11558
+ currentConfig = {
11559
+ ...config,
11560
+ traceCategories: normalizeCategories(config.traceCategories),
11561
+ traceBufferSize: Math.max(10, Math.floor(config.traceBufferSize || DEFAULT_CONFIG2.traceBufferSize))
11562
+ };
11563
+ }
11564
+ function getDebugRuntimeConfig() {
11565
+ return { ...currentConfig, traceCategories: [...currentConfig.traceCategories] };
11566
+ }
11567
+ function resetDebugRuntimeConfig() {
11568
+ currentConfig = { ...DEFAULT_CONFIG2 };
11569
+ }
11570
+ function shouldCollectTraceCategory(category) {
11571
+ const config = currentConfig;
11572
+ if (isAlwaysOnTraceCategory(category)) return true;
11573
+ if (!config.collectDebugTrace) return false;
11574
+ if (!category) return true;
11575
+ if (config.traceCategories.length === 0) return true;
11576
+ return config.traceCategories.includes(category);
11577
+ }
11578
+ var NORMAL_TRACE_BUFFER_SIZE, DEV_TRACE_BUFFER_SIZE, ALWAYS_ON_TRACE_CATEGORIES, DEFAULT_CONFIG2, currentConfig;
11579
+ var init_debug_config = __esm({
11580
+ "src/logging/debug-config.ts"() {
11581
+ "use strict";
11582
+ NORMAL_TRACE_BUFFER_SIZE = 200;
11583
+ DEV_TRACE_BUFFER_SIZE = 1e3;
11584
+ ALWAYS_ON_TRACE_CATEGORIES = ["completion-gate", "fsm-transition"];
11585
+ DEFAULT_CONFIG2 = {
11586
+ logLevel: "info",
11587
+ collectDebugTrace: false,
11588
+ traceContent: false,
11589
+ traceBufferSize: NORMAL_TRACE_BUFFER_SIZE,
11590
+ traceCategories: []
11591
+ };
11592
+ currentConfig = { ...DEFAULT_CONFIG2 };
11593
+ }
11594
+ });
11595
+
11596
+ // src/logging/debug-trace.ts
11597
+ function summarizeString(value) {
11598
+ return `[${value.length} chars]`;
11599
+ }
11600
+ function sanitizeTraceValue(value, traceContent) {
11601
+ if (traceContent) {
11602
+ if (Array.isArray(value)) return value.map((entry) => sanitizeTraceValue(entry, traceContent));
11603
+ if (value && typeof value === "object") {
11604
+ return Object.fromEntries(
11605
+ Object.entries(value).map(([key2, nested]) => [key2, sanitizeTraceValue(nested, traceContent)])
11606
+ );
11607
+ }
11608
+ return value;
11609
+ }
11610
+ if (typeof value === "string") return summarizeString(value);
11611
+ if (Array.isArray(value)) return value.map((entry) => sanitizeTraceValue(entry, traceContent));
11612
+ if (value && typeof value === "object") {
11613
+ return Object.fromEntries(
11614
+ Object.entries(value).map(([key2, nested]) => [key2, sanitizeTraceValue(nested, traceContent)])
11615
+ );
11616
+ }
11617
+ return value;
11618
+ }
11619
+ function sanitizeTracePayload(payload) {
11620
+ if (!payload) return {};
11621
+ const { traceContent } = getDebugRuntimeConfig();
11622
+ return sanitizeTraceValue(payload, traceContent);
11623
+ }
11624
+ function createEntry(event) {
11625
+ return {
11626
+ id: `trace_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`,
11627
+ ts: Date.now(),
11628
+ ...event,
11629
+ payload: sanitizeTracePayload(event.payload)
11630
+ };
11631
+ }
11632
+ function createDebugTraceStore(options) {
11633
+ const entries = [];
11634
+ const capacity = Math.max(1, Math.floor(options.capacity || 100));
11635
+ return {
11636
+ record(event) {
11637
+ if (!options.enabled && !isAlwaysOnTraceCategory(event.category)) return null;
11638
+ const entry = createEntry(event);
11639
+ entries.push(entry);
11640
+ if (entries.length > capacity) {
11641
+ entries.splice(0, entries.length - capacity);
11642
+ }
11643
+ return entry;
11644
+ },
11645
+ list(query = {}) {
11646
+ const limit = Math.max(1, Math.floor(query.limit || 100));
11647
+ 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 } : {} }));
11648
+ },
11649
+ clear() {
11650
+ entries.splice(0, entries.length);
11651
+ }
11652
+ };
11653
+ }
11654
+ function configureDebugTraceStore() {
11655
+ const config = getDebugRuntimeConfig();
11656
+ globalStore = createDebugTraceStore({
11657
+ enabled: config.collectDebugTrace,
11658
+ capacity: config.traceBufferSize
11659
+ });
11660
+ }
11661
+ function recordDebugTrace(event) {
11662
+ if (!shouldCollectTraceCategory(event.category)) return null;
11663
+ return globalStore.record(event);
11664
+ }
11665
+ function getRecentDebugTrace(query = {}) {
11666
+ return globalStore.list(query);
11667
+ }
11668
+ function clearDebugTrace() {
11669
+ globalStore.clear();
11670
+ }
11671
+ function createInteractionId(prefix = "ix") {
11672
+ return `${prefix}_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;
11673
+ }
11674
+ var globalStore;
11675
+ var init_debug_trace = __esm({
11676
+ "src/logging/debug-trace.ts"() {
11677
+ "use strict";
11678
+ init_debug_config();
11679
+ globalStore = createDebugTraceStore({ enabled: false, capacity: getDebugRuntimeConfig().traceBufferSize });
11680
+ }
11681
+ });
11682
+
11539
11683
  // src/mesh/mesh-events-stale.ts
11684
+ function recordSynthCompletionGateTrace(stage, payload) {
11685
+ recordDebugTrace({ category: "completion-gate", stage, level: "debug", payload });
11686
+ }
11540
11687
  function findRecentTerminalLedgerEvidence(args) {
11541
11688
  if (!args.sessionId && !args.nodeId) return null;
11542
11689
  const entries = readLedgerEntries(args.meshId, { tail: 200 });
@@ -11670,6 +11817,7 @@ function reconcileDirectDispatchCompletionFromTranscript(args) {
11670
11817
  completedAt
11671
11818
  });
11672
11819
  const workerResult = evidence.workerResult;
11820
+ const selfAttributing = workerResult.source === "final_summary_json";
11673
11821
  const dispatchTime = dispatch?.timestamp ? new Date(dispatch.timestamp).getTime() : Number.NaN;
11674
11822
  const transcriptTime = args.transcriptMessageAt ? new Date(args.transcriptMessageAt).getTime() : Number.NaN;
11675
11823
  const transcriptAfterDispatch = Number.isFinite(dispatchTime) && Number.isFinite(transcriptTime) && transcriptTime >= dispatchTime;
@@ -11702,7 +11850,9 @@ function reconcileDirectDispatchCompletionFromTranscript(args) {
11702
11850
  dispatchEntryId: dispatch?.id,
11703
11851
  dispatchTimestamp: dispatch?.timestamp,
11704
11852
  transcriptMessageAt: readNonEmptyString2(args.transcriptMessageAt),
11705
- transcriptFinalAssistantPresent: true
11853
+ // Honestly reflect self-attribution: a plain-text tail did NOT prove a turn-final
11854
+ // assistant message (only a self-attributing final_summary_json did).
11855
+ transcriptFinalAssistantPresent: selfAttributing
11706
11856
  },
11707
11857
  evidence
11708
11858
  }
@@ -11719,6 +11869,11 @@ function reconcileDirectDispatchCompletionFromTranscript(args) {
11719
11869
  finalSummary,
11720
11870
  taskId: args.taskId,
11721
11871
  workerResult,
11872
+ // EARLYNOTIFY-GATEBYPASS (c): mark a non-self-attributing synth WEAK so its pending
11873
+ // fingerprint is `…::weak` (isWeakCompletionMetadata reads evidenceLevel), never claiming
11874
+ // the genuine dedup slot. evidenceLevel:'weak' is deliberately NOT a false-idle marker
11875
+ // (the transcript tail existed) — it keeps the completion superseable, not suppressed.
11876
+ ...selfAttributing ? {} : { evidenceLevel: "weak" },
11722
11877
  completionDiagnostic: {
11723
11878
  reason: "direct_task_transcript_reconciliation",
11724
11879
  terminalLedgerKind: kind,
@@ -11737,6 +11892,14 @@ function reconcileDirectDispatchCompletionFromTranscript(args) {
11737
11892
  ...readNonEmptyString2(args.targetCoordinatorDaemonId) ? { targetCoordinatorDaemonId: readNonEmptyString2(args.targetCoordinatorDaemonId) } : {},
11738
11893
  ...targetCoordinatorSessionId ? { targetCoordinatorSessionId } : {}
11739
11894
  });
11895
+ recordSynthCompletionGateTrace("synth-fire", {
11896
+ producer: "transcript_reconcile",
11897
+ source: args.source || "direct_task_transcript_reconciliation",
11898
+ taskId: args.taskId,
11899
+ kind,
11900
+ selfAttributing,
11901
+ evidenceLevel: selfAttributing ? "sufficient" : "weak"
11902
+ });
11740
11903
  return { reconciled: true, kind, workerResult, ledgerEntryId: entry.id };
11741
11904
  }
11742
11905
  function buildNoProgressCompletionReconciliation(args) {
@@ -11748,10 +11911,20 @@ function buildNoProgressCompletionReconciliation(args) {
11748
11911
  const completionDiagnostic = readRecord5(args.metadataEvent.completionDiagnostic);
11749
11912
  const finalSummary = readNonEmptyString2(args.metadataEvent.finalSummary);
11750
11913
  const status = readNonEmptyString2(args.metadataEvent.status).toLowerCase();
11914
+ const noProgressSelfAttributing = Boolean(
11915
+ finalSummary || workerResult || completionDiagnostic?.finalAssistantPresent === true
11916
+ );
11751
11917
  const explicitCompletionEvidence = Boolean(
11752
- finalSummary || workerResult || completionDiagnostic?.finalAssistantPresent === true || status === "idle" || status === "ready" || status === "completed"
11918
+ noProgressSelfAttributing || status === "idle" || status === "ready" || status === "completed"
11753
11919
  );
11754
11920
  if (explicitCompletionEvidence) {
11921
+ recordSynthCompletionGateTrace("synth-fire", {
11922
+ producer: "no_progress_reconcile",
11923
+ source: "no_progress_reconciliation",
11924
+ taskId: readNonEmptyString2(args.metadataEvent.taskId),
11925
+ selfAttributing: noProgressSelfAttributing,
11926
+ evidenceLevel: noProgressSelfAttributing ? "sufficient" : "weak"
11927
+ });
11755
11928
  return {
11756
11929
  ...args.metadataEvent,
11757
11930
  targetSessionId: sessionId,
@@ -11761,6 +11934,7 @@ function buildNoProgressCompletionReconciliation(args) {
11761
11934
  source: "no_progress_reconciliation",
11762
11935
  reconciledFromEvent: "monitor:no_progress",
11763
11936
  timestamp: args.metadataEvent.timestamp ?? Date.now(),
11937
+ ...noProgressSelfAttributing ? {} : { evidenceLevel: "weak" },
11764
11938
  completionDiagnostic: {
11765
11939
  ...completionDiagnostic || {},
11766
11940
  reconciliationReason: "provider_completion_evidence"
@@ -11789,6 +11963,7 @@ var init_mesh_events_stale = __esm({
11789
11963
  init_mesh_delivery_policy();
11790
11964
  init_mesh_events_pending();
11791
11965
  init_mesh_events_utils();
11966
+ init_debug_trace();
11792
11967
  init_dist();
11793
11968
  DIRECT_DISPATCH_RECONCILE_GRACE_MS = 6e4;
11794
11969
  DIRECT_DISPATCH_IDLE_SESSION_RECONCILE_GRACE_MS = 12e4;
@@ -12838,6 +13013,32 @@ function tryAssignQueueTask(components, meshId, nodeId, sessionId, providerType)
12838
13013
  );
12839
13014
  return true;
12840
13015
  }
13016
+ function awaitClaimWindowMs(cycles) {
13017
+ return AUTO_LAUNCH_AWAIT_CLAIM_MS * Math.pow(2, Math.min(cycles, AUTO_LAUNCH_AWAIT_CLAIM_BACKOFF_CAP_CYCLES));
13018
+ }
13019
+ function remoteSessionAppearsLive(meshId, sessionId) {
13020
+ if (!sessionId) return false;
13021
+ try {
13022
+ return MeshRuntimeStore.getInstance().getRemoteIdleSessions(meshId).some((s2) => sessionIdsEquivalent(s2.sessionId, sessionId));
13023
+ } catch {
13024
+ return false;
13025
+ }
13026
+ }
13027
+ function inWindowAutoLaunchSessionIdsForNode(meshId, nodeId) {
13028
+ const nowMs = Date.now();
13029
+ const out = [];
13030
+ for (const task of getQueue(meshId, { status: ["pending"] })) {
13031
+ const al = task.autoLaunch;
13032
+ const sid = al ? readNonEmptyString2(al.sessionId) : "";
13033
+ if (!al || al.status !== "started" && al.status !== "completed" || !sid) continue;
13034
+ if (!daemonIdsEquivalent(al.nodeId, nodeId)) continue;
13035
+ const launchedAtMs = Date.parse(al.updatedAt);
13036
+ const inBaseWindow = Number.isFinite(launchedAtMs) && nowMs - launchedAtMs < AUTO_LAUNCH_AWAIT_CLAIM_MS;
13037
+ const inBackoff = autoLaunchAwaitClaimBackoff.has(`${meshId}::${task.id}`);
13038
+ if (inBaseWindow || inBackoff) out.push(sid);
13039
+ }
13040
+ return out;
13041
+ }
12841
13042
  function isActionableSkipReason(reason) {
12842
13043
  if (!reason) return false;
12843
13044
  return ACTIONABLE_SKIP_REASON_PREFIXES.some((prefix) => reason === prefix || reason.startsWith(prefix));
@@ -13077,8 +13278,24 @@ function isSessionActivelyGenerating(components, sessionId) {
13077
13278
  if (!state) return false;
13078
13279
  return sessionStateLooksActive(state);
13079
13280
  }
13281
+ function resolveSessionBusyVerdict(components, sessionId) {
13282
+ if (!sessionId) return "UNKNOWN";
13283
+ try {
13284
+ const instances = components.instanceManager?.getByCategory?.("cli") || [];
13285
+ const inst = instances.find((i) => {
13286
+ const sid = readNonEmptyString2(i?.getState?.().instanceId);
13287
+ return sid && sessionIdsEquivalent(sid, sessionId);
13288
+ });
13289
+ if (!inst) return "UNKNOWN";
13290
+ const state = inst.getState?.();
13291
+ if (!state) return "UNKNOWN";
13292
+ return sessionStateLooksActive(state) ? "GENERATING" : "IDLE_CONFIRMED";
13293
+ } catch {
13294
+ return "UNKNOWN";
13295
+ }
13296
+ }
13080
13297
  function liveSessionCountForNode(components, meshId, nodeId) {
13081
- return components.instanceManager.getByCategory("cli").filter((inst) => {
13298
+ const localInstances = components.instanceManager.getByCategory("cli").filter((inst) => {
13082
13299
  const state = inst.getState();
13083
13300
  const settings = state.settings || {};
13084
13301
  if (readNonEmptyString2(settings.meshNodeFor) !== meshId) return false;
@@ -13086,9 +13303,16 @@ function liveSessionCountForNode(components, meshId, nodeId) {
13086
13303
  if (!daemonIdsEquivalent(instNodeId, nodeId)) return false;
13087
13304
  const status = readNonEmptyString2(state.status).toLowerCase();
13088
13305
  return !isTerminalSessionStatus(status);
13089
- }).length;
13306
+ });
13307
+ let count = localInstances.length;
13308
+ const localSessionIds = localInstances.map((inst) => readNonEmptyString2(inst.getState().instanceId)).filter(Boolean);
13309
+ for (const sid of inWindowAutoLaunchSessionIdsForNode(meshId, nodeId)) {
13310
+ if (!localSessionIds.some((local) => sessionIdsEquivalent(local, sid))) count += 1;
13311
+ }
13312
+ return count;
13090
13313
  }
13091
13314
  function nodeHasLiveSessionPendingClaim(components, meshId, nodeId) {
13315
+ if (inWindowAutoLaunchSessionIdsForNode(meshId, nodeId).length > 0) return true;
13092
13316
  const busySessionIds = new Set(
13093
13317
  getQueue(meshId, { status: ["assigned"] }).filter((task) => daemonIdsEquivalent(task.assignedNodeId, nodeId)).map((task) => readNonEmptyString2(task.assignedSessionId)).filter(Boolean)
13094
13318
  );
@@ -13199,10 +13423,54 @@ async function resolveUsableProvider(components, nodeId, node, requiredTags) {
13199
13423
  function readMeshNodeId(node) {
13200
13424
  return normalizeMeshNodeId(node) ?? "";
13201
13425
  }
13426
+ function driveExpiredAwaitClaim(components, meshId, task, ctx) {
13427
+ const { sessionId, nodeId, providerType } = ctx;
13428
+ const backoffKey = `${meshId}::${task.id}`;
13429
+ const nowMs = Date.now();
13430
+ const state = autoLaunchAwaitClaimBackoff.get(backoffKey) || { cycles: 0, nextAttemptAtMs: 0 };
13431
+ if (state.nextAttemptAtMs && nowMs < state.nextAttemptAtMs) return "backoff";
13432
+ const atCap = state.cycles >= AUTO_LAUNCH_AWAIT_CLAIM_BACKOFF_CAP_CYCLES;
13433
+ const live = remoteSessionAppearsLive(meshId, sessionId);
13434
+ if ((live || atCap) && nodeId && providerType) {
13435
+ try {
13436
+ MeshRuntimeStore.getInstance().setRemoteIdleSession(meshId, nodeId, sessionId, providerType, nowMs + AUTO_LAUNCH_REMOTE_IDLE_TTL_MS);
13437
+ } catch {
13438
+ }
13439
+ const assigned = tryAssignQueueTask(components, meshId, nodeId, sessionId, providerType);
13440
+ if (assigned) {
13441
+ autoLaunchAwaitClaimBackoff.delete(backoffKey);
13442
+ const isFallback = atCap && !live;
13443
+ recordAutoLaunchEvent(meshId, {
13444
+ phase: "completed",
13445
+ taskId: task.id,
13446
+ reason: isFallback ? "await_claim_direct_dispatch_fallback" : "await_claim_redriven",
13447
+ nodeId,
13448
+ sessionId
13449
+ });
13450
+ 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})`);
13451
+ return isFallback ? "fallback" : "claimed";
13452
+ }
13453
+ if (atCap) {
13454
+ autoLaunchAwaitClaimBackoff.delete(backoffKey);
13455
+ return "respawn";
13456
+ }
13457
+ }
13458
+ const cycles = Math.min(state.cycles + 1, AUTO_LAUNCH_AWAIT_CLAIM_BACKOFF_CAP_CYCLES);
13459
+ autoLaunchAwaitClaimBackoff.set(backoffKey, { cycles, nextAttemptAtMs: nowMs + awaitClaimWindowMs(cycles) });
13460
+ recordAutoLaunchEvent(meshId, { phase: "skipped", taskId: task.id, reason: "awaiting_launched_session_claim_backoff", nodeId, sessionId });
13461
+ return "backoff";
13462
+ }
13202
13463
  async function maybeAutoLaunchOneQueueSession(components, meshId, mesh) {
13203
13464
  const queue = getQueue(meshId);
13204
13465
  const statusById = new Map(queue.map((task) => [task.id, task.status]));
13205
13466
  const pending = queue.filter((task) => task.status === "pending");
13467
+ {
13468
+ const pendingIds = new Set(pending.map((t) => t.id));
13469
+ const prefix = `${meshId}::`;
13470
+ for (const key2 of [...autoLaunchAwaitClaimBackoff.keys()]) {
13471
+ if (key2.startsWith(prefix) && !pendingIds.has(key2.slice(prefix.length))) autoLaunchAwaitClaimBackoff.delete(key2);
13472
+ }
13473
+ }
13206
13474
  if (!pending.length) return false;
13207
13475
  const maxParallelTasks = resolveMaxParallelTasks(mesh?.policy?.maxParallelTasks);
13208
13476
  const maxReadonlyParallelTasks = resolveMaxReadonlyParallelTasks(maxParallelTasks);
@@ -13227,10 +13495,18 @@ async function maybeAutoLaunchOneQueueSession(components, meshId, mesh) {
13227
13495
  }
13228
13496
  if (task.autoLaunch?.status === "completed" && task.autoLaunch.sessionId) {
13229
13497
  const launchedAtMs = Date.parse(task.autoLaunch.updatedAt);
13498
+ const alSessionId = readNonEmptyString2(task.autoLaunch.sessionId);
13499
+ const alNodeId = readNonEmptyString2(task.autoLaunch.nodeId);
13500
+ const alProvider = readNonEmptyString2(task.autoLaunch.providerType);
13230
13501
  if (Number.isFinite(launchedAtMs) && Date.now() - launchedAtMs < AUTO_LAUNCH_AWAIT_CLAIM_MS) {
13231
- recordAutoLaunchEvent(meshId, { phase: "skipped", taskId: task.id, reason: "awaiting_launched_session_claim", nodeId: task.autoLaunch.nodeId, sessionId: task.autoLaunch.sessionId });
13502
+ recordAutoLaunchEvent(meshId, { phase: "skipped", taskId: task.id, reason: "awaiting_launched_session_claim", nodeId: alNodeId, sessionId: alSessionId });
13232
13503
  continue;
13233
13504
  }
13505
+ if (Number.isFinite(launchedAtMs) && alSessionId && alNodeId) {
13506
+ const outcome = driveExpiredAwaitClaim(components, meshId, task, { sessionId: alSessionId, nodeId: alNodeId, providerType: alProvider });
13507
+ if (outcome === "claimed" || outcome === "fallback") return true;
13508
+ if (outcome === "backoff") continue;
13509
+ }
13234
13510
  }
13235
13511
  const candidateNodes = Array.isArray(mesh?.nodes) ? mesh.nodes.filter((node) => {
13236
13512
  if (task.targetNodeId && !meshNodeIdMatches(node, task.targetNodeId)) return false;
@@ -13616,7 +13892,7 @@ function runIdleMaintenanceThenAssignQueue(components, args) {
13616
13892
  });
13617
13893
  });
13618
13894
  }
13619
- var 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;
13895
+ var 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;
13620
13896
  var init_mesh_queue_assignment = __esm({
13621
13897
  "src/mesh/mesh-queue-assignment.ts"() {
13622
13898
  "use strict";
@@ -13651,6 +13927,9 @@ var init_mesh_queue_assignment = __esm({
13651
13927
  autoLaunchCooldownUntil = /* @__PURE__ */ new Map();
13652
13928
  AUTO_LAUNCH_COOLDOWN_MS = 5e3;
13653
13929
  AUTO_LAUNCH_AWAIT_CLAIM_MS = 9e4;
13930
+ AUTO_LAUNCH_AWAIT_CLAIM_BACKOFF_CAP_CYCLES = 2;
13931
+ AUTO_LAUNCH_REMOTE_IDLE_TTL_MS = 5 * 60 * 1e3;
13932
+ autoLaunchAwaitClaimBackoff = /* @__PURE__ */ new Map();
13654
13933
  lastAutoLaunchLedgerKey = /* @__PURE__ */ new Map();
13655
13934
  AUTO_LAUNCH_LEDGER_DEDUP_MAX = 2e3;
13656
13935
  ACTIONABLE_SKIP_REASON_PREFIXES = [
@@ -14678,22 +14957,26 @@ function extractFinalSummaryFromMessagesAfter(messages, minTimestampMs, maxChars
14678
14957
  return "";
14679
14958
  }
14680
14959
  function extractFinalAssistantSummaryEvidence(messages, maxChars = DEFAULT_FINAL_SUMMARY_MAX_CHARS) {
14681
- if (!Array.isArray(messages) || messages.length === 0) return { finalSummary: "" };
14960
+ const turnEnd = selectFinalAssistantTurnEndMessage(messages);
14961
+ if (!turnEnd) return { finalSummary: "" };
14962
+ return {
14963
+ finalSummary: flattenContent(turnEnd.content).trim().slice(0, maxChars),
14964
+ transcriptMessageAt: readChatMessageTimestampIso(turnEnd)
14965
+ };
14966
+ }
14967
+ function selectFinalAssistantTurnEndMessage(messages) {
14968
+ if (!Array.isArray(messages) || messages.length === 0) return null;
14682
14969
  for (let i = messages.length - 1; i >= 0; i--) {
14683
14970
  const msg = messages[i];
14684
14971
  if (!msg) continue;
14685
14972
  const classification = classifyChatMessageVisibility(msg);
14686
- if (classification.isUserFacing && (msg.role === "assistant" || msg.role === "model")) {
14687
- const text = flattenContent(msg.content).trim();
14688
- if (text) {
14689
- return {
14690
- finalSummary: text.slice(0, maxChars),
14691
- transcriptMessageAt: readChatMessageTimestampIso(msg)
14692
- };
14693
- }
14973
+ if (!classification.isUserFacing) continue;
14974
+ if (msg.role === "assistant" || msg.role === "model") {
14975
+ return flattenContent(msg.content).trim() ? msg : null;
14694
14976
  }
14977
+ return null;
14695
14978
  }
14696
- return { finalSummary: "" };
14979
+ return null;
14697
14980
  }
14698
14981
  function canonicalizeKindHint(value) {
14699
14982
  return value.trim().toLowerCase().replace(/[\s-]+/g, "_");
@@ -17687,6 +17970,11 @@ function recoverStrandedAssignedDispatches(components, meshId, store) {
17687
17970
  const assigned = getQueue(meshId, { status: ["assigned"] });
17688
17971
  if (!assigned.length) return;
17689
17972
  const nowMs = Date.now();
17973
+ const assignedKeys = new Set(assigned.map((r) => `${meshId}::${r.id}`));
17974
+ const meshKeyPrefix = `${meshId}::`;
17975
+ for (const key2 of [...deliveredNoTurnUnknownStreak.keys()]) {
17976
+ if (key2.startsWith(meshKeyPrefix) && !assignedKeys.has(key2)) deliveredNoTurnUnknownStreak.delete(key2);
17977
+ }
17690
17978
  for (const row of assigned) {
17691
17979
  const dispatchedAtMs = Date.parse(row.dispatchTimestamp ?? "");
17692
17980
  if (!Number.isFinite(dispatchedAtMs)) continue;
@@ -17710,20 +17998,45 @@ function recoverStrandedAssignedDispatches(components, meshId, store) {
17710
17998
  }
17711
17999
  if (store.taskHasConfirmedDelivery(meshId, row.id)) {
17712
18000
  if (nowMs - dispatchedAtMs < DELIVERED_NO_TURN_DEADLINE_MS) continue;
17713
- if (row.assignedSessionId && isSessionActivelyGenerating(components, row.assignedSessionId)) continue;
18001
+ const streakKey = `${meshId}::${row.id}`;
18002
+ const verdict = row.assignedSessionId ? resolveSessionBusyVerdict(components, row.assignedSessionId) : "IDLE_CONFIRMED";
18003
+ if (verdict === "GENERATING") {
18004
+ deliveredNoTurnUnknownStreak.delete(streakKey);
18005
+ continue;
18006
+ }
18007
+ let reclaimReason;
18008
+ if (verdict === "IDLE_CONFIRMED") {
18009
+ deliveredNoTurnUnknownStreak.delete(streakKey);
18010
+ reclaimReason = "delivered_no_turn_deadline";
18011
+ } else {
18012
+ const streak = (deliveredNoTurnUnknownStreak.get(streakKey) ?? 0) + 1;
18013
+ deliveredNoTurnUnknownStreak.set(streakKey, streak);
18014
+ if (streak < RECLAIM_UNKNOWN_GRACE_TICKS) {
18015
+ traceMeshEventDrop("reclaim_deferred_unknown_verdict", {
18016
+ taskId: row.id,
18017
+ sessionId: row.assignedSessionId,
18018
+ nodeId: row.assignedNodeId,
18019
+ meshId,
18020
+ event: "agent:generating_completed"
18021
+ }, `unknown ${streak}/${RECLAIM_UNKNOWN_GRACE_TICKS}`);
18022
+ continue;
18023
+ }
18024
+ reclaimReason = "reclaim_after_unknown_grace";
18025
+ }
17714
18026
  const reclaimedLost = reclaimStrandedAssignedTask(meshId, row.id, {
17715
- reason: "delivered_no_turn_deadline",
18027
+ reason: reclaimReason,
17716
18028
  ageMs: nowMs - dispatchedAtMs
17717
18029
  });
17718
18030
  if (reclaimedLost) {
17719
- 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})`);
18031
+ deliveredNoTurnUnknownStreak.delete(streakKey);
18032
+ 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})`);
17720
18033
  traceMeshEventDrop("assigned_stranded_delivered_no_turn", {
17721
18034
  taskId: row.id,
17722
18035
  sessionId: row.assignedSessionId,
17723
18036
  nodeId: row.assignedNodeId,
17724
18037
  meshId,
17725
18038
  event: "agent:generating_completed"
17726
- }, `delivered ${Math.round((nowMs - dispatchedAtMs) / 1e3)}s \u2192 ${reclaimedLost.status}`);
18039
+ }, `delivered ${Math.round((nowMs - dispatchedAtMs) / 1e3)}s ${reclaimReason} \u2192 ${reclaimedLost.status}`);
17727
18040
  }
17728
18041
  continue;
17729
18042
  }
@@ -18426,7 +18739,7 @@ function setupMeshReconcileLoop(components) {
18426
18739
  }
18427
18740
  };
18428
18741
  }
18429
- 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;
18742
+ 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;
18430
18743
  var init_mesh_reconcile_loop = __esm({
18431
18744
  "src/mesh/mesh-reconcile-loop.ts"() {
18432
18745
  "use strict";
@@ -18457,6 +18770,8 @@ var init_mesh_reconcile_loop = __esm({
18457
18770
  heldEventLedgerRecorded = /* @__PURE__ */ new Set();
18458
18771
  ASSIGNED_STRANDED_DEADLINE_MS = 5 * 6e4;
18459
18772
  DELIVERED_NO_TURN_DEADLINE_MS = 15 * 6e4;
18773
+ RECLAIM_UNKNOWN_GRACE_TICKS = 3;
18774
+ deliveredNoTurnUnknownStreak = /* @__PURE__ */ new Map();
18460
18775
  STRICT_SESSION_MATCH_TTL_MS = 6e4;
18461
18776
  unresolvedForwardRejectionCounts = /* @__PURE__ */ new Map();
18462
18777
  MAX_FORWARD_REJECTIONS = 5;
@@ -18586,63 +18901,6 @@ var init_approval_utils = __esm({
18586
18901
  }
18587
18902
  });
18588
18903
 
18589
- // src/logging/debug-config.ts
18590
- function isAlwaysOnTraceCategory(category) {
18591
- return !!category && ALWAYS_ON_TRACE_CATEGORIES.includes(category);
18592
- }
18593
- function normalizeCategories(categories) {
18594
- if (!Array.isArray(categories)) return [];
18595
- return categories.map((category) => String(category || "").trim()).filter(Boolean);
18596
- }
18597
- function resolveDebugRuntimeConfig(options = {}) {
18598
- const dev = options.dev === true;
18599
- return {
18600
- logLevel: options.logLevel || (dev ? "debug" : DEFAULT_CONFIG2.logLevel),
18601
- collectDebugTrace: typeof options.trace === "boolean" ? options.trace : dev,
18602
- traceContent: options.traceContent === true,
18603
- traceBufferSize: Number.isFinite(options.traceBufferSize) ? Math.max(10, Math.floor(options.traceBufferSize)) : dev ? DEV_TRACE_BUFFER_SIZE : DEFAULT_CONFIG2.traceBufferSize,
18604
- traceCategories: normalizeCategories(options.traceCategories)
18605
- };
18606
- }
18607
- function setDebugRuntimeConfig(config) {
18608
- currentConfig = {
18609
- ...config,
18610
- traceCategories: normalizeCategories(config.traceCategories),
18611
- traceBufferSize: Math.max(10, Math.floor(config.traceBufferSize || DEFAULT_CONFIG2.traceBufferSize))
18612
- };
18613
- }
18614
- function getDebugRuntimeConfig() {
18615
- return { ...currentConfig, traceCategories: [...currentConfig.traceCategories] };
18616
- }
18617
- function resetDebugRuntimeConfig() {
18618
- currentConfig = { ...DEFAULT_CONFIG2 };
18619
- }
18620
- function shouldCollectTraceCategory(category) {
18621
- const config = currentConfig;
18622
- if (isAlwaysOnTraceCategory(category)) return true;
18623
- if (!config.collectDebugTrace) return false;
18624
- if (!category) return true;
18625
- if (config.traceCategories.length === 0) return true;
18626
- return config.traceCategories.includes(category);
18627
- }
18628
- var NORMAL_TRACE_BUFFER_SIZE, DEV_TRACE_BUFFER_SIZE, ALWAYS_ON_TRACE_CATEGORIES, DEFAULT_CONFIG2, currentConfig;
18629
- var init_debug_config = __esm({
18630
- "src/logging/debug-config.ts"() {
18631
- "use strict";
18632
- NORMAL_TRACE_BUFFER_SIZE = 200;
18633
- DEV_TRACE_BUFFER_SIZE = 1e3;
18634
- ALWAYS_ON_TRACE_CATEGORIES = ["completion-gate", "fsm-transition"];
18635
- DEFAULT_CONFIG2 = {
18636
- logLevel: "info",
18637
- collectDebugTrace: false,
18638
- traceContent: false,
18639
- traceBufferSize: NORMAL_TRACE_BUFFER_SIZE,
18640
- traceCategories: []
18641
- };
18642
- currentConfig = { ...DEFAULT_CONFIG2 };
18643
- }
18644
- });
18645
-
18646
18904
  // src/providers/sdk/v1/schemas/cli/provider.schema.json
18647
18905
  var provider_schema_default;
18648
18906
  var init_provider_schema = __esm({
@@ -30676,97 +30934,18 @@ function resolveTargetSessionActualWorkspace(h, targetSessionId) {
30676
30934
 
30677
30935
  // src/commands/chat-commands-debug-bundle.ts
30678
30936
  init_logger();
30937
+ init_debug_trace();
30679
30938
  import * as fs7 from "fs";
30680
30939
  import * as os10 from "os";
30681
30940
  import * as path17 from "path";
30682
30941
  import { randomUUID as randomUUID11 } from "crypto";
30683
30942
 
30684
- // src/logging/debug-trace.ts
30685
- init_debug_config();
30686
- function summarizeString(value) {
30687
- return `[${value.length} chars]`;
30688
- }
30689
- function sanitizeTraceValue(value, traceContent) {
30690
- if (traceContent) {
30691
- if (Array.isArray(value)) return value.map((entry) => sanitizeTraceValue(entry, traceContent));
30692
- if (value && typeof value === "object") {
30693
- return Object.fromEntries(
30694
- Object.entries(value).map(([key2, nested]) => [key2, sanitizeTraceValue(nested, traceContent)])
30695
- );
30696
- }
30697
- return value;
30698
- }
30699
- if (typeof value === "string") return summarizeString(value);
30700
- if (Array.isArray(value)) return value.map((entry) => sanitizeTraceValue(entry, traceContent));
30701
- if (value && typeof value === "object") {
30702
- return Object.fromEntries(
30703
- Object.entries(value).map(([key2, nested]) => [key2, sanitizeTraceValue(nested, traceContent)])
30704
- );
30705
- }
30706
- return value;
30707
- }
30708
- function sanitizeTracePayload(payload) {
30709
- if (!payload) return {};
30710
- const { traceContent } = getDebugRuntimeConfig();
30711
- return sanitizeTraceValue(payload, traceContent);
30712
- }
30713
- function createEntry(event) {
30714
- return {
30715
- id: `trace_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`,
30716
- ts: Date.now(),
30717
- ...event,
30718
- payload: sanitizeTracePayload(event.payload)
30719
- };
30720
- }
30721
- function createDebugTraceStore(options) {
30722
- const entries = [];
30723
- const capacity = Math.max(1, Math.floor(options.capacity || 100));
30724
- return {
30725
- record(event) {
30726
- if (!options.enabled && !isAlwaysOnTraceCategory(event.category)) return null;
30727
- const entry = createEntry(event);
30728
- entries.push(entry);
30729
- if (entries.length > capacity) {
30730
- entries.splice(0, entries.length - capacity);
30731
- }
30732
- return entry;
30733
- },
30734
- list(query = {}) {
30735
- const limit = Math.max(1, Math.floor(query.limit || 100));
30736
- 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 } : {} }));
30737
- },
30738
- clear() {
30739
- entries.splice(0, entries.length);
30740
- }
30741
- };
30742
- }
30743
- var globalStore = createDebugTraceStore({ enabled: false, capacity: getDebugRuntimeConfig().traceBufferSize });
30744
- function configureDebugTraceStore() {
30745
- const config = getDebugRuntimeConfig();
30746
- globalStore = createDebugTraceStore({
30747
- enabled: config.collectDebugTrace,
30748
- capacity: config.traceBufferSize
30749
- });
30750
- }
30751
- function recordDebugTrace(event) {
30752
- if (!shouldCollectTraceCategory(event.category)) return null;
30753
- return globalStore.record(event);
30754
- }
30755
- function getRecentDebugTrace(query = {}) {
30756
- return globalStore.list(query);
30757
- }
30758
- function clearDebugTrace() {
30759
- globalStore.clear();
30760
- }
30761
- function createInteractionId(prefix = "ix") {
30762
- return `${prefix}_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;
30763
- }
30764
-
30765
30943
  // src/commands/chat-commands-read.ts
30766
30944
  init_contracts();
30767
30945
  import * as path16 from "path";
30768
30946
  init_coordinator_registry();
30769
30947
  init_logger();
30948
+ init_debug_trace();
30770
30949
 
30771
30950
  // src/chat/source-machine.ts
30772
30951
  var INITIAL_CHAT_SOURCE_STATE = Object.freeze({
@@ -36001,6 +36180,7 @@ ${formatManifestValidationIssues2(validation.issues)}`,
36001
36180
  };
36002
36181
 
36003
36182
  // src/commands/low-family/session-host.ts
36183
+ init_debug_trace();
36004
36184
  function toHostedCliRuntimeDescriptor(record) {
36005
36185
  if (!record || typeof record !== "object") return null;
36006
36186
  const runtimeId = typeof record.sessionId === "string" ? record.sessionId : "";
@@ -36492,6 +36672,7 @@ var refineConfigHandlers = {
36492
36672
 
36493
36673
  // src/commands/low-family/diagnostics.ts
36494
36674
  init_logger();
36675
+ init_debug_trace();
36495
36676
  import * as fs11 from "fs";
36496
36677
  var diagnosticsHandlers = {
36497
36678
  get_logs: async (_ctx, args) => {
@@ -38004,6 +38185,7 @@ function applyPreLaunchTrust(trust, workingDir) {
38004
38185
 
38005
38186
  // src/providers/spec/fsm-driver.ts
38006
38187
  init_logger();
38188
+ init_debug_trace();
38007
38189
  init_debug_config();
38008
38190
  init_pty_write_chunking();
38009
38191
  function countNewlines(s2) {
@@ -40859,6 +41041,7 @@ function createCliAdapter(provider, workingDir, cliArgs, extraEnv, transportFact
40859
41041
 
40860
41042
  // src/providers/cli-provider-instance.ts
40861
41043
  init_logger();
41044
+ init_debug_trace();
40862
41045
  init_debug_config();
40863
41046
  init_mesh_event_trace();
40864
41047
  init_control_effects();
@@ -40882,6 +41065,46 @@ function normalizeProviderSessionId(provider, providerSessionId) {
40882
41065
  return normalizedId;
40883
41066
  }
40884
41067
 
41068
+ // src/providers/native-history/antigravity-claim-registry.ts
41069
+ var claimsByUuid = /* @__PURE__ */ new Map();
41070
+ var CLAIM_STALE_MS = 10 * 60 * 1e3;
41071
+ function normalizeUuid(uuid) {
41072
+ return String(uuid || "").trim().toLowerCase();
41073
+ }
41074
+ function antigravityOwnerToken(workspace, sessionStartedAtMs, instanceId) {
41075
+ const iid = typeof instanceId === "string" ? instanceId.trim() : "";
41076
+ if (iid) return `iid:${iid}`;
41077
+ if (typeof sessionStartedAtMs === "number" && sessionStartedAtMs > 0) {
41078
+ const ws = String(workspace || "").trim().toLowerCase();
41079
+ return `spawn:${ws}:${sessionStartedAtMs}`;
41080
+ }
41081
+ return "";
41082
+ }
41083
+ function claimAntigravityConversation(uuid, owner, now = Date.now()) {
41084
+ const key2 = normalizeUuid(uuid);
41085
+ if (!key2 || !owner) return false;
41086
+ const existing = claimsByUuid.get(key2);
41087
+ if (existing && existing.owner !== owner && now - existing.refreshedAtMs < CLAIM_STALE_MS) {
41088
+ return false;
41089
+ }
41090
+ claimsByUuid.set(key2, { owner, refreshedAtMs: now });
41091
+ return true;
41092
+ }
41093
+ function isAntigravityConversationClaimedByOther(uuid, owner, now = Date.now()) {
41094
+ const key2 = normalizeUuid(uuid);
41095
+ if (!key2) return false;
41096
+ const existing = claimsByUuid.get(key2);
41097
+ if (!existing) return false;
41098
+ if (existing.owner === owner) return false;
41099
+ return now - existing.refreshedAtMs < CLAIM_STALE_MS;
41100
+ }
41101
+ function releaseAntigravityOwner(owner) {
41102
+ if (!owner) return;
41103
+ for (const [key2, claim] of claimsByUuid) {
41104
+ if (claim.owner === owner) claimsByUuid.delete(key2);
41105
+ }
41106
+ }
41107
+
40885
41108
  // src/providers/cli-provider-instance.ts
40886
41109
  init_chat_message_normalization();
40887
41110
 
@@ -41814,7 +42037,20 @@ var CliProviderInstance = class _CliProviderInstance {
41814
42037
  if (now - at > USER_INPUT_ACK_DEDUP_WINDOW_MS) this.recentUserInputAcks.delete(key2);
41815
42038
  }
41816
42039
  }
42040
+ /**
42041
+ * Owner token for this session in the antigravity conversation-claim
42042
+ * registry. Derived identically to the dispatcher's read-side token
42043
+ * (workspace + spawn time) so the claims the dispatcher records under this
42044
+ * session are the ones dispose() releases.
42045
+ */
42046
+ antigravityClaimOwner() {
42047
+ return antigravityOwnerToken(this.workingDir, this.startedAt);
42048
+ }
41817
42049
  dispose() {
42050
+ if (this.type === "antigravity-cli") {
42051
+ const owner = this.antigravityClaimOwner();
42052
+ if (owner) releaseAntigravityOwner(owner);
42053
+ }
41818
42054
  this.adapter.shutdown();
41819
42055
  this.monitor.reset();
41820
42056
  if (this.autoApproveSettleTimer) {
@@ -42569,12 +42805,21 @@ var CliProviderInstance = class _CliProviderInstance {
42569
42805
  if (this.isMeshWorkerSession()) {
42570
42806
  traceMeshEventStage("fired", this.meshTraceCtx(), `${reason} (source=${fcEvidenceSource})`);
42571
42807
  }
42808
+ if (this.completionTraceOn()) this.recordCompletionGateTrace("synth-fire", {
42809
+ path: "startup_grace_fast_collapse",
42810
+ reason,
42811
+ evidenceSource: fcEvidenceSource,
42812
+ hadFinalSummary: !!fcFinalSummary,
42813
+ missingEvidence,
42814
+ evidenceLevel: "weak"
42815
+ });
42572
42816
  this.pushEvent({
42573
42817
  event: "agent:generating_completed",
42574
42818
  chatTitle,
42575
42819
  duration: 0,
42576
42820
  timestamp: now,
42577
42821
  finalSummary: fcFinalSummary,
42822
+ evidenceLevel: "weak",
42578
42823
  completionDiagnostic: {
42579
42824
  reason,
42580
42825
  finalAssistantEvidenceSource: fcEvidenceSource,
@@ -43301,6 +43546,10 @@ ${effect.notification.body || ""}`.trim();
43301
43546
  const previousHistorySessionId = this.providerSessionId || this.instanceId;
43302
43547
  const previousProviderSessionId = this.providerSessionId;
43303
43548
  this.providerSessionId = nextSessionId;
43549
+ if (this.type === "antigravity-cli") {
43550
+ const owner = this.antigravityClaimOwner();
43551
+ if (owner) claimAntigravityConversation(nextSessionId, owner);
43552
+ }
43304
43553
  this.historyWriter.promoteHistorySession(this.type, previousHistorySessionId, nextSessionId);
43305
43554
  this.historyWriter.writeSessionStart(this.type, nextSessionId, this.workingDir, this.instanceId);
43306
43555
  if (this.shouldHydrateExistingProviderHistory()) {
@@ -47177,6 +47426,51 @@ function extractUserPrompt(payload) {
47177
47426
  if (!text) return "";
47178
47427
  return extractUserRequestContent(text);
47179
47428
  }
47429
+ function extractModelReasoning(payload) {
47430
+ const inner = firstLenField(payload, 20);
47431
+ if (!inner) return "";
47432
+ const reasoning = firstLenField(inner, 3);
47433
+ if (!reasoning || !looksLikeText(reasoning)) return "";
47434
+ return reasoning.toString("utf-8").trim();
47435
+ }
47436
+ function topLevelFieldNumbers(payload) {
47437
+ return decodeProtoFields(payload).map((f) => f.field);
47438
+ }
47439
+ var MIN_RECOVERED_MESSAGE_CHARS = 12;
47440
+ function extractUtf8TextRuns(buf) {
47441
+ if (buf.length === 0) return [];
47442
+ const decoded = buf.toString("utf-8");
47443
+ const parts = decoded.split(/[\u0000-\u0008\u000B\u000C\u000E-\u001F\u007F\uFFFD]+/);
47444
+ const runs = [];
47445
+ for (const part of parts) {
47446
+ const trimmed = part.trim();
47447
+ if (trimmed.length >= MIN_PRINTABLE_RUN) runs.push(trimmed);
47448
+ }
47449
+ return runs;
47450
+ }
47451
+ function isPlausibleMessageText(s2) {
47452
+ if (s2.length < MIN_RECOVERED_MESSAGE_CHARS) return false;
47453
+ if (!/[A-Za-zÀ-￿]/.test(s2)) return false;
47454
+ if (/^(file:\/\/|[A-Za-z]:[\\/]|\/[A-Za-z0-9._-]+\/)/.test(s2)) return false;
47455
+ if ((s2.match(/ /g) ?? []).length < 2) return false;
47456
+ if (/[[{]\s*"/.test(s2)) return false;
47457
+ const structural = (s2.match(/[{}[\]":\\]/g) ?? []).length;
47458
+ if (structural / s2.length > 0.12) return false;
47459
+ return true;
47460
+ }
47461
+ function recoverMessageText(payload, excludeTexts) {
47462
+ const exclusions = excludeTexts.map((t) => t.trim()).filter(Boolean);
47463
+ let best = "";
47464
+ for (const run of extractUtf8TextRuns(payload)) {
47465
+ const candidate = stripAnswerMarker(run).trim();
47466
+ if (!isPlausibleMessageText(candidate)) continue;
47467
+ if (exclusions.some((e) => e === candidate || e.includes(candidate) || candidate.includes(e))) {
47468
+ continue;
47469
+ }
47470
+ if (candidate.length > best.length) best = candidate;
47471
+ }
47472
+ return best;
47473
+ }
47180
47474
  function isSqliteBusyError(err) {
47181
47475
  if (!err) return false;
47182
47476
  const code = err.code;
@@ -47255,8 +47549,23 @@ function parseConversationDb(filePath, sessionId, workspace) {
47255
47549
  if (!payload || !Buffer.isBuffer(payload) || payload.length === 0) continue;
47256
47550
  const receivedAt = baseTs + messages.length;
47257
47551
  if (row.step_type === AGY_STEP_TYPE_USER) {
47258
- const content = extractUserPrompt(payload);
47259
- if (!content) continue;
47552
+ let content = extractUserPrompt(payload);
47553
+ if (!content) {
47554
+ const recovered = extractUserRequestContent(recoverMessageText(payload, []));
47555
+ if (recovered) {
47556
+ content = recovered;
47557
+ LOG.debug(
47558
+ "NativeHistory",
47559
+ `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`
47560
+ );
47561
+ } else {
47562
+ LOG.debug(
47563
+ "NativeHistory",
47564
+ `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(",")}])`
47565
+ );
47566
+ continue;
47567
+ }
47568
+ }
47260
47569
  const msg = {
47261
47570
  ts: new Date(receivedAt).toISOString(),
47262
47571
  receivedAt,
@@ -47269,8 +47578,24 @@ function parseConversationDb(filePath, sessionId, workspace) {
47269
47578
  if (normalizedWorkspace) msg.workspace = normalizedWorkspace;
47270
47579
  messages.push(msg);
47271
47580
  } else if (row.step_type === AGY_STEP_TYPE_MODEL) {
47272
- const content = extractModelAnswer(payload);
47273
- if (!content) continue;
47581
+ let content = extractModelAnswer(payload);
47582
+ if (!content) {
47583
+ const reasoning = extractModelReasoning(payload);
47584
+ const recovered = recoverMessageText(payload, reasoning ? [reasoning] : []);
47585
+ if (recovered) {
47586
+ content = recovered;
47587
+ LOG.debug(
47588
+ "NativeHistory",
47589
+ `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`
47590
+ );
47591
+ } else {
47592
+ LOG.debug(
47593
+ "NativeHistory",
47594
+ `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"})`
47595
+ );
47596
+ continue;
47597
+ }
47598
+ }
47274
47599
  const msg = {
47275
47600
  ts: new Date(receivedAt).toISOString(),
47276
47601
  receivedAt,
@@ -47516,7 +47841,8 @@ function createNativeHistoryDispatcher(reader) {
47516
47841
  const sessionId = input.sessionId || input.historySessionId || "";
47517
47842
  const requestedProviderSid = input.providerSessionId || "";
47518
47843
  const sessionStartedAtMs = typeof input.sessionStartedAtMs === "number" ? input.sessionStartedAtMs : typeof input.args?.sessionStartedAtMs === "number" ? input.args.sessionStartedAtMs : 0;
47519
- const sourcePath = resolveSourcePath(reader, workspace, sessionId, sessionStartedAtMs);
47844
+ const instanceId = typeof input.instanceId === "string" ? input.instanceId : typeof input.args?.instanceId === "string" ? input.args.instanceId : "";
47845
+ const sourcePath = resolveSourcePath(reader, workspace, sessionId, sessionStartedAtMs, instanceId);
47520
47846
  if (!sourcePath) return null;
47521
47847
  if (input.forceRefresh === true || input.args?.forceRefresh === true) {
47522
47848
  try {
@@ -47544,14 +47870,14 @@ function createNativeHistoryDispatcher(reader) {
47544
47870
  };
47545
47871
  };
47546
47872
  }
47547
- function resolveSourcePath(reader, workspace, sessionId, sessionStartedAtMs) {
47873
+ function resolveSourcePath(reader, workspace, sessionId, sessionStartedAtMs, instanceId) {
47548
47874
  switch (reader) {
47549
47875
  case "claude-cli":
47550
47876
  return resolveClaudePath(workspace, sessionId);
47551
47877
  case "codex-cli":
47552
47878
  return resolveCodexPath(workspace, sessionId, sessionStartedAtMs);
47553
47879
  case "antigravity-cli":
47554
- return resolveAntigravityPath(workspace, sessionId);
47880
+ return resolveAntigravityPath(workspace, sessionId, sessionStartedAtMs, instanceId);
47555
47881
  case "hermes-cli":
47556
47882
  return resolveHermesPath(workspace, sessionId);
47557
47883
  }
@@ -47666,27 +47992,73 @@ function resolveRealPath(value) {
47666
47992
  return value;
47667
47993
  }
47668
47994
  }
47669
- function resolveAntigravityPath(workspace, sessionId) {
47670
- void workspace;
47995
+ var AGY_SPAWN_CLAIM_GRACE_MS = 2e3;
47996
+ function resolveAntigravityPath(workspace, sessionId, sessionStartedAtMs, instanceId) {
47671
47997
  const agyRoot = path33.join(os24.homedir(), ".gemini", "antigravity-cli");
47998
+ const owner = antigravityOwnerToken(workspace, sessionStartedAtMs, instanceId);
47672
47999
  if (sessionId && isUuidLikeSessionId2(sessionId)) {
47673
48000
  const dbPath = path33.join(agyRoot, "conversations", `${sessionId}.db`);
47674
- if (fs24.existsSync(dbPath)) return dbPath;
48001
+ if (fs24.existsSync(dbPath)) {
48002
+ if (owner) claimAntigravityConversation(sessionId, owner);
48003
+ return dbPath;
48004
+ }
47675
48005
  }
47676
48006
  const brainRoot2 = path33.join(agyRoot, "brain");
47677
48007
  if (fs24.existsSync(brainRoot2)) {
47678
- const cutoff = Date.now() - RECENT_WINDOW_MS;
47679
- 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);
48008
+ const cutoff = spawnAwareCutoff(sessionStartedAtMs);
48009
+ 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);
47680
48010
  for (const e of entries) {
47681
48011
  const t = path33.join(e.p, ".system_generated", "logs", "transcript.jsonl");
47682
- if (fs24.existsSync(t) && safeSize(t) > 0) return t;
48012
+ if (fs24.existsSync(t) && safeSize(t) > 0) {
48013
+ if (owner) claimAntigravityConversation(e.uuid, owner);
48014
+ return t;
48015
+ }
47683
48016
  }
47684
48017
  }
47685
48018
  const convRoot = path33.join(agyRoot, "conversations");
47686
- const newestDb = newestRecentFile2(convRoot, /^[0-9a-f-]+\.db$/i);
47687
- if (newestDb) return newestDb;
48019
+ const picked = pickUnboundConversationDb(convRoot, sessionStartedAtMs, owner);
48020
+ if (picked) {
48021
+ if (owner) claimAntigravityConversation(picked.uuid, owner);
48022
+ return picked.path;
48023
+ }
47688
48024
  return null;
47689
48025
  }
48026
+ function pickUnboundConversationDb(convRoot, sessionFloorMs, owner) {
48027
+ let entries = [];
48028
+ try {
48029
+ entries = fs24.readdirSync(convRoot, { withFileTypes: true });
48030
+ } catch {
48031
+ return null;
48032
+ }
48033
+ const recencyCutoff = Date.now() - RECENT_WINDOW_MS;
48034
+ const candidates = [];
48035
+ for (const entry of entries) {
48036
+ if (!entry.isFile()) continue;
48037
+ const match = /^([0-9a-f-]+)\.db$/i.exec(entry.name);
48038
+ if (!match || !isUuidLikeSessionId2(match[1])) continue;
48039
+ const uuid = match[1];
48040
+ if (isAntigravityConversationClaimedByOther(uuid, owner)) continue;
48041
+ const p = path33.join(convRoot, entry.name);
48042
+ const mtime = safeMtime(p);
48043
+ if (mtime < recencyCutoff) continue;
48044
+ candidates.push({ path: p, uuid, mtime, birth: safeBirthtime(p) });
48045
+ }
48046
+ if (candidates.length === 0) return null;
48047
+ if (sessionFloorMs > 0) {
48048
+ const floor = sessionFloorMs - AGY_SPAWN_CLAIM_GRACE_MS;
48049
+ const own = candidates.filter((c) => (c.birth > 0 ? c.birth : c.mtime) >= floor);
48050
+ if (own.length === 0) return null;
48051
+ own.sort((a, b) => (a.birth || a.mtime) - (b.birth || b.mtime));
48052
+ return { path: own[0].path, uuid: own[0].uuid };
48053
+ }
48054
+ candidates.sort((a, b) => b.mtime - a.mtime);
48055
+ return { path: candidates[0].path, uuid: candidates[0].uuid };
48056
+ }
48057
+ function spawnAwareCutoff(sessionStartedAtMs) {
48058
+ const recency = Date.now() - RECENT_WINDOW_MS;
48059
+ if (sessionStartedAtMs > 0) return Math.max(recency, sessionStartedAtMs - AGY_SPAWN_CLAIM_GRACE_MS);
48060
+ return recency;
48061
+ }
47690
48062
  function resolveHermesPath(workspace, sessionId) {
47691
48063
  void workspace;
47692
48064
  void sessionId;
@@ -47743,6 +48115,15 @@ function safeMtime(p) {
47743
48115
  return 0;
47744
48116
  }
47745
48117
  }
48118
+ function safeBirthtime(p) {
48119
+ try {
48120
+ const st = fs24.statSync(p);
48121
+ const birth = Math.floor(st.birthtimeMs);
48122
+ return birth > 0 ? birth : Math.floor(st.mtimeMs);
48123
+ } catch {
48124
+ return 0;
48125
+ }
48126
+ }
47746
48127
  function safeSize(p) {
47747
48128
  try {
47748
48129
  return fs24.statSync(p).size;
@@ -53278,6 +53659,7 @@ function getRecentCommands(count = 50) {
53278
53659
  cleanOldFiles();
53279
53660
 
53280
53661
  // src/commands/router.ts
53662
+ init_debug_trace();
53281
53663
  init_mesh_host_ownership();
53282
53664
  init_mesh_work_queue();
53283
53665
  import * as fs33 from "fs";
@@ -54570,9 +54952,10 @@ async function resolveProviderTypeFromPriority(args) {
54570
54952
 
54571
54953
  // src/commands/router-refine.ts
54572
54954
  init_logger();
54573
- import { execFileSync as execFileSync8 } from "child_process";
54955
+ init_debug_trace();
54574
54956
  init_dist();
54575
54957
  init_mesh_events();
54958
+ import { execFileSync as execFileSync8 } from "child_process";
54576
54959
 
54577
54960
  // src/mesh/mesh-refine-batch.ts
54578
54961
  init_resolve_executable();
@@ -58796,6 +59179,7 @@ init_build_info();
58796
59179
  init_normalize();
58797
59180
  init_logger();
58798
59181
  init_debug_config();
59182
+ init_debug_trace();
58799
59183
 
58800
59184
  // src/ipc-protocol.ts
58801
59185
  var DEFAULT_DAEMON_PORT = 19222;