opencode-swarm 7.166.4 → 7.167.0

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 (58) hide show
  1. package/binaries/win32-arm64/swarm-sandbox-runner.exe +0 -0
  2. package/binaries/win32-x64/swarm-sandbox-runner.exe +0 -0
  3. package/dist/cli/{coder-settlement-yynntj5j.js → coder-settlement-j5e1pz2k.js} +3 -3
  4. package/dist/cli/{config-doctor-8asc35km.js → config-doctor-35pd2khv.js} +2 -2
  5. package/dist/cli/{core-qrbhs2q4.js → core-92m54spz.js} +1 -1
  6. package/dist/cli/{curator-llm-factory-rs4921ks.js → curator-llm-factory-vj5aqyd1.js} +19 -19
  7. package/dist/cli/{curator-qk4xmkv4.js → curator-pd098ytk.js} +19 -19
  8. package/dist/cli/{evidence-summary-service-rktcp3s4.js → evidence-summary-service-kwcme5fz.js} +6 -6
  9. package/dist/cli/{gate-evidence-k6nzqca1.js → gate-evidence-msn4kya1.js} +2 -2
  10. package/dist/cli/{guardrail-explain-jdspxzjr.js → guardrail-explain-2h9m8s4j.js} +20 -20
  11. package/dist/cli/{guardrail-log-962pzjev.js → guardrail-log-p6trrsvy.js} +3 -3
  12. package/dist/cli/{guardrail-reset-dv02t0bm.js → guardrail-reset-v6ds2t78.js} +19 -19
  13. package/dist/cli/{hive-promoter-9zzr28p2.js → hive-promoter-j2pjzrdh.js} +19 -19
  14. package/dist/cli/{index-wd86yj53.js → index-7yax969v.js} +1 -1
  15. package/dist/cli/{index-n189w64j.js → index-9qceke8g.js} +1 -1
  16. package/dist/cli/{index-qv4byzwp.js → index-chdyjg3s.js} +3 -3
  17. package/dist/cli/{index-st1zw5ps.js → index-d2phtxg2.js} +2 -2
  18. package/dist/cli/{index-0v6bf0j9.js → index-d9vbyb5a.js} +1 -1
  19. package/dist/cli/{index-gr5wg0nj.js → index-dczrrnzp.js} +2 -2
  20. package/dist/cli/{index-kz44j3qe.js → index-gbbahxhw.js} +3 -3
  21. package/dist/cli/{index-8ewgab6z.js → index-gw2d37dz.js} +1 -1
  22. package/dist/cli/{index-gsftf6c8.js → index-hdkt3n2k.js} +3 -3
  23. package/dist/cli/{index-gccxen4x.js → index-jhna6xnb.js} +5 -1
  24. package/dist/cli/{index-9eswrdp5.js → index-kg74hnbc.js} +1 -1
  25. package/dist/cli/{index-shqhq68n.js → index-mqbgkv5h.js} +11 -3
  26. package/dist/cli/{index-kwervbv6.js → index-n5bqrkgw.js} +3 -3
  27. package/dist/cli/{index-bxrxqwce.js → index-qmqn59mw.js} +1 -1
  28. package/dist/cli/{index-3s194swm.js → index-r09mpxtp.js} +4 -4
  29. package/dist/cli/{index-7g5kdtvw.js → index-t6hdjtfy.js} +1 -1
  30. package/dist/cli/{index-m9q6f3ty.js → index-tnb4jf94.js} +2 -2
  31. package/dist/cli/{index-v5wanchr.js → index-va2m1y35.js} +1 -1
  32. package/dist/cli/{index-z62gdhkd.js → index-wkj8m6wh.js} +3 -3
  33. package/dist/cli/{index-5qws47d4.js → index-wyca2c0w.js} +416 -72
  34. package/dist/cli/{index-n65x6e1y.js → index-ywa4jvg9.js} +5 -5
  35. package/dist/cli/{index-3ct7fd75.js → index-zq0btxga.js} +1 -1
  36. package/dist/cli/{index-x8c42y8s.js → index-zs0nyasy.js} +21 -21
  37. package/dist/cli/index.js +19 -19
  38. package/dist/cli/{knowledge-escalator-w4bfnks3.js → knowledge-escalator-skbk8tq8.js} +6 -6
  39. package/dist/cli/{knowledge-events-wmnx8m6b.js → knowledge-events-czaxq8hg.js} +4 -4
  40. package/dist/cli/{knowledge-store-5442ph4m.js → knowledge-store-wztr2gwz.js} +1 -1
  41. package/dist/cli/{knowledge-validator-5rmardr4.js → knowledge-validator-0eq5evs6.js} +2 -2
  42. package/dist/cli/{pending-delegations-ea6zpqw2.js → pending-delegations-2bran18p.js} +2 -2
  43. package/dist/cli/{pr-subscriptions-yqxt0avv.js → pr-subscriptions-rdp58505.js} +1 -1
  44. package/dist/cli/{pr-workflow-gate-px36rczj.js → pr-workflow-gate-dgk3zzgs.js} +19 -19
  45. package/dist/cli/{scan-cursor-efrage98.js → scan-cursor-ag6y6c14.js} +2 -2
  46. package/dist/cli/{schema-w2sds948.js → schema-qmh504jp.js} +3 -1
  47. package/dist/cli/{scope-persistence-dd7p3tdv.js → scope-persistence-c1ctykah.js} +5 -5
  48. package/dist/cli/{skill-generator-c0720k51.js → skill-generator-yqgwds3s.js} +7 -7
  49. package/dist/cli/{snapshot-coordination-init-dp42vvme.js → snapshot-coordination-init-62pxgka1.js} +19 -19
  50. package/dist/cli/{worktree-collision-ownership-emh2yhpx.js → worktree-collision-ownership-81773mwf.js} +2 -2
  51. package/dist/cli/{worktree-isolation-a8f1yahq.js → worktree-isolation-j2ewvha7.js} +19 -19
  52. package/dist/config/schema.d.ts +24 -0
  53. package/dist/hooks/lane-liveness-watchdog.d.ts +102 -0
  54. package/dist/hooks/pr-workflow-gate.d.ts +87 -1
  55. package/dist/index.js +12 -11
  56. package/dist/tools/dispatch-lanes.d.ts +9 -0
  57. package/opencode-swarm.schema.json +35 -0
  58. package/package.json +1 -1
