@integrity-labs/agt-cli 0.28.499 → 0.28.501

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.
@@ -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-NZMYK2WQ.js");
103
+ const { resolveClaudeBinary } = await import("./persistent-session-HL3LNPAX.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-TA2D5FPK.js.map
376
+ //# sourceMappingURL=claude-pair-runtime-U5ES3GOY.js.map
@@ -1,7 +1,9 @@
1
1
  import {
2
2
  ApiError,
3
3
  CHANNEL_SECRET_ENV_KEYS,
4
+ FIRST_CONNECT_WINDOW_MS,
4
5
  HostFlagStore,
6
+ RestartBreaker,
5
7
  SUPERVISOR_RESTART_EXIT_CODE,
6
8
  api,
7
9
  atomicWriteFileSync,
@@ -25,9 +27,11 @@ import {
25
27
  getCachedClaudeAuthMode,
26
28
  getHostId,
27
29
  givenUpMcpServerKeys,
30
+ isProvisioningReloadReason,
28
31
  isTransientAuthFailure,
29
32
  liveProxyExtraHeaderVars,
30
33
  liveProxyTokenVars,
34
+ markQuarantinedForProbe,
31
35
  migrateAgentDirToIdKeyed,
32
36
  pinAllowsUrgent,
33
37
  provision,
@@ -38,14 +42,17 @@ import {
38
42
  provisionPreCompactHook,
39
43
  provisionSessionStateHook,
40
44
  provisionStopHook,
45
+ readEnvNumber,
41
46
  reapMissingMcpSessions,
42
47
  reapStaleMcpChildren,
48
+ reaperRestartBreakerReason,
43
49
  reconstructQuarantinedMcpServerEntry,
44
50
  requireHost,
45
51
  resolveEffectivePinRaw,
46
52
  safeWriteJsonAtomic,
47
- setConfigHash
48
- } from "../chunk-Q5O2VAQA.js";
53
+ setConfigHash,
54
+ tripClass
55
+ } from "../chunk-N4Y5IBZR.js";
49
56
  import {
50
57
  getProjectDir as getProjectDir2,
51
58
  getReadyTasks,
@@ -56,7 +63,6 @@ import {
56
63
  import {
57
64
  ACCOUNT_ENFORCEMENT_MARKER_FILENAME,
58
65
  AnchorSessionClient,
59
- BIND_FAILURE_QUARANTINE_THRESHOLD,
60
66
  CLAUDE_MD_MAX_CHARS,
61
67
  CONVERSATION_FAILURE_CATEGORIES,
62
68
  DEFAULT_FRAMEWORK,
@@ -67,9 +73,6 @@ import {
67
73
  KANBAN_CHECK_COMMAND,
68
74
  KANBAN_NUDGE_ACTIONABLE_STATUSES,
69
75
  MAX_AVATAR_ENV_URL_BYTES,
70
- MIN_PROVISIONING_MAX_FOR_QUARANTINE_ORDERING,
71
- RESTART_BREAKER_PROVISIONING_MAX,
72
- RESTART_BREAKER_PROVISIONING_WINDOW_MS,
73
76
  SCHEDULED_TURN_MARKER_FILENAME,
74
77
  SUPPRESS_SENTINEL,
75
78
  StreamEncoder,
@@ -150,6 +153,7 @@ import {
150
153
  resolveClaudeBinary,
151
154
  resolveDmTarget,
152
155
  restartEgressSidecar,
156
+ rotatePaneLogForDayRollover,
153
157
  rotateSessionForWedge,
154
158
  serializeAccountEnforcementMarker,
155
159
  sessionTranscriptDir,
@@ -167,7 +171,7 @@ import {
167
171
  toOpencodeModel,
168
172
  transcriptActivityAgeSeconds,
169
173
  writeEgressAllowlist
170
- } from "../chunk-5XHO4HKA.js";
174
+ } from "../chunk-XKBUTWON.js";
171
175
  import {
172
176
  reapOrphanChannelMcps
173
177
  } from "../chunk-XWVM4KPK.js";
@@ -844,315 +848,8 @@ function logClaudeMdCeilingTransition(codeName, report, log2) {
844
848
  return line;
845
849
  }
846
850
 
847
- // src/lib/restart-breaker.ts
848
- function reaperRestartBreakerReason(activeKeys) {
849
- return activeKeys.length >= 2 ? "mcp-presence-reaper" : void 0;
850
- }
851
- var KNOWN_REASON_CLASS_MAP = {
852
- crash: true,
853
- provisioning: true,
854
- "credential-rotation": true,
855
- // ENG-8215: the self-healing class (bind-remediation - the manager's OWN
856
- // repair attempts, which must never count toward a trip). Adding it here is
857
- // forced by the Record type, which is exactly why that shape was chosen over
858
- // a Set literal (ENG-7577, CodeRabbit on #3861) - a new union member cannot
859
- // be silently omitted from the rehydration allowlist.
860
- "self-healing": true
861
- };
862
- var KNOWN_REASON_CLASSES = new Set(
863
- Object.keys(KNOWN_REASON_CLASS_MAP)
864
- );
865
- var PROVISIONING_RELOAD_REASONS = /* @__PURE__ */ new Set([
866
- "hot-reload-mcp",
867
- "managed-mcp-churn",
868
- // ENG-8215: 'bind-remediation' MOVED OUT of this set into SELF_HEALING_REASONS.
869
- // It is the manager repairing itself, not a config reload, and counting it
870
- // meant the harder the platform tried to fix an agent the more certain it
871
- // became that it should give up. Deliberately NOT re-added here.
872
- // ENG-7576: the dashboard integration-add stop itself - the first restart of
873
- // the very burst this class exists for, previously uncounted entirely.
874
- "integration-change",
875
- // ENG-7771: a sender_policy delivery restart is a deliberate config-delivery
876
- // reload (operator changed the policy, or the fail-closed first-poll verify
877
- // after a manager restart with no persisted baseline), not a crash. On the
878
- // tight crash tally, a host whose sender-policy-baseline.json write keeps
879
- // failing (disk full, permissions) would convert the fail-closed restart
880
- // into repeated crash tallies across a multi-deploy day and trip the
881
- // breaker - taking the agent DOWN, which is strictly worse than the stale
882
- // policy the restart exists to fix. The looser provisioning tally still
883
- // trips + pages on sustained thrash.
884
- "sender-policy-change"
885
- ]);
886
- function isProvisioningReloadReason(reason) {
887
- return PROVISIONING_RELOAD_REASONS.has(reason);
888
- }
889
- var CREDENTIAL_ROTATION_REASONS = /* @__PURE__ */ new Set([
890
- "credential-rotation"
891
- ]);
892
- function isCredentialRotationReason(reason) {
893
- return CREDENTIAL_ROTATION_REASONS.has(reason);
894
- }
895
- var SELF_HEALING_REASONS = /* @__PURE__ */ new Set([
896
- "bind-remediation"
897
- ]);
898
- function isSelfHealingReason(reason) {
899
- return SELF_HEALING_REASONS.has(reason);
900
- }
901
- function restartReasonClass(reason) {
902
- if (isCredentialRotationReason(reason)) return "credential-rotation";
903
- if (isSelfHealingReason(reason)) return "self-healing";
904
- return isProvisioningReloadReason(reason) ? "provisioning" : "crash";
905
- }
906
- function countByClass(events) {
907
- let crash = 0;
908
- let provisioning = 0;
909
- let credentialRotation = 0;
910
- let selfHealing = 0;
911
- for (const e of events) {
912
- const klass = restartReasonClass(e.reason);
913
- if (klass === "provisioning") provisioning += 1;
914
- else if (klass === "credential-rotation") credentialRotation += 1;
915
- else if (klass === "self-healing") selfHealing += 1;
916
- else crash += 1;
917
- }
918
- return {
919
- crash,
920
- provisioning,
921
- "credential-rotation": credentialRotation,
922
- "self-healing": selfHealing
923
- };
924
- }
925
- function maxProvisioningBucket(events) {
926
- const buckets = /* @__PURE__ */ new Map();
927
- for (const e of events) {
928
- if (!isProvisioningReloadReason(e.reason)) continue;
929
- const key = e.integrationKey ?? "";
930
- buckets.set(key, (buckets.get(key) ?? 0) + 1);
931
- }
932
- let best = { count: 0, key: "" };
933
- for (const [key, count] of buckets) {
934
- if (count > best.count) best = { count, key };
935
- }
936
- return best;
937
- }
938
- function tripClass(trip) {
939
- if (trip.trippedClass) return trip.trippedClass;
940
- if (!Array.isArray(trip.eventsAtTrip) || trip.eventsAtTrip.length === 0) return "crash";
941
- return trip.eventsAtTrip.every((e) => isProvisioningReloadReason(e.reason)) ? "provisioning" : "crash";
942
- }
943
- var DEFAULT_MAX = 2;
944
- var DEFAULT_WINDOW_MS = 6e5;
945
- var DEFAULT_PROVISIONING_MAX = RESTART_BREAKER_PROVISIONING_MAX;
946
- var DEFAULT_PROVISIONING_WINDOW_MS = RESTART_BREAKER_PROVISIONING_WINDOW_MS;
947
- function readEnvNumber(name, fallback) {
948
- const raw = process.env[name];
949
- if (!raw) return fallback;
950
- const parsed = Number(raw);
951
- return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
952
- }
953
- var RestartBreaker = class {
954
- max;
955
- windowMs;
956
- /**
957
- * ENG-8215: NOT readonly - the constructor may clamp it upward to preserve the
958
- * quarantine-fires-first ordering against a runtime override. Never mutated
959
- * after construction.
960
- */
961
- provisioningMax;
962
- provisioningWindowMs;
963
- /** Longest window either tally needs — how long the events log must retain. */
964
- retentionMs;
965
- now;
966
- events = /* @__PURE__ */ new Map();
967
- trips = /* @__PURE__ */ new Map();
968
- /**
969
- * ENG-8215: set when a supplied `provisioningMax` was raised to keep MCP
970
- * quarantine ahead of the breaker. Read once by the manager at construction so
971
- * an overridden-and-clamped value is visible in manager.log rather than
972
- * silently discarded.
973
- */
974
- quarantineOrderingClamped;
975
- constructor(opts = {}) {
976
- this.max = opts.max ?? readEnvNumber("AGT_RESTART_BREAKER_MAX", DEFAULT_MAX);
977
- this.windowMs = opts.windowMs ?? readEnvNumber("AGT_RESTART_BREAKER_WINDOW_MS", DEFAULT_WINDOW_MS);
978
- this.provisioningMax = opts.provisioningMax ?? readEnvNumber("AGT_RESTART_BREAKER_PROVISIONING_MAX", DEFAULT_PROVISIONING_MAX);
979
- this.provisioningWindowMs = opts.provisioningWindowMs ?? readEnvNumber("AGT_RESTART_BREAKER_PROVISIONING_WINDOW_MS", DEFAULT_PROVISIONING_WINDOW_MS);
980
- this.now = opts.now ?? Date.now;
981
- if (!Number.isFinite(this.max) || this.max < 1) {
982
- throw new Error("restart-breaker max must be a finite number >= 1");
983
- }
984
- if (!Number.isFinite(this.windowMs) || this.windowMs < 1e3) {
985
- throw new Error("restart-breaker windowMs must be a finite number >= 1000");
986
- }
987
- if (!Number.isFinite(this.provisioningMax) || this.provisioningMax < 1) {
988
- throw new Error("restart-breaker provisioningMax must be a finite number >= 1");
989
- }
990
- if (this.provisioningMax < MIN_PROVISIONING_MAX_FOR_QUARANTINE_ORDERING) {
991
- this.quarantineOrderingClamped = {
992
- requested: this.provisioningMax,
993
- applied: MIN_PROVISIONING_MAX_FOR_QUARANTINE_ORDERING,
994
- quarantineThreshold: BIND_FAILURE_QUARANTINE_THRESHOLD
995
- };
996
- this.provisioningMax = MIN_PROVISIONING_MAX_FOR_QUARANTINE_ORDERING;
997
- }
998
- if (!Number.isFinite(this.provisioningWindowMs) || this.provisioningWindowMs < 1e3) {
999
- throw new Error("restart-breaker provisioningWindowMs must be a finite number >= 1000");
1000
- }
1001
- this.retentionMs = Math.max(this.windowMs, this.provisioningWindowMs);
1002
- }
1003
- /**
1004
- * ENG-8215: the clamp record, if the configured provisioning max had to be
1005
- * raised to keep MCP quarantine ahead of the breaker. `undefined` when the
1006
- * configured value already satisfied the ordering.
1007
- */
1008
- getQuarantineOrderingClamp() {
1009
- return this.quarantineOrderingClamped;
1010
- }
1011
- /** True if this agent's breaker is currently tripped (manager must skip spawn). */
1012
- isTripped(codeName) {
1013
- return this.trips.has(codeName);
1014
- }
1015
- getTrip(codeName) {
1016
- return this.trips.get(codeName);
1017
- }
1018
- /**
1019
- * Record a restart event. If recording this event puts the count
1020
- * inside the window above `max`, the breaker trips and the call site
1021
- * should NOT respawn.
1022
- *
1023
- * Idempotent on already-tripped breakers: returns the existing trip
1024
- * without double-counting events. Callers may still record the reason
1025
- * via the decision-log for forensics.
1026
- */
1027
- record(codeName, reason, integrationKey) {
1028
- const existing = this.trips.get(codeName);
1029
- if (existing) {
1030
- const bucket = maxProvisioningBucket(existing.eventsAtTrip);
1031
- return {
1032
- tripped: false,
1033
- trip: existing,
1034
- windowCount: existing.eventsAtTrip.length,
1035
- classCounts: countByClass(existing.eventsAtTrip),
1036
- maxProvisioningBucket: bucket.count,
1037
- maxProvisioningBucketKey: bucket.key
1038
- };
1039
- }
1040
- const at = this.now();
1041
- const retentionCutoff = at - this.retentionMs;
1042
- const prior = (this.events.get(codeName) ?? []).filter((e) => e.at >= retentionCutoff);
1043
- prior.push(
1044
- isProvisioningReloadReason(reason) && integrationKey ? { reason, at, integrationKey } : { reason, at }
1045
- );
1046
- this.events.set(codeName, prior);
1047
- const crashCount = prior.filter(
1048
- (e) => e.at >= at - this.windowMs && restartReasonClass(e.reason) === "crash"
1049
- ).length;
1050
- const provEvents = prior.filter(
1051
- (e) => e.at >= at - this.provisioningWindowMs && isProvisioningReloadReason(e.reason)
1052
- );
1053
- const credRotCount = prior.filter(
1054
- (e) => e.at >= at - this.provisioningWindowMs && isCredentialRotationReason(e.reason)
1055
- ).length;
1056
- const selfHealCount = prior.filter(
1057
- (e) => e.at >= at - this.provisioningWindowMs && isSelfHealingReason(e.reason)
1058
- ).length;
1059
- const windowCount = prior.filter((e) => e.at >= at - this.windowMs).length;
1060
- const classCounts = {
1061
- crash: crashCount,
1062
- provisioning: provEvents.length,
1063
- "credential-rotation": credRotCount,
1064
- "self-healing": selfHealCount
1065
- };
1066
- const provBucket = maxProvisioningBucket(provEvents);
1067
- let trippedClass;
1068
- let tripEvents;
1069
- let tripWindowMs = this.windowMs;
1070
- if (crashCount > this.max) {
1071
- trippedClass = "crash";
1072
- tripEvents = prior.filter(
1073
- (e) => e.at >= at - this.windowMs && restartReasonClass(e.reason) === "crash"
1074
- );
1075
- tripWindowMs = this.windowMs;
1076
- } else if (provBucket.count > this.provisioningMax) {
1077
- trippedClass = "provisioning";
1078
- tripEvents = provEvents.filter((e) => (e.integrationKey ?? "") === provBucket.key);
1079
- tripWindowMs = this.provisioningWindowMs;
1080
- }
1081
- if (trippedClass && tripEvents) {
1082
- const trip = {
1083
- trippedAt: at,
1084
- eventsAtTrip: [...tripEvents],
1085
- statusMessage: formatStatusMessage(tripEvents, tripWindowMs, trippedClass, provBucket.key),
1086
- // ENG-7577: persist the tripping class so the recovery path can gate on
1087
- // it after a manager restart, without re-deriving it from prose.
1088
- trippedClass
1089
- };
1090
- this.trips.set(codeName, trip);
1091
- this.events.delete(codeName);
1092
- return {
1093
- tripped: true,
1094
- trip,
1095
- windowCount,
1096
- classCounts,
1097
- trippedClass,
1098
- maxProvisioningBucket: provBucket.count,
1099
- maxProvisioningBucketKey: provBucket.key
1100
- };
1101
- }
1102
- return {
1103
- tripped: false,
1104
- windowCount,
1105
- classCounts,
1106
- maxProvisioningBucket: provBucket.count,
1107
- maxProvisioningBucketKey: provBucket.key
1108
- };
1109
- }
1110
- /** Operator-initiated reset: drops the trip + the events log for this agent. */
1111
- clear(codeName) {
1112
- this.trips.delete(codeName);
1113
- this.events.delete(codeName);
1114
- }
1115
- /** Snapshot tripped agents for `manager-state.json`. */
1116
- serialize() {
1117
- return Object.fromEntries(this.trips.entries());
1118
- }
1119
- /**
1120
- * Rehydrate trip state from `manager-state.json`. Called once at
1121
- * worker startup. Window history is intentionally NOT persisted — only
1122
- * tripped state. A tripped breaker survives manager restart; an
1123
- * un-tripped one starts a fresh window in the new worker.
1124
- */
1125
- hydrate(saved) {
1126
- if (!saved) return;
1127
- for (const [codeName, trip] of Object.entries(saved)) {
1128
- if (trip && typeof trip.trippedAt === "number" && Array.isArray(trip.eventsAtTrip)) {
1129
- const klass = trip.trippedClass;
1130
- this.trips.set(
1131
- codeName,
1132
- klass === void 0 || KNOWN_REASON_CLASSES.has(klass) ? trip : { ...trip, trippedClass: void 0 }
1133
- );
1134
- }
1135
- }
1136
- }
1137
- /** Test helper — current in-window event count for `codeName`. */
1138
- windowCount(codeName) {
1139
- const cutoff = this.now() - this.windowMs;
1140
- return (this.events.get(codeName) ?? []).filter((e) => e.at >= cutoff).length;
1141
- }
1142
- };
1143
- function formatStatusMessage(events, windowMs, klass = "crash", integrationKey = "") {
1144
- const last = events[events.length - 1];
1145
- const windowLabel = windowMs < 6e4 ? `${Math.round(windowMs / 1e3)}s` : `${(windowMs / 6e4).toFixed(1).replace(/\.0$/, "")}min`;
1146
- const reasonCounts = /* @__PURE__ */ new Map();
1147
- for (const e of events) reasonCounts.set(e.reason, (reasonCounts.get(e.reason) ?? 0) + 1);
1148
- const breakdown = Array.from(reasonCounts.entries()).map(([r, n]) => `${r}=${n}`).join(", ");
1149
- const classLabel = klass === "provisioning" ? "provisioning-reload " : "";
1150
- const integrationLabel = klass === "provisioning" && integrationKey ? ` for integration '${integrationKey}'` : "";
1151
- return `Circuit breaker tripped: ${events.length} ${classLabel}restarts in ${windowLabel}${integrationLabel} (${breakdown}); most recent=${last.reason} at ${new Date(last.at).toISOString()}`;
1152
- }
1153
-
1154
851
  // src/lib/mcp-flap-dampener.ts
1155
- var DEFAULT_WINDOW_MS2 = 6e5;
852
+ var DEFAULT_WINDOW_MS = 6e5;
1156
853
  var DEFAULT_MIN_TRANSITIONS = 4;
1157
854
  var DEFAULT_MIN_DISTINCT = 2;
1158
855
  var DEFAULT_LONG_WINDOW_MS = 36e5;
@@ -1181,7 +878,7 @@ var McpFlapDampener = class {
1181
878
  // see that method for the Kylie/dig (2026-06-29) rationale.
1182
879
  lastFlapAt = /* @__PURE__ */ new Map();
1183
880
  constructor(opts = {}) {
1184
- this.windowMs = opts.windowMs ?? readEnvNumber2("AGT_MCP_FLAP_WINDOW_MS", DEFAULT_WINDOW_MS2);
881
+ this.windowMs = opts.windowMs ?? readEnvNumber2("AGT_MCP_FLAP_WINDOW_MS", DEFAULT_WINDOW_MS);
1185
882
  this.minTransitions = opts.minTransitions ?? readEnvNumber2("AGT_MCP_FLAP_MIN_TRANSITIONS", DEFAULT_MIN_TRANSITIONS);
1186
883
  this.minDistinct = opts.minDistinct ?? readEnvNumber2("AGT_MCP_FLAP_MIN_DISTINCT", DEFAULT_MIN_DISTINCT);
1187
884
  this.longWindowMs = opts.longWindowMs ?? readEnvNumber2("AGT_MCP_FLAP_LONG_WINDOW_MS", DEFAULT_LONG_WINDOW_MS);
@@ -1585,7 +1282,11 @@ async function runConnectivityProbes(integrations, options = {}) {
1585
1282
  cliBinary: integ.cli_binary,
1586
1283
  mcpServerKey: integ.mcp_server_key,
1587
1284
  connectivityTest: integ.connectivity_test ?? null,
1588
- inlineServerEntry: integ.inline_server_entry
1285
+ inlineServerEntry: integ.inline_server_entry,
1286
+ // ENG-8363: row age + quarantine status decide whether a missing
1287
+ // `.mcp.json` key is "not written yet" (transient) or "not wired" (down).
1288
+ createdAt: integ.created_at ?? null,
1289
+ expectedAbsent: integ.quarantined ?? false
1589
1290
  };
1590
1291
  let outcome;
1591
1292
  try {
@@ -9208,8 +8909,8 @@ var restartBreaker = new RestartBreaker();
9208
8909
  }
9209
8910
  }
9210
8911
  var reportedTrips = /* @__PURE__ */ new Map();
9211
- var RESTART_BREAKER_PROVISIONING_MAX2 = readEnvNumber("AGT_RESTART_BREAKER_PROVISIONING_MAX", 5);
9212
- var RESTART_BREAKER_PROVISIONING_WINDOW_MS2 = readEnvNumber(
8912
+ var RESTART_BREAKER_PROVISIONING_MAX = readEnvNumber("AGT_RESTART_BREAKER_PROVISIONING_MAX", 5);
8913
+ var RESTART_BREAKER_PROVISIONING_WINDOW_MS = readEnvNumber(
9213
8914
  "AGT_RESTART_BREAKER_PROVISIONING_WINDOW_MS",
9214
8915
  18e5
9215
8916
  );
@@ -9254,13 +8955,13 @@ function recordRestartForBreaker(codeName, reason) {
9254
8955
  let integrationKey;
9255
8956
  if (isProvisioningReloadReason(reason)) {
9256
8957
  const attribution = agentState.provisioningAttribution.get(codeName);
9257
- if (attribution && Date.now() - attribution.at <= RESTART_BREAKER_PROVISIONING_WINDOW_MS2) {
8958
+ if (attribution && Date.now() - attribution.at <= RESTART_BREAKER_PROVISIONING_WINDOW_MS) {
9258
8959
  integrationKey = attribution.key;
9259
8960
  }
9260
8961
  }
9261
8962
  const result = restartBreaker.record(codeName, reason, integrationKey);
9262
8963
  if (!result.tripped || !result.trip) {
9263
- if (isProvisioningReloadReason(reason) && result.maxProvisioningBucket >= RESTART_BREAKER_PROVISIONING_MAX2) {
8964
+ if (isProvisioningReloadReason(reason) && result.maxProvisioningBucket >= RESTART_BREAKER_PROVISIONING_MAX) {
9264
8965
  const culprit = result.maxProvisioningBucketKey ? ` [${result.maxProvisioningBucketKey}]` : "";
9265
8966
  log(
9266
8967
  `[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)`
@@ -9649,11 +9350,7 @@ function bindRemediationEnabled() {
9649
9350
  return hostFlagStore().getBoolean("bind-remediation");
9650
9351
  }
9651
9352
  var BIND_REMEDIATION_JITTER_MS = 3e4;
9652
- var BIND_REMEDIATION_FIRST_CONNECT_WINDOW_MS = readEnvNumber(
9653
- "AGT_BIND_REMEDIATION_FIRST_CONNECT_WINDOW_MS",
9654
- 9e5
9655
- // 15 min
9656
- );
9353
+ var BIND_REMEDIATION_FIRST_CONNECT_WINDOW_MS = FIRST_CONNECT_WINDOW_MS;
9657
9354
  var BIND_REMEDIATION_MAX_CONNECTIVITY_DEFERRALS = readEnvNumber(
9658
9355
  "AGT_BIND_REMEDIATION_MAX_CONNECTIVITY_DEFERRALS",
9659
9356
  3
@@ -9953,7 +9650,13 @@ async function runAgentConnectivityProbes(agent, integrations, projectDir) {
9953
9650
  // ENG-8055: forward the reconstructed inline server entry (managed
9954
9651
  // quarantined rows) so the MCP probe legs hit the real server instead of
9955
9652
  // the missing `.mcp.json` key. Absent on normal (active) rows.
9956
- inline_server_entry: i.inline_server_entry
9653
+ inline_server_entry: i.inline_server_entry,
9654
+ // ENG-8363: age + quarantine status, so an absent `.mcp.json` key is
9655
+ // classified rather than guessed. Forwarding both is what makes the
9656
+ // escalation to `down` reachable at all — an omitted `created_at` reads
9657
+ // as "still settling" and never escalates (fail-open by design).
9658
+ created_at: i.created_at ?? null,
9659
+ quarantined: i.quarantined ?? false
9957
9660
  };
9958
9661
  }),
9959
9662
  { probeDeps, intervalMs: intervalSec * 1e3 }
@@ -10250,7 +9953,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
10250
9953
  var lastVersionCheckAt = 0;
10251
9954
  var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
10252
9955
  var lastResponsivenessProbeAt = 0;
10253
- var agtCliVersion = true ? "0.28.499" : "dev";
9956
+ var agtCliVersion = true ? "0.28.501" : "dev";
10254
9957
  function resolveBrewPath(execFileSync2) {
10255
9958
  try {
10256
9959
  const out = execFileSync2("which", ["brew"], { timeout: 5e3 }).toString().trim();
@@ -11413,7 +11116,7 @@ function flushRestartedAgentDiagnostics(hostId, codeNames) {
11413
11116
  if (codeNames.length === 0) return;
11414
11117
  void (async () => {
11415
11118
  try {
11416
- const { collectDiagnostics } = await import("../persistent-session-NZMYK2WQ.js");
11119
+ const { collectDiagnostics } = await import("../persistent-session-HL3LNPAX.js");
11417
11120
  await api.post("/host/heartbeat", {
11418
11121
  host_id: hostId,
11419
11122
  agent_diagnostics: collectDiagnostics(codeNames, quarantineEntriesFor, claudeMdSizeFor)
@@ -11520,7 +11223,7 @@ async function pollCycle() {
11520
11223
  }
11521
11224
  try {
11522
11225
  const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
11523
- const { collectDiagnostics } = await import("../persistent-session-NZMYK2WQ.js");
11226
+ const { collectDiagnostics } = await import("../persistent-session-HL3LNPAX.js");
11524
11227
  const diagCodeNames = [...agentState.persistentSessionAgents];
11525
11228
  const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames, quarantineEntriesFor, claudeMdSizeFor) : void 0;
11526
11229
  let tailscaleHostname;
@@ -11635,7 +11338,7 @@ async function pollCycle() {
11635
11338
  collectResponsivenessProbes,
11636
11339
  collectPanelessActivityProbes,
11637
11340
  getResponsivenessIntervalMs
11638
- } = await import("../responsiveness-probe-RFANLJWP.js");
11341
+ } = await import("../responsiveness-probe-AZ44ONES.js");
11639
11342
  const probeIntervalMs = getResponsivenessIntervalMs();
11640
11343
  if (now - lastResponsivenessProbeAt > probeIntervalMs) {
11641
11344
  const probeCodeNames = [...agentState.persistentSessionAgents];
@@ -11699,7 +11402,7 @@ async function pollCycle() {
11699
11402
  collectResponsivenessProbes,
11700
11403
  livePendingInboundOldestAgeSeconds,
11701
11404
  parkPendingInbound
11702
- } = await import("../responsiveness-probe-RFANLJWP.js");
11405
+ } = await import("../responsiveness-probe-AZ44ONES.js");
11703
11406
  const { getProjectDir: wedgeProjectDir } = await import("../scheduler-engine-NDP36U7O.js");
11704
11407
  const wedgeNow = /* @__PURE__ */ new Date();
11705
11408
  const liveAgents = agentState.persistentSessionAgents;
@@ -13314,7 +13017,7 @@ async function processAgent(agent, agentStates) {
13314
13017
  );
13315
13018
  }
13316
13019
  }
13317
- probeSet = [...probeSet, ...qRows];
13020
+ probeSet = [...probeSet, ...markQuarantinedForProbe(qRows)];
13318
13021
  log(
13319
13022
  `Auto-resume: connectivity-probing ${qRows.length} quarantined integration(s) for '${agent.code_name}'`
13320
13023
  );
@@ -14762,6 +14465,9 @@ async function ensurePersistentSession(agent, tasks, boardItems, refreshData) {
14762
14465
  }
14763
14466
  }
14764
14467
  }
14468
+ if (restartTrigger === "day-rollover") {
14469
+ rotatePaneLogForDayRollover(codeName, log, agentTimezone);
14470
+ }
14765
14471
  if (restartBreaker.isTripped(codeName)) {
14766
14472
  const trip = restartBreaker.getTrip(codeName);
14767
14473
  return {
@@ -15188,7 +14894,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
15188
14894
  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}`));
15189
14895
  void (async () => {
15190
14896
  try {
15191
- const { collectDiagnostics } = await import("../persistent-session-NZMYK2WQ.js");
14897
+ const { collectDiagnostics } = await import("../persistent-session-HL3LNPAX.js");
15192
14898
  await api.post("/host/heartbeat", {
15193
14899
  host_id: hostId,
15194
14900
  agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor)
@@ -15238,7 +14944,7 @@ async function respawnAgentAfterMcpStop(codeName, reason) {
15238
14944
  }
15239
14945
  try {
15240
14946
  const hostId = await getHostId();
15241
- const { collectDiagnostics } = await import("../persistent-session-NZMYK2WQ.js");
14947
+ const { collectDiagnostics } = await import("../persistent-session-HL3LNPAX.js");
15242
14948
  await api.post("/host/heartbeat", {
15243
14949
  host_id: hostId,
15244
14950
  agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor)
@@ -15726,7 +15432,7 @@ async function processClaudePairSessions(agents) {
15726
15432
  killPairSession,
15727
15433
  pairTmuxSession,
15728
15434
  finalizeClaudePairOnboarding
15729
- } = await import("../claude-pair-runtime-TA2D5FPK.js");
15435
+ } = await import("../claude-pair-runtime-U5ES3GOY.js");
15730
15436
  for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
15731
15437
  log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
15732
15438
  const killed = await killPairSession(pairTmuxSession(pairId));