@adhdev/daemon-core 0.9.82-rc.457 → 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.
Files changed (30) hide show
  1. package/dist/index.d.ts +1 -1
  2. package/dist/index.js +677 -189
  3. package/dist/index.js.map +1 -1
  4. package/dist/index.mjs +676 -190
  5. package/dist/index.mjs.map +1 -1
  6. package/dist/logging/debug-config.d.ts +16 -0
  7. package/dist/mesh/mesh-queue-assignment.d.ts +28 -0
  8. package/dist/mesh/mesh-reconcile-loop.d.ts +1 -0
  9. package/dist/mesh/worktree-bootstrap-config.d.ts +45 -0
  10. package/dist/providers/chat-message-normalization.d.ts +26 -0
  11. package/dist/providers/cli-provider-instance.d.ts +7 -0
  12. package/dist/providers/native-history/antigravity-claim-registry.d.ts +28 -0
  13. package/dist/providers/native-history/antigravity-cli-transcript.d.ts +11 -0
  14. package/dist/providers/native-history/dispatcher.d.ts +4 -0
  15. package/package.json +3 -3
  16. package/src/index.ts +2 -0
  17. package/src/logging/debug-config.ts +25 -0
  18. package/src/logging/debug-trace.ts +7 -2
  19. package/src/mesh/coordinator-prompt.ts +1 -1
  20. package/src/mesh/mesh-events-stale.ts +55 -4
  21. package/src/mesh/mesh-fast-forward.ts +22 -9
  22. package/src/mesh/mesh-queue-assignment.ts +220 -3
  23. package/src/mesh/mesh-reconcile-loop.ts +83 -10
  24. package/src/mesh/mesh-refine-gates.ts +22 -9
  25. package/src/mesh/worktree-bootstrap-config.ts +130 -0
  26. package/src/providers/chat-message-normalization.ts +44 -10
  27. package/src/providers/cli-provider-instance.ts +46 -0
  28. package/src/providers/native-history/antigravity-claim-registry.ts +131 -0
  29. package/src/providers/native-history/antigravity-cli-transcript.ts +154 -4
  30. package/src/providers/native-history/dispatcher.ts +150 -20
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 ? "29441f596e5efe1972b874e0fb5b3d380c9d9bda" : void 0) ?? "unknown";
413
- const commitShort = readInjected(true ? "29441f59" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
414
- const version = readInjected(true ? "0.9.82-rc.457" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
415
- const builtAt = readInjected(true ? "2026-07-04T08:51:27.287Z" : 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
  }
@@ -3704,7 +3704,7 @@ function buildRulesSection(coordinatorCliType) {
3704
3704
  - **Verify via git, not source.** Use \`mesh_git_status\` to confirm side effects. Treat agent summaries as self-reports, not verification.
3705
3705
  - **Limit parallelism.** Start with 1\u20132 tasks; scale only on success. Never duplicate a session because \`mesh_read_chat\` shows no final message while tool/terminal activity is ongoing. This caps *concurrent* load \u2014 it does not mean serialize independent work: when a new, independent request arrives and there is headroom under \`maxParallelTasks\`, dispatch it right away rather than waiting for an in-flight task or a user nudge (read-only diagnosis especially, since it has no merge cost).
3706
3706
  - **Check history first.** Call \`mesh_task_history\` at session start to avoid duplicate work and inform recovery. On failure, read task history before retrying.
3707
- - **Sequence shared-base-moving merges.** Parallel dispatch is encouraged, but merging one worktree can advance another in-flight worktree's base \u2014 especially the oss submodule pointer \u2014 turning a clean fast-forward into a diverged rebase (patch-equivalence correctly blocks this). Before merging an in-flight worktree while siblings are also in flight, land in an intentional order, re-clone long-running worktrees from the advanced base, or expect to manually rebase + ff-only the laggards; merging an independent fix mid-flight can strand siblings into a rebase.
3707
+ - **Sequence shared-base-moving merges.** Parallel dispatch is encouraged, but merging one worktree can advance another in-flight worktree's base \u2014 especially a shared submodule pointer \u2014 turning a clean fast-forward into a diverged rebase (patch-equivalence correctly blocks this). Before merging an in-flight worktree while siblings are also in flight, land in an intentional order, re-clone long-running worktrees from the advanced base, or expect to manually rebase + ff-only the laggards; merging an independent fix mid-flight can strand siblings into a rebase.
3708
3708
  - **Converge branches.** After worktree tasks: refine/fast-forward, or classify as \`pushed_feature_branch_needs_merge\` / \`blocked_review\` / \`cleanup_candidate\` / \`not_mergeable\`. Clean up with \`mesh_remove_node\`.
3709
3709
  - **Refinery is config-driven.** \`mesh_refine_node\` must run validation from \`.adhdev/refine.{json,yaml,yml}\` or \`repo-mesh.refine.*\`. Heuristics are scaffolding only.
3710
3710
  - **Submodule reachability = publish-needed.** \`submodule_reachability_failed\` \u2192 classify as \`blocked_review\`, request user approval to push to submodule main, then rerun \`mesh_refine_node\`.
@@ -8931,12 +8931,15 @@ var worktree_bootstrap_config_exports = {};
8931
8931
  __export(worktree_bootstrap_config_exports, {
8932
8932
  MESH_WORKTREE_BOOTSTRAP_CONFIG_LOCATIONS: () => MESH_WORKTREE_BOOTSTRAP_CONFIG_LOCATIONS,
8933
8933
  MESH_WORKTREE_BOOTSTRAP_CONFIG_SCHEMA: () => MESH_WORKTREE_BOOTSTRAP_CONFIG_SCHEMA,
8934
+ SUBMODULE_DEFAULT_BRANCH_FALLBACK: () => SUBMODULE_DEFAULT_BRANCH_FALLBACK,
8934
8935
  WORKTREE_BOOTSTRAP_STALE_RUNNING_MS: () => WORKTREE_BOOTSTRAP_STALE_RUNNING_MS,
8935
8936
  computeStaleInputsDigest: () => computeStaleInputsDigest,
8936
8937
  evaluateWorktreeBootstrapState: () => evaluateWorktreeBootstrapState,
8937
8938
  getRegisteredSubmodulePaths: () => getRegisteredSubmodulePaths,
8939
+ getSubmoduleConfiguredBranches: () => getSubmoduleConfiguredBranches,
8938
8940
  isWorktreeBootstrapStaleRunning: () => isWorktreeBootstrapStaleRunning,
8939
8941
  loadMeshWorktreeBootstrapConfig: () => loadMeshWorktreeBootstrapConfig,
8942
+ resolveSubmoduleDefaultBranch: () => resolveSubmoduleDefaultBranch,
8940
8943
  runMeshWorktreeBootstrap: () => runMeshWorktreeBootstrap,
8941
8944
  shouldDeferDispatchForBootstrap: () => shouldDeferDispatchForBootstrap,
8942
8945
  validateMeshWorktreeBootstrapConfig: () => validateMeshWorktreeBootstrapConfig
@@ -8961,6 +8964,81 @@ function getRegisteredSubmodulePaths(workspace) {
8961
8964
  }
8962
8965
  return paths;
8963
8966
  }
8967
+ function getSubmoduleConfiguredBranches(workspace) {
8968
+ const branchesByPath = /* @__PURE__ */ new Map();
8969
+ try {
8970
+ const out = (0, import_node_child_process3.execFileSync)(
8971
+ resolveWin32Executable("git"),
8972
+ ["config", "--file", ".gitmodules", "--list"],
8973
+ { cwd: workspace, encoding: "utf8", timeout: 1e4, windowsHide: true }
8974
+ );
8975
+ const pathByName = /* @__PURE__ */ new Map();
8976
+ const branchByName = /* @__PURE__ */ new Map();
8977
+ for (const line of String(out).split(/\r?\n/)) {
8978
+ const trimmed = line.trim();
8979
+ if (!trimmed) continue;
8980
+ const eq = trimmed.indexOf("=");
8981
+ if (eq < 0) continue;
8982
+ const key2 = trimmed.slice(0, eq);
8983
+ const value = trimmed.slice(eq + 1).trim();
8984
+ const match = /^submodule\.(.+)\.(path|branch)$/.exec(key2);
8985
+ if (!match) continue;
8986
+ const name = match[1];
8987
+ if (match[2] === "path") {
8988
+ const norm = value.replace(/\\/g, "/").replace(/\/+$/, "");
8989
+ if (norm) pathByName.set(name, norm);
8990
+ } else if (value) {
8991
+ branchByName.set(name, value);
8992
+ }
8993
+ }
8994
+ for (const [name, submodulePath] of pathByName) {
8995
+ const branch = branchByName.get(name);
8996
+ if (branch && branch !== ".") branchesByPath.set(submodulePath, branch);
8997
+ }
8998
+ } catch {
8999
+ }
9000
+ return branchesByPath;
9001
+ }
9002
+ function isPlausibleBranchName(name) {
9003
+ return typeof name === "string" && name.length > 0 && !/\s/.test(name) && name !== "HEAD";
9004
+ }
9005
+ async function resolveSubmoduleDefaultBranch(opts) {
9006
+ const remote = opts.remote?.trim() || "origin";
9007
+ const localTimeout = opts.timeoutMs ?? 1e4;
9008
+ const git = resolveWin32Executable("git");
9009
+ const execFileAsync4 = (0, import_node_util3.promisify)(import_node_child_process3.execFile);
9010
+ if (opts.superprojectWorkspace && opts.submodulePath) {
9011
+ try {
9012
+ const normalized = opts.submodulePath.replace(/\\/g, "/").replace(/\/+$/, "");
9013
+ const configured = getSubmoduleConfiguredBranches(opts.superprojectWorkspace).get(normalized);
9014
+ if (isPlausibleBranchName(configured)) return configured;
9015
+ } catch {
9016
+ }
9017
+ }
9018
+ try {
9019
+ const { stdout } = await execFileAsync4(
9020
+ git,
9021
+ ["symbolic-ref", "--short", `refs/remotes/${remote}/HEAD`],
9022
+ { cwd: opts.submoduleRepoPath, encoding: "utf8", timeout: localTimeout, windowsHide: true }
9023
+ );
9024
+ const short = String(stdout || "").trim();
9025
+ const prefix = `${remote}/`;
9026
+ const branch = short.startsWith(prefix) ? short.slice(prefix.length) : short;
9027
+ if (isPlausibleBranchName(branch)) return branch;
9028
+ } catch {
9029
+ }
9030
+ try {
9031
+ const { stdout } = await execFileAsync4(
9032
+ git,
9033
+ ["ls-remote", "--symref", remote, "HEAD"],
9034
+ { cwd: opts.submoduleRepoPath, encoding: "utf8", timeout: Math.max(localTimeout, 3e4), windowsHide: true }
9035
+ );
9036
+ const match = /^ref:\s+refs\/heads\/(\S+)\s+HEAD/m.exec(String(stdout || ""));
9037
+ if (match && isPlausibleBranchName(match[1])) return match[1];
9038
+ } catch {
9039
+ }
9040
+ return SUBMODULE_DEFAULT_BRANCH_FALLBACK;
9041
+ }
8964
9042
  function isCleanIgnoringSubmoduleGitlinks(porcelain, submodulePaths) {
8965
9043
  const lines = porcelain.split(/\r?\n/).filter((line) => line.length > 0);
8966
9044
  for (const line of lines) {
@@ -9203,7 +9281,7 @@ async function runMeshWorktreeBootstrap(mesh, workspace) {
9203
9281
  }
9204
9282
  return state;
9205
9283
  }
9206
- var import_fs9, import_path8, import_node_child_process3, import_node_crypto2, import_node_util3, yaml3, WORKTREE_BOOTSTRAP_STALE_RUNNING_MS, MESH_WORKTREE_BOOTSTRAP_CONFIG_LOCATIONS, MESH_WORKTREE_BOOTSTRAP_CONFIG_SCHEMA, DEFAULT_TIMEOUT_MS2, DEFAULT_OUTPUT_LIMIT_BYTES, OUTPUT_SUMMARY_CHARS;
9284
+ var import_fs9, import_path8, import_node_child_process3, import_node_crypto2, import_node_util3, yaml3, WORKTREE_BOOTSTRAP_STALE_RUNNING_MS, SUBMODULE_DEFAULT_BRANCH_FALLBACK, MESH_WORKTREE_BOOTSTRAP_CONFIG_LOCATIONS, MESH_WORKTREE_BOOTSTRAP_CONFIG_SCHEMA, DEFAULT_TIMEOUT_MS2, DEFAULT_OUTPUT_LIMIT_BYTES, OUTPUT_SUMMARY_CHARS;
9207
9285
  var init_worktree_bootstrap_config = __esm({
9208
9286
  "src/mesh/worktree-bootstrap-config.ts"() {
9209
9287
  "use strict";
@@ -9216,6 +9294,7 @@ var init_worktree_bootstrap_config = __esm({
9216
9294
  init_resolve_executable();
9217
9295
  init_refine_config();
9218
9296
  WORKTREE_BOOTSTRAP_STALE_RUNNING_MS = 10 * 60 * 1e3;
9297
+ SUBMODULE_DEFAULT_BRANCH_FALLBACK = "main";
9219
9298
  MESH_WORKTREE_BOOTSTRAP_CONFIG_LOCATIONS = [
9220
9299
  ".adhdev/worktree_bootstrap.json",
9221
9300
  ".adhdev/worktree_bootstrap.yaml",
@@ -9832,15 +9911,24 @@ async function resolveSubmodulePushes(status, options, execute, timeoutMs) {
9832
9911
  results.push({ ...base, code: "submodule_status_incomplete" });
9833
9912
  continue;
9834
9913
  }
9914
+ const remoteBranch = await resolveSubmoduleDefaultBranch({
9915
+ submoduleRepoPath: repoPath,
9916
+ superprojectWorkspace: status.repoRoot ?? status.workspace,
9917
+ submodulePath: submodule.path,
9918
+ timeoutMs
9919
+ });
9920
+ base.remoteBranch = remoteBranch;
9921
+ const remoteRef = `refs/remotes/origin/${remoteBranch}`;
9922
+ const fetchRefspec = `refs/heads/${remoteBranch}:${remoteRef}`;
9835
9923
  try {
9836
- await runGit(repoPath, ["-c", "protocol.file.allow=always", "fetch", "origin", "refs/heads/main:refs/remotes/origin/main"], { timeoutMs: timeoutMs ?? 3e4 });
9924
+ await runGit(repoPath, ["-c", "protocol.file.allow=always", "fetch", "origin", fetchRefspec], { timeoutMs: timeoutMs ?? 3e4 });
9837
9925
  } catch (error) {
9838
9926
  results.push({ ...base, code: "submodule_fetch_failed", error: formatGitError2(error) });
9839
9927
  continue;
9840
9928
  }
9841
9929
  let alreadyReachable = false;
9842
9930
  try {
9843
- await runGit(repoPath, ["merge-base", "--is-ancestor", submodule.commit, "refs/remotes/origin/main"], { timeoutMs: timeoutMs ?? 15e3 });
9931
+ await runGit(repoPath, ["merge-base", "--is-ancestor", submodule.commit, remoteRef], { timeoutMs: timeoutMs ?? 15e3 });
9844
9932
  alreadyReachable = true;
9845
9933
  } catch {
9846
9934
  }
@@ -9849,20 +9937,20 @@ async function resolveSubmodulePushes(status, options, execute, timeoutMs) {
9849
9937
  continue;
9850
9938
  }
9851
9939
  try {
9852
- await runGit(repoPath, ["merge-base", "--is-ancestor", "refs/remotes/origin/main", submodule.commit], { timeoutMs: timeoutMs ?? 15e3 });
9940
+ await runGit(repoPath, ["merge-base", "--is-ancestor", remoteRef, submodule.commit], { timeoutMs: timeoutMs ?? 15e3 });
9853
9941
  } catch (error) {
9854
9942
  results.push({ ...base, pushed: false, skipped: false, code: "submodule_non_fast_forward", error: formatGitError2(error) });
9855
9943
  continue;
9856
9944
  }
9857
- const refspec = `${submodule.commit}:refs/heads/main`;
9945
+ const refspec = `${submodule.commit}:refs/heads/${remoteBranch}`;
9858
9946
  if (!execute) {
9859
9947
  results.push({ ...base, pushed: false, skipped: false, code: "submodule_push_available", refspec });
9860
9948
  continue;
9861
9949
  }
9862
9950
  try {
9863
9951
  await runGit(repoPath, ["push", "origin", refspec], { timeoutMs: timeoutMs ?? 3e4 });
9864
- await runGit(repoPath, ["-c", "protocol.file.allow=always", "fetch", "origin", "refs/heads/main:refs/remotes/origin/main"], { timeoutMs: timeoutMs ?? 3e4 });
9865
- await runGit(repoPath, ["merge-base", "--is-ancestor", submodule.commit, "refs/remotes/origin/main"], { timeoutMs: timeoutMs ?? 15e3 });
9952
+ await runGit(repoPath, ["-c", "protocol.file.allow=always", "fetch", "origin", fetchRefspec], { timeoutMs: timeoutMs ?? 3e4 });
9953
+ await runGit(repoPath, ["merge-base", "--is-ancestor", submodule.commit, remoteRef], { timeoutMs: timeoutMs ?? 15e3 });
9866
9954
  results.push({ ...base, pushed: true, skipped: false, code: "submodule_pushed", refspec });
9867
9955
  } catch (error) {
9868
9956
  results.push({ ...base, pushed: false, skipped: false, code: "submodule_push_failed", refspec, error: formatGitError2(error) });
@@ -10130,6 +10218,7 @@ var init_mesh_fast_forward = __esm({
10130
10218
  "use strict";
10131
10219
  init_git_status();
10132
10220
  init_git_executor();
10221
+ init_worktree_bootstrap_config();
10133
10222
  STATUS_OPTIONS = { refreshUpstream: true, includeSubmodules: true, timeoutMs: 15e3, forceFresh: true };
10134
10223
  }
10135
10224
  });
@@ -11454,7 +11543,154 @@ var init_mesh_events_pending = __esm({
11454
11543
  }
11455
11544
  });
11456
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
+
11457
11690
  // src/mesh/mesh-events-stale.ts
11691
+ function recordSynthCompletionGateTrace(stage, payload) {
11692
+ recordDebugTrace({ category: "completion-gate", stage, level: "debug", payload });
11693
+ }
11458
11694
  function findRecentTerminalLedgerEvidence(args) {
11459
11695
  if (!args.sessionId && !args.nodeId) return null;
11460
11696
  const entries = readLedgerEntries(args.meshId, { tail: 200 });
@@ -11588,6 +11824,7 @@ function reconcileDirectDispatchCompletionFromTranscript(args) {
11588
11824
  completedAt
11589
11825
  });
11590
11826
  const workerResult = evidence.workerResult;
11827
+ const selfAttributing = workerResult.source === "final_summary_json";
11591
11828
  const dispatchTime = dispatch?.timestamp ? new Date(dispatch.timestamp).getTime() : Number.NaN;
11592
11829
  const transcriptTime = args.transcriptMessageAt ? new Date(args.transcriptMessageAt).getTime() : Number.NaN;
11593
11830
  const transcriptAfterDispatch = Number.isFinite(dispatchTime) && Number.isFinite(transcriptTime) && transcriptTime >= dispatchTime;
@@ -11620,7 +11857,9 @@ function reconcileDirectDispatchCompletionFromTranscript(args) {
11620
11857
  dispatchEntryId: dispatch?.id,
11621
11858
  dispatchTimestamp: dispatch?.timestamp,
11622
11859
  transcriptMessageAt: readNonEmptyString2(args.transcriptMessageAt),
11623
- 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
11624
11863
  },
11625
11864
  evidence
11626
11865
  }
@@ -11637,6 +11876,11 @@ function reconcileDirectDispatchCompletionFromTranscript(args) {
11637
11876
  finalSummary,
11638
11877
  taskId: args.taskId,
11639
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" },
11640
11884
  completionDiagnostic: {
11641
11885
  reason: "direct_task_transcript_reconciliation",
11642
11886
  terminalLedgerKind: kind,
@@ -11655,6 +11899,14 @@ function reconcileDirectDispatchCompletionFromTranscript(args) {
11655
11899
  ...readNonEmptyString2(args.targetCoordinatorDaemonId) ? { targetCoordinatorDaemonId: readNonEmptyString2(args.targetCoordinatorDaemonId) } : {},
11656
11900
  ...targetCoordinatorSessionId ? { targetCoordinatorSessionId } : {}
11657
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
+ });
11658
11910
  return { reconciled: true, kind, workerResult, ledgerEntryId: entry.id };
11659
11911
  }
11660
11912
  function buildNoProgressCompletionReconciliation(args) {
@@ -11666,10 +11918,20 @@ function buildNoProgressCompletionReconciliation(args) {
11666
11918
  const completionDiagnostic = readRecord5(args.metadataEvent.completionDiagnostic);
11667
11919
  const finalSummary = readNonEmptyString2(args.metadataEvent.finalSummary);
11668
11920
  const status = readNonEmptyString2(args.metadataEvent.status).toLowerCase();
11921
+ const noProgressSelfAttributing = Boolean(
11922
+ finalSummary || workerResult || completionDiagnostic?.finalAssistantPresent === true
11923
+ );
11669
11924
  const explicitCompletionEvidence = Boolean(
11670
- finalSummary || workerResult || completionDiagnostic?.finalAssistantPresent === true || status === "idle" || status === "ready" || status === "completed"
11925
+ noProgressSelfAttributing || status === "idle" || status === "ready" || status === "completed"
11671
11926
  );
11672
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
+ });
11673
11935
  return {
11674
11936
  ...args.metadataEvent,
11675
11937
  targetSessionId: sessionId,
@@ -11679,6 +11941,7 @@ function buildNoProgressCompletionReconciliation(args) {
11679
11941
  source: "no_progress_reconciliation",
11680
11942
  reconciledFromEvent: "monitor:no_progress",
11681
11943
  timestamp: args.metadataEvent.timestamp ?? Date.now(),
11944
+ ...noProgressSelfAttributing ? {} : { evidenceLevel: "weak" },
11682
11945
  completionDiagnostic: {
11683
11946
  ...completionDiagnostic || {},
11684
11947
  reconciliationReason: "provider_completion_evidence"
@@ -11707,6 +11970,7 @@ var init_mesh_events_stale = __esm({
11707
11970
  init_mesh_delivery_policy();
11708
11971
  init_mesh_events_pending();
11709
11972
  init_mesh_events_utils();
11973
+ init_debug_trace();
11710
11974
  init_dist();
11711
11975
  DIRECT_DISPATCH_RECONCILE_GRACE_MS = 6e4;
11712
11976
  DIRECT_DISPATCH_IDLE_SESSION_RECONCILE_GRACE_MS = 12e4;
@@ -12753,6 +13017,32 @@ function tryAssignQueueTask(components, meshId, nodeId, sessionId, providerType)
12753
13017
  );
12754
13018
  return true;
12755
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
+ }
12756
13046
  function isActionableSkipReason(reason) {
12757
13047
  if (!reason) return false;
12758
13048
  return ACTIONABLE_SKIP_REASON_PREFIXES.some((prefix) => reason === prefix || reason.startsWith(prefix));
@@ -12992,8 +13282,24 @@ function isSessionActivelyGenerating(components, sessionId) {
12992
13282
  if (!state) return false;
12993
13283
  return sessionStateLooksActive(state);
12994
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
+ }
12995
13301
  function liveSessionCountForNode(components, meshId, nodeId) {
12996
- return components.instanceManager.getByCategory("cli").filter((inst) => {
13302
+ const localInstances = components.instanceManager.getByCategory("cli").filter((inst) => {
12997
13303
  const state = inst.getState();
12998
13304
  const settings = state.settings || {};
12999
13305
  if (readNonEmptyString2(settings.meshNodeFor) !== meshId) return false;
@@ -13001,9 +13307,16 @@ function liveSessionCountForNode(components, meshId, nodeId) {
13001
13307
  if (!daemonIdsEquivalent(instNodeId, nodeId)) return false;
13002
13308
  const status = readNonEmptyString2(state.status).toLowerCase();
13003
13309
  return !isTerminalSessionStatus(status);
13004
- }).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;
13005
13317
  }
13006
13318
  function nodeHasLiveSessionPendingClaim(components, meshId, nodeId) {
13319
+ if (inWindowAutoLaunchSessionIdsForNode(meshId, nodeId).length > 0) return true;
13007
13320
  const busySessionIds = new Set(
13008
13321
  getQueue(meshId, { status: ["assigned"] }).filter((task) => daemonIdsEquivalent(task.assignedNodeId, nodeId)).map((task) => readNonEmptyString2(task.assignedSessionId)).filter(Boolean)
13009
13322
  );
@@ -13114,10 +13427,54 @@ async function resolveUsableProvider(components, nodeId, node, requiredTags) {
13114
13427
  function readMeshNodeId(node) {
13115
13428
  return normalizeMeshNodeId(node) ?? "";
13116
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
+ }
13117
13467
  async function maybeAutoLaunchOneQueueSession(components, meshId, mesh) {
13118
13468
  const queue = getQueue(meshId);
13119
13469
  const statusById = new Map(queue.map((task) => [task.id, task.status]));
13120
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
+ }
13121
13478
  if (!pending.length) return false;
13122
13479
  const maxParallelTasks = resolveMaxParallelTasks(mesh?.policy?.maxParallelTasks);
13123
13480
  const maxReadonlyParallelTasks = resolveMaxReadonlyParallelTasks(maxParallelTasks);
@@ -13142,10 +13499,18 @@ async function maybeAutoLaunchOneQueueSession(components, meshId, mesh) {
13142
13499
  }
13143
13500
  if (task.autoLaunch?.status === "completed" && task.autoLaunch.sessionId) {
13144
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);
13145
13505
  if (Number.isFinite(launchedAtMs) && Date.now() - launchedAtMs < AUTO_LAUNCH_AWAIT_CLAIM_MS) {
13146
- 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 });
13147
13507
  continue;
13148
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
+ }
13149
13514
  }
13150
13515
  const candidateNodes = Array.isArray(mesh?.nodes) ? mesh.nodes.filter((node) => {
13151
13516
  if (task.targetNodeId && !meshNodeIdMatches(node, task.targetNodeId)) return false;
@@ -13531,7 +13896,7 @@ function runIdleMaintenanceThenAssignQueue(components, args) {
13531
13896
  });
13532
13897
  });
13533
13898
  }
13534
- 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;
13535
13900
  var init_mesh_queue_assignment = __esm({
13536
13901
  "src/mesh/mesh-queue-assignment.ts"() {
13537
13902
  "use strict";
@@ -13567,6 +13932,9 @@ var init_mesh_queue_assignment = __esm({
13567
13932
  autoLaunchCooldownUntil = /* @__PURE__ */ new Map();
13568
13933
  AUTO_LAUNCH_COOLDOWN_MS = 5e3;
13569
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();
13570
13938
  lastAutoLaunchLedgerKey = /* @__PURE__ */ new Map();
13571
13939
  AUTO_LAUNCH_LEDGER_DEDUP_MAX = 2e3;
13572
13940
  ACTIONABLE_SKIP_REASON_PREFIXES = [
@@ -14594,22 +14962,26 @@ function extractFinalSummaryFromMessagesAfter(messages, minTimestampMs, maxChars
14594
14962
  return "";
14595
14963
  }
14596
14964
  function extractFinalAssistantSummaryEvidence(messages, maxChars = DEFAULT_FINAL_SUMMARY_MAX_CHARS) {
14597
- 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;
14598
14974
  for (let i = messages.length - 1; i >= 0; i--) {
14599
14975
  const msg = messages[i];
14600
14976
  if (!msg) continue;
14601
14977
  const classification = classifyChatMessageVisibility(msg);
14602
- if (classification.isUserFacing && (msg.role === "assistant" || msg.role === "model")) {
14603
- const text = flattenContent(msg.content).trim();
14604
- if (text) {
14605
- return {
14606
- finalSummary: text.slice(0, maxChars),
14607
- transcriptMessageAt: readChatMessageTimestampIso(msg)
14608
- };
14609
- }
14978
+ if (!classification.isUserFacing) continue;
14979
+ if (msg.role === "assistant" || msg.role === "model") {
14980
+ return flattenContent(msg.content).trim() ? msg : null;
14610
14981
  }
14982
+ return null;
14611
14983
  }
14612
- return { finalSummary: "" };
14984
+ return null;
14613
14985
  }
14614
14986
  function canonicalizeKindHint(value) {
14615
14987
  return value.trim().toLowerCase().replace(/[\s-]+/g, "_");
@@ -17603,6 +17975,11 @@ function recoverStrandedAssignedDispatches(components, meshId, store) {
17603
17975
  const assigned = getQueue(meshId, { status: ["assigned"] });
17604
17976
  if (!assigned.length) return;
17605
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
+ }
17606
17983
  for (const row of assigned) {
17607
17984
  const dispatchedAtMs = Date.parse(row.dispatchTimestamp ?? "");
17608
17985
  if (!Number.isFinite(dispatchedAtMs)) continue;
@@ -17626,20 +18003,45 @@ function recoverStrandedAssignedDispatches(components, meshId, store) {
17626
18003
  }
17627
18004
  if (store.taskHasConfirmedDelivery(meshId, row.id)) {
17628
18005
  if (nowMs - dispatchedAtMs < DELIVERED_NO_TURN_DEADLINE_MS) continue;
17629
- 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
+ }
17630
18031
  const reclaimedLost = reclaimStrandedAssignedTask(meshId, row.id, {
17631
- reason: "delivered_no_turn_deadline",
18032
+ reason: reclaimReason,
17632
18033
  ageMs: nowMs - dispatchedAtMs
17633
18034
  });
17634
18035
  if (reclaimedLost) {
17635
- 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})`);
17636
18038
  traceMeshEventDrop("assigned_stranded_delivered_no_turn", {
17637
18039
  taskId: row.id,
17638
18040
  sessionId: row.assignedSessionId,
17639
18041
  nodeId: row.assignedNodeId,
17640
18042
  meshId,
17641
18043
  event: "agent:generating_completed"
17642
- }, `delivered ${Math.round((nowMs - dispatchedAtMs) / 1e3)}s \u2192 ${reclaimedLost.status}`);
18044
+ }, `delivered ${Math.round((nowMs - dispatchedAtMs) / 1e3)}s ${reclaimReason} \u2192 ${reclaimedLost.status}`);
17643
18045
  }