@@ -25,13 +25,13 @@ import {
25
25
  protectedRoots,
26
26
  redactDecisionLineForArchive,
27
27
  stableCanonicalStringify
28
- } from "./index-n189w64j.js";
28
+ } from "./index-9qceke8g.js";
29
29
  import {
30
30
  detectStraySwarmDirs,
31
31
  readDoctorArtifact,
32
32
  removeStraySwarmDir,
33
33
  runConfigDoctor
34
- } from "./index-gccxen4x.js";
34
+ } from "./index-jhna6xnb.js";
35
35
  import {
36
36
  MAX_TRANSIENT_RETRIES,
37
37
  archiveEvidence,
@@ -72,7 +72,7 @@ import {
72
72
  updateTaskCheckpointReceipt,
73
73
  updateTaskStatus,
74
74
  validateProjectRoot
75
- } from "./index-kwervbv6.js";
75
+ } from "./index-n5bqrkgw.js";
76
76
  import {
77
77
  EvaluationTaskV1Schema,
78
78
  GateAuditManifestV1Schema,
@@ -128,15 +128,15 @@ import {
128
128
  retireSkill,
129
129
  selectCandidateEntries,
130
130
  syncBundledProjectSkillsIfMissingAsync
131
- } from "./index-qv4byzwp.js";
131
+ } from "./index-chdyjg3s.js";
132
132
  import {
133
133
  readRecentEscalations
134
- } from "./index-n65x6e1y.js";
134
+ } from "./index-ywa4jvg9.js";
135
135
  import {
136
136
  alreadyCuratedThisGeneration,
137
137
  claimNextScanBatch,
138
138
  resolveCohortId
139
- } from "./index-7g5kdtvw.js";
139
+ } from "./index-t6hdjtfy.js";
140
140
  import {
141
141
  CURATOR_INIT_PROMPT,
142
142
  CURATOR_PHASE_PROMPT,
@@ -179,7 +179,7 @@ import {
179
179
  listCoderSettlementWalStates,
180
180
  recoverCoderSettlement,
181
181
  recoverStaleCoderSettlements
182
- } from "./index-z62gdhkd.js";
182
+ } from "./index-wkj8m6wh.js";
183
183
  import {
184
184
  parsePorcelainV2Snapshot,
185
185
  resolveCommitCountSince,
@@ -248,13 +248,13 @@ import {
248
248
  transitionTaskWorkflowEvidence,
249
249
  withTaskEvidenceTransaction,
250
250
  writeWorkflowWalFile
251
- } from "./index-bxrxqwce.js";
251
+ } from "./index-qmqn59mw.js";
252
252
  import {
253
253
  isPathUnderSwarmWorktreeBase,
254
254
  makeWorktreeBranchName,
255
255
  provisionWorktree,
256
256
  removeWorktree
257
- } from "./index-8ewgab6z.js";
257
+ } from "./index-gw2d37dz.js";
258
258
  import {
259
259
  DEFAULT_STALE_DELEGATION_TIMEOUT_MS,
260
260
  DELEGATION_COMPACTION_HIGH_WATER_BYTES,
@@ -288,7 +288,7 @@ import {
288
288
  scanBackgroundCoderReservationsForAdmission,
289
289
  scanDelegationsForRecovery,
290
290
  sweepStaleDelegations
291
- } from "./index-3ct7fd75.js";
291
+ } from "./index-zq0btxga.js";
292
292
  import {
293
293
  MAX_EVENT_LOG_ENTRIES,
294
294
  _internals,
@@ -304,7 +304,7 @@ import {
304
304
  recordKnowledgeEvent,
305
305
  recordPhaseCloseIntent,
306
306
  resolveKnowledgeEventsPath
307
- } from "./index-kz44j3qe.js";
307
+ } from "./index-gbbahxhw.js";
308
308
  import {
309
309
  estimateTokens,
310
310
  readSwarmFileAsync,
@@ -330,7 +330,7 @@ import {
330
330
  validateActionableFields,
331
331
  validateLesson,
332
332
  validateSkillPath
333
- } from "./index-wd86yj53.js";
333
+ } from "./index-7yax969v.js";
334
334
  import {
335
335
  MAX_CURATION_PROPOSALS,
336
336
  authorizeCuration,
@@ -341,7 +341,7 @@ import {
341
341
  } from "./index-rtry5xyf.js";
342
342
  import {
343
343
  resolveWorktreeIsolationConfig
344
- } from "./index-st1zw5ps.js";
344
+ } from "./index-d2phtxg2.js";
345
345
  import {
346
346
  RetrospectiveEvidenceSchema
347
347
  } from "./index-3qf1vxtb.js";
