@adhdev/daemon-core 0.9.82-rc.467 → 0.9.82-rc.469

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 (37) hide show
  1. package/dist/index.d.ts +7 -5
  2. package/dist/index.js +955 -726
  3. package/dist/index.js.map +1 -1
  4. package/dist/index.mjs +953 -731
  5. package/dist/index.mjs.map +1 -1
  6. package/dist/mesh/mesh-completion-synthesis.d.ts +4 -0
  7. package/dist/mesh/mesh-delivery-policy.d.ts +0 -27
  8. package/dist/mesh/mesh-events-pending.d.ts +40 -0
  9. package/dist/mesh/mesh-events.d.ts +2 -2
  10. package/dist/mesh/mesh-ledger.d.ts +1 -1
  11. package/dist/mesh/mesh-reconcile-config.d.ts +6 -0
  12. package/dist/mesh/mesh-remote-event-pull.d.ts +15 -0
  13. package/dist/mesh/mesh-runtime-store.d.ts +0 -22
  14. package/dist/mesh/mesh-work-queue.d.ts +45 -0
  15. package/dist/providers/cli-provider-effect-format.d.ts +30 -0
  16. package/dist/providers/cli-provider-instance-types.d.ts +45 -0
  17. package/dist/providers/cli-provider-instance.d.ts +12 -6
  18. package/dist/providers/cli-provider-transcript-merge.d.ts +7 -0
  19. package/package.json +3 -3
  20. package/src/index.ts +11 -5
  21. package/src/mesh/coordinator-prompt.ts +15 -0
  22. package/src/mesh/mesh-completion-synthesis.ts +398 -0
  23. package/src/mesh/mesh-delivery-policy.ts +7 -38
  24. package/src/mesh/mesh-event-forwarding.ts +9 -10
  25. package/src/mesh/mesh-events-pending.ts +178 -0
  26. package/src/mesh/mesh-events.ts +6 -1
  27. package/src/mesh/mesh-ledger.ts +5 -0
  28. package/src/mesh/mesh-queue-assignment.ts +16 -2
  29. package/src/mesh/mesh-reconcile-config.ts +66 -0
  30. package/src/mesh/mesh-reconcile-loop.ts +21 -647
  31. package/src/mesh/mesh-remote-event-pull.ts +279 -0
  32. package/src/mesh/mesh-runtime-store.ts +92 -83
  33. package/src/mesh/mesh-work-queue.ts +90 -0
  34. package/src/providers/cli-provider-effect-format.ts +53 -0
  35. package/src/providers/cli-provider-instance-types.ts +131 -0
  36. package/src/providers/cli-provider-instance.ts +87 -303
  37. package/src/providers/cli-provider-transcript-merge.ts +114 -0
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 ? "e0f04b7d54855e0f0d5ed4200078d95596ab9f6f" : void 0) ?? "unknown";
408
- const commitShort = readInjected(true ? "e0f04b7d" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
409
- const version = readInjected(true ? "0.9.82-rc.467" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
410
- const builtAt = readInjected(true ? "2026-07-05T10:01:33.435Z" : void 0);
407
+ const commit = readInjected(true ? "7e34ff6bc7c6528fca49478a57e0a83620f3a063" : void 0) ?? "unknown";
408
+ const commitShort = readInjected(true ? "7e34ff6b" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
409
+ const version = readInjected(true ? "0.9.82-rc.469" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
410
+ const builtAt = readInjected(true ? "2026-07-05T12:18:38.077Z" : void 0);
411
411
  cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
412
412
  return cached;
413
413
  }
@@ -2765,12 +2765,57 @@ function summarizeGitShape(status) {
2765
2765
  submodules
2766
2766
  };
2767
2767
  }
2768
- var DAEMON_ID_PREFIXES, MAGI_RAW_ANSWER_CAP;
2768
+ var DAEMON_ID_PREFIXES, MAGI_RAW_ANSWER_CAP, CANONICAL_MESH_TOOL_NAMES, CANONICAL_MESH_TOOL_COUNT;
2769
2769
  var init_dist = __esm({
2770
2770
  "../mesh-shared/dist/index.mjs"() {
2771
2771
  "use strict";
2772
2772
  DAEMON_ID_PREFIXES = ["daemon_", "standalone_"];
2773
2773
  MAGI_RAW_ANSWER_CAP = 4e3;
2774
+ CANONICAL_MESH_TOOL_NAMES = [
2775
+ "mesh_status",
2776
+ "mesh_list_nodes",
2777
+ "mesh_enqueue_task",
2778
+ "mesh_view_queue",
2779
+ "mesh_queue_cancel",
2780
+ "mesh_queue_requeue",
2781
+ "mesh_send_task",
2782
+ "mesh_read_chat",
2783
+ "mesh_read_debug",
2784
+ "mesh_launch_session",
2785
+ "mesh_git_status",
2786
+ "mesh_read_node_logs",
2787
+ "mesh_fast_forward_node",
2788
+ "mesh_restart_daemon",
2789
+ "mesh_checkpoint",
2790
+ "mesh_approve",
2791
+ "mesh_clone_node",
2792
+ "mesh_remove_node",
2793
+ "mesh_refine_node",
2794
+ "mesh_refine_batch",
2795
+ "mesh_refine_config",
2796
+ "mesh_change_impact_config",
2797
+ "mesh_init",
2798
+ "mesh_reinit",
2799
+ "mesh_write_mesh_json_config",
2800
+ "mesh_refine_plan",
2801
+ "mesh_cleanup_sessions",
2802
+ "mesh_prune_stale_direct",
2803
+ "mesh_task_history",
2804
+ "mesh_record_note",
2805
+ "mesh_forget_note",
2806
+ "mesh_reconcile_ledger",
2807
+ "mesh_requeue_held_events",
2808
+ "mesh_mission_upsert",
2809
+ "mesh_mission_list",
2810
+ "mesh_review_inbox",
2811
+ "mesh_magi_review",
2812
+ "mesh_magi_collect",
2813
+ "mesh_magi_panel_set",
2814
+ "mesh_magi_panel_list",
2815
+ "mesh_magi_kind_panel_set",
2816
+ "mesh_magi_kind_panel_list"
2817
+ ];
2818
+ CANONICAL_MESH_TOOL_COUNT = CANONICAL_MESH_TOOL_NAMES.length;
2774
2819
  }
2775
2820
  });
2776
2821
 
@@ -3792,24 +3837,39 @@ var init_coordinator_prompt = __esm({
3792
3837
  | \`mesh_queue_cancel\` | Cancel a queue task without deleting audit history |
3793
3838
  | \`mesh_queue_requeue\` | Return a task to pending for retry; clears stale session targets |
3794
3839
  | \`mesh_send_task\` | Legacy push: enqueue a task targeted at a specific node |
3840
+ | \`mesh_mission_upsert\` | Create/update a persistent mission so a multi-task plan survives coordinator restarts; set status completed/abandoned when the outcome is decided |
3841
+ | \`mesh_mission_list\` | List every mission with goal, status, and live task progress \u2014 the authority for "what work remains" (never hidden by status) |
3795
3842
  | \`mesh_launch_session\` | Start a new agent session on a node |
3796
3843
  | \`mesh_read_chat\` | Read recent chat messages from a delegated agent session |
3797
3844
  | \`mesh_read_debug\` | Collect a daemon-side chat/parser debug bundle for a session |
3798
3845
  | \`mesh_task_history\` | Read the task ledger \u2014 dispatches, completions, failures. Use to understand what has been done before deciding next steps |
3846
+ | \`mesh_reconcile_ledger\` | Reconcile daemon-local ledgers over P2P \u2014 import missing entries from remote nodes into the coordinator local ledger |
3847
+ | \`mesh_requeue_held_events\` | Restore recoverable held coordinator events (T6 quarantine / pending-trim) back to the pending queue; lossless, no double-requeue |
3848
+ | \`mesh_review_inbox\` | List local worktree nodes needing human review \u2014 merge candidates and Refinery-blocked results with evidence/diff summaries |
3799
3849
  | \`mesh_record_note\` | Record a durable, provider-neutral operating note (provider quirk / pattern to avoid / recovery lesson). Future coordinators see it under "## Operating Notes" at launch |
3800
3850
  | \`mesh_forget_note\` | Retract a stale/wrong operating note by note_id or exact text so it stops riding into future coordinators' prompts (append-only tombstone; history preserved) |
3801
3851
  | \`mesh_git_status\` | Check git status on a specific node |
3802
3852
  | \`mesh_read_node_logs\` | Fetch a remote node's daemon log tail directly over P2P (grep/since/byte-bounded, secrets redacted) \u2014 no session/PowerShell needed to debug a node's daemon |
3803
3853
  | \`mesh_fast_forward_node\` | Safely dry-run or explicitly execute an obvious clean fast-forward without launching an agent session |
3854
+ | \`mesh_restart_daemon\` | Update a node's daemon to the latest published version on its channel and restart it (the dashboard "preview update" path, as a mesh command) |
3804
3855
  | \`mesh_checkpoint\` | Create a git checkpoint on a node |
3805
3856
  | \`mesh_approve\` | Approve/reject a pending agent action |
3806
3857
  | \`mesh_clone_node\` | Create a worktree node for isolated parallel branch work |
3807
3858
  | \`mesh_refine_node\` | Validate and merge a completed worktree node back into its base branch |
3859
+ | \`mesh_refine_batch\` | Batch Refinery: converge multiple sibling worktree nodes onto the base branch in one conflict-aware sequential pipeline |
3860
+ | \`mesh_refine_plan\` | Dry-run Refinery plan for a worktree node \u2014 config source, validation commands, merge/cleanup intent \u2014 without executing validation or git merge |
3861
+ | \`mesh_refine_config\` | Refinery config helper (read-only) \u2014 unified entry for schema/validate/suggest via a required \`mode\` |
3862
+ | \`mesh_change_impact_config\` | Change Impact config helper \u2014 unified entry for schema/validate/suggest via a required \`mode\` |
3808
3863
  | \`mesh_remove_node\` | Remove a node (cleans up worktree if applicable) |
3809
3864
  | \`mesh_cleanup_sessions\` | Manually clean up delegated session records for a node |
3865
+ | \`mesh_prune_stale_direct\` | Prune orphaned staleDirect dispatch records (dry-run by default); live/pending work and audit history preserved |
3810
3866
  | \`mesh_init\` | Guided onboarding for a fresh repo: dry-run scan \u2192 suggest \`.adhdev/*\` configs (refine/bootstrap/change-impact) + providerPriority + current-config echo; gated write on approval |
3811
3867
  | \`mesh_reinit\` | Re-onboard an already-configured repo: re-suggest with overwrite semantics + current-vs-suggested diff; dry-run preview first, per-section approval before write |
3812
3868
  | \`mesh_write_mesh_json_config\` | Gated write of \`.adhdev/mesh.json\` (repo coordinator-prompt config) from the mesh entry \u2014 dry-run/overwrite like mesh_init |
3869
+ | \`mesh_magi_review\` | Cross-verify a read-only investigation across a standing panel of independent mesh agents (different machines/providers) instead of a single worker |
3870
+ | \`mesh_magi_collect\` | Collect + synthesize a previously dispatched MAGI fan-out by its consensus group id (async companion to mesh_magi_review wait:false) |
3871
+ | \`mesh_magi_panel_set\` | Upsert a named MAGI panel (standing set of independent node\xD7provider members) into machine-local config |
3872
+ | \`mesh_magi_panel_list\` | List configured MAGI panels and resolve each member's availability against the current mesh (read-only) |
3813
3873
  | \`mesh_magi_kind_panel_set\` | Bind a task_kind \u2192 MAGI kind-panel slots (machine-local, wholesale replacement \u2014 approve current-vs-new first) |
3814
3874
  | \`mesh_magi_kind_panel_list\` | List configured task_kind \u2192 MAGI kind-panel slot bindings (machine-local, read-only) |`;
3815
3875
  TOOL_EXPOSURE_PREFLIGHT_SECTION = `## Tool Exposure Preflight
@@ -5267,29 +5327,6 @@ function getActiveSessionDeliveries(meshId, sessionId) {
5267
5327
  return [];
5268
5328
  }
5269
5329
  }
5270
- function recordCompletionConflict(opts) {
5271
- try {
5272
- MeshRuntimeStore.getInstance().recordCompletionConflict({
5273
- id: randomUUID5(),
5274
- meshId: opts.meshId,
5275
- fingerprint: opts.fingerprint,
5276
- conflictingTaskId: opts.conflictingTaskId,
5277
- conflictingSessionId: opts.conflictingSessionId,
5278
- originalTaskId: opts.originalTaskId,
5279
- originalSessionId: opts.originalSessionId,
5280
- event: opts.event,
5281
- createdAt: (/* @__PURE__ */ new Date()).toISOString()
5282
- });
5283
- } catch {
5284
- }
5285
- }
5286
- function getRecentCompletionConflicts(meshId, limitMs) {
5287
- try {
5288
- return MeshRuntimeStore.getInstance().getRecentCompletionConflicts(meshId, limitMs);
5289
- } catch {
5290
- return [];
5291
- }
5292
- }
5293
5330
  function markSessionDeliveriesTerminal(meshId, sessionId, terminalStatus) {
5294
5331
  try {
5295
5332
  const active = MeshRuntimeStore.getInstance().getActiveSessionDeliveries(meshId, sessionId);
@@ -5363,6 +5400,8 @@ __export(mesh_work_queue_exports, {
5363
5400
  ACTIVE_MESH_QUEUE_STATUSES: () => ACTIVE_MESH_QUEUE_STATUSES,
5364
5401
  HISTORICAL_MESH_QUEUE_STATUSES: () => HISTORICAL_MESH_QUEUE_STATUSES,
5365
5402
  MESH_TASK_MODES: () => MESH_TASK_MODES,
5403
+ MESH_TASK_PRIORITIES: () => MESH_TASK_PRIORITIES,
5404
+ NOT_BEFORE_RELATIVE_THRESHOLD_MS: () => NOT_BEFORE_RELATIVE_THRESHOLD_MS,
5366
5405
  __clearDirectDispatchesForTests: () => __clearDirectDispatchesForTests,
5367
5406
  __clearMeshQueueForTests: () => __clearMeshQueueForTests,
5368
5407
  __replaceMeshQueueForTests: () => __replaceMeshQueueForTests,
@@ -5383,15 +5422,19 @@ __export(mesh_work_queue_exports, {
5383
5422
  insertDirectDispatch: () => insertDirectDispatch,
5384
5423
  isTaskReadonly: () => isTaskReadonly,
5385
5424
  markStaleDirectDispatches: () => markStaleDirectDispatches,
5425
+ meshTaskNotBeforeReady: () => meshTaskNotBeforeReady,
5426
+ meshTaskPriorityRank: () => meshTaskPriorityRank,
5386
5427
  nodeSatisfiesRequiredTags: () => nodeSatisfiesRequiredTags,
5387
5428
  normalizeMeshCapabilityTags: () => normalizeMeshCapabilityTags,
5388
5429
  normalizeMeshTaskMode: () => normalizeMeshTaskMode,
5430
+ normalizeMeshTaskPriority: () => normalizeMeshTaskPriority,
5389
5431
  reclaimStrandedAssignedTask: () => reclaimStrandedAssignedTask,
5390
5432
  recordDirectDispatchTask: () => recordDirectDispatchTask,
5391
5433
  recordMeshToolCall: () => recordMeshToolCall,
5392
5434
  recordTaskAutoLaunch: () => recordTaskAutoLaunch,
5393
5435
  requeueTask: () => requeueTask,
5394
5436
  resolveConvergeRequiredTags: () => resolveConvergeRequiredTags,
5437
+ resolveNotBefore: () => resolveNotBefore,
5395
5438
  taskDependenciesSatisfied: () => taskDependenciesSatisfied,
5396
5439
  updateDirectDispatchStatus: () => updateDirectDispatchStatus,
5397
5440
  updateSessionTaskStatus: () => updateSessionTaskStatus,
@@ -5399,6 +5442,41 @@ __export(mesh_work_queue_exports, {
5399
5442
  validateMeshTaskModeRequest: () => validateMeshTaskModeRequest
5400
5443
  });
5401
5444
  import { randomUUID as randomUUID6 } from "crypto";
5445
+ function meshTaskPriorityRank(priority) {
5446
+ switch (priority) {
5447
+ case "high":
5448
+ return 2;
5449
+ case "low":
5450
+ return 0;
5451
+ default:
5452
+ return 1;
5453
+ }
5454
+ }
5455
+ function normalizeMeshTaskPriority(value) {
5456
+ return value === "low" || value === "normal" || value === "high" ? value : void 0;
5457
+ }
5458
+ function resolveNotBefore(value, nowMs = Date.now()) {
5459
+ if (value === void 0 || value === null) return void 0;
5460
+ let absMs;
5461
+ if (typeof value === "number" && Number.isFinite(value)) {
5462
+ absMs = value < NOT_BEFORE_RELATIVE_THRESHOLD_MS ? nowMs + value : value;
5463
+ } else if (typeof value === "string" && value.trim()) {
5464
+ const parsed = Date.parse(value.trim());
5465
+ if (Number.isNaN(parsed)) return void 0;
5466
+ absMs = parsed;
5467
+ } else {
5468
+ return void 0;
5469
+ }
5470
+ if (absMs <= nowMs) return new Date(nowMs).toISOString();
5471
+ return new Date(absMs).toISOString();
5472
+ }
5473
+ function meshTaskNotBeforeReady(task, nowMs = Date.now()) {
5474
+ const nb = task?.notBefore;
5475
+ if (!nb) return true;
5476
+ const parsed = Date.parse(nb);
5477
+ if (Number.isNaN(parsed)) return true;
5478
+ return parsed <= nowMs;
5479
+ }
5402
5480
  function isTaskReadonly(task) {
5403
5481
  if (!task) return false;
5404
5482
  return task.readonly === true || task.taskMode === "live_debug_readonly";
@@ -5726,6 +5804,9 @@ function enqueueTask(meshId, message, opts) {
5726
5804
  }
5727
5805
  const id = typeof opts?.id === "string" && opts.id.trim() ? opts.id.trim() : randomUUID6();
5728
5806
  const dependsOn = normalizeDependsOn(opts?.dependsOn);
5807
+ const priority = normalizeMeshTaskPriority(opts?.priority);
5808
+ const notBefore = resolveNotBefore(opts?.notBefore);
5809
+ const maxRetries = typeof opts?.maxRetries === "number" && Number.isFinite(opts.maxRetries) && opts.maxRetries >= 0 ? Math.floor(opts.maxRetries) : void 0;
5729
5810
  return withQueueLock(meshId, () => {
5730
5811
  if (MeshRuntimeStore.getInstance().findQueueEntryById(meshId, id)) {
5731
5812
  throw new Error(`duplicate_task_id: task '${id}' already exists in mesh '${meshId}'`);
@@ -5749,6 +5830,12 @@ function enqueueTask(meshId, message, opts) {
5749
5830
  targetSessionId: opts?.targetSessionId,
5750
5831
  requiredTags: resolvedRequiredTags,
5751
5832
  ...dependsOn.length > 0 ? { dependsOn } : {},
5833
+ // G6: only persist a non-default priority so legacy/normal rows stay minimal.
5834
+ ...priority && priority !== "normal" ? { priority } : {},
5835
+ // G7: hold-until gate (stored ISO). Omitted when absent/immediate.
5836
+ ...notBefore ? { notBefore } : {},
5837
+ // P3: explicit retry cap. Omitted → requeue path falls back to policy default.
5838
+ ...maxRetries !== void 0 ? { maxRetries } : {},
5752
5839
  ...typeof opts?.missionId === "string" && opts.missionId.trim() ? { missionId: opts.missionId.trim() } : {},
5753
5840
  ...typeof opts?.consensusGroupId === "string" && opts.consensusGroupId.trim() ? { consensusGroupId: opts.consensusGroupId.trim() } : {},
5754
5841
  ...typeof opts?.model === "string" && opts.model.trim() ? { model: opts.model.trim() } : {},
@@ -6089,7 +6176,7 @@ function recordMeshToolCall(opts) {
6089
6176
  return { rateLimitExceeded: false, callsInWindow: 0, advisory: null };
6090
6177
  }
6091
6178
  }
6092
- var ACTIVE_MESH_QUEUE_STATUSES, HISTORICAL_MESH_QUEUE_STATUSES, MESH_TASK_MODES, LIVE_DEBUG_READONLY_FORBIDDEN, NEGATION_CUES, NEGATION_WINDOW_TOKENS, GIT_MUTATION_SUBCOMMANDS, GIT_STASH_READONLY_SUBCOMMANDS, DEPENDENCY_FAILURE_TERMINALS, MAX_STRANDED_RECLAIMS;
6179
+ var ACTIVE_MESH_QUEUE_STATUSES, HISTORICAL_MESH_QUEUE_STATUSES, MESH_TASK_MODES, MESH_TASK_PRIORITIES, NOT_BEFORE_RELATIVE_THRESHOLD_MS, LIVE_DEBUG_READONLY_FORBIDDEN, NEGATION_CUES, NEGATION_WINDOW_TOKENS, GIT_MUTATION_SUBCOMMANDS, GIT_STASH_READONLY_SUBCOMMANDS, DEPENDENCY_FAILURE_TERMINALS, MAX_STRANDED_RECLAIMS;
6093
6180
  var init_mesh_work_queue = __esm({
6094
6181
  "src/mesh/mesh-work-queue.ts"() {
6095
6182
  "use strict";
@@ -6105,6 +6192,8 @@ var init_mesh_work_queue = __esm({
6105
6192
  ACTIVE_MESH_QUEUE_STATUSES = ["pending", "assigned"];
6106
6193
  HISTORICAL_MESH_QUEUE_STATUSES = ["completed", "failed", "cancelled"];
6107
6194
  MESH_TASK_MODES = ["code_change", "validation", "live_debug_readonly", "launch_app", "convergence"];
6195
+ MESH_TASK_PRIORITIES = ["low", "normal", "high"];
6196
+ NOT_BEFORE_RELATIVE_THRESHOLD_MS = 365 * 24 * 60 * 60 * 1e3;
6108
6197
  LIVE_DEBUG_READONLY_FORBIDDEN = [
6109
6198
  { label: "source_edit", pattern: /\b(edit|modify|patch|apply\s+patch|write\s+(?:to\s+)?(?:file|source)|overwrite|delete\s+file|remove\s+file|create\s+file|touch\s+file)\b/i },
6110
6199
  { label: "checkpoint", pattern: /\b(checkpoint|mesh_checkpoint)\b/i },
@@ -6159,7 +6248,7 @@ var init_mesh_work_queue = __esm({
6159
6248
  });
6160
6249
 
6161
6250
  // src/mesh/mesh-runtime-store.ts
6162
- import { existsSync as existsSync8, mkdirSync as mkdirSync5, readFileSync as readFileSync6, renameSync as renameSync3, statSync as statSync5 } from "fs";
6251
+ import { existsSync as existsSync8, mkdirSync as mkdirSync5, readFileSync as readFileSync6, renameSync as renameSync3, statSync as statSync5, unlinkSync as unlinkSync2 } from "fs";
6163
6252
  import { dirname as dirname2, join as join9 } from "path";
6164
6253
  function loadDatabaseCtor() {
6165
6254
  if (DatabaseCtor) return DatabaseCtor;
@@ -6172,9 +6261,28 @@ function safeMeshId(meshId) {
6172
6261
  function legacyQueuePath(meshId) {
6173
6262
  return join9(getLedgerDir(), `${safeMeshId(meshId)}.queue.json`);
6174
6263
  }
6264
+ function cleanupStrayRootRuntimeDb(canonicalPath) {
6265
+ try {
6266
+ const strayPath = join9(getConfigDir(), "mesh-runtime.db");
6267
+ if (strayPath === canonicalPath) return;
6268
+ if (!existsSync8(strayPath)) return;
6269
+ if (statSync5(strayPath).size !== 0) return;
6270
+ unlinkSync2(strayPath);
6271
+ if (!loggedStrayCleanup) {
6272
+ loggedStrayCleanup = true;
6273
+ LOG.info("MeshRuntimeStore", `Removed stray 0-byte root mesh-runtime.db at ${strayPath}`);
6274
+ }
6275
+ } catch (err) {
6276
+ if (!loggedStrayCleanup) {
6277
+ loggedStrayCleanup = true;
6278
+ LOG.warn("MeshRuntimeStore", `Stray root mesh-runtime.db cleanup failed (ignored): ${err?.message || err}`);
6279
+ }
6280
+ }
6281
+ }
6175
6282
  function meshRuntimeStorePath() {
6176
6283
  const dir = getLedgerDir();
6177
6284
  const nextPath = join9(dir, "mesh-runtime.db");
6285
+ cleanupStrayRootRuntimeDb(nextPath);
6178
6286
  if (existsSync8(nextPath)) return nextPath;
6179
6287
  const legacyPath = join9(dir, "beads.db");
6180
6288
  if (!existsSync8(legacyPath)) return nextPath;
@@ -6198,16 +6306,18 @@ function meshRuntimeStorePath() {
6198
6306
  }
6199
6307
  return nextPath;
6200
6308
  }
6201
- var DatabaseCtor, loggedMigrationFailure, MeshRuntimeStore;
6309
+ var DatabaseCtor, loggedMigrationFailure, loggedStrayCleanup, MeshRuntimeStore;
6202
6310
  var init_mesh_runtime_store = __esm({
6203
6311
  "src/mesh/mesh-runtime-store.ts"() {
6204
6312
  "use strict";
6205
6313
  init_logger();
6206
6314
  init_load_better_sqlite3();
6315
+ init_config();
6207
6316
  init_mesh_ledger();
6208
6317
  init_mesh_work_queue();
6209
6318
  init_dist();
6210
6319
  loggedMigrationFailure = false;
6320
+ loggedStrayCleanup = false;
6211
6321
  MeshRuntimeStore = class _MeshRuntimeStore {
6212
6322
  static instance;
6213
6323
  db;
@@ -6356,20 +6466,9 @@ var init_mesh_runtime_store = __esm({
6356
6466
  CREATE INDEX IF NOT EXISTS idx_mesh_session_delivery_task
6357
6467
  ON mesh_session_delivery(mesh_id, task_id);
6358
6468
 
6359
- CREATE TABLE IF NOT EXISTS mesh_completion_conflicts (
6360
- id TEXT PRIMARY KEY,
6361
- mesh_id TEXT NOT NULL,
6362
- fingerprint TEXT NOT NULL,
6363
- conflicting_task_id TEXT,
6364
- conflicting_session_id TEXT,
6365
- original_task_id TEXT,
6366
- original_session_id TEXT,
6367
- event TEXT NOT NULL,
6368
- created_at TEXT NOT NULL
6369
- );
6370
-
6371
- CREATE INDEX IF NOT EXISTS idx_mesh_completion_conflicts_mesh
6372
- ON mesh_completion_conflicts(mesh_id, created_at);
6469
+ -- MESH-COMPLEXITY-AUDIT Part 8-2: mesh_completion_conflicts removed
6470
+ -- (write-only fingerprint-collision diagnostic, no production reader,
6471
+ -- no no-loss role). Dropped in migrateMeshIsolationColumns step 6.
6373
6472
 
6374
6473
  CREATE TABLE IF NOT EXISTS mesh_tool_call_log (
6375
6474
  id INTEGER PRIMARY KEY AUTOINCREMENT,
@@ -6550,6 +6649,8 @@ var init_mesh_runtime_store = __esm({
6550
6649
  ON mesh_pending_events(mesh_id, event_id)
6551
6650
  WHERE event_id IS NOT NULL
6552
6651
  `);
6652
+ this.db.exec(`DROP TABLE IF EXISTS mesh_direct_delivered_events`);
6653
+ this.db.exec(`DROP TABLE IF EXISTS mesh_completion_conflicts`);
6553
6654
  } catch (err) {
6554
6655
  if (!loggedMigrationFailure) {
6555
6656
  loggedMigrationFailure = true;
@@ -6859,24 +6960,27 @@ var init_mesh_runtime_store = __esm({
6859
6960
  }
6860
6961
  const nodeIdForms = expandDaemonIdForms(nodeId);
6861
6962
  const nodePinnedPlaceholders = nodeIdForms.map(() => "?").join(", ");
6862
- const rows = [
6863
- ...this.db.prepare(`
6963
+ const parseTier = (query, ...params) => {
6964
+ const tierRows = this.db.prepare(query).all(...params);
6965
+ return tierRows.map((row) => JSON.parse(row.payload)).sort((a, b) => meshTaskPriorityRank(b.priority) - meshTaskPriorityRank(a.priority));
6966
+ };
6967
+ const candidates = [
6968
+ ...parseTier(`
6864
6969
  SELECT payload FROM mesh_queue
6865
6970
  WHERE mesh_id = ? AND status = 'pending' AND target_session_id = ?
6866
6971
  ORDER BY created_at ASC
6867
- `).all(meshId, sessionId),
6868
- ...this.db.prepare(`
6972
+ `, meshId, sessionId),
6973
+ ...parseTier(`
6869
6974
  SELECT payload FROM mesh_queue
6870
6975
  WHERE mesh_id = ? AND status = 'pending' AND target_node_id IN (${nodePinnedPlaceholders}) AND target_session_id IS NULL
6871
6976
  ORDER BY created_at ASC
6872
- `).all(meshId, ...nodeIdForms),
6873
- ...this.db.prepare(`
6977
+ `, meshId, ...nodeIdForms),
6978
+ ...parseTier(`
6874
6979
  SELECT payload FROM mesh_queue
6875
6980
  WHERE mesh_id = ? AND status = 'pending' AND target_node_id IS NULL AND target_session_id IS NULL
6876
6981
  ORDER BY created_at ASC
6877
- `).all(meshId)
6982
+ `, meshId)
6878
6983
  ];
6879
- const candidates = rows.map((row) => JSON.parse(row.payload));
6880
6984
  const depIds = [...new Set(candidates.flatMap((c) => Array.isArray(c.dependsOn) ? c.dependsOn : []))];
6881
6985
  const depStatus = /* @__PURE__ */ new Map();
6882
6986
  if (depIds.length > 0) {
@@ -6891,6 +6995,8 @@ var init_mesh_runtime_store = __esm({
6891
6995
  if (isTaskReadonly(candidate)) return true;
6892
6996
  return !nodeBusy;
6893
6997
  };
6998
+ const claimNowMs = Date.now();
6999
+ const notBeforeReady = (candidate) => meshTaskNotBeforeReady(candidate, claimNowMs);
6894
7000
  const nodeIsWorktree = opts?.nodeIsWorktree === true;
6895
7001
  const convergenceAllows = (candidate) => candidate.taskMode !== "convergence" || !nodeIsWorktree;
6896
7002
  const targetMatches = (candidate) => {
@@ -6900,7 +7006,7 @@ var init_mesh_runtime_store = __esm({
6900
7006
  }
6901
7007
  return true;
6902
7008
  };
6903
- const entry = candidates.find((candidate) => nodeSatisfiesRequiredTags(candidate.requiredTags, capabilityTags) && dependenciesSatisfied(candidate) && convergenceAllows(candidate) && targetMatches(candidate) && nodeConflictAllows(candidate));
7009
+ const entry = candidates.find((candidate) => nodeSatisfiesRequiredTags(candidate.requiredTags, capabilityTags) && dependenciesSatisfied(candidate) && notBeforeReady(candidate) && convergenceAllows(candidate) && targetMatches(candidate) && nodeConflictAllows(candidate));
6904
7010
  if (!entry) return null;
6905
7011
  const now = (/* @__PURE__ */ new Date()).toISOString();
6906
7012
  entry.status = "assigned";
@@ -7260,43 +7366,11 @@ var init_mesh_runtime_store = __esm({
7260
7366
  this.db.prepare("DELETE FROM mesh_session_delivery WHERE mesh_id = ?").run(meshId);
7261
7367
  }
7262
7368
  // ── Completion Conflict Diagnostics ──────────────────────────────────────
7263
- recordCompletionConflict(entry) {
7264
- this.db.prepare(`
7265
- INSERT OR IGNORE INTO mesh_completion_conflicts
7266
- (id, mesh_id, fingerprint, conflicting_task_id, conflicting_session_id,
7267
- original_task_id, original_session_id, event, created_at)
7268
- VALUES (@id, @meshId, @fingerprint, @conflictingTaskId, @conflictingSessionId,
7269
- @originalTaskId, @originalSessionId, @event, @createdAt)
7270
- `).run({
7271
- id: entry.id,
7272
- meshId: entry.meshId,
7273
- fingerprint: entry.fingerprint,
7274
- conflictingTaskId: entry.conflictingTaskId ?? null,
7275
- conflictingSessionId: entry.conflictingSessionId ?? null,
7276
- originalTaskId: entry.originalTaskId ?? null,
7277
- originalSessionId: entry.originalSessionId ?? null,
7278
- event: entry.event,
7279
- createdAt: entry.createdAt
7280
- });
7281
- this.maybeCheckpointWal();
7282
- }
7283
- getRecentCompletionConflicts(meshId, limitMs = 60 * 60 * 1e3) {
7284
- const cutoff = new Date(Date.now() - limitMs).toISOString();
7285
- const rows = this.db.prepare(
7286
- "SELECT * FROM mesh_completion_conflicts WHERE mesh_id = ? AND created_at >= ? ORDER BY created_at DESC LIMIT 50"
7287
- ).all(meshId, cutoff);
7288
- return rows.map((r) => ({
7289
- id: r.id,
7290
- meshId: r.mesh_id,
7291
- fingerprint: r.fingerprint,
7292
- conflictingTaskId: r.conflicting_task_id,
7293
- conflictingSessionId: r.conflicting_session_id,
7294
- originalTaskId: r.original_task_id,
7295
- originalSessionId: r.original_session_id,
7296
- event: r.event,
7297
- createdAt: r.created_at
7298
- }));
7299
- }
7369
+ // MESH-COMPLEXITY-AUDIT Part 8-2: recordCompletionConflict /
7370
+ // getRecentCompletionConflicts (and their mesh_completion_conflicts table)
7371
+ // were removed. They were a write-only diagnostic of fingerprint-dedup
7372
+ // collisions with no production reader and no part in the no-loss delivery
7373
+ // contract; the table is dropped in migrateMeshIsolationColumns (step 6).
7300
7374
  /**
7301
7375
  * Record a mesh tool call and check whether this mesh+tool combination is
7302
7376
  * being called too rapidly (sliding window rate guard).
@@ -11510,7 +11584,7 @@ var init_mesh_events_utils = __esm({
11510
11584
  });
11511
11585
 
11512
11586
  // src/mesh/mesh-events-pending.ts
11513
- import { appendFileSync as appendFileSync2, existsSync as existsSync15, readFileSync as readFileSync12, renameSync as renameSync4, statSync as statSync6, unlinkSync as unlinkSync2, writeFileSync as writeFileSync6 } from "fs";
11587
+ import { appendFileSync as appendFileSync2, existsSync as existsSync15, readFileSync as readFileSync12, renameSync as renameSync4, statSync as statSync6, unlinkSync as unlinkSync3, writeFileSync as writeFileSync6 } from "fs";
11514
11588
  import { join as join16 } from "path";
11515
11589
  import { randomUUID as randomUUID8 } from "crypto";
11516
11590
  function normalizeCoordinatorDaemonIds(coordinatorDaemonId) {
@@ -11537,7 +11611,11 @@ function ledgerRecordQuarantinedEvent(event, reason) {
11537
11611
  targetCoordinatorDaemonId: event.targetCoordinatorDaemonId ?? null,
11538
11612
  ...readNonEmptyString2(event.eventId) ? { eventId: event.eventId } : {},
11539
11613
  queuedAt: event.queuedAt,
11540
- ...finalSummary ? { finalSummary } : {}
11614
+ ...finalSummary ? { finalSummary } : {},
11615
+ // Full original event so mesh_requeue_held_events can restore it
11616
+ // losslessly (event_held→pending). The summary/label fields above stay
11617
+ // for human-readable audit; `heldEvent` is the machine recovery copy.
11618
+ heldEvent: event
11541
11619
  }
11542
11620
  });
11543
11621
  } catch (e) {
@@ -11848,8 +11926,11 @@ function trimPendingEventsIfNeeded(path45) {
11848
11926
  nodeLabel: event.nodeLabel,
11849
11927
  ...event.workspace ? { workspace: event.workspace } : {},
11850
11928
  targetCoordinatorDaemonId: event.targetCoordinatorDaemonId ?? null,
11929
+ ...readNonEmptyString2(event.eventId) ? { eventId: event.eventId } : {},
11851
11930
  queuedAt: event.queuedAt,
11852
- ...finalSummary ? { finalSummary } : {}
11931
+ ...finalSummary ? { finalSummary } : {},
11932
+ // Full original event for lossless mesh_requeue_held_events restore.
11933
+ heldEvent: event
11853
11934
  }
11854
11935
  });
11855
11936
  LOG.warn("MeshEvents", `Pending-events trim dropping undelivered ${event.event} for mesh ${event.meshId} \u2014 recorded to ledger (recoverable)`);
@@ -11986,13 +12067,13 @@ function atomicDrainFile(path45) {
11986
12067
  try {
11987
12068
  const content = readFileSync12(tmpPath, "utf-8");
11988
12069
  try {
11989
- unlinkSync2(tmpPath);
12070
+ unlinkSync3(tmpPath);
11990
12071
  } catch {
11991
12072
  }
11992
12073
  return content;
11993
12074
  } catch {
11994
12075
  try {
11995
- unlinkSync2(tmpPath);
12076
+ unlinkSync3(tmpPath);
11996
12077
  } catch {
11997
12078
  }
11998
12079
  return null;
@@ -12010,7 +12091,7 @@ function selectiveDrainFile(path45, predicate) {
12010
12091
  content = readFileSync12(tmpPath, "utf-8");
12011
12092
  } catch {
12012
12093
  try {
12013
- unlinkSync2(tmpPath);
12094
+ unlinkSync3(tmpPath);
12014
12095
  } catch {
12015
12096
  }
12016
12097
  return [];
@@ -12035,7 +12116,7 @@ function selectiveDrainFile(path45, predicate) {
12035
12116
  if (keptLines.length > 0) {
12036
12117
  writeFileSync6(path45, keptLines.join("\n") + "\n", "utf-8");
12037
12118
  }
12038
- unlinkSync2(tmpPath);
12119
+ unlinkSync3(tmpPath);
12039
12120
  } catch {
12040
12121
  try {
12041
12122
  if (existsSync15(tmpPath) && !existsSync15(path45)) renameSync4(tmpPath, path45);
@@ -12176,6 +12257,83 @@ function getPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId, opts) {
12176
12257
  });
12177
12258
  return reconcilePendingMeshCoordinatorEvents(meshId, routed);
12178
12259
  }
12260
+ function readHeldTaskId(restored, payload) {
12261
+ const fromMeta = restored?.metadataEvent && typeof restored.metadataEvent === "object" ? readNonEmptyString2(restored.metadataEvent.taskId) : "";
12262
+ return fromMeta || readNonEmptyString2(payload.taskId) || "";
12263
+ }
12264
+ function requeueHeldMeshCoordinatorEvents(meshId, filter) {
12265
+ const result = {
12266
+ meshId,
12267
+ matched: 0,
12268
+ alreadyRequeued: 0,
12269
+ unrecoverable: 0,
12270
+ requeued: 0,
12271
+ dedupSuppressed: 0,
12272
+ entries: []
12273
+ };
12274
+ const all = readLedgerEntries(meshId);
12275
+ const requeuedIds = /* @__PURE__ */ new Set();
12276
+ for (const entry of all) {
12277
+ if (entry.kind !== "event_held_requeued") continue;
12278
+ const id = readNonEmptyString2(entry.payload?.heldEntryId);
12279
+ if (id) requeuedIds.add(id);
12280
+ }
12281
+ const sinceMs = filter?.since ? new Date(filter.since).getTime() : NaN;
12282
+ const wantEvent = readNonEmptyString2(filter?.event);
12283
+ const wantNode = readNonEmptyString2(filter?.nodeId);
12284
+ const wantTask = readNonEmptyString2(filter?.taskId);
12285
+ const wantReason = readNonEmptyString2(filter?.reason);
12286
+ for (const entry of all) {
12287
+ if (entry.kind !== "event_held") continue;
12288
+ const payload = entry.payload && typeof entry.payload === "object" ? entry.payload : {};
12289
+ if (payload.recoverable !== true) continue;
12290
+ const restored = payload.heldEvent && typeof payload.heldEvent === "object" ? { ...payload.heldEvent } : void 0;
12291
+ const eventName = restored?.event || readNonEmptyString2(payload.event);
12292
+ const nodeId = restored?.nodeId || entry.nodeId || readNonEmptyString2(payload.nodeId) || void 0;
12293
+ const taskId = readHeldTaskId(restored, payload);
12294
+ const reason = readNonEmptyString2(payload.reason) || void 0;
12295
+ if (wantEvent && eventName !== wantEvent) continue;
12296
+ if (wantNode && nodeId !== wantNode) continue;
12297
+ if (wantTask && taskId !== wantTask) continue;
12298
+ if (wantReason && reason !== wantReason) continue;
12299
+ if (filter?.since && !Number.isNaN(sinceMs) && new Date(entry.timestamp).getTime() < sinceMs) continue;
12300
+ result.matched++;
12301
+ if (requeuedIds.has(entry.id)) {
12302
+ result.alreadyRequeued++;
12303
+ result.entries.push({ heldEntryId: entry.id, event: eventName, ...nodeId ? { nodeId } : {}, ...taskId ? { taskId } : {}, ...reason ? { reason } : {}, outcome: "already_requeued" });
12304
+ continue;
12305
+ }
12306
+ if (!restored || !readNonEmptyString2(restored.event) || !readNonEmptyString2(restored.meshId)) {
12307
+ result.unrecoverable++;
12308
+ result.entries.push({ heldEntryId: entry.id, event: eventName, ...nodeId ? { nodeId } : {}, ...taskId ? { taskId } : {}, ...reason ? { reason } : {}, outcome: "unrecoverable" });
12309
+ continue;
12310
+ }
12311
+ const beforeDup = hasPendingCoordinatorEventDuplicate(restored);
12312
+ let ok = false;
12313
+ try {
12314
+ ok = queuePendingMeshCoordinatorEvent(restored);
12315
+ } catch (e) {
12316
+ LOG.warn("MeshEvents", `Requeue of held ${eventName} for mesh ${meshId} failed: ${e?.message || e}`);
12317
+ }
12318
+ appendLedgerEntry(meshId, {
12319
+ kind: "event_held_requeued",
12320
+ ...nodeId ? { nodeId } : {},
12321
+ payload: {
12322
+ heldEntryId: entry.id,
12323
+ event: eventName,
12324
+ requeued: ok,
12325
+ ...taskId ? { taskId } : {},
12326
+ ...reason ? { reason } : {},
12327
+ ...beforeDup ? { dedupSuppressed: true } : {}
12328
+ }
12329
+ });
12330
+ requeuedIds.add(entry.id);
12331
+ result.requeued++;
12332
+ if (beforeDup) result.dedupSuppressed++;
12333
+ result.entries.push({ heldEntryId: entry.id, event: eventName, ...nodeId ? { nodeId } : {}, ...taskId ? { taskId } : {}, ...reason ? { reason } : {}, outcome: "requeued" });
12334
+ }
12335
+ return result;
12336
+ }
12179
12337
  function clearPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
12180
12338
  if (!meshId) return;
12181
12339
  try {
@@ -12185,7 +12343,7 @@ function clearPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
12185
12343
  const paths = coordinatorDaemonId ? [getPendingEventsPath(meshId, coordinatorDaemonId), getPendingEventsPath(meshId)] : [getPendingEventsPath(meshId)];
12186
12344
  for (const path45 of paths) {
12187
12345
  if (existsSync15(path45)) try {
12188
- unlinkSync2(path45);
12346
+ unlinkSync3(path45);
12189
12347
  } catch {
12190
12348
  }
12191
12349
  }
@@ -14211,7 +14369,7 @@ function driveExpiredAwaitClaim(components, meshId, task, ctx) {
14211
14369
  async function maybeAutoLaunchOneQueueSession(components, meshId, mesh) {
14212
14370
  const queue = getQueue(meshId);
14213
14371
  const statusById = new Map(queue.map((task) => [task.id, task.status]));
14214
- const pending = queue.filter((task) => task.status === "pending");
14372
+ const pending = queue.filter((task) => task.status === "pending").sort((a, b) => meshTaskPriorityRank(b.priority) - meshTaskPriorityRank(a.priority));
14215
14373
  {
14216
14374
  const pendingIds = new Set(pending.map((t) => t.id));
14217
14375
  const prefix = `${meshId}::`;
@@ -14227,6 +14385,10 @@ async function maybeAutoLaunchOneQueueSession(components, meshId, mesh) {
14227
14385
  markAutoLaunch(meshId, task.id, { status: "skipped", reason: "dependencies_unsatisfied" });
14228
14386
  continue;
14229
14387
  }
14388
+ if (!meshTaskNotBeforeReady(task)) {
14389
+ markAutoLaunch(meshId, task.id, { status: "skipped", reason: "not_before_delayed" });
14390
+ continue;
14391
+ }
14230
14392
  const isReadonly = isTaskReadonly(task);
14231
14393
  if (isReadonly) {
14232
14394
  if (activeReadonlyAssignedCount(meshId) >= maxReadonlyParallelTasks) {
@@ -17362,15 +17524,6 @@ function isDuplicateMeshCompletionEvent(args) {
17362
17524
  const fingerprint = buildMeshCompletionFingerprint(args);
17363
17525
  if (!fingerprint) return false;
17364
17526
  if (hasFingerprintSeen(args.meshId, fingerprint)) {
17365
- if (args.taskId) {
17366
- recordCompletionConflict({
17367
- meshId: args.meshId,
17368
- fingerprint,
17369
- conflictingTaskId: args.taskId,
17370
- conflictingSessionId: args.sessionId,
17371
- event: args.event
17372
- });
17373
- }
17374
17527
  return true;
17375
17528
  }
17376
17529
  recordFingerprintSeen(args.meshId, fingerprint);
@@ -18448,6 +18601,347 @@ var init_mesh_reconcile_identity = __esm({
18448
18601
  }
18449
18602
  });
18450
18603
 
18604
+ // src/mesh/mesh-reconcile-acked-hold.ts
18605
+ function resolveTunedReconcileMs(envName, def, min, max) {
18606
+ const raw = readNonEmptyString2(process.env[envName]);
18607
+ if (raw) {
18608
+ const parsed = Number.parseInt(raw, 10);
18609
+ if (Number.isFinite(parsed) && parsed >= min && parsed <= max) return parsed;
18610
+ }
18611
+ return def;
18612
+ }
18613
+ function resolveAckedDeathDeadlineMs() {
18614
+ return resolveTunedReconcileMs("MESH_INFLIGHT_ACKED_DEATH_DEADLINE_MS", 8 * 6e4, 0, 60 * 6e4);
18615
+ }
18616
+ function resolveAckedTranscriptFastTrackGraceMs() {
18617
+ return resolveTunedReconcileMs("MESH_INFLIGHT_ACKED_TRANSCRIPT_FASTTRACK_GRACE_MS", 4e4, 0, 5 * 6e4);
18618
+ }
18619
+ function inFlightSynthKey(meshId, taskId) {
18620
+ return `${meshId}::${taskId}`;
18621
+ }
18622
+ function taskIdFromSynthKey(meshId, synthKey) {
18623
+ const prefix = `${meshId}::`;
18624
+ return synthKey.startsWith(prefix) ? synthKey.slice(prefix.length) : synthKey;
18625
+ }
18626
+ function holdStore() {
18627
+ try {
18628
+ return MeshRuntimeStore.getInstance();
18629
+ } catch {
18630
+ return void 0;
18631
+ }
18632
+ }
18633
+ function getHoldState(synthKey, meshId) {
18634
+ const cached3 = inFlightAckedHoldState.get(synthKey);
18635
+ if (cached3) return cached3;
18636
+ const store = holdStore();
18637
+ if (!store) return void 0;
18638
+ let row;
18639
+ try {
18640
+ row = store.getInflightHold(taskIdFromSynthKey(meshId, synthKey));
18641
+ } catch {
18642
+ return void 0;
18643
+ }
18644
+ if (!row) return void 0;
18645
+ const state = {
18646
+ liveConfirmedSinceAck: row.holdReason === "live",
18647
+ consecutiveReadFailures: row.readFailureCount ?? 0,
18648
+ ...row.firstIdleSinceAck !== null && row.firstIdleSinceAck !== void 0 ? { transcriptIdleSinceMs: row.firstIdleSinceAck } : {}
18649
+ };
18650
+ inFlightAckedHoldState.set(synthKey, state);
18651
+ return state;
18652
+ }
18653
+ function setHoldState(synthKey, meshId, state) {
18654
+ inFlightAckedHoldState.set(synthKey, state);
18655
+ const store = holdStore();
18656
+ if (!store) return;
18657
+ try {
18658
+ store.upsertInflightHold({
18659
+ taskId: taskIdFromSynthKey(meshId, synthKey),
18660
+ meshId,
18661
+ holdReason: state.liveConfirmedSinceAck ? "live" : "unconfirmed",
18662
+ firstIdleSinceAck: state.transcriptIdleSinceMs ?? null,
18663
+ readFailureCount: state.consecutiveReadFailures
18664
+ });
18665
+ } catch {
18666
+ }
18667
+ }
18668
+ function deleteHoldState(synthKey, meshId) {
18669
+ inFlightAckedHoldState.delete(synthKey);
18670
+ const store = holdStore();
18671
+ if (!store) return;
18672
+ try {
18673
+ store.deleteInflightHold(taskIdFromSynthKey(meshId, synthKey));
18674
+ } catch {
18675
+ }
18676
+ }
18677
+ function rehydrateAckedHoldsForMesh(meshId) {
18678
+ if (rehydratedHoldMeshes.has(meshId)) return;
18679
+ rehydratedHoldMeshes.add(meshId);
18680
+ const store = holdStore();
18681
+ if (!store) return;
18682
+ let rows;
18683
+ try {
18684
+ rows = store.listInflightHoldsByMesh(meshId);
18685
+ } catch {
18686
+ return;
18687
+ }
18688
+ for (const row of rows) {
18689
+ const synthKey = inFlightSynthKey(meshId, row.taskId);
18690
+ if (inFlightAckedHoldState.has(synthKey)) continue;
18691
+ inFlightAckedHoldState.set(synthKey, {
18692
+ liveConfirmedSinceAck: row.holdReason === "live",
18693
+ consecutiveReadFailures: row.readFailureCount ?? 0,
18694
+ ...row.firstIdleSinceAck !== null && row.firstIdleSinceAck !== void 0 ? { transcriptIdleSinceMs: row.firstIdleSinceAck } : {}
18695
+ });
18696
+ }
18697
+ if (rows.length > 0) {
18698
+ LOG.info("MeshReconcile", `Rehydrated ${rows.length} persisted acked-hold row(s) for mesh ${meshId} after (re)start`);
18699
+ }
18700
+ }
18701
+ function collectHeldSynthKeysForMesh(meshId) {
18702
+ const heldKeys = /* @__PURE__ */ new Set();
18703
+ for (const key2 of inFlightAckedHoldState.keys()) {
18704
+ if (key2.startsWith(`${meshId}::`)) heldKeys.add(key2);
18705
+ }
18706
+ const store = holdStore();
18707
+ if (store) {
18708
+ try {
18709
+ for (const row of store.listInflightHoldsByMesh(meshId)) {
18710
+ heldKeys.add(inFlightSynthKey(meshId, row.taskId));
18711
+ }
18712
+ } catch {
18713
+ }
18714
+ }
18715
+ return heldKeys;
18716
+ }
18717
+ var ACKED_DEATH_CONSECUTIVE_READ_FAILURES, inFlightAckedHoldState, rehydratedHoldMeshes;
18718
+ var init_mesh_reconcile_acked_hold = __esm({
18719
+ "src/mesh/mesh-reconcile-acked-hold.ts"() {
18720
+ "use strict";
18721
+ init_logger();
18722
+ init_mesh_runtime_store();
18723
+ init_mesh_events_utils();
18724
+ ACKED_DEATH_CONSECUTIVE_READ_FAILURES = 3;
18725
+ inFlightAckedHoldState = /* @__PURE__ */ new Map();
18726
+ rehydratedHoldMeshes = /* @__PURE__ */ new Set();
18727
+ }
18728
+ });
18729
+
18730
+ // src/mesh/mesh-reconcile-config.ts
18731
+ function resolveAutoPruneMinAgeMs() {
18732
+ const raw = readNonEmptyString2(process.env.MESH_AUTO_PRUNE_MIN_AGE_MS);
18733
+ if (raw) {
18734
+ const parsed = Number.parseInt(raw, 10);
18735
+ if (Number.isFinite(parsed) && parsed >= 60 * 6e4 && parsed <= 30 * 24 * 60 * 6e4) return parsed;
18736
+ }
18737
+ return DEFAULT_AUTO_PRUNE_MIN_AGE_MS;
18738
+ }
18739
+ function resolvePendingHeldDrainEscalateMs() {
18740
+ return resolveTunedReconcileMs("MESH_PENDING_HELD_DRAIN_ESCALATE_MS", DEFAULT_PENDING_HELD_DRAIN_ESCALATE_MS, 4e3, 5 * 6e4);
18741
+ }
18742
+ function resolveReconcileIntervalMs() {
18743
+ const raw = readNonEmptyString2(process.env.MESH_RECONCILE_INTERVAL_MS);
18744
+ if (raw) {
18745
+ const parsed = Number.parseInt(raw, 10);
18746
+ if (Number.isFinite(parsed) && parsed >= 1e3 && parsed <= 6e4) return parsed;
18747
+ }
18748
+ return DEFAULT_RECONCILE_INTERVAL_MS;
18749
+ }
18750
+ var DEFAULT_RECONCILE_INTERVAL_MS, DEFAULT_AUTO_PRUNE_MIN_AGE_MS, DEFAULT_PENDING_HELD_DRAIN_ESCALATE_MS;
18751
+ var init_mesh_reconcile_config = __esm({
18752
+ "src/mesh/mesh-reconcile-config.ts"() {
18753
+ "use strict";
18754
+ init_mesh_events_utils();
18755
+ init_mesh_reconcile_acked_hold();
18756
+ DEFAULT_RECONCILE_INTERVAL_MS = 4e3;
18757
+ DEFAULT_AUTO_PRUNE_MIN_AGE_MS = 24 * 60 * 6e4;
18758
+ DEFAULT_PENDING_HELD_DRAIN_ESCALATE_MS = 12e3;
18759
+ }
18760
+ });
18761
+
18762
+ // src/mesh/mesh-remote-event-pull.ts
18763
+ async function pullRemoteNodeQueues(components, mesh, localDaemonId, candidateDaemonIds) {
18764
+ const dispatchMeshCommand = components.dispatchMeshCommand;
18765
+ if (!dispatchMeshCommand) return;
18766
+ const meshId = mesh.id;
18767
+ const pulls = candidateDaemonIds.length > 0 ? candidateDaemonIds.map((id) => ({ meshId, coordinatorDaemonId: id })) : [{ meshId }];
18768
+ await Promise.allSettled(mesh.nodes.map(async (node) => {
18769
+ const nodeDaemonId = readNonEmptyString2(node.daemonId);
18770
+ if (!nodeDaemonId) return;
18771
+ if (daemonIdsEquivalent(nodeDaemonId, localDaemonId)) return;
18772
+ if (daemonIdListIncludes(candidateDaemonIds, nodeDaemonId)) return;
18773
+ const peerSnapshot = components.getMeshPeerConnectionStatus?.(nodeDaemonId);
18774
+ if (peerSnapshot && String(peerSnapshot.state) !== "connected") return;
18775
+ for (const pendingEventArgs of pulls) {
18776
+ let events;
18777
+ try {
18778
+ events = await dispatchMeshCommand(nodeDaemonId, "get_pending_mesh_events", pendingEventArgs);
18779
+ } catch {
18780
+ break;
18781
+ }
18782
+ const list = extractPendingEvents(events).filter((e) => readNonEmptyString2(e?.meshId) === meshId);
18783
+ for (const event of list) {
18784
+ const payload = buildForwardPayloadFromPending(event);
18785
+ if (!payload.event || !payload.meshId) continue;
18786
+ try {
18787
+ handleMeshForwardEvent(components, payload);
18788
+ } catch {
18789
+ }
18790
+ }
18791
+ }
18792
+ }));
18793
+ }
18794
+ function unwrapReadChatPayload(raw) {
18795
+ let cursor = raw;
18796
+ for (let depth = 0; depth < 4 && cursor && typeof cursor === "object"; depth++) {
18797
+ const record = cursor;
18798
+ if (Array.isArray(record.messages)) return record;
18799
+ if (record.payload && typeof record.payload === "object") {
18800
+ cursor = record.payload;
18801
+ continue;
18802
+ }
18803
+ if (record.result && typeof record.result === "object") {
18804
+ cursor = record.result;
18805
+ continue;
18806
+ }
18807
+ if (record.data && typeof record.data === "object") {
18808
+ cursor = record.data;
18809
+ continue;
18810
+ }
18811
+ break;
18812
+ }
18813
+ return cursor && typeof cursor === "object" ? cursor : null;
18814
+ }
18815
+ function readChatPayloadStatus(payload) {
18816
+ return readNonEmptyString2(payload?.status).toLowerCase();
18817
+ }
18818
+ function realTerminalEmitPendingForTask(meshId, taskId) {
18819
+ let pending;
18820
+ try {
18821
+ pending = getPendingMeshCoordinatorEvents(meshId);
18822
+ } catch {
18823
+ return false;
18824
+ }
18825
+ return pending.some((e) => readNonEmptyString2(e.metadataEvent?.taskId) === taskId && (e.event === "agent:generating_completed" || e.event === "agent:stopped"));
18826
+ }
18827
+ async function reprobeWorkerStatus(components, args) {
18828
+ try {
18829
+ if (args.isLocalNode) {
18830
+ const r = await components.commandHandler.handle("read_chat", args.readArgs);
18831
+ if (r && r.success === false) return null;
18832
+ return readChatPayloadStatus(unwrapReadChatPayload(r));
18833
+ }
18834
+ if (components.dispatchMeshCommand) {
18835
+ const r = await components.dispatchMeshCommand(args.nodeDaemonId, "read_chat", args.readArgs);
18836
+ const p = unwrapReadChatPayload(r);
18837
+ if (p && p.success === false) return null;
18838
+ return readChatPayloadStatus(p);
18839
+ }
18840
+ } catch {
18841
+ return null;
18842
+ }
18843
+ return null;
18844
+ }
18845
+ async function collectLiveNodesWithSessions(components, mesh, selfIds, localDaemonId) {
18846
+ const dispatchMeshCommand = components.dispatchMeshCommand;
18847
+ return Promise.all(mesh.nodes.map(async (node) => {
18848
+ const nodeDaemonId = readNonEmptyString2(node.daemonId);
18849
+ const isLocalNode = !nodeDaemonId || daemonIdListIncludes(selfIds, nodeDaemonId) || daemonIdsEquivalent(nodeDaemonId, localDaemonId);
18850
+ if (!isLocalNode) {
18851
+ const peerSnapshot = components.getMeshPeerConnectionStatus?.(nodeDaemonId);
18852
+ if (peerSnapshot && String(peerSnapshot.state) !== "connected") return node;
18853
+ }
18854
+ let statusResult;
18855
+ try {
18856
+ if (isLocalNode) {
18857
+ statusResult = await components.commandHandler.handle("get_status_metadata", {});
18858
+ } else if (dispatchMeshCommand) {
18859
+ statusResult = await dispatchMeshCommand(nodeDaemonId, "get_status_metadata", {});
18860
+ } else {
18861
+ return node;
18862
+ }
18863
+ } catch {
18864
+ return node;
18865
+ }
18866
+ const sessions = extractStatusMetadataSessions(statusResult);
18867
+ return sessions.length > 0 ? { ...node, sessions } : node;
18868
+ }));
18869
+ }
18870
+ function extractStatusMetadataSessions(raw) {
18871
+ let cursor = raw;
18872
+ for (let depth = 0; depth < 4 && cursor && typeof cursor === "object"; depth++) {
18873
+ const record = cursor;
18874
+ const status = record.status && typeof record.status === "object" ? record.status : void 0;
18875
+ if (status && Array.isArray(status.sessions)) return status.sessions;
18876
+ if (Array.isArray(record.sessions)) return record.sessions;
18877
+ if (record.payload && typeof record.payload === "object") {
18878
+ cursor = record.payload;
18879
+ continue;
18880
+ }
18881
+ if (record.result && typeof record.result === "object") {
18882
+ cursor = record.result;
18883
+ continue;
18884
+ }
18885
+ if (record.data && typeof record.data === "object") {
18886
+ cursor = record.data;
18887
+ continue;
18888
+ }
18889
+ break;
18890
+ }
18891
+ return [];
18892
+ }
18893
+ function extractPendingEvents(raw) {
18894
+ if (Array.isArray(raw)) return raw;
18895
+ if (raw && typeof raw === "object") {
18896
+ const events = raw.events;
18897
+ if (Array.isArray(events)) return events;
18898
+ }
18899
+ return [];
18900
+ }
18901
+ function buildForwardPayloadFromPending(event) {
18902
+ const metadata = event?.metadataEvent && typeof event.metadataEvent === "object" ? event.metadataEvent : {};
18903
+ return {
18904
+ event: readNonEmptyString2(event?.event),
18905
+ meshId: readNonEmptyString2(event?.meshId),
18906
+ nodeId: readNonEmptyString2(event?.nodeId) || readNonEmptyString2(metadata.meshNodeId),
18907
+ workspace: readNonEmptyString2(event?.workspace) || readNonEmptyString2(metadata.workspace),
18908
+ // Preserve the originating coordinator session id across the relay. It is normally
18909
+ // carried inside metadataEvent.meshCoordinatorSessionId (spread below), but pass the
18910
+ // top-level field through explicitly too so the handleMeshForwardEvent whitelist
18911
+ // recovers it regardless of which carrier the producing daemon used.
18912
+ ...readNonEmptyString2(event?.targetCoordinatorSessionId) ? { targetCoordinatorSessionId: readNonEmptyString2(event.targetCoordinatorSessionId) } : {},
18913
+ ...metadata,
18914
+ // NOTIF-MISS (FIX 3): surface the dispatch task id at the TOP LEVEL so the relay's
18915
+ // received-stage trace (and buildRelayMetadataEvent) recovers it regardless of which
18916
+ // carrier the producing daemon used. The metadata spread above may carry the id only as
18917
+ // `meshActiveTaskId` (a worker provider event), leaving top-level `taskId` unset and the
18918
+ // received stage rendering `task=-`. Resolve both carriers into an explicit `taskId` so
18919
+ // dedup stays task-scoped end-to-end. Only set when a non-empty id exists (no clobber to
18920
+ // undefined when neither is present).
18921
+ ...(() => {
18922
+ const tid = readNonEmptyString2(metadata.taskId) || readNonEmptyString2(metadata.meshActiveTaskId);
18923
+ return tid ? { taskId: tid } : {};
18924
+ })(),
18925
+ // T4 (B3b): carry the v2 envelope (protocolVersion/eventId/scope/dispatchedBy/
18926
+ // intendedFor) across the P2P relay boundary at the TOP LEVEL. These live on the
18927
+ // pending event itself, not inside metadataEvent, so without this the remote pull
18928
+ // re-queue would re-stamp a fresh eventId — breaking cross-machine idempotency and
18929
+ // downgrading the relayed completion to v1 broadcast routing. Spread LAST so the
18930
+ // authoritative envelope always wins over any stale key the metadata spread carried.
18931
+ ...serializeV2EnvelopeToWire(event)
18932
+ };
18933
+ }
18934
+ var init_mesh_remote_event_pull = __esm({
18935
+ "src/mesh/mesh-remote-event-pull.ts"() {
18936
+ "use strict";
18937
+ init_mesh_events_pending();
18938
+ init_mesh_events_coordinator();
18939
+ init_mesh_events_utils();
18940
+ init_dist();
18941
+ init_mesh_reconcile_identity();
18942
+ }
18943
+ });
18944
+
18451
18945
  // src/mesh/mesh-reconcile-v2-backstop.ts
18452
18946
  function getMeshV2BackstopCounters() {
18453
18947
  return { ...meshV2BackstopCounters };
@@ -18480,152 +18974,205 @@ var init_mesh_reconcile_v2_backstop = __esm({
18480
18974
  }
18481
18975
  });
18482
18976
 
18483
- // src/mesh/mesh-reconcile-acked-hold.ts
18484
- function resolveTunedReconcileMs(envName, def, min, max) {
18485
- const raw = readNonEmptyString2(process.env[envName]);
18486
- if (raw) {
18487
- const parsed = Number.parseInt(raw, 10);
18488
- if (Number.isFinite(parsed) && parsed >= min && parsed <= max) return parsed;
18489
- }
18490
- return def;
18491
- }
18492
- function resolveAckedDeathDeadlineMs() {
18493
- return resolveTunedReconcileMs("MESH_INFLIGHT_ACKED_DEATH_DEADLINE_MS", 8 * 6e4, 0, 60 * 6e4);
18494
- }
18495
- function resolveAckedTranscriptFastTrackGraceMs() {
18496
- return resolveTunedReconcileMs("MESH_INFLIGHT_ACKED_TRANSCRIPT_FASTTRACK_GRACE_MS", 4e4, 0, 5 * 6e4);
18497
- }
18498
- function inFlightSynthKey(meshId, taskId) {
18499
- return `${meshId}::${taskId}`;
18500
- }
18501
- function taskIdFromSynthKey(meshId, synthKey) {
18502
- const prefix = `${meshId}::`;
18503
- return synthKey.startsWith(prefix) ? synthKey.slice(prefix.length) : synthKey;
18504
- }
18505
- function holdStore() {
18506
- try {
18507
- return MeshRuntimeStore.getInstance();
18508
- } catch {
18509
- return void 0;
18510
- }
18511
- }
18512
- function getHoldState(synthKey, meshId) {
18513
- const cached3 = inFlightAckedHoldState.get(synthKey);
18514
- if (cached3) return cached3;
18515
- const store = holdStore();
18516
- if (!store) return void 0;
18517
- let row;
18518
- try {
18519
- row = store.getInflightHold(taskIdFromSynthKey(meshId, synthKey));
18520
- } catch {
18521
- return void 0;
18522
- }
18523
- if (!row) return void 0;
18524
- const state = {
18525
- liveConfirmedSinceAck: row.holdReason === "live",
18526
- consecutiveReadFailures: row.readFailureCount ?? 0,
18527
- ...row.firstIdleSinceAck !== null && row.firstIdleSinceAck !== void 0 ? { transcriptIdleSinceMs: row.firstIdleSinceAck } : {}
18528
- };
18529
- inFlightAckedHoldState.set(synthKey, state);
18530
- return state;
18531
- }
18532
- function setHoldState(synthKey, meshId, state) {
18533
- inFlightAckedHoldState.set(synthKey, state);
18534
- const store = holdStore();
18535
- if (!store) return;
18536
- try {
18537
- store.upsertInflightHold({
18538
- taskId: taskIdFromSynthKey(meshId, synthKey),
18539
- meshId,
18540
- holdReason: state.liveConfirmedSinceAck ? "live" : "unconfirmed",
18541
- firstIdleSinceAck: state.transcriptIdleSinceMs ?? null,
18542
- readFailureCount: state.consecutiveReadFailures
18543
- });
18544
- } catch {
18545
- }
18546
- }
18547
- function deleteHoldState(synthKey, meshId) {
18548
- inFlightAckedHoldState.delete(synthKey);
18549
- const store = holdStore();
18550
- if (!store) return;
18551
- try {
18552
- store.deleteInflightHold(taskIdFromSynthKey(meshId, synthKey));
18553
- } catch {
18554
- }
18555
- }
18556
- function rehydrateAckedHoldsForMesh(meshId) {
18557
- if (rehydratedHoldMeshes.has(meshId)) return;
18558
- rehydratedHoldMeshes.add(meshId);
18559
- const store = holdStore();
18560
- if (!store) return;
18561
- let rows;
18562
- try {
18563
- rows = store.listInflightHoldsByMesh(meshId);
18564
- } catch {
18565
- return;
18566
- }
18567
- for (const row of rows) {
18568
- const synthKey = inFlightSynthKey(meshId, row.taskId);
18569
- if (inFlightAckedHoldState.has(synthKey)) continue;
18570
- inFlightAckedHoldState.set(synthKey, {
18571
- liveConfirmedSinceAck: row.holdReason === "live",
18572
- consecutiveReadFailures: row.readFailureCount ?? 0,
18573
- ...row.firstIdleSinceAck !== null && row.firstIdleSinceAck !== void 0 ? { transcriptIdleSinceMs: row.firstIdleSinceAck } : {}
18574
- });
18575
- }
18576
- if (rows.length > 0) {
18577
- LOG.info("MeshReconcile", `Rehydrated ${rows.length} persisted acked-hold row(s) for mesh ${meshId} after (re)start`);
18578
- }
18579
- }
18580
- function collectHeldSynthKeysForMesh(meshId) {
18581
- const heldKeys = /* @__PURE__ */ new Set();
18582
- for (const key2 of inFlightAckedHoldState.keys()) {
18583
- if (key2.startsWith(`${meshId}::`)) heldKeys.add(key2);
18977
+ // src/mesh/mesh-completion-synthesis.ts
18978
+ async function reconcileUnterminatedDirectDispatches(components, mesh, selfIds, localDaemonId) {
18979
+ const dispatches = getActiveDirectDispatches(mesh.id);
18980
+ rehydrateAckedHoldsForMesh(mesh.id);
18981
+ const activeTaskKeys = new Set(
18982
+ dispatches.map((d) => readNonEmptyString2(d.taskId)).filter(Boolean).map((taskId) => inFlightSynthKey(mesh.id, taskId))
18983
+ );
18984
+ const heldKeys = collectHeldSynthKeysForMesh(mesh.id);
18985
+ for (const key2 of heldKeys) {
18986
+ if (!activeTaskKeys.has(key2)) deleteHoldState(key2, mesh.id);
18584
18987
  }
18585
- const store = holdStore();
18586
- if (store) {
18988
+ if (dispatches.length === 0) return;
18989
+ const dispatchMeshCommand = components.dispatchMeshCommand;
18990
+ const nodeById = new Map(mesh.nodes.map((n) => [n.id, n]));
18991
+ for (const dispatch of dispatches) {
18992
+ const sessionId = readNonEmptyString2(dispatch.sessionId);
18993
+ const nodeId = readNonEmptyString2(dispatch.nodeId);
18994
+ const taskId = readNonEmptyString2(dispatch.taskId);
18995
+ if (!sessionId || !nodeId || !taskId) continue;
18996
+ const node = nodeById.get(nodeId);
18997
+ const nodeDaemonId = readNonEmptyString2(node?.daemonId);
18998
+ const isLocalNode = !nodeDaemonId || daemonIdListIncludes(selfIds, nodeDaemonId) || daemonIdsEquivalent(nodeDaemonId, localDaemonId) || !!components.instanceManager.getInstance(sessionId);
18999
+ const providerType = readNonEmptyString2(dispatch.providerType);
19000
+ const readArgs = {
19001
+ sessionId,
19002
+ targetSessionId: sessionId,
19003
+ tailLimit: 10,
19004
+ ...node?.workspace ? { workspace: node.workspace } : {},
19005
+ ...providerType ? { agentType: providerType, providerType } : {}
19006
+ };
19007
+ const synthKey = inFlightSynthKey(mesh.id, taskId);
19008
+ const isAcked = dispatch.status === "acked";
19009
+ let backstopKind;
19010
+ let payload = null;
19011
+ let readFailed = false;
18587
19012
  try {
18588
- for (const row of store.listInflightHoldsByMesh(meshId)) {
18589
- heldKeys.add(inFlightSynthKey(meshId, row.taskId));
19013
+ if (isLocalNode) {
19014
+ const result = await components.commandHandler.handle("read_chat", readArgs);
19015
+ if (result && result.success === false) {
19016
+ readFailed = true;
19017
+ } else {
19018
+ payload = unwrapReadChatPayload(result);
19019
+ }
19020
+ } else if (dispatchMeshCommand) {
19021
+ const result = await dispatchMeshCommand(nodeDaemonId, "read_chat", readArgs);
19022
+ payload = unwrapReadChatPayload(result);
19023
+ if (payload && payload.success === false) {
19024
+ payload = null;
19025
+ readFailed = true;
19026
+ }
19027
+ } else {
19028
+ continue;
18590
19029
  }
18591
19030
  } catch {
19031
+ readFailed = true;
19032
+ }
19033
+ if (!payload && !readFailed) continue;
19034
+ if (readFailed || !payload) {
19035
+ if (isAcked) {
19036
+ const prior = getHoldState(synthKey, mesh.id);
19037
+ const failures = (prior?.consecutiveReadFailures ?? 0) + 1;
19038
+ const liveConfirmedSinceAck = prior?.liveConfirmedSinceAck ?? false;
19039
+ setHoldState(synthKey, mesh.id, { liveConfirmedSinceAck, consecutiveReadFailures: failures });
19040
+ if (liveConfirmedSinceAck && failures >= ACKED_DEATH_CONSECUTIVE_READ_FAILURES) {
19041
+ LOG.warn("MeshReconcile", `Acked-hold death signal: task ${taskId} on node ${nodeId} (mesh ${mesh.id}) read_chat failed ${failures}x consecutively after a live-confirmed ack \u2014 worker session presumed gone mid-turn; releasing the indefinite synth hold to the stranded-reclaim / orphan-prune nets`);
19042
+ }
19043
+ }
19044
+ continue;
19045
+ }
19046
+ const priorHoldState = getHoldState(synthKey, mesh.id);
19047
+ setHoldState(synthKey, mesh.id, {
19048
+ liveConfirmedSinceAck: true,
19049
+ consecutiveReadFailures: 0,
19050
+ ...priorHoldState?.transcriptIdleSinceMs !== void 0 ? { transcriptIdleSinceMs: priorHoldState.transcriptIdleSinceMs } : {}
19051
+ });
19052
+ const nowMs = Date.now();
19053
+ if (readChatPayloadStatus(payload) !== "idle") {
19054
+ setHoldState(synthKey, mesh.id, { liveConfirmedSinceAck: true, consecutiveReadFailures: 0 });
19055
+ continue;
19056
+ }
19057
+ const messages = Array.isArray(payload.messages) ? payload.messages : [];
19058
+ const evidence = extractFinalAssistantSummaryEvidence(messages);
19059
+ if (isAcked) {
19060
+ const ackedAtMs = Date.parse(readNonEmptyString2(dispatch.updatedAt));
19061
+ const sinceAckMs = Number.isFinite(ackedAtMs) ? nowMs - ackedAtMs : Number.POSITIVE_INFINITY;
19062
+ const deathDeadlineMs = resolveAckedDeathDeadlineMs();
19063
+ const holdState = getHoldState(synthKey, mesh.id);
19064
+ let fastTrackReady = false;
19065
+ if (evidence.finalSummary) {
19066
+ const idleSinceMs = holdState?.transcriptIdleSinceMs ?? nowMs;
19067
+ if (holdState && holdState.transcriptIdleSinceMs === void 0) {
19068
+ setHoldState(synthKey, mesh.id, { ...holdState, transcriptIdleSinceMs: idleSinceMs });
19069
+ }
19070
+ const fastTrackGraceMs = resolveAckedTranscriptFastTrackGraceMs();
19071
+ const idleHeldMs = nowMs - idleSinceMs;
19072
+ if (idleHeldMs >= fastTrackGraceMs) {
19073
+ fastTrackReady = true;
19074
+ backstopKind = "ackedHoldFastTrackFired";
19075
+ LOG.info("MeshReconcile", `Acked-hold transcript fast-track: task ${taskId} on node ${nodeId} (mesh ${mesh.id}) read idle WITH a final assistant message for ${Math.round(idleHeldMs / 1e3)}s continuous (grace ${Math.round(fastTrackGraceMs / 1e3)}s) \u2014 promoting the synth ahead of the ${Math.round(deathDeadlineMs / 1e3)}s death backstop; the worker's real emit was lost/late and a later one no-ops idempotently.`);
19076
+ }
19077
+ } else if (holdState?.transcriptIdleSinceMs !== void 0) {
19078
+ setHoldState(synthKey, mesh.id, { ...holdState, transcriptIdleSinceMs: void 0 });
19079
+ }
19080
+ if (!fastTrackReady && sinceAckMs < deathDeadlineMs) {
19081
+ LOG.info("MeshReconcile", `Acked-hold: task ${taskId} on node ${nodeId} (mesh ${mesh.id}) read idle ${Number.isFinite(sinceAckMs) ? Math.round(sinceAckMs / 1e3) + "s" : "\u221E"} since the generating_started ack \u2014 HOLDING synth (worker presumed alive; a later real emit is idempotent). Transcript fast-track promotes at ${Math.round(resolveAckedTranscriptFastTrackGraceMs() / 1e3)}s continuous idle-with-final-assistant; death backstop at ${Math.round(deathDeadlineMs / 1e3)}s or on consecutive read failures.`);
19082
+ continue;
19083
+ }
19084
+ if (!fastTrackReady) {
19085
+ backstopKind = "ackedHoldDeathDeadlineFired";
19086
+ LOG.warn("MeshReconcile", `Acked-hold death deadline reached: task ${taskId} on node ${nodeId} (mesh ${mesh.id}) still idle ${Math.round(sinceAckMs / 1e3)}s after the ack (deadline ${Math.round(deathDeadlineMs / 1e3)}s) \u2014 synthesizing the missing completion as a notification-loss net (a real emit, if it ever lands, no-ops idempotently).`);
19087
+ }
19088
+ }
19089
+ if (realTerminalEmitPendingForTask(mesh.id, taskId)) {
19090
+ deleteHoldState(synthKey, mesh.id);
19091
+ LOG.info("MeshReconcile", `Worker-emit priority: task ${taskId} on node ${nodeId} (mesh ${mesh.id}) has a real terminal completion already queued \u2014 yielding synth to the worker's own emit`);
19092
+ continue;
19093
+ }
19094
+ if (!evidence.finalSummary) continue;
19095
+ const dispatchedAtMs = Date.parse(readNonEmptyString2(dispatch.dispatchedAt));
19096
+ const transcriptAtMs = Date.parse(evidence.transcriptMessageAt ?? "");
19097
+ if (Number.isFinite(dispatchedAtMs) && Number.isFinite(transcriptAtMs) && transcriptAtMs < dispatchedAtMs) {
19098
+ LOG.info("MeshReconcile", `Stale-summary guard: skipping transcript reconcile for task ${taskId} on node ${nodeId} (mesh ${mesh.id}) \u2014 final assistant message (${evidence.transcriptMessageAt}) predates this task's dispatch (${dispatch.dispatchedAt}); it is a prior task's summary`);
19099
+ traceMeshEventDrop("reconcile_stale_summary_before_dispatch", {
19100
+ taskId,
19101
+ sessionId,
19102
+ nodeId,
19103
+ meshId: mesh.id,
19104
+ event: "agent:generating_completed"
19105
+ }, `transcriptAt=${evidence.transcriptMessageAt} < dispatchedAt=${dispatch.dispatchedAt}`);
19106
+ continue;
19107
+ }
19108
+ const reprobeStatus = await reprobeWorkerStatus(components, { isLocalNode, nodeDaemonId, readArgs });
19109
+ if (reprobeStatus && reprobeStatus !== "idle") {
19110
+ deleteHoldState(synthKey, mesh.id);
19111
+ LOG.info("MeshReconcile", `Live re-probe defer: task ${taskId} on node ${nodeId} (mesh ${mesh.id}) read '${reprobeStatus}' at synth-commit time \u2014 worker resumed generating; deferring synth to a later tick`);
19112
+ continue;
19113
+ }
19114
+ const providerSessionId = readNonEmptyString2(payload.providerSessionId);
19115
+ const coordinatorDaemonId = selfIds.find((id) => !!id);
19116
+ try {
19117
+ const result = reconcileDirectDispatchCompletionFromTranscript({
19118
+ meshId: mesh.id,
19119
+ nodeId,
19120
+ sessionId,
19121
+ providerType: providerType || void 0,
19122
+ providerSessionId: providerSessionId || void 0,
19123
+ taskId,
19124
+ finalSummary: evidence.finalSummary,
19125
+ ...evidence.transcriptMessageAt ? { transcriptMessageAt: evidence.transcriptMessageAt } : {},
19126
+ ...coordinatorDaemonId ? { targetCoordinatorDaemonId: coordinatorDaemonId } : {},
19127
+ source: "daemon_reconcile_transcript_completion"
19128
+ });
19129
+ if (result.reconciled) {
19130
+ recordBackstopFire(backstopKind ?? "phase4SynthesisFired", `task ${taskId} on node ${nodeId} (mesh ${mesh.id}), kind=${result.kind}`);
19131
+ LOG.info("MeshReconcile", `Synthesized missing completion (${result.kind}) for task ${taskId} on node ${nodeId} (mesh ${mesh.id})`);
19132
+ }
19133
+ } catch (e) {
19134
+ LOG.warn("MeshReconcile", `Transcript completion reconcile threw for task ${taskId}: ${e?.message || e}`);
18592
19135
  }
18593
19136
  }
18594
- return heldKeys;
18595
19137
  }
18596
- var ACKED_DEATH_CONSECUTIVE_READ_FAILURES, inFlightAckedHoldState, rehydratedHoldMeshes;
18597
- var init_mesh_reconcile_acked_hold = __esm({
18598
- "src/mesh/mesh-reconcile-acked-hold.ts"() {
19138
+ async function autoPruneStaleDirectDispatches(components, mesh, selfIds, localDaemonId, minAgeMs) {
19139
+ const directDispatches = getActiveDirectDispatches(mesh.id);
19140
+ if (directDispatches.length === 0) return;
19141
+ const liveNodes = await collectLiveNodesWithSessions(components, mesh, selfIds, localDaemonId);
19142
+ const result = pruneStaleDirectDispatches({
19143
+ meshId: mesh.id,
19144
+ queue: getQueue(mesh.id),
19145
+ ledgerEntries: readLedgerEntries(mesh.id, { tail: 500 }),
19146
+ directDispatches,
19147
+ nodes: liveNodes,
19148
+ execute: true,
19149
+ minAgeMs,
19150
+ source: "daemon_reconcile_auto_prune"
19151
+ });
19152
+ if (result.prunedCount > 0) {
19153
+ LOG.info("MeshReconcile", `Auto-pruned ${result.prunedCount} orphaned direct dispatch record(s) for mesh ${mesh.id}`);
19154
+ }
19155
+ }
19156
+ var init_mesh_completion_synthesis = __esm({
19157
+ "src/mesh/mesh-completion-synthesis.ts"() {
18599
19158
  "use strict";
18600
19159
  init_logger();
18601
- init_mesh_runtime_store();
18602
19160
  init_mesh_events_utils();
18603
- ACKED_DEATH_CONSECUTIVE_READ_FAILURES = 3;
18604
- inFlightAckedHoldState = /* @__PURE__ */ new Map();
18605
- rehydratedHoldMeshes = /* @__PURE__ */ new Set();
19161
+ init_mesh_event_trace();
19162
+ init_dist();
19163
+ init_mesh_reconcile_identity();
19164
+ init_mesh_work_queue();
19165
+ init_mesh_ledger();
19166
+ init_mesh_active_work();
19167
+ init_mesh_events_stale();
19168
+ init_chat_message_normalization();
19169
+ init_mesh_reconcile_v2_backstop();
19170
+ init_mesh_reconcile_acked_hold();
19171
+ init_mesh_remote_event_pull();
18606
19172
  }
18607
19173
  });
18608
19174
 
18609
19175
  // src/mesh/mesh-reconcile-loop.ts
18610
- function resolveAutoPruneMinAgeMs() {
18611
- const raw = readNonEmptyString2(process.env.MESH_AUTO_PRUNE_MIN_AGE_MS);
18612
- if (raw) {
18613
- const parsed = Number.parseInt(raw, 10);
18614
- if (Number.isFinite(parsed) && parsed >= 60 * 6e4 && parsed <= 30 * 24 * 60 * 6e4) return parsed;
18615
- }
18616
- return DEFAULT_AUTO_PRUNE_MIN_AGE_MS;
18617
- }
18618
- function resolvePendingHeldDrainEscalateMs() {
18619
- return resolveTunedReconcileMs("MESH_PENDING_HELD_DRAIN_ESCALATE_MS", DEFAULT_PENDING_HELD_DRAIN_ESCALATE_MS, 4e3, 5 * 6e4);
18620
- }
18621
- function resolveReconcileIntervalMs() {
18622
- const raw = readNonEmptyString2(process.env.MESH_RECONCILE_INTERVAL_MS);
18623
- if (raw) {
18624
- const parsed = Number.parseInt(raw, 10);
18625
- if (Number.isFinite(parsed) && parsed >= 1e3 && parsed <= 6e4) return parsed;
18626
- }
18627
- return DEFAULT_RECONCILE_INTERVAL_MS;
18628
- }
18629
19176
  function findLiveCoordinators(components) {
18630
19177
  const out = [];
18631
19178
  for (const inst of components.instanceManager.getByCategory("cli")) {
@@ -19304,349 +19851,6 @@ async function retryUnresolvedDelegateForwards(components) {
19304
19851
  LOG.info("MeshReconcile", `Retried+delivered unresolved-delegate ${readNonEmptyString2(entry.payload.event)} to coordinator ${entry.coordinatorDaemonId}`);
19305
19852
  }
19306
19853
  }
19307
- async function pullRemoteNodeQueues(components, mesh, localDaemonId, candidateDaemonIds) {
19308
- const dispatchMeshCommand = components.dispatchMeshCommand;
19309
- if (!dispatchMeshCommand) return;
19310
- const meshId = mesh.id;
19311
- const pulls = candidateDaemonIds.length > 0 ? candidateDaemonIds.map((id) => ({ meshId, coordinatorDaemonId: id })) : [{ meshId }];
19312
- for (const node of mesh.nodes) {
19313
- const nodeDaemonId = readNonEmptyString2(node.daemonId);
19314
- if (!nodeDaemonId) continue;
19315
- if (daemonIdsEquivalent(nodeDaemonId, localDaemonId)) continue;
19316
- if (daemonIdListIncludes(candidateDaemonIds, nodeDaemonId)) continue;
19317
- for (const pendingEventArgs of pulls) {
19318
- let events;
19319
- try {
19320
- events = await dispatchMeshCommand(nodeDaemonId, "get_pending_mesh_events", pendingEventArgs);
19321
- } catch {
19322
- break;
19323
- }
19324
- const list = extractPendingEvents(events).filter((e) => readNonEmptyString2(e?.meshId) === meshId);
19325
- for (const event of list) {
19326
- const payload = buildForwardPayloadFromPending(event);
19327
- if (!payload.event || !payload.meshId) continue;
19328
- try {
19329
- handleMeshForwardEvent(components, payload);
19330
- } catch {
19331
- }
19332
- }
19333
- }
19334
- }
19335
- }
19336
- function unwrapReadChatPayload(raw) {
19337
- let cursor = raw;
19338
- for (let depth = 0; depth < 4 && cursor && typeof cursor === "object"; depth++) {
19339
- const record = cursor;
19340
- if (Array.isArray(record.messages)) return record;
19341
- if (record.payload && typeof record.payload === "object") {
19342
- cursor = record.payload;
19343
- continue;
19344
- }
19345
- if (record.result && typeof record.result === "object") {
19346
- cursor = record.result;
19347
- continue;
19348
- }
19349
- if (record.data && typeof record.data === "object") {
19350
- cursor = record.data;
19351
- continue;
19352
- }
19353
- break;
19354
- }
19355
- return cursor && typeof cursor === "object" ? cursor : null;
19356
- }
19357
- function readChatPayloadStatus(payload) {
19358
- return readNonEmptyString2(payload?.status).toLowerCase();
19359
- }
19360
- function realTerminalEmitPendingForTask(meshId, taskId) {
19361
- let pending;
19362
- try {
19363
- pending = getPendingMeshCoordinatorEvents(meshId);
19364
- } catch {
19365
- return false;
19366
- }
19367
- return pending.some((e) => readNonEmptyString2(e.metadataEvent?.taskId) === taskId && (e.event === "agent:generating_completed" || e.event === "agent:stopped"));
19368
- }
19369
- async function reprobeWorkerStatus(components, args) {
19370
- try {
19371
- if (args.isLocalNode) {
19372
- const r = await components.commandHandler.handle("read_chat", args.readArgs);
19373
- if (r && r.success === false) return null;
19374
- return readChatPayloadStatus(unwrapReadChatPayload(r));
19375
- }
19376
- if (components.dispatchMeshCommand) {
19377
- const r = await components.dispatchMeshCommand(args.nodeDaemonId, "read_chat", args.readArgs);
19378
- const p = unwrapReadChatPayload(r);
19379
- if (p && p.success === false) return null;
19380
- return readChatPayloadStatus(p);
19381
- }
19382
- } catch {
19383
- return null;
19384
- }
19385
- return null;
19386
- }
19387
- async function reconcileUnterminatedDirectDispatches(components, mesh, selfIds, localDaemonId) {
19388
- const dispatches = getActiveDirectDispatches(mesh.id);
19389
- rehydrateAckedHoldsForMesh(mesh.id);
19390
- const activeTaskKeys = new Set(
19391
- dispatches.map((d) => readNonEmptyString2(d.taskId)).filter(Boolean).map((taskId) => inFlightSynthKey(mesh.id, taskId))
19392
- );
19393
- const heldKeys = collectHeldSynthKeysForMesh(mesh.id);
19394
- for (const key2 of heldKeys) {
19395
- if (!activeTaskKeys.has(key2)) deleteHoldState(key2, mesh.id);
19396
- }
19397
- if (dispatches.length === 0) return;
19398
- const dispatchMeshCommand = components.dispatchMeshCommand;
19399
- const nodeById = new Map(mesh.nodes.map((n) => [n.id, n]));
19400
- for (const dispatch of dispatches) {
19401
- const sessionId = readNonEmptyString2(dispatch.sessionId);
19402
- const nodeId = readNonEmptyString2(dispatch.nodeId);
19403
- const taskId = readNonEmptyString2(dispatch.taskId);
19404
- if (!sessionId || !nodeId || !taskId) continue;
19405
- const node = nodeById.get(nodeId);
19406
- const nodeDaemonId = readNonEmptyString2(node?.daemonId);
19407
- const isLocalNode = !nodeDaemonId || daemonIdListIncludes(selfIds, nodeDaemonId) || daemonIdsEquivalent(nodeDaemonId, localDaemonId) || !!components.instanceManager.getInstance(sessionId);
19408
- const providerType = readNonEmptyString2(dispatch.providerType);
19409
- const readArgs = {
19410
- sessionId,
19411
- targetSessionId: sessionId,
19412
- tailLimit: 10,
19413
- ...node?.workspace ? { workspace: node.workspace } : {},
19414
- ...providerType ? { agentType: providerType, providerType } : {}
19415
- };
19416
- const synthKey = inFlightSynthKey(mesh.id, taskId);
19417
- const isAcked = dispatch.status === "acked";
19418
- let backstopKind;
19419
- let payload = null;
19420
- let readFailed = false;
19421
- try {
19422
- if (isLocalNode) {
19423
- const result = await components.commandHandler.handle("read_chat", readArgs);
19424
- if (result && result.success === false) {
19425
- readFailed = true;
19426
- } else {
19427
- payload = unwrapReadChatPayload(result);
19428
- }
19429
- } else if (dispatchMeshCommand) {
19430
- const result = await dispatchMeshCommand(nodeDaemonId, "read_chat", readArgs);
19431
- payload = unwrapReadChatPayload(result);
19432
- if (payload && payload.success === false) {
19433
- payload = null;
19434
- readFailed = true;
19435
- }
19436
- } else {
19437
- continue;
19438
- }
19439
- } catch {
19440
- readFailed = true;
19441
- }
19442
- if (!payload && !readFailed) continue;
19443
- if (readFailed || !payload) {
19444
- if (isAcked) {
19445
- const prior = getHoldState(synthKey, mesh.id);
19446
- const failures = (prior?.consecutiveReadFailures ?? 0) + 1;
19447
- const liveConfirmedSinceAck = prior?.liveConfirmedSinceAck ?? false;
19448
- setHoldState(synthKey, mesh.id, { liveConfirmedSinceAck, consecutiveReadFailures: failures });
19449
- if (liveConfirmedSinceAck && failures >= ACKED_DEATH_CONSECUTIVE_READ_FAILURES) {
19450
- LOG.warn("MeshReconcile", `Acked-hold death signal: task ${taskId} on node ${nodeId} (mesh ${mesh.id}) read_chat failed ${failures}x consecutively after a live-confirmed ack \u2014 worker session presumed gone mid-turn; releasing the indefinite synth hold to the stranded-reclaim / orphan-prune nets`);
19451
- }
19452
- }
19453
- continue;
19454
- }
19455
- const priorHoldState = getHoldState(synthKey, mesh.id);
19456
- setHoldState(synthKey, mesh.id, {
19457
- liveConfirmedSinceAck: true,
19458
- consecutiveReadFailures: 0,
19459
- ...priorHoldState?.transcriptIdleSinceMs !== void 0 ? { transcriptIdleSinceMs: priorHoldState.transcriptIdleSinceMs } : {}
19460
- });
19461
- const nowMs = Date.now();
19462
- if (readChatPayloadStatus(payload) !== "idle") {
19463
- setHoldState(synthKey, mesh.id, { liveConfirmedSinceAck: true, consecutiveReadFailures: 0 });
19464
- continue;
19465
- }
19466
- const messages = Array.isArray(payload.messages) ? payload.messages : [];
19467
- const evidence = extractFinalAssistantSummaryEvidence(messages);
19468
- if (isAcked) {
19469
- const ackedAtMs = Date.parse(readNonEmptyString2(dispatch.updatedAt));
19470
- const sinceAckMs = Number.isFinite(ackedAtMs) ? nowMs - ackedAtMs : Number.POSITIVE_INFINITY;
19471
- const deathDeadlineMs = resolveAckedDeathDeadlineMs();
19472
- const holdState = getHoldState(synthKey, mesh.id);
19473
- let fastTrackReady = false;
19474
- if (evidence.finalSummary) {
19475
- const idleSinceMs = holdState?.transcriptIdleSinceMs ?? nowMs;
19476
- if (holdState && holdState.transcriptIdleSinceMs === void 0) {
19477
- setHoldState(synthKey, mesh.id, { ...holdState, transcriptIdleSinceMs: idleSinceMs });
19478
- }
19479
- const fastTrackGraceMs = resolveAckedTranscriptFastTrackGraceMs();
19480
- const idleHeldMs = nowMs - idleSinceMs;
19481
- if (idleHeldMs >= fastTrackGraceMs) {
19482
- fastTrackReady = true;
19483
- backstopKind = "ackedHoldFastTrackFired";
19484
- LOG.info("MeshReconcile", `Acked-hold transcript fast-track: task ${taskId} on node ${nodeId} (mesh ${mesh.id}) read idle WITH a final assistant message for ${Math.round(idleHeldMs / 1e3)}s continuous (grace ${Math.round(fastTrackGraceMs / 1e3)}s) \u2014 promoting the synth ahead of the ${Math.round(deathDeadlineMs / 1e3)}s death backstop; the worker's real emit was lost/late and a later one no-ops idempotently.`);
19485
- }
19486
- } else if (holdState?.transcriptIdleSinceMs !== void 0) {
19487
- setHoldState(synthKey, mesh.id, { ...holdState, transcriptIdleSinceMs: void 0 });
19488
- }
19489
- if (!fastTrackReady && sinceAckMs < deathDeadlineMs) {
19490
- LOG.info("MeshReconcile", `Acked-hold: task ${taskId} on node ${nodeId} (mesh ${mesh.id}) read idle ${Number.isFinite(sinceAckMs) ? Math.round(sinceAckMs / 1e3) + "s" : "\u221E"} since the generating_started ack \u2014 HOLDING synth (worker presumed alive; a later real emit is idempotent). Transcript fast-track promotes at ${Math.round(resolveAckedTranscriptFastTrackGraceMs() / 1e3)}s continuous idle-with-final-assistant; death backstop at ${Math.round(deathDeadlineMs / 1e3)}s or on consecutive read failures.`);
19491
- continue;
19492
- }
19493
- if (!fastTrackReady) {
19494
- backstopKind = "ackedHoldDeathDeadlineFired";
19495
- LOG.warn("MeshReconcile", `Acked-hold death deadline reached: task ${taskId} on node ${nodeId} (mesh ${mesh.id}) still idle ${Math.round(sinceAckMs / 1e3)}s after the ack (deadline ${Math.round(deathDeadlineMs / 1e3)}s) \u2014 synthesizing the missing completion as a notification-loss net (a real emit, if it ever lands, no-ops idempotently).`);
19496
- }
19497
- }
19498
- if (realTerminalEmitPendingForTask(mesh.id, taskId)) {
19499
- deleteHoldState(synthKey, mesh.id);
19500
- LOG.info("MeshReconcile", `Worker-emit priority: task ${taskId} on node ${nodeId} (mesh ${mesh.id}) has a real terminal completion already queued \u2014 yielding synth to the worker's own emit`);
19501
- continue;
19502
- }
19503
- if (!evidence.finalSummary) continue;
19504
- const dispatchedAtMs = Date.parse(readNonEmptyString2(dispatch.dispatchedAt));
19505
- const transcriptAtMs = Date.parse(evidence.transcriptMessageAt ?? "");
19506
- if (Number.isFinite(dispatchedAtMs) && Number.isFinite(transcriptAtMs) && transcriptAtMs < dispatchedAtMs) {
19507
- LOG.info("MeshReconcile", `Stale-summary guard: skipping transcript reconcile for task ${taskId} on node ${nodeId} (mesh ${mesh.id}) \u2014 final assistant message (${evidence.transcriptMessageAt}) predates this task's dispatch (${dispatch.dispatchedAt}); it is a prior task's summary`);
19508
- traceMeshEventDrop("reconcile_stale_summary_before_dispatch", {
19509
- taskId,
19510
- sessionId,
19511
- nodeId,
19512
- meshId: mesh.id,
19513
- event: "agent:generating_completed"
19514
- }, `transcriptAt=${evidence.transcriptMessageAt} < dispatchedAt=${dispatch.dispatchedAt}`);
19515
- continue;
19516
- }
19517
- const reprobeStatus = await reprobeWorkerStatus(components, { isLocalNode, nodeDaemonId, readArgs });
19518
- if (reprobeStatus && reprobeStatus !== "idle") {
19519
- deleteHoldState(synthKey, mesh.id);
19520
- LOG.info("MeshReconcile", `Live re-probe defer: task ${taskId} on node ${nodeId} (mesh ${mesh.id}) read '${reprobeStatus}' at synth-commit time \u2014 worker resumed generating; deferring synth to a later tick`);
19521
- continue;
19522
- }
19523
- const providerSessionId = readNonEmptyString2(payload.providerSessionId);
19524
- const coordinatorDaemonId = selfIds.find((id) => !!id);
19525
- try {
19526
- const result = reconcileDirectDispatchCompletionFromTranscript({
19527
- meshId: mesh.id,
19528
- nodeId,
19529
- sessionId,
19530
- providerType: providerType || void 0,
19531
- providerSessionId: providerSessionId || void 0,
19532
- taskId,
19533
- finalSummary: evidence.finalSummary,
19534
- ...evidence.transcriptMessageAt ? { transcriptMessageAt: evidence.transcriptMessageAt } : {},
19535
- ...coordinatorDaemonId ? { targetCoordinatorDaemonId: coordinatorDaemonId } : {},
19536
- source: "daemon_reconcile_transcript_completion"
19537
- });
19538
- if (result.reconciled) {
19539
- recordBackstopFire(backstopKind ?? "phase4SynthesisFired", `task ${taskId} on node ${nodeId} (mesh ${mesh.id}), kind=${result.kind}`);
19540
- LOG.info("MeshReconcile", `Synthesized missing completion (${result.kind}) for task ${taskId} on node ${nodeId} (mesh ${mesh.id})`);
19541
- }
19542
- } catch (e) {
19543
- LOG.warn("MeshReconcile", `Transcript completion reconcile threw for task ${taskId}: ${e?.message || e}`);
19544
- }
19545
- }
19546
- }
19547
- async function autoPruneStaleDirectDispatches(components, mesh, selfIds, localDaemonId, minAgeMs) {
19548
- const directDispatches = getActiveDirectDispatches(mesh.id);
19549
- if (directDispatches.length === 0) return;
19550
- const liveNodes = await collectLiveNodesWithSessions(components, mesh, selfIds, localDaemonId);
19551
- const result = pruneStaleDirectDispatches({
19552
- meshId: mesh.id,
19553
- queue: getQueue(mesh.id),
19554
- ledgerEntries: readLedgerEntries(mesh.id, { tail: 500 }),
19555
- directDispatches,
19556
- nodes: liveNodes,
19557
- execute: true,
19558
- minAgeMs,
19559
- source: "daemon_reconcile_auto_prune"
19560
- });
19561
- if (result.prunedCount > 0) {
19562
- LOG.info("MeshReconcile", `Auto-pruned ${result.prunedCount} orphaned direct dispatch record(s) for mesh ${mesh.id}`);
19563
- }
19564
- }
19565
- async function collectLiveNodesWithSessions(components, mesh, selfIds, localDaemonId) {
19566
- const dispatchMeshCommand = components.dispatchMeshCommand;
19567
- return Promise.all(mesh.nodes.map(async (node) => {
19568
- const nodeDaemonId = readNonEmptyString2(node.daemonId);
19569
- const isLocalNode = !nodeDaemonId || daemonIdListIncludes(selfIds, nodeDaemonId) || daemonIdsEquivalent(nodeDaemonId, localDaemonId);
19570
- let statusResult;
19571
- try {
19572
- if (isLocalNode) {
19573
- statusResult = await components.commandHandler.handle("get_status_metadata", {});
19574
- } else if (dispatchMeshCommand) {
19575
- statusResult = await dispatchMeshCommand(nodeDaemonId, "get_status_metadata", {});
19576
- } else {
19577
- return node;
19578
- }
19579
- } catch {
19580
- return node;
19581
- }
19582
- const sessions = extractStatusMetadataSessions(statusResult);
19583
- return sessions.length > 0 ? { ...node, sessions } : node;
19584
- }));
19585
- }
19586
- function extractStatusMetadataSessions(raw) {
19587
- let cursor = raw;
19588
- for (let depth = 0; depth < 4 && cursor && typeof cursor === "object"; depth++) {
19589
- const record = cursor;
19590
- const status = record.status && typeof record.status === "object" ? record.status : void 0;
19591
- if (status && Array.isArray(status.sessions)) return status.sessions;
19592
- if (Array.isArray(record.sessions)) return record.sessions;
19593
- if (record.payload && typeof record.payload === "object") {
19594
- cursor = record.payload;
19595
- continue;
19596
- }
19597
- if (record.result && typeof record.result === "object") {
19598
- cursor = record.result;
19599
- continue;
19600
- }
19601
- if (record.data && typeof record.data === "object") {
19602
- cursor = record.data;
19603
- continue;
19604
- }
19605
- break;
19606
- }
19607
- return [];
19608
- }
19609
- function extractPendingEvents(raw) {
19610
- if (Array.isArray(raw)) return raw;
19611
- if (raw && typeof raw === "object") {
19612
- const events = raw.events;
19613
- if (Array.isArray(events)) return events;
19614
- }
19615
- return [];
19616
- }
19617
- function buildForwardPayloadFromPending(event) {
19618
- const metadata = event?.metadataEvent && typeof event.metadataEvent === "object" ? event.metadataEvent : {};
19619
- return {
19620
- event: readNonEmptyString2(event?.event),
19621
- meshId: readNonEmptyString2(event?.meshId),
19622
- nodeId: readNonEmptyString2(event?.nodeId) || readNonEmptyString2(metadata.meshNodeId),
19623
- workspace: readNonEmptyString2(event?.workspace) || readNonEmptyString2(metadata.workspace),
19624
- // Preserve the originating coordinator session id across the relay. It is normally
19625
- // carried inside metadataEvent.meshCoordinatorSessionId (spread below), but pass the
19626
- // top-level field through explicitly too so the handleMeshForwardEvent whitelist
19627
- // recovers it regardless of which carrier the producing daemon used.
19628
- ...readNonEmptyString2(event?.targetCoordinatorSessionId) ? { targetCoordinatorSessionId: readNonEmptyString2(event.targetCoordinatorSessionId) } : {},
19629
- ...metadata,
19630
- // NOTIF-MISS (FIX 3): surface the dispatch task id at the TOP LEVEL so the relay's
19631
- // received-stage trace (and buildRelayMetadataEvent) recovers it regardless of which
19632
- // carrier the producing daemon used. The metadata spread above may carry the id only as
19633
- // `meshActiveTaskId` (a worker provider event), leaving top-level `taskId` unset and the
19634
- // received stage rendering `task=-`. Resolve both carriers into an explicit `taskId` so
19635
- // dedup stays task-scoped end-to-end. Only set when a non-empty id exists (no clobber to
19636
- // undefined when neither is present).
19637
- ...(() => {
19638
- const tid = readNonEmptyString2(metadata.taskId) || readNonEmptyString2(metadata.meshActiveTaskId);
19639
- return tid ? { taskId: tid } : {};
19640
- })(),
19641
- // T4 (B3b): carry the v2 envelope (protocolVersion/eventId/scope/dispatchedBy/
19642
- // intendedFor) across the P2P relay boundary at the TOP LEVEL. These live on the
19643
- // pending event itself, not inside metadataEvent, so without this the remote pull
19644
- // re-queue would re-stamp a fresh eventId — breaking cross-machine idempotency and
19645
- // downgrading the relayed completion to v1 broadcast routing. Spread LAST so the
19646
- // authoritative envelope always wins over any stale key the metadata spread carried.
19647
- ...serializeV2EnvelopeToWire(event)
19648
- };
19649
- }
19650
19854
  function setupMeshReconcileLoop(components) {
19651
19855
  const intervalMs = resolveReconcileIntervalMs();
19652
19856
  let running = false;
@@ -19666,7 +19870,7 @@ function setupMeshReconcileLoop(components) {
19666
19870
  }
19667
19871
  };
19668
19872
  }
19669
- var DEFAULT_RECONCILE_INTERVAL_MS, DEFAULT_AUTO_PRUNE_MIN_AGE_MS, DEFAULT_PENDING_HELD_DRAIN_ESCALATE_MS, 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;
19873
+ var 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;
19670
19874
  var init_mesh_reconcile_loop = __esm({
19671
19875
  "src/mesh/mesh-reconcile-loop.ts"() {
19672
19876
  "use strict";
@@ -19685,17 +19889,13 @@ var init_mesh_reconcile_loop = __esm({
19685
19889
  init_mesh_work_queue();
19686
19890
  init_mesh_queue_assignment();
19687
19891
  init_mesh_ledger();
19688
- init_mesh_active_work();
19689
19892
  init_mesh_events_stale();
19690
- init_chat_message_normalization();
19691
19893
  init_mesh_reconcile_identity();
19894
+ init_mesh_reconcile_config();
19895
+ init_mesh_remote_event_pull();
19896
+ init_mesh_completion_synthesis();
19692
19897
  init_mesh_reconcile_v2_backstop();
19693
19898
  init_mesh_reconcile_acked_hold();
19694
- init_mesh_reconcile_v2_backstop();
19695
- init_mesh_reconcile_acked_hold();
19696
- DEFAULT_RECONCILE_INTERVAL_MS = 4e3;
19697
- DEFAULT_AUTO_PRUNE_MIN_AGE_MS = 24 * 60 * 6e4;
19698
- DEFAULT_PENDING_HELD_DRAIN_ESCALATE_MS = 12e3;
19699
19899
  coordinatorModalParkState = /* @__PURE__ */ new Map();
19700
19900
  heldEventLedgerRecorded = /* @__PURE__ */ new Set();
19701
19901
  ASSIGNED_STRANDED_DEADLINE_MS = 5 * 6e4;
@@ -19725,6 +19925,7 @@ __export(mesh_events_exports, {
19725
19925
  queuePendingMeshCoordinatorEvent: () => queuePendingMeshCoordinatorEvent,
19726
19926
  readV2EnvelopeFromWire: () => readV2EnvelopeFromWire,
19727
19927
  reconcileDirectDispatchCompletionFromTranscript: () => reconcileDirectDispatchCompletionFromTranscript,
19928
+ requeueHeldMeshCoordinatorEvents: () => requeueHeldMeshCoordinatorEvents,
19728
19929
  resolveCoordinatorDrainDeliverability: () => resolveCoordinatorDrainDeliverability,
19729
19930
  runMeshReconcileTick: () => runMeshReconcileTick,
19730
19931
  serializeV2EnvelopeToWire: () => serializeV2EnvelopeToWire,
@@ -26611,6 +26812,7 @@ init_mesh_config();
26611
26812
  init_dist();
26612
26813
  init_dist();
26613
26814
  init_dist();
26815
+ init_dist();
26614
26816
  init_coordinator_prompt();
26615
26817
  init_mesh_missions();
26616
26818
  init_mesh_task_stats();
@@ -42306,7 +42508,7 @@ async function waitForCliAdapterReady(adapter, options) {
42306
42508
  throw new Error(`CLI runtime did not become ready within ${timeoutMs}ms`);
42307
42509
  }
42308
42510
 
42309
- // src/providers/cli-provider-instance.ts
42511
+ // src/providers/cli-provider-instance-types.ts
42310
42512
  var STATUS_HYDRATION_TAIL_LIMIT = 200;
42311
42513
  var COMPLETED_FINALIZATION_RETRY_MS = 1e3;
42312
42514
  var COMPLETED_FINALIZATION_MAX_WAIT_MS = 3e4;
@@ -42318,6 +42520,123 @@ var TERMINAL_MESH_EVENTS = /* @__PURE__ */ new Set([
42318
42520
  "agent:stopped",
42319
42521
  "agent:ready"
42320
42522
  ]);
42523
+
42524
+ // src/providers/cli-provider-transcript-merge.ts
42525
+ init_contracts2();
42526
+ init_chat_message_normalization();
42527
+ function mergeConversationMessages(runtimeMessages, parsedMessages) {
42528
+ if (runtimeMessages.length === 0) return normalizeChatMessages(parsedMessages);
42529
+ const parsedEntries = parsedMessages.map((message, index) => ({
42530
+ message,
42531
+ index,
42532
+ source: "parsed"
42533
+ }));
42534
+ const getRole = (message) => typeof message.role === "string" ? message.role.trim().toLowerCase() : "";
42535
+ const runtimeEntries = runtimeMessages.map((entry, index) => ({
42536
+ message: entry.message,
42537
+ index: parsedMessages.length + index,
42538
+ source: "runtime",
42539
+ runtimeKey: entry.key
42540
+ })).filter((entry) => {
42541
+ const meta = entry.message.meta && typeof entry.message.meta === "object" && !Array.isArray(entry.message.meta) ? entry.message.meta : {};
42542
+ if (meta.runtimeInputAck !== true) return true;
42543
+ const runtimeText = flattenContent(entry.message.content).replace(/\s+/g, " ").trim();
42544
+ if (!runtimeText) return false;
42545
+ return !parsedEntries.some((parsedEntry) => {
42546
+ const parsedRole = getRole(parsedEntry.message);
42547
+ if (parsedRole !== "user" && parsedRole !== "human") return false;
42548
+ const parsedText = flattenContent(parsedEntry.message.content).replace(/\s+/g, " ").trim();
42549
+ return parsedText === runtimeText;
42550
+ });
42551
+ });
42552
+ const getTime = (message) => {
42553
+ const value = typeof message.receivedAt === "number" ? message.receivedAt : typeof message.timestamp === "number" ? message.timestamp : 0;
42554
+ return Number.isFinite(value) && value > 0 ? value : 0;
42555
+ };
42556
+ const isRuntimeOverlay = (entry) => {
42557
+ if (entry.source !== "runtime") return false;
42558
+ const key2 = typeof entry.runtimeKey === "string" ? entry.runtimeKey.trim().toLowerCase() : "";
42559
+ if (key2.startsWith("auto_approval:")) return true;
42560
+ return !isUserFacingChatMessage(entry.message);
42561
+ };
42562
+ const shouldKeepParsedBeforeUntimedRuntime = (message) => {
42563
+ const role = getRole(message);
42564
+ return role === "user" || role === "human";
42565
+ };
42566
+ const shouldKeepParsedAfterUntimedRuntime = (message) => {
42567
+ const role = getRole(message);
42568
+ if (role !== "assistant") return false;
42569
+ const kind = resolveChatMessageKind(message);
42570
+ return kind === "standard" || kind === "terminal";
42571
+ };
42572
+ return normalizeChatMessages([...parsedEntries, ...runtimeEntries].sort((a, b) => {
42573
+ const aTime = getTime(a.message);
42574
+ const bTime = getTime(b.message);
42575
+ if (aTime && bTime && aTime !== bTime) return aTime - bTime;
42576
+ if (a.source !== b.source && aTime !== bTime) {
42577
+ const parsedEntry = a.source === "parsed" ? a : b.source === "parsed" ? b : null;
42578
+ const runtimeEntry = a.source === "runtime" ? a : b.source === "runtime" ? b : null;
42579
+ if (parsedEntry && runtimeEntry && isRuntimeOverlay(runtimeEntry) && getTime(parsedEntry.message) === 0 && getTime(runtimeEntry.message) > 0) {
42580
+ if (shouldKeepParsedBeforeUntimedRuntime(parsedEntry.message)) {
42581
+ return a.source === "parsed" ? -1 : 1;
42582
+ }
42583
+ if (shouldKeepParsedAfterUntimedRuntime(parsedEntry.message)) {
42584
+ return a.source === "parsed" ? 1 : -1;
42585
+ }
42586
+ }
42587
+ }
42588
+ return a.index - b.index;
42589
+ }).map((entry) => entry.message));
42590
+ }
42591
+ function buildExternalTranscriptProbe(messages, sourcePath, sourceMtimeMs) {
42592
+ const visibleMessages = messages.filter((message) => isUserFacingChatMessage(message));
42593
+ const lastVisible = visibleMessages[visibleMessages.length - 1];
42594
+ const readAt = Date.now();
42595
+ const mtimeMs = Number(sourceMtimeMs) || 0;
42596
+ return {
42597
+ readAt,
42598
+ msgCount: messages.length,
42599
+ lastRole: typeof lastVisible?.role === "string" ? lastVisible.role.trim().toLowerCase() : null,
42600
+ lastKind: typeof lastVisible?.kind === "string" ? lastVisible.kind : null,
42601
+ contentLen: lastVisible ? flattenContent(lastVisible.content).trim().length : 0,
42602
+ sourcePath: typeof sourcePath === "string" && sourcePath ? sourcePath : null,
42603
+ sourceMtimeMs: mtimeMs || null,
42604
+ mtimeAgeMs: mtimeMs ? Math.max(0, readAt - mtimeMs) : null
42605
+ };
42606
+ }
42607
+
42608
+ // src/providers/cli-provider-effect-format.ts
42609
+ function getEffectDedupKey(effect) {
42610
+ if (effect.id) return `provider_effect:${effect.id}`;
42611
+ if (effect.type === "message") {
42612
+ const content = typeof effect.message?.content === "string" ? effect.message.content : JSON.stringify(effect.message?.content || "");
42613
+ return `provider_effect:message:${content}`;
42614
+ }
42615
+ if (effect.type === "notification") {
42616
+ return `provider_effect:notification:${effect.notification?.title || ""}:${effect.notification?.body || ""}`;
42617
+ }
42618
+ return `provider_effect:toast:${effect.toast?.message || ""}`;
42619
+ }
42620
+ function formatApprovalRequestMessage(modalMessage, buttons) {
42621
+ const lines = ["Approval requested"];
42622
+ const cleanMessage = String(modalMessage || "").trim();
42623
+ if (cleanMessage) lines.push(cleanMessage);
42624
+ const labels = (buttons || []).map((button) => String(button || "").trim()).filter(Boolean);
42625
+ if (labels.length > 0) {
42626
+ lines.push(labels.map((label) => `[${label}]`).join(" "));
42627
+ }
42628
+ return lines.join("\n");
42629
+ }
42630
+ function formatMarkerTimestamp(timestamp) {
42631
+ const date = new Date(timestamp);
42632
+ const pad = (value) => String(value).padStart(2, "0");
42633
+ return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`;
42634
+ }
42635
+
42636
+ // src/providers/cli-provider-instance.ts
42637
+ function approvalModalSignature(message, affirmativeAnchor) {
42638
+ return [typeof message === "string" ? message.trim() : "", affirmativeAnchor].join("::");
42639
+ }
42321
42640
  var CliProviderInstance = class _CliProviderInstance {
42322
42641
  constructor(provider, workingDir, cliArgs = [], instanceId, transportFactory, options) {
42323
42642
  this.provider = provider;
@@ -42565,7 +42884,7 @@ var CliProviderInstance = class _CliProviderInstance {
42565
42884
  const resumedAt = Date.now();
42566
42885
  this.historyWriter.appendSystemMarker(
42567
42886
  this.type,
42568
- `Resumed saved session at ${this.formatMarkerTimestamp(resumedAt)}`,
42887
+ `Resumed saved session at ${formatMarkerTimestamp(resumedAt)}`,
42569
42888
  {
42570
42889
  instanceId: this.instanceId,
42571
42890
  historySessionId: this.providerSessionId,
@@ -42677,7 +42996,7 @@ var CliProviderInstance = class _CliProviderInstance {
42677
42996
  if (historyMessageCount !== null) {
42678
42997
  parsedMessages = historyMessageCount > 0 ? parsedMessages.slice(-historyMessageCount) : [];
42679
42998
  }
42680
- const mergedMessages = this.mergeConversationMessages(parsedMessages);
42999
+ const mergedMessages = mergeConversationMessages(this.runtimeMessages, parsedMessages);
42681
43000
  const canonicalBackedHistory = this.shouldHydrateExistingProviderHistory() ? this.syncCanonicalSavedHistoryIfNeeded() : false;
42682
43001
  const statusMessages = canonicalBackedHistory && this.lastPersistedHistoryMessages.length > 0 ? this.lastPersistedHistoryMessages.map((message) => ({
42683
43002
  role: message.role,
@@ -43142,22 +43461,6 @@ var CliProviderInstance = class _CliProviderInstance {
43142
43461
  }
43143
43462
  return true;
43144
43463
  }
43145
- buildExternalTranscriptProbe(messages, sourcePath, sourceMtimeMs) {
43146
- const visibleMessages = messages.filter((message) => isUserFacingChatMessage(message));
43147
- const lastVisible = visibleMessages[visibleMessages.length - 1];
43148
- const readAt = Date.now();
43149
- const mtimeMs = Number(sourceMtimeMs) || 0;
43150
- return {
43151
- readAt,
43152
- msgCount: messages.length,
43153
- lastRole: typeof lastVisible?.role === "string" ? lastVisible.role.trim().toLowerCase() : null,
43154
- lastKind: typeof lastVisible?.kind === "string" ? lastVisible.kind : null,
43155
- contentLen: lastVisible ? flattenContent(lastVisible.content).trim().length : 0,
43156
- sourcePath: typeof sourcePath === "string" && sourcePath ? sourcePath : null,
43157
- sourceMtimeMs: mtimeMs || null,
43158
- mtimeAgeMs: mtimeMs ? Math.max(0, readAt - mtimeMs) : null
43159
- };
43160
- }
43161
43464
  recordPendingTranscriptProbe(pending) {
43162
43465
  const probe = this.lastExternalCompletionProbe;
43163
43466
  if (!probe) return null;
@@ -43209,7 +43512,7 @@ var CliProviderInstance = class _CliProviderInstance {
43209
43512
  this.lastExternalCompletionProbe = null;
43210
43513
  return null;
43211
43514
  }
43212
- this.lastExternalCompletionProbe = this.buildExternalTranscriptProbe(
43515
+ this.lastExternalCompletionProbe = buildExternalTranscriptProbe(
43213
43516
  restoredHistory.messages,
43214
43517
  restoredHistory.sourcePath,
43215
43518
  restoredHistory.sourceMtimeMs
@@ -43457,6 +43760,27 @@ var CliProviderInstance = class _CliProviderInstance {
43457
43760
  autoApproveContinuityWindowMs() {
43458
43761
  return this.autoApproveMaskSince > 0 && this.isMeshWorkerSession() ? _CliProviderInstance.AUTO_APPROVE_FLAP_CONTINUITY_MS : _CliProviderInstance.AUTO_APPROVE_GATE_HYSTERESIS_MS;
43459
43762
  }
43763
+ /**
43764
+ * The settle-gate identity signature for a raw activeModal, or null when the
43765
+ * modal is NOT a concrete auto-approvable consent prompt (no captured buttons,
43766
+ * a picker/confirm kind, or no reliable affirmative+decline anchor). Mirrors the
43767
+ * gates the auto-approve fire path applies before computing modalSignature, so
43768
+ * the mask-stall nudge can ask the SAME question the settle gate is tracking —
43769
+ * "is THIS frame's modal the identity the settle clock is accruing against?" —
43770
+ * without duplicating the button-pick logic. The signature is message +
43771
+ * normalized affirmative label only (no volatile counters/button set), matching
43772
+ * the fire path exactly (AUTOAPPROVE-SETTLE-FLAP).
43773
+ */
43774
+ approvableModalSignature(modal) {
43775
+ const buttons = Array.isArray(modal?.buttons) ? modal.buttons.map((b) => String(b || "").trim()).filter(Boolean) : [];
43776
+ if (!modal || buttons.length === 0) return null;
43777
+ const modalKind = typeof modal?.kind === "string" ? modal.kind : "approval";
43778
+ if (modalKind !== "approval") return null;
43779
+ const { index: buttonIndex, label: buttonLabel } = pickApprovalButton(buttons, this.provider);
43780
+ const hasReliableConsentAnchor = hasNegativeApprovalOption(buttons) || hasReliableApprovalAffirmative(buttons);
43781
+ if (buttonIndex < 0 || !hasReliableConsentAnchor) return null;
43782
+ return approvalModalSignature(modal?.message, normalizeApprovalLabel(buttonLabel));
43783
+ }
43460
43784
  // FALSE-IDLE (self-coordinator settle): an autonomously-progressing mesh session
43461
43785
  // is either a delegated worker (isMeshWorkerSession) OR the coordinator's OWN
43462
43786
  // claude-cli session (meshCoordinatorFor). Both run auto-approved tool turns whose
@@ -43760,10 +44084,7 @@ var CliProviderInstance = class _CliProviderInstance {
43760
44084
  return autoApproveActive;
43761
44085
  }
43762
44086
  const affirmativeAnchor = normalizeApprovalLabel(buttonLabel);
43763
- const modalSignature = [
43764
- typeof modal?.message === "string" ? modal.message.trim() : "",
43765
- affirmativeAnchor
43766
- ].join("::");
44087
+ const modalSignature = approvalModalSignature(modal?.message, affirmativeAnchor);
43767
44088
  const approvalEntrySeq = typeof adapterStatus?.approvalEntrySeq === "number" ? adapterStatus.approvalEntrySeq : 0;
43768
44089
  const busySignature = `${approvalEntrySeq}::${modalSignature}`;
43769
44090
  if (this.autoApproveBusy && busySignature === this.lastAutoApprovalSignature) {
@@ -43996,7 +44317,7 @@ var CliProviderInstance = class _CliProviderInstance {
43996
44317
  if (approvalFingerprint !== this.lastApprovalEventFingerprint) {
43997
44318
  this.lastApprovalEventFingerprint = approvalFingerprint;
43998
44319
  this.appendRuntimeSystemMessage(
43999
- this.formatApprovalRequestMessage(modal?.message, modal?.buttons),
44320
+ formatApprovalRequestMessage(modal?.message, modal?.buttons),
44000
44321
  `approval_request:${now}`,
44001
44322
  now
44002
44323
  );
@@ -44297,7 +44618,7 @@ var CliProviderInstance = class _CliProviderInstance {
44297
44618
  const effectWhen = effect.when || "immediate";
44298
44619
  if (effectWhen === "turn_completed" && options.phase !== "turn_completed") continue;
44299
44620
  if (effectWhen === "immediate" && options.phase === "turn_completed") continue;
44300
- const effectKey = this.getEffectDedupKey(effect);
44621
+ const effectKey = getEffectDedupKey(effect);
44301
44622
  if (this.appliedEffectKeys.has(effectKey)) continue;
44302
44623
  this.appliedEffectKeys.add(effectKey);
44303
44624
  if (effect.persist !== false) {
@@ -44340,34 +44661,6 @@ var CliProviderInstance = class _CliProviderInstance {
44340
44661
  this.appliedEffectKeys = new Set(Array.from(this.appliedEffectKeys).slice(-100));
44341
44662
  }
44342
44663
  }
44343
- getEffectDedupKey(effect) {
44344
- if (effect.id) return `provider_effect:${effect.id}`;
44345
- if (effect.type === "message") {
44346
- const content = typeof effect.message?.content === "string" ? effect.message.content : JSON.stringify(effect.message?.content || "");
44347
- return `provider_effect:message:${content}`;
44348
- }
44349
- if (effect.type === "notification") {
44350
- return `provider_effect:notification:${effect.notification?.title || ""}:${effect.notification?.body || ""}`;
44351
- }
44352
- return `provider_effect:toast:${effect.toast?.message || ""}`;
44353
- }
44354
- getPersistedEffectContent(effect) {
44355
- if (effect.type === "message") {
44356
- return typeof effect.message?.content === "string" ? effect.message.content : JSON.stringify(effect.message?.content || "");
44357
- }
44358
- if (effect.type === "toast") {
44359
- return effect.toast?.message || null;
44360
- }
44361
- if (effect.type === "notification") {
44362
- if (typeof effect.notification?.bubbleContent === "string") return effect.notification.bubbleContent;
44363
- if (typeof effect.notification?.title === "string" && effect.notification.title.trim()) {
44364
- return `${effect.notification.title}
44365
- ${effect.notification.body || ""}`.trim();
44366
- }
44367
- return effect.notification?.body || null;
44368
- }
44369
- return null;
44370
- }
44371
44664
  // ─── Adapter access (backward compat) ──────────────────
44372
44665
  getAdapter() {
44373
44666
  return this.adapter;
@@ -44439,15 +44732,16 @@ ${effect.notification.body || ""}`.trim();
44439
44732
  if (!this.isMeshWorkerSession()) return;
44440
44733
  if (adapterStatus?.status !== "waiting_approval") return;
44441
44734
  if (!this.autoApproveMaskStalled(now)) return;
44442
- const modalButtons = Array.isArray(adapterStatus.activeModal?.buttons) ? adapterStatus.activeModal.buttons.map((b) => String(b || "").trim()).filter(Boolean) : [];
44443
- if (this.pendingAutoApprovalSince && modalButtons.length > 0) return;
44735
+ const currentSignature = this.approvableModalSignature(adapterStatus.activeModal);
44736
+ const settleProgressing = !!currentSignature && this.pendingAutoApprovalSince > 0 && currentSignature === this.pendingAutoApprovalSignature;
44737
+ if (settleProgressing) return;
44444
44738
  if (this.stalledApprovalNudgeEpisode === this.autoApproveMaskSince) return;
44445
44739
  this.stalledApprovalNudgeEpisode = this.autoApproveMaskSince;
44446
44740
  const modal = adapterStatus.activeModal;
44447
44741
  const dirName = workingDirBasename(this.workingDir);
44448
44742
  const chatTitle = `${this.provider.name} \xB7 ${dirName}`;
44449
44743
  this.appendRuntimeSystemMessage(
44450
- this.formatApprovalRequestMessage(modal?.message, modal?.buttons),
44744
+ formatApprovalRequestMessage(modal?.message, modal?.buttons),
44451
44745
  `approval_request:${now}`,
44452
44746
  now
44453
44747
  );
@@ -44477,11 +44771,6 @@ ${effect.notification.body || ""}`.trim();
44477
44771
  now
44478
44772
  );
44479
44773
  }
44480
- formatMarkerTimestamp(timestamp) {
44481
- const date = new Date(timestamp);
44482
- const pad = (value) => String(value).padStart(2, "0");
44483
- return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`;
44484
- }
44485
44774
  maybeAppendRuntimeRecoveryMessage(runtime) {
44486
44775
  if (!runtime?.restoredFromStorage || !runtime.runtimeId) return;
44487
44776
  const recoveryState = String(runtime.recoveryState || "").trim();
@@ -44542,81 +44831,7 @@ ${effect.notification.body || ""}`.trim();
44542
44831
  }
44543
44832
  }
44544
44833
  mergeRuntimeChatMessages(parsedMessages) {
44545
- return this.mergeConversationMessages(parsedMessages);
44546
- }
44547
- mergeConversationMessages(parsedMessages) {
44548
- if (this.runtimeMessages.length === 0) return normalizeChatMessages(parsedMessages);
44549
- const parsedEntries = parsedMessages.map((message, index) => ({
44550
- message,
44551
- index,
44552
- source: "parsed"
44553
- }));
44554
- const getRole = (message) => typeof message.role === "string" ? message.role.trim().toLowerCase() : "";
44555
- const runtimeEntries = this.runtimeMessages.map((entry, index) => ({
44556
- message: entry.message,
44557
- index: parsedMessages.length + index,
44558
- source: "runtime",
44559
- runtimeKey: entry.key
44560
- })).filter((entry) => {
44561
- const meta = entry.message.meta && typeof entry.message.meta === "object" && !Array.isArray(entry.message.meta) ? entry.message.meta : {};
44562
- if (meta.runtimeInputAck !== true) return true;
44563
- const runtimeText = flattenContent(entry.message.content).replace(/\s+/g, " ").trim();
44564
- if (!runtimeText) return false;
44565
- return !parsedEntries.some((parsedEntry) => {
44566
- const parsedRole = getRole(parsedEntry.message);
44567
- if (parsedRole !== "user" && parsedRole !== "human") return false;
44568
- const parsedText = flattenContent(parsedEntry.message.content).replace(/\s+/g, " ").trim();
44569
- return parsedText === runtimeText;
44570
- });
44571
- });
44572
- const getTime = (message) => {
44573
- const value = typeof message.receivedAt === "number" ? message.receivedAt : typeof message.timestamp === "number" ? message.timestamp : 0;
44574
- return Number.isFinite(value) && value > 0 ? value : 0;
44575
- };
44576
- const isRuntimeOverlay = (entry) => {
44577
- if (entry.source !== "runtime") return false;
44578
- const key2 = typeof entry.runtimeKey === "string" ? entry.runtimeKey.trim().toLowerCase() : "";
44579
- if (key2.startsWith("auto_approval:")) return true;
44580
- return !isUserFacingChatMessage(entry.message);
44581
- };
44582
- const shouldKeepParsedBeforeUntimedRuntime = (message) => {
44583
- const role = getRole(message);
44584
- return role === "user" || role === "human";
44585
- };
44586
- const shouldKeepParsedAfterUntimedRuntime = (message) => {
44587
- const role = getRole(message);
44588
- if (role !== "assistant") return false;
44589
- const kind = resolveChatMessageKind(message);
44590
- return kind === "standard" || kind === "terminal";
44591
- };
44592
- return normalizeChatMessages([...parsedEntries, ...runtimeEntries].sort((a, b) => {
44593
- const aTime = getTime(a.message);
44594
- const bTime = getTime(b.message);
44595
- if (aTime && bTime && aTime !== bTime) return aTime - bTime;
44596
- if (a.source !== b.source && aTime !== bTime) {
44597
- const parsedEntry = a.source === "parsed" ? a : b.source === "parsed" ? b : null;
44598
- const runtimeEntry = a.source === "runtime" ? a : b.source === "runtime" ? b : null;
44599
- if (parsedEntry && runtimeEntry && isRuntimeOverlay(runtimeEntry) && getTime(parsedEntry.message) === 0 && getTime(runtimeEntry.message) > 0) {
44600
- if (shouldKeepParsedBeforeUntimedRuntime(parsedEntry.message)) {
44601
- return a.source === "parsed" ? -1 : 1;
44602
- }
44603
- if (shouldKeepParsedAfterUntimedRuntime(parsedEntry.message)) {
44604
- return a.source === "parsed" ? 1 : -1;
44605
- }
44606
- }
44607
- }
44608
- return a.index - b.index;
44609
- }).map((entry) => entry.message));
44610
- }
44611
- formatApprovalRequestMessage(modalMessage, buttons) {
44612
- const lines = ["Approval requested"];
44613
- const cleanMessage = String(modalMessage || "").trim();
44614
- if (cleanMessage) lines.push(cleanMessage);
44615
- const labels = (buttons || []).map((button) => String(button || "").trim()).filter(Boolean);
44616
- if (labels.length > 0) {
44617
- lines.push(labels.map((label) => `[${label}]`).join(" "));
44618
- }
44619
- return lines.join("\n");
44834
+ return mergeConversationMessages(this.runtimeMessages, parsedMessages);
44620
44835
  }
44621
44836
  promoteProviderSessionId(sessionId, opts = {}) {
44622
44837
  const nextSessionId = String(sessionId || "").trim();
@@ -68322,6 +68537,8 @@ export {
68322
68537
  AcpProviderInstance,
68323
68538
  AgentStreamPoller,
68324
68539
  BUILTIN_CHAT_MESSAGE_KINDS,
68540
+ CANONICAL_MESH_TOOL_COUNT,
68541
+ CANONICAL_MESH_TOOL_NAMES,
68325
68542
  CHANGE_IMPACT_CONFIG_LOCATIONS,
68326
68543
  CHANGE_IMPACT_CONFIG_SCHEMA,
68327
68544
  CHAT_MESSAGE_ACTIVITY_SOURCES,
@@ -68379,11 +68596,13 @@ export {
68379
68596
  MESH_REFINE_CONFIG_LOCATIONS,
68380
68597
  MESH_REFINE_CONFIG_SCHEMA,
68381
68598
  MESH_SCHEDULING_STRATEGIES,
68599
+ MESH_TASK_PRIORITIES,
68382
68600
  MESH_WORKTREE_BOOTSTRAP_CONFIG_LOCATIONS,
68383
68601
  MESH_WORKTREE_BOOTSTRAP_CONFIG_SCHEMA,
68384
68602
  MIN_GIT_WORKSPACE_POLL_INTERVAL_MS,
68385
68603
  MIN_MACHINE_RUNTIME_SUBSCRIPTION_INTERVAL_MS,
68386
68604
  MIN_SESSION_HOST_DIAGNOSTICS_SUBSCRIPTION_INTERVAL_MS,
68605
+ NOT_BEFORE_RELATIVE_THRESHOLD_MS,
68387
68606
  NodePtyTransportFactory,
68388
68607
  OPERATING_NOTE_DEDUPE_WINDOW,
68389
68608
  OPERATING_NOTE_KEEP_LATEST,
@@ -68531,7 +68750,6 @@ export {
68531
68750
  getQueue,
68532
68751
  getRecentActivity,
68533
68752
  getRecentCommands,
68534
- getRecentCompletionConflicts,
68535
68753
  getRecentDebugTrace,
68536
68754
  getRecentLogs,
68537
68755
  getSavedProviderSessions,
@@ -68595,6 +68813,8 @@ export {
68595
68813
  maybeRunDaemonUpgradeHelperFromEnv,
68596
68814
  mergeAndNormalizePolicy,
68597
68815
  meshNodeIdMatches,
68816
+ meshTaskNotBeforeReady,
68817
+ meshTaskPriorityRank,
68598
68818
  namedKeyToAnsi,
68599
68819
  namedKeysToAnsi,
68600
68820
  nodeSatisfiesRequiredTags,
@@ -68617,6 +68837,7 @@ export {
68617
68837
  normalizeMeshNodeId,
68618
68838
  normalizeMeshSchedulingStrategy,
68619
68839
  normalizeMeshTaskMode,
68840
+ normalizeMeshTaskPriority,
68620
68841
  normalizeMeshWorkerResult,
68621
68842
  normalizeMessageParts,
68622
68843
  normalizeRepoIdentity,
@@ -68645,7 +68866,6 @@ export {
68645
68866
  readOperatingNotes,
68646
68867
  readV2EnvelopeFromWire,
68647
68868
  reconcileDirectDispatchCompletionFromTranscript,
68648
- recordCompletionConflict,
68649
68869
  recordDebugTrace,
68650
68870
  recordDirectDispatchTask,
68651
68871
  recordMeshToolCall,
@@ -68655,6 +68875,7 @@ export {
68655
68875
  removeMagiPanel,
68656
68876
  removeNode,
68657
68877
  removeWorktree,
68878
+ requeueHeldMeshCoordinatorEvents,
68658
68879
  requeueTask,
68659
68880
  requireMeshHostQueueOwner,
68660
68881
  resetConfig,
@@ -68675,6 +68896,7 @@ export {
68675
68896
  resolveMeshRefineValidationPlan,
68676
68897
  resolveMeshSurfacedSessionPreview,
68677
68898
  resolveNodeSchedulingPriority,
68899
+ resolveNotBefore,
68678
68900
  resolveProviderMaxParallel,
68679
68901
  resolveSessionHostAppName,
68680
68902
  resolveSessionHostAppNameResolution,