17644
18046
  continue;
17645
18047
  }
@@ -18342,7 +18744,7 @@ function setupMeshReconcileLoop(components) {
18342
18744
  }
18343
18745
  };
18344
18746
  }
18345
- 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;
18346
18748
  var init_mesh_reconcile_loop = __esm({
18347
18749
  "src/mesh/mesh-reconcile-loop.ts"() {
18348
18750
  "use strict";
@@ -18373,6 +18775,8 @@ var init_mesh_reconcile_loop = __esm({
18373
18775
  heldEventLedgerRecorded = /* @__PURE__ */ new Set();
18374
18776
  ASSIGNED_STRANDED_DEADLINE_MS = 5 * 6e4;
18375
18777
  DELIVERED_NO_TURN_DEADLINE_MS = 15 * 6e4;
18778
+ RECLAIM_UNKNOWN_GRACE_TICKS = 3;
18779
+ deliveredNoTurnUnknownStreak = /* @__PURE__ */ new Map();
18376
18780
  STRICT_SESSION_MATCH_TTL_MS = 6e4;
18377
18781
  unresolvedForwardRejectionCounts = /* @__PURE__ */ new Map();
18378
18782
  MAX_FORWARD_REJECTIONS = 5;
@@ -18502,58 +18906,6 @@ var init_approval_utils = __esm({
18502
18906
  }
18503
18907
  });
18504
18908
 
18505
- // src/logging/debug-config.ts
18506
- function normalizeCategories(categories) {
18507
- if (!Array.isArray(categories)) return [];
18508
- return categories.map((category) => String(category || "").trim()).filter(Boolean);
18509
- }
18510
- function resolveDebugRuntimeConfig(options = {}) {
18511
- const dev = options.dev === true;
18512
- return {
18513
- logLevel: options.logLevel || (dev ? "debug" : DEFAULT_CONFIG2.logLevel),
18514
- collectDebugTrace: typeof options.trace === "boolean" ? options.trace : dev,
18515
- traceContent: options.traceContent === true,
18516
- traceBufferSize: Number.isFinite(options.traceBufferSize) ? Math.max(10, Math.floor(options.traceBufferSize)) : dev ? DEV_TRACE_BUFFER_SIZE : DEFAULT_CONFIG2.traceBufferSize,
18517
- traceCategories: normalizeCategories(options.traceCategories)
18518
- };
18519
- }
18520
- function setDebugRuntimeConfig(config) {
18521
- currentConfig = {
18522
- ...config,
18523
- traceCategories: normalizeCategories(config.traceCategories),
18524
- traceBufferSize: Math.max(10, Math.floor(config.traceBufferSize || DEFAULT_CONFIG2.traceBufferSize))
18525
- };
18526
- }
18527
- function getDebugRuntimeConfig() {
18528
- return { ...currentConfig, traceCategories: [...currentConfig.traceCategories] };
18529
- }
18530
- function resetDebugRuntimeConfig() {
18531
- currentConfig = { ...DEFAULT_CONFIG2 };
18532
- }
18533
- function shouldCollectTraceCategory(category) {
18534
- const config = currentConfig;
18535
- if (!config.collectDebugTrace) return false;
18536
- if (!category) return true;
18537
- if (config.traceCategories.length === 0) return true;
18538
- return config.traceCategories.includes(category);
18539
- }
18540
- var NORMAL_TRACE_BUFFER_SIZE, DEV_TRACE_BUFFER_SIZE, DEFAULT_CONFIG2, currentConfig;
18541
- var init_debug_config = __esm({
18542
- "src/logging/debug-config.ts"() {
18543
- "use strict";
18544
- NORMAL_TRACE_BUFFER_SIZE = 200;
18545
- DEV_TRACE_BUFFER_SIZE = 1e3;
18546
- DEFAULT_CONFIG2 = {
18547
- logLevel: "info",
18548
- collectDebugTrace: false,
18549
- traceContent: false,
18550
- traceBufferSize: NORMAL_TRACE_BUFFER_SIZE,
18551
- traceCategories: []
18552
- };
18553
- currentConfig = { ...DEFAULT_CONFIG2 };
18554
- }
18555
- });
18556
-
18557
18909
  // src/providers/sdk/v1/schemas/cli/provider.schema.json
18558
18910
  var provider_schema_default;
18559
18911
  var init_provider_schema = __esm({
@@ -24063,6 +24415,7 @@ var init_require_whitelist = __esm({
24063
24415
  // src/index.ts
24064
24416
  var index_exports = {};
24065
24417
  __export(index_exports, {
24418
+ ALWAYS_ON_TRACE_CATEGORIES: () => ALWAYS_ON_TRACE_CATEGORIES,
24066
24419
  AcpProviderInstance: () => AcpProviderInstance,
24067
24420
  AgentStreamPoller: () => AgentStreamPoller,
24068
24421
  BUILTIN_CHAT_MESSAGE_KINDS: () => BUILTIN_CHAT_MESSAGE_KINDS,
@@ -24294,6 +24647,7 @@ __export(index_exports, {
24294
24647
  installGlobalInterceptor: () => installGlobalInterceptor,
24295
24648
  interactivePromptFromClaudeAskUserQuestion: () => interactivePromptFromClaudeAskUserQuestion,
24296
24649
  isActivityChatMessage: () => isActivityChatMessage,
24650
+ isAlwaysOnTraceCategory: () => isAlwaysOnTraceCategory,
24297
24651
  isBuiltinChatMessageKind: () => isBuiltinChatMessageKind,
24298
24652
  isCdpConnected: () => isCdpConnected,
24299
24653
  isExtensionInstalled: () => isExtensionInstalled,
@@ -30993,93 +31347,14 @@ var os10 = __toESM(require("os"));
30993
31347
  var path17 = __toESM(require("path"));
30994
31348
  var import_node_crypto3 = require("crypto");
30995
31349
  init_logger();
30996
-
30997
- // src/logging/debug-trace.ts
30998
- init_debug_config();
30999
- function summarizeString(value) {
31000
- return `[${value.length} chars]`;
31001
- }
31002
- function sanitizeTraceValue(value, traceContent) {
31003
- if (traceContent) {
31004
- if (Array.isArray(value)) return value.map((entry) => sanitizeTraceValue(entry, traceContent));
31005
- if (value && typeof value === "object") {
31006
- return Object.fromEntries(
31007
- Object.entries(value).map(([key2, nested]) => [key2, sanitizeTraceValue(nested, traceContent)])
31008
- );
31009
- }
31010
- return value;
31011
- }
31012
- if (typeof value === "string") return summarizeString(value);
31013
- if (Array.isArray(value)) return value.map((entry) => sanitizeTraceValue(entry, traceContent));
31014
- if (value && typeof value === "object") {
31015
- return Object.fromEntries(
31016
- Object.entries(value).map(([key2, nested]) => [key2, sanitizeTraceValue(nested, traceContent)])
31017
- );
31018
- }
31019
- return value;
31020
- }
31021
- function sanitizeTracePayload(payload) {
31022
- if (!payload) return {};
31023
- const { traceContent } = getDebugRuntimeConfig();
31024
- return sanitizeTraceValue(payload, traceContent);
31025
- }
31026
- function createEntry(event) {
31027
- return {
31028
- id: `trace_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`,
31029
- ts: Date.now(),
31030
- ...event,
31031
- payload: sanitizeTracePayload(event.payload)
31032
- };
31033
- }
31034
- function createDebugTraceStore(options) {
31035
- const entries = [];
31036
- const capacity = Math.max(1, Math.floor(options.capacity || 100));
31037
- return {
31038
- record(event) {
31039
- if (!options.enabled) return null;
31040
- const entry = createEntry(event);
31041
- entries.push(entry);
31042
- if (entries.length > capacity) {
31043
- entries.splice(0, entries.length - capacity);
31044
- }
31045
- return entry;
31046
- },
31047
- list(query = {}) {
31048
- const limit = Math.max(1, Math.floor(query.limit || 100));
31049
- 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 } : {} }));
31050
- },
31051
- clear() {
31052
- entries.splice(0, entries.length);
31053
- }
31054
- };
31055
- }
31056
- var globalStore = createDebugTraceStore({ enabled: false, capacity: getDebugRuntimeConfig().traceBufferSize });
31057
- function configureDebugTraceStore() {
31058
- const config = getDebugRuntimeConfig();
31059
- globalStore = createDebugTraceStore({
31060
- enabled: config.collectDebugTrace,
31061
- capacity: config.traceBufferSize
31062
- });
31063
- }
31064
- function recordDebugTrace(event) {
31065
- if (!shouldCollectTraceCategory(event.category)) return null;
31066
- return globalStore.record(event);
31067
- }
31068
- function getRecentDebugTrace(query = {}) {
31069
- return globalStore.list(query);
31070
- }
31071
- function clearDebugTrace() {
31072
- globalStore.clear();
31073
- }
31074
- function createInteractionId(prefix = "ix") {
31075
- return `${prefix}_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;
31076
- }
31350
+ init_debug_trace();
31077
31351
 
31078
31352
  // src/commands/chat-commands-read.ts
31079
31353
  var path16 = __toESM(require("path"));
31080
31354
  init_contracts();
31081
31355
  init_coordinator_registry();
31082
31356
  init_logger();
31357
+ init_debug_trace();
31083
31358
 
31084
31359
  // src/chat/source-machine.ts
31085
31360
  var INITIAL_CHAT_SOURCE_STATE = Object.freeze({
@@ -36314,6 +36589,7 @@ ${formatManifestValidationIssues2(validation.issues)}`,
36314
36589
  };
36315
36590
 
36316
36591
  // src/commands/low-family/session-host.ts
36592
+ init_debug_trace();
36317
36593
  function toHostedCliRuntimeDescriptor(record) {
36318
36594
  if (!record || typeof record !== "object") return null;
36319
36595
  const runtimeId = typeof record.sessionId === "string" ? record.sessionId : "";
@@ -36806,6 +37082,7 @@ var refineConfigHandlers = {
36806
37082
  // src/commands/low-family/diagnostics.ts
36807
37083
  var fs11 = __toESM(require("fs"));
36808
37084
  init_logger();
37085
+ init_debug_trace();
36809
37086
  var diagnosticsHandlers = {
36810
37087
  get_logs: async (_ctx, args) => {
36811
37088
  const count = parseInt(args?.count) || parseInt(args?.lines) || 100;
@@ -38317,6 +38594,7 @@ function applyPreLaunchTrust(trust, workingDir) {
38317
38594
 
38318
38595
  // src/providers/spec/fsm-driver.ts
38319
38596
  init_logger();
38597
+ init_debug_trace();
38320
38598
  init_debug_config();
38321
38599
  init_pty_write_chunking();
38322
38600
  function countNewlines(s2) {
@@ -41172,6 +41450,7 @@ function createCliAdapter(provider, workingDir, cliArgs, extraEnv, transportFact
41172
41450
 
41173
41451
  // src/providers/cli-provider-instance.ts
41174
41452
  init_logger();
41453
+ init_debug_trace();
41175
41454
  init_debug_config();
41176
41455
  init_mesh_event_trace();
41177
41456
  init_control_effects();
@@ -41195,6 +41474,46 @@ function normalizeProviderSessionId(provider, providerSessionId) {
41195
41474
  return normalizedId;
41196
41475
  }
41197
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
+
41198
41517
  // src/providers/cli-provider-instance.ts
41199
41518
  init_chat_message_normalization();
41200
41519
 
@@ -42127,7 +42446,20 @@ var CliProviderInstance = class _CliProviderInstance {
42127
42446
  if (now - at > USER_INPUT_ACK_DEDUP_WINDOW_MS) this.recentUserInputAcks.delete(key2);
42128
42447
  }
42129
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
+ }
42130
42458
  dispose() {
42459
+ if (this.type === "antigravity-cli") {
42460
+ const owner = this.antigravityClaimOwner();
42461
+ if (owner) releaseAntigravityOwner(owner);
42462
+ }
42131
42463
  this.adapter.shutdown();
42132
42464
  this.monitor.reset();
42133
42465
  if (this.autoApproveSettleTimer) {
@@ -42882,12 +43214,21 @@ var CliProviderInstance = class _CliProviderInstance {
42882
43214
  if (this.isMeshWorkerSession()) {
42883
43215
  traceMeshEventStage("fired", this.meshTraceCtx(), `${reason} (source=${fcEvidenceSource})`);
42884
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
+ });
42885
43225
  this.pushEvent({
42886
43226
  event: "agent:generating_completed",
42887
43227
  chatTitle,
42888
43228
  duration: 0,
42889
43229
  timestamp: now,
42890
43230
  finalSummary: fcFinalSummary,
43231
+ evidenceLevel: "weak",
42891
43232
  completionDiagnostic: {
42892
43233
  reason,
42893
43234
  finalAssistantEvidenceSource: fcEvidenceSource,
@@ -43614,6 +43955,10 @@ ${effect.notification.body || ""}`.trim();
43614
43955
  const previousHistorySessionId = this.providerSessionId || this.instanceId;
43615
43956
  const previousProviderSessionId = this.providerSessionId;
43616
43957
  this.providerSessionId = nextSessionId;
43958
+ if (this.type === "antigravity-cli") {
43959
+ const owner = this.antigravityClaimOwner();
43960
+ if (owner) claimAntigravityConversation(nextSessionId, owner);
43961
+ }
43617
43962
  this.historyWriter.promoteHistorySession(this.type, previousHistorySessionId, nextSessionId);
43618
43963
  this.historyWriter.writeSessionStart(this.type, nextSessionId, this.workingDir, this.instanceId);
43619
43964
  if (this.shouldHydrateExistingProviderHistory()) {
@@ -47485,6 +47830,51 @@ function extractUserPrompt(payload) {
47485
47830
  if (!text) return "";
47486
47831
  return extractUserRequestContent(text);
47487
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
+ }
47488
47878
  function isSqliteBusyError(err) {
47489
47879
  if (!err) return false;
47490
47880
  const code = err.code;
@@ -47563,8 +47953,23 @@ function parseConversationDb(filePath, sessionId, workspace) {
47563
47953
  if (!payload || !Buffer.isBuffer(payload) || payload.length === 0) continue;
47564
47954
  const receivedAt = baseTs + messages.length;
47565
47955
  if (row.step_type === AGY_STEP_TYPE_USER) {
47566
- const content = extractUserPrompt(payload);
47567
- 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
+ }
47568
47973
  const msg = {
47569
47974
  ts: new Date(receivedAt).toISOString(),
47570
47975
  receivedAt,
@@ -47577,8 +47982,24 @@ function parseConversationDb(filePath, sessionId, workspace) {
47577
47982
  if (normalizedWorkspace) msg.workspace = normalizedWorkspace;
47578
47983
  messages.push(msg);
47579
47984
  } else if (row.step_type === AGY_STEP_TYPE_MODEL) {
47580
- const content = extractModelAnswer(payload);
47581
- 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
+ }
47582
48003
  const msg = {
47583
48004
  ts: new Date(receivedAt).toISOString(),
47584
48005
  receivedAt,
@@ -47824,7 +48245,8 @@ function createNativeHistoryDispatcher(reader) {
47824
48245
  const sessionId = input.sessionId || input.historySessionId || "";
47825
48246
  const requestedProviderSid = input.providerSessionId || "";
47826
48247
  const sessionStartedAtMs = typeof input.sessionStartedAtMs === "number" ? input.sessionStartedAtMs : typeof input.args?.sessionStartedAtMs === "number" ? input.args.sessionStartedAtMs : 0;
47827
- 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);
47828
48250
  if (!sourcePath) return null;
47829
48251
  if (input.forceRefresh === true || input.args?.forceRefresh === true) {
47830
48252
  try {
@@ -47852,14 +48274,14 @@ function createNativeHistoryDispatcher(reader) {
47852
48274
  };
47853
48275
  };
47854
48276
  }
47855
- function resolveSourcePath(reader, workspace, sessionId, sessionStartedAtMs) {
48277
+ function resolveSourcePath(reader, workspace, sessionId, sessionStartedAtMs, instanceId) {
47856
48278
  switch (reader) {
47857
48279
  case "claude-cli":
47858
48280
  return resolveClaudePath(workspace, sessionId);
47859
48281
  case "codex-cli":
47860
48282
  return resolveCodexPath(workspace, sessionId, sessionStartedAtMs);
47861
48283
  case "antigravity-cli":
47862
- return resolveAntigravityPath(workspace, sessionId);
48284
+ return resolveAntigravityPath(workspace, sessionId, sessionStartedAtMs, instanceId);
47863
48285
  case "hermes-cli":
47864
48286
  return resolveHermesPath(workspace, sessionId);
47865
48287
  }
@@ -47974,27 +48396,73 @@ function resolveRealPath(value) {
47974
48396
  return value;
47975
48397
  }
47976
48398
  }
47977
- function resolveAntigravityPath(workspace, sessionId) {
47978
- void workspace;
48399
+ var AGY_SPAWN_CLAIM_GRACE_MS = 2e3;
48400
+ function resolveAntigravityPath(workspace, sessionId, sessionStartedAtMs, instanceId) {
47979
48401
  const agyRoot = path33.join(os24.homedir(), ".gemini", "antigravity-cli");
48402
+ const owner = antigravityOwnerToken(workspace, sessionStartedAtMs, instanceId);
47980
48403
  if (sessionId && isUuidLikeSessionId2(sessionId)) {
47981
48404
  const dbPath = path33.join(agyRoot, "conversations", `${sessionId}.db`);
47982
- if (fs24.existsSync(dbPath)) return dbPath;
48405
+ if (fs24.existsSync(dbPath)) {
48406
+ if (owner) claimAntigravityConversation(sessionId, owner);
48407
+ return dbPath;
48408
+ }
47983
48409
  }
47984
48410
  const brainRoot2 = path33.join(agyRoot, "brain");
47985
48411
  if (fs24.existsSync(brainRoot2)) {
47986
- const cutoff = Date.now() - RECENT_WINDOW_MS;
47987
- 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);
47988
48414
  for (const e of entries) {
47989
48415
  const t = path33.join(e.p, ".system_generated", "logs", "transcript.jsonl");
47990
- 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
+ }
47991
48420
  }
47992
48421
  }
47993
48422
  const convRoot = path33.join(agyRoot, "conversations");
47994
- const newestDb = newestRecentFile2(convRoot, /^[0-9a-f-]+\.db$/i);
47995
- 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
+ }
47996
48428
  return null;
47997
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
+ }
47998
48466
  function resolveHermesPath(workspace, sessionId) {
47999
48467
  void workspace;
48000
48468
  void sessionId;
@@ -48051,6 +48519,15 @@ function safeMtime(p) {
48051
48519
  return 0;
48052
48520
  }
48053
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
+ }
48054
48531
  function safeSize(p) {
48055
48532
  try {
48056
48533
  return fs24.statSync(p).size;
@@ -53586,6 +54063,7 @@ function getRecentCommands(count = 50) {
53586
54063
  cleanOldFiles();
53587
54064
 
53588
54065
  // src/commands/router.ts
54066
+ init_debug_trace();
53589
54067
  init_mesh_host_ownership();
53590
54068
  init_mesh_work_queue();
53591
54069
  var fs33 = __toESM(require("fs"));
@@ -54879,6 +55357,7 @@ async function resolveProviderTypeFromPriority(args) {
54879
55357
  // src/commands/router-refine.ts
54880
55358
  var import_node_child_process7 = require("child_process");
54881
55359
  init_logger();
55360
+ init_debug_trace();
54882
55361
  init_dist();
54883
55362
  init_mesh_events();
54884
55363
 
@@ -55664,6 +56143,7 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree, opti
55664
56143
  commit: gitlink.commit,
55665
56144
  reachable: false
55666
56145
  };
56146
+ let submoduleDefaultBranch = "main";
55667
56147
  try {
55668
56148
  if (!fs30.existsSync(submodulePath)) {
55669
56149
  entry.error = `Submodule checkout missing at ${gitlink.path}`;
@@ -55716,9 +56196,14 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree, opti
55716
56196
  entries.push(entry);
55717
56197
  continue;
55718
56198
  }
55719
- entry.remoteMainBranch = "main";
56199
+ submoduleDefaultBranch = await resolveSubmoduleDefaultBranch({
56200
+ submoduleRepoPath: submodulePath,
56201
+ superprojectWorkspace: repoRoot,
56202
+ submodulePath: gitlink.path
56203
+ });
56204
+ entry.remoteMainBranch = submoduleDefaultBranch;
55720
56205
  try {
55721
- await verifyRemoteMainContainsCommit(submodulePath, gitlink.commit, "main");
56206
+ await verifyRemoteMainContainsCommit(submodulePath, gitlink.commit, submoduleDefaultBranch);
55722
56207
  entry.fetchedFromOrigin = true;
55723
56208
  entry.remoteReachable = true;
55724
56209
  entry.remoteMainReachable = true;
@@ -55728,17 +56213,17 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree, opti
55728
56213
  entry.remoteMainReachable = false;
55729
56214
  entry.publishRequired = true;
55730
56215
  const details = truncateValidationOutput(e?.stderr || e?.message || String(e));
55731
- entry.error = `Submodule remote main reachability check failed for origin/main: ${details}`;
56216
+ entry.error = `Submodule remote main reachability check failed for origin/${submoduleDefaultBranch}: ${details}`;
55732
56217
  if (options.allowAutoPublishSubmoduleMainCommits === true && entry.localReachable === true) {
55733
56218
  entry.autoPublishAllowed = true;
55734
56219
  entry.autoPublishAttempted = true;
55735
56220
  try {
55736
- const publish = await publishCommitToRemoteMain(submodulePath, gitlink.commit, "main");
56221
+ const publish = await publishCommitToRemoteMain(submodulePath, gitlink.commit, submoduleDefaultBranch);
55737
56222
  entry.autoPublishRefspec = publish.refspec;
55738
56223
  entry.publishStdout = truncateValidationOutput(publish.stdout);
55739
56224
  entry.publishStderr = truncateValidationOutput(publish.stderr);
55740
56225
  entry.autoPublishSucceeded = true;
55741
- await verifyRemoteMainContainsCommit(submodulePath, gitlink.commit, "main");
56226
+ await verifyRemoteMainContainsCommit(submodulePath, gitlink.commit, submoduleDefaultBranch);
55742
56227
  entry.fetchedFromOrigin = true;
55743
56228
  entry.remoteReachable = true;
55744
56229
  entry.remoteMainReachable = true;
@@ -55750,12 +56235,12 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree, opti
55750
56235
  entry.autoPublishSucceeded = false;
55751
56236
  entry.autoPublishVerified = false;
55752
56237
  const publishDetails = truncateValidationOutput(publishError?.stderr || publishError?.message || String(publishError));
55753
- entry.error = `Submodule auto-publish to origin/main failed or could not be verified: ${publishDetails}`;
56238
+ entry.error = `Submodule auto-publish to origin/${submoduleDefaultBranch} failed or could not be verified: ${publishDetails}`;
55754
56239
  }
55755
56240
  } else if (options.allowAutoPublishSubmoduleMainCommits === true) {
55756
56241
  entry.autoPublishAllowed = true;
55757
56242
  entry.autoPublishAttempted = false;
55758
- entry.autoPublishSkippedReason = entry.autoPublishSkippedReason || "candidate commit is not reachable in the source checkout or worktree submodule, so Refinery cannot push it to origin/main";
56243
+ entry.autoPublishSkippedReason = entry.autoPublishSkippedReason || `candidate commit is not reachable in the source checkout or worktree submodule, so Refinery cannot push it to origin/${submoduleDefaultBranch}`;
55759
56244
  }
55760
56245
  }
55761
56246
  } catch (e) {
@@ -55763,7 +56248,7 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree, opti
55763
56248
  entry.remoteMainReachable = false;
55764
56249
  entry.publishRequired = true;
55765
56250
  const details = truncateValidationOutput(e?.stderr || e?.message || String(e));
55766
- entry.error = `Submodule remote main reachability check failed for origin/main: ${details}`;
56251
+ entry.error = `Submodule remote main reachability check failed for origin/${submoduleDefaultBranch}: ${details}`;
55767
56252
  }
55768
56253
  } catch (e) {
55769
56254
  entry.error = truncateValidationOutput(e?.message || String(e));
@@ -59098,6 +59583,7 @@ init_build_info();
59098
59583
  init_normalize();
59099
59584
  init_logger();
59100
59585
  init_debug_config();
59586
+ init_debug_trace();
59101
59587
 
59102
59588
  // src/ipc-protocol.ts
59103
59589
  var DEFAULT_DAEMON_PORT = 19222;
@@ -67053,6 +67539,7 @@ var V1_ALL_PRIMITIVES = Object.freeze(
67053
67539
  var V1_CONTRACT_VERSION = "1.0.0";
67054
67540
  // Annotate the CommonJS export names for ESM import in node:
67055
67541
  0 && (module.exports = {
67542
+ ALWAYS_ON_TRACE_CATEGORIES,
67056
67543
  AcpProviderInstance,
67057
67544
  AgentStreamPoller,
67058
67545
  BUILTIN_CHAT_MESSAGE_KINDS,
@@ -67284,6 +67771,7 @@ var V1_CONTRACT_VERSION = "1.0.0";
67284
67771
  installGlobalInterceptor,
67285
67772
  interactivePromptFromClaudeAskUserQuestion,
67286
67773
  isActivityChatMessage,
67774
+ isAlwaysOnTraceCategory,
67287
67775
  isBuiltinChatMessageKind,
67288
67776
  isCdpConnected,
67289
67777
  isExtensionInstalled,