@@ -351,7 +351,7 @@ import {
351
351
  clearAllScopes,
352
352
  clearScopeBindingFromDisk,
353
353
  clearScopeBindings
354
- } from "./index-gr5wg0nj.js";
354
+ } from "./index-dczrrnzp.js";
355
355
  import {
356
356
  appendLedgerEvent,
357
357
  computePlanLedgerHash,
@@ -364,7 +364,7 @@ import {
364
364
  readPlanEpochIdentity,
365
365
  replayFromLedgerWithStatus,
366
366
  takeSnapshotEvent
367
- } from "./index-v5wanchr.js";
367
+ } from "./index-va2m1y35.js";
368
368
  import {
369
369
  CORE_EVENT_LOCKED,
370
370
  appendCoreEventSync,
@@ -447,7 +447,7 @@ import {
447
447
  transactFile,
448
448
  transactKnowledge,
449
449
  wordBigrams
450
- } from "./index-3s194swm.js";
450
+ } from "./index-r09mpxtp.js";
451
451
  import {
452
452
  readTailJsonl,
453
453
  readTailJsonlDetailed,
@@ -510,7 +510,7 @@ import {
510
510
  loadGateOverrides,
511
511
  loadPluginConfig,
512
512
  loadPluginConfigWithMeta
513
- } from "./index-9eswrdp5.js";
513
+ } from "./index-kg74hnbc.js";
514
514
  import {
515
515
  init_git_executable,
516
516
  resolveGitExecutable,
@@ -527,6 +527,7 @@ import {
527
527
  DEFAULT_SKILL_OPT_CONFIG,
528
528
  FALLBACK_MODELS_MAX,
529
529
  KnowledgeConfigSchema,
530
+ LaneLivenessWatchdogConfigSchema,
530
531
  MemoryConfigSchema,
531
532
  SkillImproverConfigSchema,
532
533
  getCanonicalAgentRole,
@@ -537,7 +538,7 @@ import {
537
538
  resolveAutoReviewConfig,
538
539
  resolveGeneratedAgentRole,
539
540
  stripKnownSwarmPrefix
540
- } from "./index-shqhq68n.js";
541
+ } from "./index-mqbgkv5h.js";
541
542
  import {
542
543
  AGENT_TOOL_MAP,
543
544
  ALL_AGENT_NAMES,
@@ -9488,7 +9489,7 @@ async function importLegacyPrWorkflowGateStateIfNeeded(directory, sessionID, all
9488
9489
  return null;
9489
9490
  throw error2;
9490
9491
  }
9491
- const legacy = allowSalvagedImport ? (await (await import("./pr-workflow-gate-px36rczj.js")).readPrWorkflowGateStateForRecovery(directory, sessionID))?.state ?? null : await readPrWorkflowGateStateFileFromDisk(filePath, sessionID);
9492
+ const legacy = allowSalvagedImport ? (await (await import("./pr-workflow-gate-dgk3zzgs.js")).readPrWorkflowGateStateForRecovery(directory, sessionID))?.state ?? null : await readPrWorkflowGateStateFileFromDisk(filePath, sessionID);
9492
9493
  if (!legacy)
9493
9494
  return null;
9494
9495
  const namespace = workflowGateStateCoordinationNamespace(sessionID);
@@ -9558,7 +9559,7 @@ async function deleteStateWhileLocked(directory, sessionID, options = {}) {
9558
9559
  let recoveryState = null;
9559
9560
  if (!currentAuthoritative) {
9560
9561
  if (options.allowSalvagedRead) {
9561
- const { readPrWorkflowGateStateForRecovery } = await import("./pr-workflow-gate-px36rczj.js");
9562
+ const { readPrWorkflowGateStateForRecovery } = await import("./pr-workflow-gate-dgk3zzgs.js");
9562
9563
  recoveryState = (await readPrWorkflowGateStateForRecovery(directory, normalizedSessionID))?.state ?? null;
9563
9564
  }
9564
9565
  if (!recoveryState) {
@@ -11883,6 +11884,49 @@ function bindingRejection(state, event) {
11883
11884
  // src/hooks/pr-workflow-gate.ts
11884
11885
  init_tool_metadata();
11885
11886
  init_logger();
11887
+
11888
+ // src/hooks/lane-liveness-watchdog.ts
11889
+ init_schema();
11890
+ var LANE_LIVENESS_WATCHDOG_DEFAULTS = LaneLivenessWatchdogConfigSchema.parse({});
11891
+ var MAX_LANE_LIVENESS_DISCLOSED_IDS = 10;
11892
+ function classifyLaneLivenessCondition(input) {
11893
+ if (input.recordStatus === "error") {
11894
+ return "completed_failure";
11895
+ }
11896
+ const sessionLiveOrUnknown = input.sessionStatusType === undefined || input.sessionStatusType === "busy" || input.sessionStatusType === "retry";
11897
+ if (input.waitBudgetExpired && sessionLiveOrUnknown) {
11898
+ return "observer_deadline";
11899
+ }
11900
+ if (input.sessionStatusType === "retry") {
11901
+ return "provider_retry_in_flight";
11902
+ }
11903
+ if (input.exceededEffectiveHorizon) {
11904
+ return "execution_deadline";
11905
+ }
11906
+ return "idle_failed_child";
11907
+ }
11908
+ function resolveEffectivePrLaneHorizonMs(watchdog, backgroundPendingTimeoutMs) {
11909
+ const watchdogOwnsHorizon = watchdog?.enabled === true && (watchdog.timeout_ms ?? 0) > 0;
11910
+ const horizonMs = watchdogOwnsHorizon ? watchdog?.timeout_ms : DEFAULT_STALE_DELEGATION_TIMEOUT_MS;
11911
+ return {
11912
+ horizonMs,
11913
+ source: watchdogOwnsHorizon ? "watchdog-timeout" : "reachability-floor",
11914
+ conflictDisclosed: backgroundPendingTimeoutMs !== undefined && backgroundPendingTimeoutMs > 0 && backgroundPendingTimeoutMs !== horizonMs
11915
+ };
11916
+ }
11917
+ var ZERO_LANE_ACTIVITY = {
11918
+ stepsObserved: 0,
11919
+ estimatedTokens: 0
11920
+ };
11921
+ var defaultReadLaneActivity = () => ZERO_LANE_ACTIVITY;
11922
+ function laneLivenessWatchdogFeatures(watchdog) {
11923
+ const enabled = watchdog?.enabled === true;
11924
+ return {
11925
+ deadlineActive: enabled && (watchdog?.timeout_ms ?? 0) > 0,
11926
+ stallActive: enabled && (watchdog?.stall_threshold_ms ?? 0) > 0 && (watchdog?.stall_min_steps ?? 0) > 0 && (watchdog?.stall_token_threshold ?? 0) > 0
11927
+ };
11928
+ }
11929
+ // src/hooks/pr-workflow-gate.ts
11886
11930
  function readPrWorkflowGateStateFromDisk3(directory, sessionID) {
11887
11931
  return readPrWorkflowGateStateFromDisk(directory, sessionID);
11888
11932
  }
@@ -12694,39 +12738,266 @@ function prWorkflowLaneLabel(record) {
12694
12738
  function isOpenPrWorkflowLane(record, sessionID) {
12695
12739
  return record.parentSessionId === sessionID && record.mode?.startsWith("swarm-pr-") === true && (record.status === "pending" || record.status === "running");
12696
12740
  }
12697
- async function settlePresumedStalePrWorkflowLanes(directory, sessionID) {
12741
+ var laneLivenessWatchdogSurface = {
12742
+ resolveEffectivePrLaneHorizonMs,
12743
+ classifyLaneLivenessCondition,
12744
+ evaluateLaneLivenessWatchdog: evaluateLaneLivenessWatchdogEscalation,
12745
+ readLaneActivity: defaultReadLaneActivity,
12746
+ hostStatusCalls: 0,
12747
+ hostAbortCalls: 0,
12748
+ evaluations: 0
12749
+ };
12750
+ async function abortLaneSessionForWatchdog(record) {
12751
+ const session = _test_exports2.getSessionOps();
12752
+ const abortOp = session?.abort;
12753
+ if (!session || typeof abortOp !== "function" || !record.subagentSessionId) {
12754
+ return false;
12755
+ }
12756
+ try {
12757
+ await withTimeout(abortOp.call(session, { path: { id: record.subagentSessionId } }), _test_exports2.laneLivenessProbeTimeoutMs, new Error("lane-liveness watchdog abort exceeded its deadline"));
12758
+ return true;
12759
+ } catch {
12760
+ return false;
12761
+ }
12762
+ }
12763
+ function lastWatchdogEscalationsByLaneLabel(directory, sessionID) {
12764
+ const escalations = new Map;
12765
+ const activityObservations = new Map;
12766
+ const deadlineLabels = new Set;
12767
+ let text = "";
12768
+ try {
12769
+ text = readCoreEvents(directory).text;
12770
+ } catch {
12771
+ return { escalations, activityObservations, deadlineLabels };
12772
+ }
12773
+ for (const line of text.split(`
12774
+ `)) {
12775
+ const trimmed = line.trim();
12776
+ if (!trimmed || !trimmed.includes("pr_workflow_lane_watchdog"))
12777
+ continue;
12778
+ let event;
12779
+ try {
12780
+ event = JSON.parse(trimmed);
12781
+ } catch {
12782
+ continue;
12783
+ }
12784
+ if (event.type !== "pr_workflow_lane_watchdog")
12785
+ continue;
12786
+ if (sessionID !== undefined && event.sessionID !== sessionID)
12787
+ continue;
12788
+ const isEscalation = event.escalated === true;
12789
+ const isActivityObservation = !isEscalation && event.activityObserved === true;
12790
+ const isDeadlineEvent = !isEscalation && !isActivityObservation && event.condition === "execution_deadline";
12791
+ if (!isEscalation && !isActivityObservation && !isDeadlineEvent)
12792
+ continue;
12793
+ const timestamp = Date.parse(`${event.timestamp}`);
12794
+ if (!Number.isFinite(timestamp))
12795
+ continue;
12796
+ const laneIds = event.laneIds;
12797
+ if (!Array.isArray(laneIds))
12798
+ continue;
12799
+ const target = isEscalation ? escalations : activityObservations;
12800
+ for (const label of laneIds) {
12801
+ if (typeof label !== "string")
12802
+ continue;
12803
+ if (isDeadlineEvent) {
12804
+ deadlineLabels.add(label);
12805
+ continue;
12806
+ }
12807
+ const prior = target.get(label);
12808
+ if (prior === undefined || timestamp > prior)
12809
+ target.set(label, timestamp);
12810
+ }
12811
+ }
12812
+ return { escalations, activityObservations, deadlineLabels };
12813
+ }
12814
+ function appendWatchdogActivityObservation(directory, sessionID, labels, horizon, condition) {
12815
+ try {
12816
+ appendCoreEventSync(directory, {
12817
+ type: "pr_workflow_lane_watchdog",
12818
+ timestamp: isoNow(),
12819
+ sessionID,
12820
+ condition,
12821
+ laneIds: labels.slice(0, MAX_LANE_LIVENESS_DISCLOSED_IDS),
12822
+ effectiveHorizonMs: horizon.horizonMs,
12823
+ horizonSource: horizon.source,
12824
+ escalated: false,
12825
+ activityObserved: true,
12826
+ disclosure: `${labels.length} lane(s) progressed (activity observed since the last escalation); stall escalation baseline reset`
12827
+ });
12828
+ } catch {}
12829
+ }
12830
+ async function evaluateLaneLivenessWatchdogEscalation(args) {
12831
+ const { directory, sessionID, lanes, sessionTypes, watchdog, horizon } = args;
12832
+ const candidates = lanes.filter((record) => {
12833
+ if (!record.subagentSessionId)
12834
+ return false;
12835
+ const type = sessionTypes.get(record.subagentSessionId);
12836
+ return type === "busy" || type === "retry";
12837
+ });
12838
+ if (candidates.length === 0)
12839
+ return;
12840
+ const lastEscalations = lastWatchdogEscalationsByLaneLabel(directory, sessionID);
12841
+ const escalated = [];
12842
+ const progressed = [];
12843
+ let firstEscalatedSteps = 0;
12844
+ let firstEscalatedTokens = 0;
12845
+ for (const record of candidates) {
12846
+ let activity = null;
12847
+ try {
12848
+ activity = await laneLivenessWatchdogSurface.readLaneActivity(directory, record.subagentSessionId);
12849
+ } catch {
12850
+ activity = null;
12851
+ }
12852
+ const steps = activity?.stepsObserved ?? 0;
12853
+ const tokens = activity?.estimatedTokens ?? 0;
12854
+ const progressing = steps >= watchdog.stall_min_steps || tokens >= watchdog.stall_token_threshold;
12855
+ if (progressing) {
12856
+ progressed.push(record);
12857
+ continue;
12858
+ }
12859
+ const label = prWorkflowLaneLabel(record);
12860
+ const lastEscalation = lastEscalations.escalations.get(label);
12861
+ if (lastEscalation !== undefined) {
12862
+ const lastActivity = activity?.lastActivityAtMs;
12863
+ const activitySince = lastActivity !== undefined && lastActivity >= lastEscalation || (lastEscalations.activityObservations.get(label) ?? -Infinity) >= lastEscalation;
12864
+ if (!activitySince)
12865
+ continue;
12866
+ }
12867
+ if (escalated.length === 0) {
12868
+ firstEscalatedSteps = steps;
12869
+ firstEscalatedTokens = tokens;
12870
+ }
12871
+ escalated.push(record);
12872
+ }
12873
+ if (progressed.length > 0) {
12874
+ const firstProgressed = progressed[0];
12875
+ const firstProgressedType = firstProgressed.subagentSessionId ? sessionTypes.get(firstProgressed.subagentSessionId) : undefined;
12876
+ appendWatchdogActivityObservation(directory, sessionID, progressed.map(prWorkflowLaneLabel), horizon, firstProgressedType === "retry" ? "provider_retry_in_flight" : "idle_failed_child");
12877
+ }
12878
+ if (escalated.length === 0)
12879
+ return;
12880
+ const first = escalated[0];
12881
+ const condition = classifyLaneLivenessCondition({
12882
+ sessionStatusType: first.subagentSessionId ? sessionTypes.get(first.subagentSessionId) : undefined,
12883
+ recordStatus: first.status,
12884
+ waitBudgetExpired: false,
12885
+ exceededEffectiveHorizon: Date.now() - first.updatedAt > horizon.horizonMs
12886
+ });
12887
+ const laneLabels = escalated.map(prWorkflowLaneLabel);
12888
+ const disclosure = `${laneLabels.length} lane(s) stalled (fewer than ${watchdog.stall_min_steps} steps ` + `and fewer than ~${watchdog.stall_token_threshold} estimated tokens in the last ` + `${watchdog.stall_threshold_ms}ms): inspect the lane transcript or abort via ` + `/swarm abort-pr-workflow (force): ${laneLabels.slice(0, MAX_LANE_LIVENESS_DISCLOSED_IDS).join(", ")}`;
12889
+ try {
12890
+ appendCoreEventSync(directory, {
12891
+ type: "pr_workflow_lane_watchdog",
12892
+ timestamp: isoNow(),
12893
+ sessionID,
12894
+ condition,
12895
+ laneIds: laneLabels.slice(0, MAX_LANE_LIVENESS_DISCLOSED_IDS),
12896
+ effectiveHorizonMs: horizon.horizonMs,
12897
+ horizonSource: horizon.source,
12898
+ escalated: true,
12899
+ stall: {
12900
+ stepsObserved: firstEscalatedSteps,
12901
+ estimatedTokens: firstEscalatedTokens,
12902
+ stallThresholdMs: watchdog.stall_threshold_ms,
12903
+ stallMinSteps: watchdog.stall_min_steps,
12904
+ stallTokenThreshold: watchdog.stall_token_threshold
12905
+ },
12906
+ disclosure
12907
+ });
12908
+ } catch {}
12909
+ }
12910
+ async function settlePresumedStalePrWorkflowLanes(directory, sessionID, options) {
12911
+ const watchdog = options?.laneLivenessWatchdog;
12912
+ const { deadlineActive, stallActive } = laneLivenessWatchdogFeatures(watchdog);
12913
+ const watchdogWork = deadlineActive || stallActive;
12914
+ const horizon = resolveEffectivePrLaneHorizonMs(watchdog, options?.backgroundPendingTimeoutMs);
12915
+ const horizonConflictNote = horizon.conflictDisclosed ? horizon.source === "watchdog-timeout" ? `lane_liveness_watchdog.timeout_ms (${horizon.horizonMs}ms) governs the PR-lane settlement horizon; hooks.background_pending_timeout_minutes was also set and disagrees \u2014 it was not applied (one effective horizon)` : `PR-lane settlement uses the ${Math.round(horizon.horizonMs / 60000)}min reachability floor; hooks.background_pending_timeout_minutes disagrees with it and does not change this horizon` : undefined;
12698
12916
  const now = Date.now();
12699
12917
  const open4 = [];
12700
12918
  const presumedStale = [];
12701
12919
  for (const record of readDelegations(directory)) {
12702
12920
  if (!isOpenPrWorkflowLane(record, sessionID))
12703
12921
  continue;
12704
- if (now - record.updatedAt > PR_WORKFLOW_STALE_LANE_TIMEOUT_MS) {
12922
+ if (now - record.updatedAt > horizon.horizonMs) {
12705
12923
  presumedStale.push(record);
12706
12924
  } else {
12707
12925
  open4.push(record);
12708
12926
  }
12709
12927
  }
12928
+ if (watchdogWork && (open4.length > 0 || presumedStale.length > 0)) {
12929
+ laneLivenessWatchdogSurface.evaluations += 1;
12930
+ }
12710
12931
  if (presumedStale.length === 0) {
12932
+ if (watchdogWork && stallActive && open4.length > 0) {
12933
+ let statuses = new Map;
12934
+ try {
12935
+ const probe2 = await _test_exports2.probeLaneSessionStatusTypesAsync(directory, open4);
12936
+ statuses = probe2.statuses;
12937
+ if (!probe2.degradedReason)
12938
+ laneLivenessWatchdogSurface.hostStatusCalls += 1;
12939
+ } catch {}
12940
+ if (statuses.size > 0) {
12941
+ await evaluateLaneLivenessWatchdogEscalation({
12942
+ directory,
12943
+ sessionID,
12944
+ lanes: open4,
12945
+ sessionTypes: statuses,
12946
+ watchdog,
12947
+ horizon
12948
+ });
12949
+ }
12950
+ }
12711
12951
  const freshOnlyLaneIds = open4.map(prWorkflowLaneLabel);
12712
12952
  return {
12713
12953
  openLaneIds: freshOnlyLaneIds,
12714
12954
  openLanes: open4.length,
12715
12955
  freshOpenLanes: open4.length,
12716
- presumedStaleLaneIds: []
12956
+ presumedStaleLaneIds: [],
12957
+ ...horizonConflictNote ? { horizonConflictNote } : {}
12717
12958
  };
12718
12959
  }
12719
12960
  let probe;
12720
- try {
12721
- probe = await _test_exports2.probeLaneLivenessAsync(directory, presumedStale);
12722
- } catch {
12723
- probe = { alive: new Set, degradedReason: "probe-error" };
12961
+ let sessionTypes = new Map;
12962
+ if (watchdogWork) {
12963
+ try {
12964
+ const typesProbe = await _test_exports2.probeLaneSessionStatusTypesAsync(directory, stallActive ? [...presumedStale, ...open4] : presumedStale);
12965
+ sessionTypes = typesProbe.statuses;
12966
+ if (!typesProbe.degradedReason) {
12967
+ laneLivenessWatchdogSurface.hostStatusCalls += 1;
12968
+ }
12969
+ const alive = new Set;
12970
+ for (const [sessionId, type] of typesProbe.statuses) {
12971
+ if (isLiveSessionStatusType(type))
12972
+ alive.add(sessionId);
12973
+ }
12974
+ probe = typesProbe.degradedReason ? {
12975
+ alive: new Set,
12976
+ degradedReason: typesProbe.degradedReason
12977
+ } : { alive };
12978
+ } catch {
12979
+ probe = { alive: new Set, degradedReason: "probe-error" };
12980
+ }
12981
+ } else {
12982
+ try {
12983
+ probe = await _test_exports2.probeLaneLivenessAsync(directory, presumedStale);
12984
+ } catch {
12985
+ probe = { alive: new Set, degradedReason: "probe-error" };
12986
+ }
12724
12987
  }
12725
12988
  const probeRetained = [];
12726
12989
  const settled = [];
12990
+ const deadlineLanes = [];
12727
12991
  for (const record of presumedStale) {
12728
- if (record.subagentSessionId && probe.alive.has(record.subagentSessionId)) {
12992
+ const type = record.subagentSessionId ? sessionTypes.get(record.subagentSessionId) : undefined;
12993
+ if (deadlineActive && type !== "retry") {
12994
+ deadlineLanes.push(record);
12995
+ settled.push(record);
12996
+ } else if (record.subagentSessionId && probe.alive.has(record.subagentSessionId)) {
12729
12997
  probeRetained.push(record);
12998
+ } else if (deadlineActive) {
12999
+ deadlineLanes.push(record);
13000
+ settled.push(record);
12730
13001
  } else {
12731
13002
  settled.push(record);
12732
13003
  }
@@ -12742,19 +13013,60 @@ async function settlePresumedStalePrWorkflowLanes(directory, sessionID) {
12742
13013
  ...probe.degradedReason ? { probeDegradedReason: probe.degradedReason } : {}
12743
13014
  };
12744
13015
  if (settled.length === 0) {
13016
+ if (watchdogWork && stallActive && probeRetained.length > 0) {
13017
+ await evaluateLaneLivenessWatchdogEscalation({
13018
+ directory,
13019
+ sessionID,
13020
+ lanes: probeRetained,
13021
+ sessionTypes,
13022
+ watchdog,
13023
+ horizon
13024
+ });
13025
+ }
12745
13026
  return {
12746
13027
  openLaneIds,
12747
13028
  openLanes: openLaneIds.length,
12748
13029
  freshOpenLanes: open4.length,
12749
13030
  presumedStaleLaneIds: [],
13031
+ ...horizonConflictNote ? { horizonConflictNote } : {},
12750
13032
  ...retentionFields,
12751
13033
  disclosure: retentionDisclosure
12752
13034
  };
12753
13035
  }
13036
+ if (deadlineActive) {
13037
+ const priorDeadlineLabels = lastWatchdogEscalationsByLaneLabel(directory, sessionID).deadlineLabels;
13038
+ let abortAttempted = false;
13039
+ for (const record of deadlineLanes) {
13040
+ const type = record.subagentSessionId ? sessionTypes.get(record.subagentSessionId) : undefined;
13041
+ if (type !== "busy" || !record.subagentSessionId)
13042
+ continue;
13043
+ if (priorDeadlineLabels.has(prWorkflowLaneLabel(record)))
13044
+ continue;
13045
+ abortAttempted = true;
13046
+ const aborted = await abortLaneSessionForWatchdog(record);
13047
+ if (aborted)
13048
+ laneLivenessWatchdogSurface.hostAbortCalls += 1;
13049
+ }
13050
+ if (deadlineLanes.length > 0) {
13051
+ try {
13052
+ appendCoreEventSync(directory, {
13053
+ type: "pr_workflow_lane_watchdog",
13054
+ timestamp: isoNow(),
13055
+ sessionID,
13056
+ condition: "execution_deadline",
13057
+ laneIds: deadlineLanes.map(prWorkflowLaneLabel).slice(0, MAX_LANE_LIVENESS_DISCLOSED_IDS),
13058
+ effectiveHorizonMs: horizon.horizonMs,
13059
+ horizonSource: horizon.source,
13060
+ escalated: false,
13061
+ disclosure: `${deadlineLanes.length} lane(s) exceeded the ${horizon.horizonMs}ms execution ` + `deadline (${horizon.source}); ` + (abortAttempted ? "sessions aborted best-effort and settled " : "no session abort was attempted (the liveness probe could not confirm these sessions were running); lanes settled ") + `through the shared path with the real outcome: no output observed (no ` + `transcript activity recorded for these lanes)`
13062
+ });
13063
+ } catch {}
13064
+ }
13065
+ }
12754
13066
  const presumedStaleLaneIds = settled.map(prWorkflowLaneLabel);
12755
- const disclosure = `${presumedStaleLaneIds.length} lane(s) stale >` + `${Math.round(PR_WORKFLOW_STALE_LANE_TIMEOUT_MS / 60000)}min, ` + `treated as settled: ${presumedStaleLaneIds.slice(0, MAX_DISCLOSED_LANE_IDS).join(", ")}` + (probe.degradedReason ? `; settled despite liveness probe failure (${probe.degradedReason})` : "; liveness probe found no live session") + (retentionDisclosure ? `; ${retentionDisclosure}` : "");
13067
+ const disclosure = `${presumedStaleLaneIds.length} lane(s) stale >` + `${Math.round(horizon.horizonMs / 60000)}min, ` + `treated as settled: ${presumedStaleLaneIds.slice(0, MAX_DISCLOSED_LANE_IDS).join(", ")}` + (probe.degradedReason ? `; settled despite liveness probe failure (${probe.degradedReason})` : "; liveness probe found no live session") + (retentionDisclosure ? `; ${retentionDisclosure}` : "");
12756
13068
  try {
12757
- await _test_exports2.sweepStaleDelegationsAsync(directory, PR_WORKFLOW_STALE_LANE_TIMEOUT_MS, {
13069
+ await _test_exports2.sweepStaleDelegationsAsync(directory, horizon.horizonMs, {
12758
13070
  statuses: PR_WORKFLOW_SWEEPABLE_LANE_STATUSES,
12759
13071
  excludeCorrelationIds: new Set(probeRetained.map((record) => record.correlationId))
12760
13072
  });
@@ -12765,24 +13077,38 @@ async function settlePresumedStalePrWorkflowLanes(directory, sessionID) {
12765
13077
  timestamp: isoNow(),
12766
13078
  sessionID,
12767
13079
  presumedStaleLanes: presumedStaleLaneIds.slice(0, MAX_DISCLOSED_LANE_IDS),
12768
- staleTimeoutMs: PR_WORKFLOW_STALE_LANE_TIMEOUT_MS,
13080
+ staleTimeoutMs: horizon.horizonMs,
12769
13081
  probeStatus: probe.degradedReason ?? "ok",
12770
13082
  probedAliveLanes: probedAliveLaneIds.slice(0, MAX_DISCLOSED_LANE_IDS),
12771
13083
  disclosure
12772
13084
  });
12773
13085
  } catch {}
13086
+ if (watchdogWork && stallActive && !(deadlineActive && deadlineLanes.length > 0)) {
13087
+ const stallCandidates = [...open4, ...probeRetained];
13088
+ if (stallCandidates.length > 0 && sessionTypes.size > 0) {
13089
+ await evaluateLaneLivenessWatchdogEscalation({
13090
+ directory,
13091
+ sessionID,
13092
+ lanes: stallCandidates,
13093
+ sessionTypes,
13094
+ watchdog,
13095
+ horizon
13096
+ });
13097
+ } else if (stallCandidates.length > 0) {}
13098
+ }
12774
13099
  return {
12775
13100
  openLaneIds,
12776
13101
  openLanes: openLaneIds.length,
12777
13102
  freshOpenLanes: open4.length,
12778
13103
  presumedStaleLaneIds,
13104
+ ...horizonConflictNote ? { horizonConflictNote } : {},
12779
13105
  ...retentionFields,
12780
13106
  disclosure
12781
13107
  };
12782
13108
  }
12783
- async function finalizeOverriddenProbeRetainedLanes(directory, sessionID, correlationIds) {
13109
+ async function finalizeOverriddenProbeRetainedLanes(directory, sessionID, correlationIds, horizonMs = PR_WORKFLOW_STALE_LANE_TIMEOUT_MS) {
12784
13110
  try {
12785
- await _test_exports2.sweepStaleDelegationsAsync(directory, PR_WORKFLOW_STALE_LANE_TIMEOUT_MS, {
13111
+ await _test_exports2.sweepStaleDelegationsAsync(directory, horizonMs, {
12786
13112
  statuses: PR_WORKFLOW_SWEEPABLE_LANE_STATUSES,
12787
13113
  includeCorrelationIds: new Set(correlationIds)
12788
13114
  });
@@ -12853,7 +13179,7 @@ async function abortPrWorkflow(directory, sessionID, options = { kind: "recovery
12853
13179
  if ((state.prFeedbackReadyToPublish || recovery.armedShapeUnreadable) && !options.cancelPublication) {
12854
13180
  throw new Error(`BLOCKED: ${state.mode} is armed for publication; abort is blocked. Complete the workflow with complete_pr_workflow (or push the bound commit first) before aborting, or use the audited cancellation (abort_pr_workflow with cancel_publication and a reason).` + (recovery.armedShapeUnreadable ? " The publication-arming record is itself unreadable, so it is treated as armed (fail-closed)." : ""));
12855
13181
  }
12856
- const laneSettlement = await settlePresumedStalePrWorkflowLanes(directory, state.sessionID);
13182
+ const laneSettlement = await settlePresumedStalePrWorkflowLanes(directory, state.sessionID, options.laneLiveness);
12857
13183
  const probeRetainedLanes = laneSettlement.probedAliveLaneIds ?? [];
12858
13184
  const overridesProbeRetention = options.kind === "force" && laneSettlement.freshOpenLanes === 0 && probeRetainedLanes.length > 0;
12859
13185
  if (laneSettlement.openLanes > 0 && !overridesProbeRetention) {
@@ -12920,7 +13246,7 @@ async function abortPrWorkflow(directory, sessionID, options = { kind: "recovery
12920
13246
  } catch {}
12921
13247
  throw error2;
12922
13248
  }
12923
- const overrideOutcome = overridesProbeRetention ? await finalizeOverriddenProbeRetainedLanes(directory, state.sessionID, overrideTargetedLaneIds) : {
13249
+ const overrideOutcome = overridesProbeRetention ? await finalizeOverriddenProbeRetainedLanes(directory, state.sessionID, overrideTargetedLaneIds, resolveEffectivePrLaneHorizonMs(options.laneLiveness?.laneLivenessWatchdog, options.laneLiveness?.backgroundPendingTimeoutMs).horizonMs) : {
12924
13250
  sessionOpenLaneIds: [],
12925
13251
  finalizedLaneIds: [],
12926
13252
  sparedLaneDescriptions: []
@@ -12981,7 +13307,7 @@ async function recoverArmedPrWorkflow(directory, sessionID, request) {
12981
13307
  if (request.workflowInstanceId !== undefined && state.workflowInstanceId !== undefined && request.workflowInstanceId !== state.workflowInstanceId) {
12982
13308
  throw new Error(`BLOCKED: armed recovery workflow identity mismatch: active workflow is "${state.workflowInstanceId}", request declared "${request.workflowInstanceId}".`);
12983
13309
  }
12984
- const laneSettlement = await settlePresumedStalePrWorkflowLanes(directory, state.sessionID);
13310
+ const laneSettlement = await settlePresumedStalePrWorkflowLanes(directory, state.sessionID, request.laneLiveness);
12985
13311
  if (laneSettlement.openLanes > 0) {
12986
13312
  const laneIds = laneSettlement.openLaneIds.filter(Boolean).slice(0, MAX_DISCLOSED_LANE_IDS).join(", ");
12987
13313
  throw new Error(`BLOCKED: armed recovery refused while ${laneSettlement.openLanes} PR workflow lane(s) are still in flight (lane ids: ${laneIds}). Collect their results or let them settle before recovering.` + describePrWorkflowLaneProbe(laneSettlement));
@@ -16284,10 +16610,10 @@ function assertSamePrFeedbackHandoff(state, relativePath, read, requestedPrUrl)
16284
16610
  throw new Error(`BLOCKED: session "${state.sessionID}" is already active in PR_FEEDBACK for a different handoff or PR`);
16285
16611
  }
16286
16612
  }
16287
- async function assertPrReviewTerminalReady(directory, sessionID) {
16613
+ async function assertPrReviewTerminalReady(directory, sessionID, laneLiveness) {
16288
16614
  const state = await requireBoundState2(directory, sessionID, "PR_REVIEW");
16289
16615
  await assertPrReviewCleanCheckout(directory, "PR_REVIEW");
16290
- const laneSettlement = await settlePresumedStalePrWorkflowLanes(directory, state.sessionID);
16616
+ const laneSettlement = await settlePresumedStalePrWorkflowLanes(directory, state.sessionID, laneLiveness);
16291
16617
  if (laneSettlement.openLanes > 0) {
16292
16618
  throw new Error(`BLOCKED: PR_REVIEW transition has ${laneSettlement.openLanes} unsettled PR workflow lane(s)` + describePrWorkflowLaneProbe(laneSettlement));
16293
16619
  }
@@ -16351,7 +16677,7 @@ async function transitionPrReviewToFeedback(directory, sessionID, request) {
16351
16677
  if (preliminary.mode !== "PR_REVIEW") {
16352
16678
  throw wrongModeError(preliminary, "PR_REVIEW");
16353
16679
  }
16354
- const ready = (await assertPrReviewTerminalReady(directory, normalizedSessionID)).state;
16680
+ const ready = (await assertPrReviewTerminalReady(directory, normalizedSessionID, request.laneLiveness)).state;
16355
16681
  if (workflowIdentity(ready) !== workflowIdentity(preliminary) || ready.revision !== preliminary.revision || ready.mode !== "PR_REVIEW" || ready.prReviewHandoffPath !== normalizedHandoff.relativePath || ready.prReviewArtifactRunId !== request.runId || !ready.prHeadSha || ready.prHeadSha.toLowerCase() !== artifact.pr_head_sha.toLowerCase() || canonicalGitHubPrUrl(artifact.pr_url) !== canonicalGitHubPrUrl(request.prUrl ?? artifact.pr_url)) {
16356
16682
  throw new Error("BLOCKED: PR_REVIEW feedback handoff does not match the terminal active review state");
16357
16683
  }
@@ -16758,7 +17084,7 @@ async function completePrWorkflow(directory, sessionID, expectedMode, prHeadSha,
16758
17084
  if (state.prHeadSha !== normalizedHead) {
16759
17085
  throw new Error(`BLOCKED: cannot complete ${expectedMode} at PR head "${normalizedHead}"; workflow is bound to "${state.prHeadSha}"`);
16760
17086
  }
16761
- const laneSettlement = await settlePresumedStalePrWorkflowLanes(directory, state.sessionID);
17087
+ const laneSettlement = await settlePresumedStalePrWorkflowLanes(directory, state.sessionID, options?.laneLiveness);
16762
17088
  if (laneSettlement.openLanes > 0) {
16763
17089
  throw new Error(`BLOCKED: ${expectedMode} completion has ${laneSettlement.openLanes} unsettled PR workflow lane(s)` + describePrWorkflowLaneProbe(laneSettlement));
16764
17090
  }
@@ -16798,7 +17124,7 @@ async function completePrWorkflow(directory, sessionID, expectedMode, prHeadSha,
16798
17124
  if (!preAllowed.includes(verdict)) {
16799
17125
  throw new Error(`BLOCKED: PR_REVIEW ${settlement.kind} completion allows report_verdict ${preAllowed.join(" | ")}; got "${verdict}". Partial coverage never approves and never claims a full review.`);
16800
17126
  }
16801
- const ready = await assertPrReviewTerminalReady(directory, sessionID);
17127
+ const ready = await assertPrReviewTerminalReady(directory, sessionID, options?.laneLiveness);
16802
17128
  const readyState = ready.state;
16803
17129
  if (workflowIdentity(readyState) !== workflowIdentity(state) || readyState.revision !== state.revision) {
16804
17130
  throw new Error("BLOCKED: PR_REVIEW state changed while checking terminal readiness; retry from current state");
@@ -17024,6 +17350,11 @@ var _test_exports2 = {
17024
17350
  _test_exports2.classifyPrWorkflowGitStateAsync = classifyPrWorkflowGitState;
17025
17351
  _test_exports2.sweepStaleDelegationsAsync = sweepStaleDelegations;
17026
17352
  _test_exports2.probeLaneLivenessAsync = probeAlivePrWorkflowLaneSessions;
17353
+ _test_exports2.probeLaneSessionStatusTypesAsync = probePrWorkflowLaneSessionStatusTypes;
17354
+ laneLivenessWatchdogSurface.hostStatusCalls = 0;
17355
+ laneLivenessWatchdogSurface.hostAbortCalls = 0;
17356
+ laneLivenessWatchdogSurface.evaluations = 0;
17357
+ laneLivenessWatchdogSurface.readLaneActivity = defaultReadLaneActivity;
17027
17358
  _test_exports2.getSessionOps = defaultGetSessionOps;
17028
17359
  _test_exports2.laneLivenessProbeTimeoutMs = PR_WORKFLOW_LANE_LIVENESS_PROBE_TIMEOUT_MS;
17029
17360
  _test_exports2.pendingLaneLivenessThresholdMs = PR_WORKFLOW_PENDING_LIVENESS_THRESHOLD_MS;
@@ -17048,6 +17379,8 @@ var _test_exports2 = {
17048
17379
  classifyPrWorkflowGitStateAsync: classifyPrWorkflowGitState,
17049
17380
  sweepStaleDelegationsAsync: sweepStaleDelegations,
17050
17381
  probeLaneLivenessAsync: probeAlivePrWorkflowLaneSessions,
17382
+ probeLaneSessionStatusTypesAsync: probePrWorkflowLaneSessionStatusTypes,
17383
+ laneLivenessWatchdog: laneLivenessWatchdogSurface,
17051
17384
  getSessionOps: defaultGetSessionOps,
17052
17385
  laneLivenessProbeTimeoutMs: PR_WORKFLOW_LANE_LIVENESS_PROBE_TIMEOUT_MS,
17053
17386
  pendingLaneLivenessThresholdMs: PR_WORKFLOW_PENDING_LIVENESS_THRESHOLD_MS,
@@ -19136,6 +19469,7 @@ init_tool_metadata();
19136
19469
  init_logger();
19137
19470
 
19138
19471
  // src/commands/registry.ts
19472
+ init_loader();
19139
19473
  init_logger();
19140
19474
 
19141
19475
  // src/commands/abort-pr-workflow.ts
@@ -26291,7 +26625,7 @@ function planMerges(active, threshold, maxComparisons, maxMerges) {
26291
26625
  };
26292
26626
  }
26293
26627
  async function sweepActiveNearDuplicates(directory, options = {}) {
26294
- const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-gsftf6c8.js");
26628
+ const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-hdkt3n2k.js");
26295
26629
  const { config } = loadPluginConfigWithMeta2(directory);
26296
26630
  const sweepConfig = config.learning?.dedup_sweep;
26297
26631
  if (sweepConfig?.enabled === false)
@@ -27415,7 +27749,7 @@ async function runCuratorPhase(directory, phase, agentsDispatched, config, knowl
27415
27749
  }
27416
27750
  if (config.skill_generation_enabled === true && skillCandidates.length > 0) {
27417
27751
  try {
27418
- const skillModule = await import("./skill-generator-c0720k51.js");
27752
+ const skillModule = await import("./skill-generator-yqgwds3s.js");
27419
27753
  for (const cand of skillCandidates) {
27420
27754
  if (cand.confidence < (config.min_skill_confidence ?? DEFAULT_SKILL_MIN_CONFIDENCE)) {
27421
27755
  continue;
@@ -27887,7 +28221,7 @@ async function applyCuratorKnowledgeUpdates(directory, recommendations, knowledg
27887
28221
  } catch {}
27888
28222
  }
27889
28223
  if (contradictedEntries.length > 0 && knowledgeConfig.contradiction_threshold_action === "quarantine") {
27890
- const { maybeQuarantineOnContradiction } = await import("./knowledge-escalator-w4bfnks3.js");
28224
+ const { maybeQuarantineOnContradiction } = await import("./knowledge-escalator-skbk8tq8.js");
27891
28225
  for (const { id } of contradictedEntries) {
27892
28226
  try {
27893
28227
  await maybeQuarantineOnContradiction(directory, id, knowledgeConfig.contradiction_quarantine_threshold, knowledgeConfig.contradiction_quarantine_window_days);
@@ -28719,7 +29053,7 @@ async function runCuratorPostMortem(directory, options = {}) {
28719
29053
  warnings.push("Failed to collect knowledge summary.");
28720
29054
  }
28721
29055
  try {
28722
- const { getScanStatus } = await import("./scan-cursor-efrage98.js");
29056
+ const { getScanStatus } = await import("./scan-cursor-ag6y6c14.js");
28723
29057
  const scanStatus = await getScanStatus(directory);
28724
29058
  if (scanStatus.remaining_estimate > 0) {
28725
29059
  warnings.push(`Fair scan: reviewed ${knowledgeSummary.length} entries this sweep (generation ${scanStatus.generation}); ${scanStatus.remaining_estimate} more eligible entries will be visited in future curation sweeps.`);
@@ -28891,9 +29225,9 @@ var _internals27 = {
28891
29225
  verifyPostMortemKnowledgeActions,
28892
29226
  repairPostMortemActions,
28893
29227
  loadDefaultKnowledgeConfig: async (directory) => {
28894
- const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-w2sds948.js");
29228
+ const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-qmh504jp.js");
28895
29229
  try {
28896
- const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-gsftf6c8.js");
29230
+ const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-hdkt3n2k.js");
28897
29231
  const loaded = loadPluginConfigWithMeta2(directory);
28898
29232
  return KnowledgeConfigSchema2.parse(loaded.config.knowledge ?? {});
28899
29233
  } catch {
@@ -28901,11 +29235,11 @@ var _internals27 = {
28901
29235
  }
28902
29236
  },
28903
29237
  applyCuratorKnowledgeUpdates: async (directory, recommendations, knowledgeConfig, generation) => {
28904
- const { applyCuratorKnowledgeUpdates: applyCuratorKnowledgeUpdates2 } = await import("./curator-qk4xmkv4.js");
29238
+ const { applyCuratorKnowledgeUpdates: applyCuratorKnowledgeUpdates2 } = await import("./curator-pd098ytk.js");
28905
29239
  return applyCuratorKnowledgeUpdates2(directory, recommendations, knowledgeConfig, generation);
28906
29240
  },
28907
29241
  checkHivePromotions: async (entries, knowledgeConfig, directory) => {
28908
- const { checkHivePromotions } = await import("./hive-promoter-9zzr28p2.js");
29242
+ const { checkHivePromotions } = await import("./hive-promoter-j2pjzrdh.js");
28909
29243
  return checkHivePromotions(entries, knowledgeConfig, directory);
28910
29244
  },
28911
29245
  applyProposalTriage: async (directory, triage) => {
@@ -28914,7 +29248,7 @@ var _internals27 = {
28914
29248
  activateProposal,
28915
29249
  listSkills: listSkills2,
28916
29250
  sanitizeSlug
28917
- } = await import("./skill-generator-c0720k51.js");
29251
+ } = await import("./skill-generator-yqgwds3s.js");
28918
29252
  const result = {
28919
29253
  approved: [],
28920
29254
  rejected: [],
@@ -30322,9 +30656,9 @@ function hashContent(content) {
30322
30656
  return createHash18("sha1").update(content).digest("hex");
30323
30657
  }
30324
30658
  async function loadConfigForPolicyCurator(directory) {
30325
- const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-w2sds948.js");
30659
+ const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-qmh504jp.js");
30326
30660
  try {
30327
- const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-gsftf6c8.js");
30661
+ const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-hdkt3n2k.js");
30328
30662
  const { config: loadedConfig } = loadPluginConfigWithMeta2(directory);
30329
30663
  return KnowledgeConfigSchema2.parse(loadedConfig.knowledge ?? {});
30330
30664
  } catch {
@@ -31807,7 +32141,7 @@ function serializeAgentSession(s) {
31807
32141
  }
31808
32142
  async function writeSnapshot(directory, state) {
31809
32143
  try {
31810
- const { ensureSnapshotCoordinationReady } = await import("./snapshot-coordination-init-dp42vvme.js");
32144
+ const { ensureSnapshotCoordinationReady } = await import("./snapshot-coordination-init-62pxgka1.js");
31811
32145
  await ensureSnapshotCoordinationReady(directory);
31812
32146
  const snapshot = {
31813
32147
  version: 3,
@@ -45316,7 +45650,7 @@ async function runFinalizeStage(ctx) {
45316
45650
  }
45317
45651
  }
45318
45652
  try {
45319
- const { CuratorConfigSchema: CCS } = await import("./schema-w2sds948.js");
45653
+ const { CuratorConfigSchema: CCS } = await import("./schema-qmh504jp.js");
45320
45654
  const { config: pmLoadedConfig } = _internals44.loadPluginConfigWithMeta(ctx.directory);
45321
45655
  const curatorCfg = CCS.parse(pmLoadedConfig.curator ?? {});
45322
45656
  if (curatorCfg.enabled && curatorCfg.postmortem_enabled) {
@@ -47604,9 +47938,9 @@ var _internals48 = {
47604
47938
  loadPluginConfigWithMeta,
47605
47939
  loadCuratorDeps: async () => {
47606
47940
  const [{ CuratorConfigSchema }, curator, { createCuratorLLMDelegate: createCuratorLLMDelegate2 }] = await Promise.all([
47607
- import("./schema-w2sds948.js"),
47608
- import("./curator-qk4xmkv4.js"),
47609
- import("./curator-llm-factory-rs4921ks.js")
47941
+ import("./schema-qmh504jp.js"),
47942
+ import("./curator-pd098ytk.js"),
47943
+ import("./curator-llm-factory-vj5aqyd1.js")
47610
47944
  ]);
47611
47945
  return { CuratorConfigSchema, curator, createCuratorLLMDelegate: createCuratorLLMDelegate2 };
47612
47946
  }
@@ -48657,7 +48991,7 @@ async function computeCurationDiagnostics(directory, entries2) {
48657
48991
  let scanCompleted = false;
48658
48992
  let scanRemaining = 0;
48659
48993
  try {
48660
- const { getScanStatus } = await import("./scan-cursor-efrage98.js");
48994
+ const { getScanStatus } = await import("./scan-cursor-ag6y6c14.js");
48661
48995
  const status = await getScanStatus(directory);
48662
48996
  scanGeneration = status.generation;
48663
48997
  scanCompleted = status.completed;
@@ -48667,10 +49001,10 @@ async function computeCurationDiagnostics(directory, entries2) {
48667
49001
  try {
48668
49002
  const { isLinked: isLinked2 } = await import("./knowledge-link-w1fwqts4.js");
48669
49003
  if (isLinked2(directory)) {
48670
- const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-w2sds948.js");
49004
+ const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-qmh504jp.js");
48671
49005
  let config;
48672
49006
  try {
48673
- const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-gsftf6c8.js");
49007
+ const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-hdkt3n2k.js");
48674
49008
  const loaded = loadPluginConfigWithMeta2(directory);
48675
49009
  config = KnowledgeConfigSchema2.parse(loaded.config.knowledge ?? {});
48676
49010
  } catch {
@@ -50068,7 +50402,7 @@ async function handleDoctorCommand(directory, args) {
50068
50402
  const result = runConfigDoctor(config, directory);
50069
50403
  let output;
50070
50404
  if (enableAutoFix && result.hasAutoFixableIssues) {
50071
- const { runConfigDoctorWithFixes } = await import("./config-doctor-8asc35km.js");
50405
+ const { runConfigDoctorWithFixes } = await import("./config-doctor-35pd2khv.js");
50072
50406
  const fixResult = await runConfigDoctorWithFixes(directory, config, true, {
50073
50407
  applyLossy: true
50074
50408
  });
@@ -51022,7 +51356,7 @@ async function handleEvidenceCommand(directory, args) {
51022
51356
  return formatTaskEvidenceMarkdown(evidenceData);
51023
51357
  }
51024
51358
  async function handleEvidenceSummaryCommand(directory) {
51025
- const { buildEvidenceSummary } = await import("./evidence-summary-service-rktcp3s4.js");
51359
+ const { buildEvidenceSummary } = await import("./evidence-summary-service-kwcme5fz.js");
51026
51360
  const artifact = await buildEvidenceSummary(directory);
51027
51361
  if (!artifact) {
51028
51362
  return "No plan found. Run `/swarm plan` to check plan status.";
@@ -89583,7 +89917,7 @@ function buildDetailedHelp(commandName, entry) {
89583
89917
  async function handleHelpCommand(ctx) {
89584
89918
  const targetCommand = ctx.args.join(" ");
89585
89919
  if (!targetCommand) {
89586
- const { buildHelpText } = await import("./index-x8c42y8s.js");
89920
+ const { buildHelpText } = await import("./index-zs0nyasy.js");
89587
89921
  return buildHelpText();
89588
89922
  }
89589
89923
  const tokens = targetCommand.split(/\s+/);
@@ -89597,7 +89931,7 @@ async function handleHelpCommand(ctx) {
89597
89931
  > Note: \`/swarm ${resolved.key}\` is a deprecated alias for \`/swarm ${aliasTarget}\`.` : detailed;
89598
89932
  }
89599
89933
  const similar = _internals105.findSimilarCommands(targetCommand);
89600
- const { buildHelpText: fullHelp } = await import("./index-x8c42y8s.js");
89934
+ const { buildHelpText: fullHelp } = await import("./index-zs0nyasy.js");
89601
89935
  if (similar.length > 0) {
89602
89936
  return `Command '/swarm ${targetCommand}' not found.
89603
89937
 
@@ -89642,12 +89976,22 @@ async function handlePrFeedbackCommandWithTransition(ctx) {
89642
89976
  }
89643
89977
  if (parsed.continuation) {
89644
89978
  const exactCommand = parsed.prUrl ? `/swarm pr-feedback ${parsed.prUrl} continue from ${parsed.continuation.handoffPath}` : `/swarm pr-feedback continue from ${parsed.continuation.handoffPath}`;
89979
+ let laneLiveness;
89980
+ try {
89981
+ const config = loadPluginConfig(ctx.directory);
89982
+ const hooks2 = config.hooks;
89983
+ laneLiveness = {
89984
+ laneLivenessWatchdog: config.lane_liveness_watchdog,
89985
+ backgroundPendingTimeoutMs: hooks2?.background_pending_timeout_minutes !== undefined ? hooks2.background_pending_timeout_minutes * 60000 : undefined
89986
+ };
89987
+ } catch {}
89645
89988
  await transitionPrReviewToFeedback(ctx.directory, ctx.sessionID, {
89646
89989
  runId: parsed.continuation.runId,
89647
89990
  handoffPath: parsed.continuation.handoffPath,
89648
89991
  prUrl: parsed.prUrl,
89649
89992
  exactCommand,
89650
- confirmedByUser: true
89993
+ confirmedByUser: true,
89994
+ ...laneLiveness ? { laneLiveness } : {}
89651
89995
  });
89652
89996
  } else {
89653
89997
  await activatePrWorkflow(ctx.directory, ctx.sessionID, "PR_FEEDBACK", {
@@ -89902,7 +90246,7 @@ var COMMAND_REGISTRY = {
89902
90246
  },
89903
90247
  "guardrail explain": {
89904
90248
  handler: async (ctx) => {
89905
- const { handleGuardrailExplain } = await import("./guardrail-explain-jdspxzjr.js");
90249
+ const { handleGuardrailExplain } = await import("./guardrail-explain-2h9m8s4j.js");
89906
90250
  return handleGuardrailExplain(ctx.directory, ctx.args);
89907
90251
  },
89908
90252
  description: "Dry-run: show what the guardrails would do to a command or write target (executes nothing)",
@@ -89912,7 +90256,7 @@ var COMMAND_REGISTRY = {
89912
90256
  },
89913
90257
  "guardrail reset": {
89914
90258
  handler: async (ctx) => {
89915
- const { handleGuardrailReset } = await import("./guardrail-reset-dv02t0bm.js");
90259
+ const { handleGuardrailReset } = await import("./guardrail-reset-v6ds2t78.js");
89916
90260
  return handleGuardrailReset(ctx.args, ctx.sessionID);
89917
90261
  },
89918
90262
  description: "Reset one exact active invocation/action circuit after repair",
@@ -89933,7 +90277,7 @@ var COMMAND_REGISTRY = {
89933
90277
  },
89934
90278
  "guardrail-log": {
89935
90279
  handler: async (ctx) => {
89936
- const { handleGuardrailLog } = await import("./guardrail-log-962pzjev.js");
90280
+ const { handleGuardrailLog } = await import("./guardrail-log-p6trrsvy.js");
89937
90281
  return handleGuardrailLog(ctx.directory, ctx.args);
89938
90282
  },
89939
90283
  description: "Read the guardrail decision log (use --blocks-only for blocks)",
@@ -95979,7 +96323,7 @@ function getDisplayFinalPromptPressure() {
95979
96323
  async function rehydratePrSubscriptions(sessionID, directory) {
95980
96324
  const map = new Map;
95981
96325
  try {
95982
- const { listActive: listActive2 } = await import("./pr-subscriptions-yqxt0avv.js");
96326
+ const { listActive: listActive2 } = await import("./pr-subscriptions-rdp58505.js");
95983
96327
  const records = await listActive2(directory);
95984
96328
  for (const record of records) {
95985
96329
  if (record.sessionID !== sessionID)
@@ -96425,7 +96769,7 @@ function isLaneOwnedByCurrentSession(branchName, expectedSessionId) {
96425
96769
  return extracted === expectedSessionId;
96426
96770
  }
96427
96771
  async function inspectStandardWorktreeCollisionOwnership(identity) {
96428
- const collisionOwnership = await import("./worktree-collision-ownership-emh2yhpx.js");
96772
+ const collisionOwnership = await import("./worktree-collision-ownership-81773mwf.js");
96429
96773
  return collisionOwnership.inspectStandardWorktreeCollisionOwnership(identity);
96430
96774
  }
96431
96775
  async function runRecoveryGit(directory, args, timeoutMs = 15000) {
@@ -96838,7 +97182,7 @@ async function precreateStandardWorktreeSession(args) {
96838
97182
  const laneProfile = computeLaneRuntimeProfile(worktreeConfig.runtime_isolation, laneIndex, handle.worktreePath);
96839
97183
  if (laneProfile) {
96840
97184
  try {
96841
- const { writeLaneProfileToDiskReal } = await import("./core-qrbhs2q4.js");
97185
+ const { writeLaneProfileToDiskReal } = await import("./core-92m54spz.js");
96842
97186
  await writeLaneProfileToDiskReal(handle.worktreePath, laneProfile.laneIndex, laneProfile.envOverrides);
96843
97187
  } catch {}
96844
97188
  }
@@ -97772,7 +98116,7 @@ async function finishStandardWorktreeDispatch(directory, dispatch, config, callI
97772
98116
  }
97773
98117
  clearWorktreeMergeStatus(statusKey);
97774
98118
  try {
97775
- const { removeLaneProfileFromDiskReal } = await import("./core-qrbhs2q4.js");
98119
+ const { removeLaneProfileFromDiskReal } = await import("./core-92m54spz.js");
97776
98120
  await removeLaneProfileFromDiskReal(dispatch.handle.worktreePath, dispatch.laneIndex);
97777
98121
  } catch {}
97778
98122
  const state = serializationStateBySessionID.get(dispatch.parentSessionID);