@integrity-labs/agt-cli 0.28.451 → 0.28.453

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.
@@ -29,7 +29,7 @@ import {
29
29
  resolveConnectivityProbe,
30
30
  worseConnectivityOutcome,
31
31
  wrapScheduledTaskPrompt
32
- } from "./chunk-ESZRW7A3.js";
32
+ } from "./chunk-3NJHNIO3.js";
33
33
  import {
34
34
  parsePsRows
35
35
  } from "./chunk-XWVM4KPK.js";
@@ -4910,7 +4910,7 @@ function requireHost() {
4910
4910
  }
4911
4911
 
4912
4912
  // src/lib/api-client.ts
4913
- var agtCliVersion = true ? "0.28.451" : "dev";
4913
+ var agtCliVersion = true ? "0.28.453" : "dev";
4914
4914
  var lastConfigHash = null;
4915
4915
  function setConfigHash(hash) {
4916
4916
  lastConfigHash = hash && hash.length > 0 ? hash : null;
@@ -7411,4 +7411,4 @@ export {
7411
7411
  managerInstallSystemUnitCommand,
7412
7412
  managerUninstallSystemUnitCommand
7413
7413
  };
7414
- //# sourceMappingURL=chunk-MY5HPJUW.js.map
7414
+ //# sourceMappingURL=chunk-HYKSLRTJ.js.map
@@ -100,7 +100,7 @@ async function spawnPairSession(session) {
100
100
  return { ok: true };
101
101
  } catch {
102
102
  }
103
- const { resolveClaudeBinary } = await import("./persistent-session-7HZXY56P.js");
103
+ const { resolveClaudeBinary } = await import("./persistent-session-X5N7UFEF.js");
104
104
  const claudeBin = resolveClaudeBinary();
105
105
  const pairEnv = {
106
106
  ...process.env,
@@ -373,4 +373,4 @@ export {
373
373
  startClaudePair,
374
374
  submitClaudePairCode
375
375
  };
376
- //# sourceMappingURL=claude-pair-runtime-RCH4LKDE.js.map
376
+ //# sourceMappingURL=claude-pair-runtime-NRKOKQYR.js.map
@@ -42,7 +42,7 @@ import {
42
42
  resolveEffectivePinRaw,
43
43
  safeWriteJsonAtomic,
44
44
  setConfigHash
45
- } from "../chunk-MY5HPJUW.js";
45
+ } from "../chunk-HYKSLRTJ.js";
46
46
  import {
47
47
  getProjectDir as getProjectDir2,
48
48
  getReadyTasks,
@@ -53,6 +53,7 @@ import {
53
53
  import {
54
54
  ACCOUNT_ENFORCEMENT_MARKER_FILENAME,
55
55
  AnchorSessionClient,
56
+ BIND_FAILURE_QUARANTINE_THRESHOLD,
56
57
  CLAUDE_MD_MAX_CHARS,
57
58
  CONVERSATION_FAILURE_CATEGORIES,
58
59
  DEFAULT_FRAMEWORK,
@@ -63,6 +64,9 @@ import {
63
64
  KANBAN_CHECK_COMMAND,
64
65
  KANBAN_NUDGE_ACTIONABLE_STATUSES,
65
66
  MAX_AVATAR_ENV_URL_BYTES,
67
+ MIN_PROVISIONING_MAX_FOR_QUARANTINE_ORDERING,
68
+ RESTART_BREAKER_PROVISIONING_MAX,
69
+ RESTART_BREAKER_PROVISIONING_WINDOW_MS,
66
70
  SCHEDULED_TURN_MARKER_FILENAME,
67
71
  SUPPRESS_SENTINEL,
68
72
  StreamEncoder,
@@ -160,7 +164,7 @@ import {
160
164
  toOpencodeModel,
161
165
  transcriptActivityAgeSeconds,
162
166
  writeEgressAllowlist
163
- } from "../chunk-ESZRW7A3.js";
167
+ } from "../chunk-3NJHNIO3.js";
164
168
  import {
165
169
  reapOrphanChannelMcps
166
170
  } from "../chunk-XWVM4KPK.js";
@@ -841,10 +845,27 @@ function logClaudeMdCeilingTransition(codeName, report, log2) {
841
845
  function reaperRestartBreakerReason(activeKeys) {
842
846
  return activeKeys.length >= 2 ? "mcp-presence-reaper" : void 0;
843
847
  }
848
+ var KNOWN_REASON_CLASS_MAP = {
849
+ crash: true,
850
+ provisioning: true,
851
+ "credential-rotation": true,
852
+ // ENG-8215: the self-healing class (bind-remediation - the manager's OWN
853
+ // repair attempts, which must never count toward a trip). Adding it here is
854
+ // forced by the Record type, which is exactly why that shape was chosen over
855
+ // a Set literal (ENG-7577, CodeRabbit on #3861) - a new union member cannot
856
+ // be silently omitted from the rehydration allowlist.
857
+ "self-healing": true
858
+ };
859
+ var KNOWN_REASON_CLASSES = new Set(
860
+ Object.keys(KNOWN_REASON_CLASS_MAP)
861
+ );
844
862
  var PROVISIONING_RELOAD_REASONS = /* @__PURE__ */ new Set([
845
863
  "hot-reload-mcp",
846
864
  "managed-mcp-churn",
847
- "bind-remediation",
865
+ // ENG-8215: 'bind-remediation' MOVED OUT of this set into SELF_HEALING_REASONS.
866
+ // It is the manager repairing itself, not a config reload, and counting it
867
+ // meant the harder the platform tried to fix an agent the more certain it
868
+ // became that it should give up. Deliberately NOT re-added here.
848
869
  // ENG-7576: the dashboard integration-add stop itself - the first restart of
849
870
  // the very burst this class exists for, previously uncounted entirely.
850
871
  "integration-change",
@@ -868,21 +889,35 @@ var CREDENTIAL_ROTATION_REASONS = /* @__PURE__ */ new Set([
868
889
  function isCredentialRotationReason(reason) {
869
890
  return CREDENTIAL_ROTATION_REASONS.has(reason);
870
891
  }
892
+ var SELF_HEALING_REASONS = /* @__PURE__ */ new Set([
893
+ "bind-remediation"
894
+ ]);
895
+ function isSelfHealingReason(reason) {
896
+ return SELF_HEALING_REASONS.has(reason);
897
+ }
871
898
  function restartReasonClass(reason) {
872
899
  if (isCredentialRotationReason(reason)) return "credential-rotation";
900
+ if (isSelfHealingReason(reason)) return "self-healing";
873
901
  return isProvisioningReloadReason(reason) ? "provisioning" : "crash";
874
902
  }
875
903
  function countByClass(events) {
876
904
  let crash = 0;
877
905
  let provisioning = 0;
878
906
  let credentialRotation = 0;
907
+ let selfHealing = 0;
879
908
  for (const e of events) {
880
909
  const klass = restartReasonClass(e.reason);
881
910
  if (klass === "provisioning") provisioning += 1;
882
911
  else if (klass === "credential-rotation") credentialRotation += 1;
912
+ else if (klass === "self-healing") selfHealing += 1;
883
913
  else crash += 1;
884
914
  }
885
- return { crash, provisioning, "credential-rotation": credentialRotation };
915
+ return {
916
+ crash,
917
+ provisioning,
918
+ "credential-rotation": credentialRotation,
919
+ "self-healing": selfHealing
920
+ };
886
921
  }
887
922
  function maxProvisioningBucket(events) {
888
923
  const buckets = /* @__PURE__ */ new Map();
@@ -897,10 +932,15 @@ function maxProvisioningBucket(events) {
897
932
  }
898
933
  return best;
899
934
  }
935
+ function tripClass(trip) {
936
+ if (trip.trippedClass) return trip.trippedClass;
937
+ if (!Array.isArray(trip.eventsAtTrip) || trip.eventsAtTrip.length === 0) return "crash";
938
+ return trip.eventsAtTrip.every((e) => isProvisioningReloadReason(e.reason)) ? "provisioning" : "crash";
939
+ }
900
940
  var DEFAULT_MAX = 2;
901
941
  var DEFAULT_WINDOW_MS = 6e5;
902
- var DEFAULT_PROVISIONING_MAX = 5;
903
- var DEFAULT_PROVISIONING_WINDOW_MS = 18e5;
942
+ var DEFAULT_PROVISIONING_MAX = RESTART_BREAKER_PROVISIONING_MAX;
943
+ var DEFAULT_PROVISIONING_WINDOW_MS = RESTART_BREAKER_PROVISIONING_WINDOW_MS;
904
944
  function readEnvNumber(name, fallback) {
905
945
  const raw = process.env[name];
906
946
  if (!raw) return fallback;
@@ -910,6 +950,11 @@ function readEnvNumber(name, fallback) {
910
950
  var RestartBreaker = class {
911
951
  max;
912
952
  windowMs;
953
+ /**
954
+ * ENG-8215: NOT readonly - the constructor may clamp it upward to preserve the
955
+ * quarantine-fires-first ordering against a runtime override. Never mutated
956
+ * after construction.
957
+ */
913
958
  provisioningMax;
914
959
  provisioningWindowMs;
915
960
  /** Longest window either tally needs — how long the events log must retain. */
@@ -917,6 +962,13 @@ var RestartBreaker = class {
917
962
  now;
918
963
  events = /* @__PURE__ */ new Map();
919
964
  trips = /* @__PURE__ */ new Map();
965
+ /**
966
+ * ENG-8215: set when a supplied `provisioningMax` was raised to keep MCP
967
+ * quarantine ahead of the breaker. Read once by the manager at construction so
968
+ * an overridden-and-clamped value is visible in manager.log rather than
969
+ * silently discarded.
970
+ */
971
+ quarantineOrderingClamped;
920
972
  constructor(opts = {}) {
921
973
  this.max = opts.max ?? readEnvNumber("AGT_RESTART_BREAKER_MAX", DEFAULT_MAX);
922
974
  this.windowMs = opts.windowMs ?? readEnvNumber("AGT_RESTART_BREAKER_WINDOW_MS", DEFAULT_WINDOW_MS);
@@ -932,11 +984,27 @@ var RestartBreaker = class {
932
984
  if (!Number.isFinite(this.provisioningMax) || this.provisioningMax < 1) {
933
985
  throw new Error("restart-breaker provisioningMax must be a finite number >= 1");
934
986
  }
987
+ if (this.provisioningMax < MIN_PROVISIONING_MAX_FOR_QUARANTINE_ORDERING) {
988
+ this.quarantineOrderingClamped = {
989
+ requested: this.provisioningMax,
990
+ applied: MIN_PROVISIONING_MAX_FOR_QUARANTINE_ORDERING,
991
+ quarantineThreshold: BIND_FAILURE_QUARANTINE_THRESHOLD
992
+ };
993
+ this.provisioningMax = MIN_PROVISIONING_MAX_FOR_QUARANTINE_ORDERING;
994
+ }
935
995
  if (!Number.isFinite(this.provisioningWindowMs) || this.provisioningWindowMs < 1e3) {
936
996
  throw new Error("restart-breaker provisioningWindowMs must be a finite number >= 1000");
937
997
  }
938
998
  this.retentionMs = Math.max(this.windowMs, this.provisioningWindowMs);
939
999
  }
1000
+ /**
1001
+ * ENG-8215: the clamp record, if the configured provisioning max had to be
1002
+ * raised to keep MCP quarantine ahead of the breaker. `undefined` when the
1003
+ * configured value already satisfied the ordering.
1004
+ */
1005
+ getQuarantineOrderingClamp() {
1006
+ return this.quarantineOrderingClamped;
1007
+ }
940
1008
  /** True if this agent's breaker is currently tripped (manager must skip spawn). */
941
1009
  isTripped(codeName) {
942
1010
  return this.trips.has(codeName);
@@ -982,11 +1050,15 @@ var RestartBreaker = class {
982
1050
  const credRotCount = prior.filter(
983
1051
  (e) => e.at >= at - this.provisioningWindowMs && isCredentialRotationReason(e.reason)
984
1052
  ).length;
1053
+ const selfHealCount = prior.filter(
1054
+ (e) => e.at >= at - this.provisioningWindowMs && isSelfHealingReason(e.reason)
1055
+ ).length;
985
1056
  const windowCount = prior.filter((e) => e.at >= at - this.windowMs).length;
986
1057
  const classCounts = {
987
1058
  crash: crashCount,
988
1059
  provisioning: provEvents.length,
989
- "credential-rotation": credRotCount
1060
+ "credential-rotation": credRotCount,
1061
+ "self-healing": selfHealCount
990
1062
  };
991
1063
  const provBucket = maxProvisioningBucket(provEvents);
992
1064
  let trippedClass;
@@ -1007,7 +1079,10 @@ var RestartBreaker = class {
1007
1079
  const trip = {
1008
1080
  trippedAt: at,
1009
1081
  eventsAtTrip: [...tripEvents],
1010
- statusMessage: formatStatusMessage(tripEvents, tripWindowMs, trippedClass, provBucket.key)
1082
+ statusMessage: formatStatusMessage(tripEvents, tripWindowMs, trippedClass, provBucket.key),
1083
+ // ENG-7577: persist the tripping class so the recovery path can gate on
1084
+ // it after a manager restart, without re-deriving it from prose.
1085
+ trippedClass
1011
1086
  };
1012
1087
  this.trips.set(codeName, trip);
1013
1088
  this.events.delete(codeName);
@@ -1048,7 +1123,11 @@ var RestartBreaker = class {
1048
1123
  if (!saved) return;
1049
1124
  for (const [codeName, trip] of Object.entries(saved)) {
1050
1125
  if (trip && typeof trip.trippedAt === "number" && Array.isArray(trip.eventsAtTrip)) {
1051
- this.trips.set(codeName, trip);
1126
+ const klass = trip.trippedClass;
1127
+ this.trips.set(
1128
+ codeName,
1129
+ klass === void 0 || KNOWN_REASON_CLASSES.has(klass) ? trip : { ...trip, trippedClass: void 0 }
1130
+ );
1052
1131
  }
1053
1132
  }
1054
1133
  }
@@ -1275,6 +1354,9 @@ function decideAutoResume(opts) {
1275
1354
  const { trip, marker, config: config2, now } = opts;
1276
1355
  if (!config2.enabled) return { action: "skip", reason: "disabled" };
1277
1356
  if (!trip) return { action: "skip", reason: "no-trip" };
1357
+ if (tripClass(trip) !== "provisioning") {
1358
+ return { action: "skip", reason: "class-not-eligible" };
1359
+ }
1278
1360
  if (marker && now - marker.autoResumedAt < config2.backoffResetMs) {
1279
1361
  return { action: "skip", reason: "already-auto-resumed" };
1280
1362
  }
@@ -1296,6 +1378,28 @@ function hydrateAutoResumeMarkers(saved) {
1296
1378
  return map;
1297
1379
  }
1298
1380
 
1381
+ // src/lib/breaker-stale-trip.ts
1382
+ var DEFAULT_STALE_TRIP_SETTLE_MS = 12e4;
1383
+ var MIN_STALE_TRIP_SETTLE_MS = 1e3;
1384
+ function readStaleTripSettleMs() {
1385
+ return Math.max(
1386
+ MIN_STALE_TRIP_SETTLE_MS,
1387
+ readEnvNumber("AGT_RESTART_BREAKER_STALE_TRIP_SETTLE_MS", DEFAULT_STALE_TRIP_SETTLE_MS)
1388
+ );
1389
+ }
1390
+ function decideStaleTripClear(opts) {
1391
+ const { trip, agentStatus, killSwitched, settleMs, now } = opts;
1392
+ if (!trip) return { action: "hold", reason: "no-trip" };
1393
+ if (agentStatus !== "active" || killSwitched) {
1394
+ return { action: "hold", reason: "pause-in-force" };
1395
+ }
1396
+ const ageMs = now - trip.trippedAt;
1397
+ if (ageMs < settleMs) {
1398
+ return { action: "hold", reason: "settling", remainingMs: settleMs - ageMs };
1399
+ }
1400
+ return { action: "clear", ageMs };
1401
+ }
1402
+
1299
1403
  // src/lib/resume-reconciler.ts
1300
1404
  var DEFAULT_MIN_HEALTHY_CYCLES = 2;
1301
1405
  var DEFAULT_BACKOFF_RESET_MS2 = 864e5;
@@ -8818,9 +8922,17 @@ var pendingSessionRestarts = /* @__PURE__ */ new Map();
8818
8922
  var lastRestartWasExternal = /* @__PURE__ */ new Map();
8819
8923
  var pendingRestartVerifications = /* @__PURE__ */ new Map();
8820
8924
  var restartBreaker = new RestartBreaker();
8925
+ {
8926
+ const clamp = restartBreaker.getQuarantineOrderingClamp();
8927
+ if (clamp) {
8928
+ log(
8929
+ `[circuit-breaker] provisioningMax=${clamp.requested} would trip before MCP quarantine (threshold=${clamp.quarantineThreshold}); raised to ${clamp.applied} so a failing integration is isolated before the whole agent is paused (ENG-8215)`
8930
+ );
8931
+ }
8932
+ }
8821
8933
  var reportedTrips = /* @__PURE__ */ new Map();
8822
- var RESTART_BREAKER_PROVISIONING_MAX = readEnvNumber("AGT_RESTART_BREAKER_PROVISIONING_MAX", 5);
8823
- var RESTART_BREAKER_PROVISIONING_WINDOW_MS = readEnvNumber(
8934
+ var RESTART_BREAKER_PROVISIONING_MAX2 = readEnvNumber("AGT_RESTART_BREAKER_PROVISIONING_MAX", 5);
8935
+ var RESTART_BREAKER_PROVISIONING_WINDOW_MS2 = readEnvNumber(
8824
8936
  "AGT_RESTART_BREAKER_PROVISIONING_WINDOW_MS",
8825
8937
  18e5
8826
8938
  );
@@ -8865,13 +8977,13 @@ function recordRestartForBreaker(codeName, reason) {
8865
8977
  let integrationKey;
8866
8978
  if (isProvisioningReloadReason(reason)) {
8867
8979
  const attribution = agentState.provisioningAttribution.get(codeName);
8868
- if (attribution && Date.now() - attribution.at <= RESTART_BREAKER_PROVISIONING_WINDOW_MS) {
8980
+ if (attribution && Date.now() - attribution.at <= RESTART_BREAKER_PROVISIONING_WINDOW_MS2) {
8869
8981
  integrationKey = attribution.key;
8870
8982
  }
8871
8983
  }
8872
8984
  const result = restartBreaker.record(codeName, reason, integrationKey);
8873
8985
  if (!result.tripped || !result.trip) {
8874
- if (isProvisioningReloadReason(reason) && result.maxProvisioningBucket >= RESTART_BREAKER_PROVISIONING_MAX) {
8986
+ if (isProvisioningReloadReason(reason) && result.maxProvisioningBucket >= RESTART_BREAKER_PROVISIONING_MAX2) {
8875
8987
  const culprit = result.maxProvisioningBucketKey ? ` [${result.maxProvisioningBucketKey}]` : "";
8876
8988
  log(
8877
8989
  `[restart-breaker] agent=${codeName} provisioning-reload churn at the trip bar: ${result.maxProvisioningBucket} restarts for one integration${culprit} in window (reason=${reason}); one more will auto-pause the agent; that integration is likely churning (ENG-7560, ENG-7812)`
@@ -8905,6 +9017,33 @@ function maybeReportCurrentTrip(codeName) {
8905
9017
  log(`[circuit-breaker] Failed to report trip for '${codeName}' to API: ${err.message}`);
8906
9018
  });
8907
9019
  }
9020
+ function maybeClearStaleTrip(agent) {
9021
+ const codeName = agent.code_name;
9022
+ const trip = restartBreaker.getTrip(codeName);
9023
+ const decision = decideStaleTripClear({
9024
+ trip,
9025
+ agentStatus: agent.status,
9026
+ killSwitched: Boolean(agent.kill_switch),
9027
+ settleMs: readStaleTripSettleMs(),
9028
+ now: Date.now()
9029
+ });
9030
+ if (decision.action !== "clear") return;
9031
+ restartBreaker.clear(codeName);
9032
+ reportedTrips.delete(codeName);
9033
+ dependencyRecoveryLedger.clear(codeName);
9034
+ log(
9035
+ `[circuit-breaker] agent=${codeName} cleared STALE trip \u2014 authoritative status=active while a trip was held (age=${Math.round(decision.ageMs / 6e4)}min, trippedAt=${new Date(trip.trippedAt).toISOString()}); the pause this trip caused is no longer in force (ENG-7577)`
9036
+ );
9037
+ const marker = autoResumeMarkers.get(codeName);
9038
+ const isSelfResume = marker !== void 0 && Date.now() - marker.autoResumedAt < AUTO_RESUME_SELF_WINDOW_MS;
9039
+ if (!isSelfResume) autoResumeMarkers.delete(codeName);
9040
+ state6 = {
9041
+ ...state6,
9042
+ circuitBreakerTrips: restartBreaker.serialize(),
9043
+ circuitBreakerAutoResumes: Object.fromEntries(autoResumeMarkers.entries())
9044
+ };
9045
+ send({ type: "state-update", state: state6 });
9046
+ }
8908
9047
  var autoResumeMarkers = /* @__PURE__ */ new Map();
8909
9048
  var autoResumeInFlight = /* @__PURE__ */ new Set();
8910
9049
  var AUTO_RESUME_SELF_WINDOW_MS = 12e4;
@@ -8931,11 +9070,11 @@ function maybeAutoResume(agent) {
8931
9070
  now: Date.now()
8932
9071
  });
8933
9072
  if (decision.action === "skip") {
8934
- if ((decision.reason === "already-auto-resumed" || decision.reason === "not-quiet-yet") && trip) {
9073
+ if ((decision.reason === "already-auto-resumed" || decision.reason === "not-quiet-yet" || decision.reason === "class-not-eligible") && trip) {
8935
9074
  const key = `${codeName}:${trip.trippedAt}`;
8936
9075
  if (autoResumeLoggedSkips.get(key) !== decision.reason) {
8937
9076
  autoResumeLoggedSkips.set(key, decision.reason);
8938
- const detail = decision.reason === "not-quiet-yet" ? ` (~${Math.ceil((decision.remainingMs ?? 0) / 6e4)}min remaining)` : " \u2014 credit spent for this cycle; operator resume re-arms it";
9077
+ const detail = decision.reason === "not-quiet-yet" ? ` (~${Math.ceil((decision.remainingMs ?? 0) / 6e4)}min remaining)` : decision.reason === "class-not-eligible" ? ` class=${tripClass(trip)} \u2014 the blind quiet-timer only auto-recovers provisioning-reload trips; this one stays paused for an operator (ENG-7577)` : " \u2014 credit spent for this cycle; operator resume re-arms it";
8939
9078
  log(`[auto-resume] agent=${codeName} decision=skip reason=${decision.reason}${detail} (ENG-6088)`);
8940
9079
  }
8941
9080
  }
@@ -9810,7 +9949,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
9810
9949
  var lastVersionCheckAt = 0;
9811
9950
  var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
9812
9951
  var lastResponsivenessProbeAt = 0;
9813
- var agtCliVersion = true ? "0.28.451" : "dev";
9952
+ var agtCliVersion = true ? "0.28.453" : "dev";
9814
9953
  function resolveBrewPath(execFileSync2) {
9815
9954
  try {
9816
9955
  const out = execFileSync2("which", ["brew"], { timeout: 5e3 }).toString().trim();
@@ -10971,7 +11110,7 @@ function flushRestartedAgentDiagnostics(hostId, codeNames) {
10971
11110
  if (codeNames.length === 0) return;
10972
11111
  void (async () => {
10973
11112
  try {
10974
- const { collectDiagnostics } = await import("../persistent-session-7HZXY56P.js");
11113
+ const { collectDiagnostics } = await import("../persistent-session-X5N7UFEF.js");
10975
11114
  await api.post("/host/heartbeat", {
10976
11115
  host_id: hostId,
10977
11116
  agent_diagnostics: collectDiagnostics(codeNames, quarantineEntriesFor, claudeMdSizeFor)
@@ -11078,7 +11217,7 @@ async function pollCycle() {
11078
11217
  }
11079
11218
  try {
11080
11219
  const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
11081
- const { collectDiagnostics } = await import("../persistent-session-7HZXY56P.js");
11220
+ const { collectDiagnostics } = await import("../persistent-session-X5N7UFEF.js");
11082
11221
  const diagCodeNames = [...agentState.persistentSessionAgents];
11083
11222
  const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames, quarantineEntriesFor, claudeMdSizeFor) : void 0;
11084
11223
  let tailscaleHostname;
@@ -11192,7 +11331,7 @@ async function pollCycle() {
11192
11331
  collectResponsivenessProbes,
11193
11332
  collectPanelessActivityProbes,
11194
11333
  getResponsivenessIntervalMs
11195
- } = await import("../responsiveness-probe-AIA7ZEBW.js");
11334
+ } = await import("../responsiveness-probe-OAZ55KPC.js");
11196
11335
  const probeIntervalMs = getResponsivenessIntervalMs();
11197
11336
  if (now - lastResponsivenessProbeAt > probeIntervalMs) {
11198
11337
  const probeCodeNames = [...agentState.persistentSessionAgents];
@@ -11256,7 +11395,7 @@ async function pollCycle() {
11256
11395
  collectResponsivenessProbes,
11257
11396
  livePendingInboundOldestAgeSeconds,
11258
11397
  parkPendingInbound
11259
- } = await import("../responsiveness-probe-AIA7ZEBW.js");
11398
+ } = await import("../responsiveness-probe-OAZ55KPC.js");
11260
11399
  const { getProjectDir: wedgeProjectDir } = await import("../scheduler-engine-NDP36U7O.js");
11261
11400
  const wedgeNow = /* @__PURE__ */ new Date();
11262
11401
  const liveAgents = agentState.persistentSessionAgents;
@@ -11801,6 +11940,7 @@ async function processAgent(agent, agentStates) {
11801
11940
  const previousKnownStatus = agentState.knownStatuses.get(agent.agent_id);
11802
11941
  agentState.agentDisplayNames.set(agent.code_name, agent.display_name);
11803
11942
  agentState.codeNameToAgentId.set(agent.code_name, agent.agent_id);
11943
+ maybeClearStaleTrip(agent);
11804
11944
  maybeReportCurrentTrip(agent.code_name);
11805
11945
  if (agent.framework) {
11806
11946
  agentFrameworkCache.set(agent.code_name, agent.framework);
@@ -11943,6 +12083,7 @@ async function processAgent(agent, agentStates) {
11943
12083
  if (previousStatus === "paused" && agent.status === "active" && restartBreaker.isTripped(agent.code_name)) {
11944
12084
  restartBreaker.clear(agent.code_name);
11945
12085
  reportedTrips.delete(agent.code_name);
12086
+ dependencyRecoveryLedger.clear(agent.code_name);
11946
12087
  log(`[circuit-breaker] Cleared trip for '${agent.code_name}' on operator resume (paused \u2192 active)`);
11947
12088
  }
11948
12089
  if (previousStatus === "paused" && agent.status === "active") {
@@ -14626,7 +14767,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
14626
14767
  void api.post("/host/restart-ack", { host_id: hostId, agent_id: agentId, restart_requested_at: requestedAt }).catch((err) => log(`[restart-lane] ack failed for '${codeName}': ${err.message}`));
14627
14768
  void (async () => {
14628
14769
  try {
14629
- const { collectDiagnostics } = await import("../persistent-session-7HZXY56P.js");
14770
+ const { collectDiagnostics } = await import("../persistent-session-X5N7UFEF.js");
14630
14771
  await api.post("/host/heartbeat", {
14631
14772
  host_id: hostId,
14632
14773
  agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor)
@@ -14676,7 +14817,7 @@ async function respawnAgentAfterMcpStop(codeName, reason) {
14676
14817
  }
14677
14818
  try {
14678
14819
  const hostId = await getHostId();
14679
- const { collectDiagnostics } = await import("../persistent-session-7HZXY56P.js");
14820
+ const { collectDiagnostics } = await import("../persistent-session-X5N7UFEF.js");
14680
14821
  await api.post("/host/heartbeat", {
14681
14822
  host_id: hostId,
14682
14823
  agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor)
@@ -15129,7 +15270,7 @@ async function processClaudePairSessions(agents) {
15129
15270
  killPairSession,
15130
15271
  pairTmuxSession,
15131
15272
  finalizeClaudePairOnboarding
15132
- } = await import("../claude-pair-runtime-RCH4LKDE.js");
15273
+ } = await import("../claude-pair-runtime-NRKOKQYR.js");
15133
15274
  for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
15134
15275
  log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
15135
15276
  const killed = await killPairSession(pairTmuxSession(pairId));