@integrity-labs/agt-cli 0.28.660 → 0.28.662

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.
package/dist/bin/agt.js CHANGED
@@ -40,10 +40,10 @@ import {
40
40
  success,
41
41
  table,
42
42
  warn
43
- } from "../chunk-ESEOTR5J.js";
43
+ } from "../chunk-77YTVCXK.js";
44
44
  import {
45
45
  readDirectChatSessionState
46
- } from "../chunk-Y63W2XP5.js";
46
+ } from "../chunk-5JAUM7J2.js";
47
47
  import {
48
48
  AnchorSessionClient,
49
49
  CHANNEL_REGISTRY,
@@ -73,7 +73,7 @@ import {
73
73
  requiredMcpWildcard,
74
74
  resolveChannels,
75
75
  serializeManifestForSlackCli
76
- } from "../chunk-VR3VB3FR.js";
76
+ } from "../chunk-SU2J2QRH.js";
77
77
  import "../chunk-XWVM4KPK.js";
78
78
 
79
79
  // src/bin/agt.ts
@@ -4909,7 +4909,7 @@ import { execFileSync, execSync } from "child_process";
4909
4909
  import { existsSync as existsSync10, realpathSync as realpathSync2 } from "fs";
4910
4910
  import chalk18 from "chalk";
4911
4911
  import ora16 from "ora";
4912
- var cliVersion = true ? "0.28.660" : "dev";
4912
+ var cliVersion = true ? "0.28.662" : "dev";
4913
4913
  async function fetchLatestVersion() {
4914
4914
  const host2 = getHost();
4915
4915
  if (!host2) return null;
@@ -6089,7 +6089,7 @@ function handleError(err) {
6089
6089
  }
6090
6090
 
6091
6091
  // src/bin/agt.ts
6092
- var cliVersion2 = true ? "0.28.660" : "dev";
6092
+ var cliVersion2 = true ? "0.28.662" : "dev";
6093
6093
  var program = new Command();
6094
6094
  program.name("agt").description("Augmented CLI \u2014 agent provisioning and management").version(cliVersion2).option("--json", "Emit machine-readable JSON output (suppress spinners and colors)").option("--skip-update-check", "Skip the automatic update check on startup");
6095
6095
  program.hook("preAction", async (thisCommand, actionCommand) => {
@@ -16,7 +16,7 @@ import {
16
16
  rotateDailySession,
17
17
  sessionFileExists,
18
18
  todayLocalIso
19
- } from "./chunk-VR3VB3FR.js";
19
+ } from "./chunk-SU2J2QRH.js";
20
20
  import {
21
21
  reapOrphanChannelMcps
22
22
  } from "./chunk-XWVM4KPK.js";
@@ -4322,4 +4322,4 @@ export {
4322
4322
  stopAllSessionsAndWait,
4323
4323
  getProjectDir
4324
4324
  };
4325
- //# sourceMappingURL=chunk-Y63W2XP5.js.map
4325
+ //# sourceMappingURL=chunk-5JAUM7J2.js.map
@@ -8,7 +8,7 @@ import {
8
8
  isolationMode,
9
9
  log,
10
10
  parseEnvIntegrations
11
- } from "./chunk-Y63W2XP5.js";
11
+ } from "./chunk-5JAUM7J2.js";
12
12
  import {
13
13
  BIND_FAILURE_QUARANTINE_THRESHOLD,
14
14
  INTEGRATIONS_SECTION_END,
@@ -55,7 +55,7 @@ import {
55
55
  resolveConnectivityProbe,
56
56
  worseConnectivityOutcome,
57
57
  wrapScheduledTaskPrompt
58
- } from "./chunk-VR3VB3FR.js";
58
+ } from "./chunk-SU2J2QRH.js";
59
59
  import {
60
60
  parsePsRows
61
61
  } from "./chunk-XWVM4KPK.js";
@@ -6342,7 +6342,7 @@ function exchangeFailureKind(err) {
6342
6342
  }
6343
6343
 
6344
6344
  // src/lib/api-client.ts
6345
- var agtCliVersion = true ? "0.28.660" : "dev";
6345
+ var agtCliVersion = true ? "0.28.662" : "dev";
6346
6346
  var lastConfigHash = null;
6347
6347
  function setConfigHash(hash) {
6348
6348
  lastConfigHash = hash && hash.length > 0 ? hash : null;
@@ -10084,4 +10084,4 @@ export {
10084
10084
  managerInstallSystemUnitCommand,
10085
10085
  managerUninstallSystemUnitCommand
10086
10086
  };
10087
- //# sourceMappingURL=chunk-ESEOTR5J.js.map
10087
+ //# sourceMappingURL=chunk-77YTVCXK.js.map
@@ -12334,4 +12334,4 @@ export {
12334
12334
  minutesSinceLocalMidnight,
12335
12335
  peekCurrentSession
12336
12336
  };
12337
- //# sourceMappingURL=chunk-VR3VB3FR.js.map
12337
+ //# sourceMappingURL=chunk-SU2J2QRH.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-ADS4LIGF.js");
103
+ const { resolveClaudeBinary } = await import("./persistent-session-WOZN2ORO.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-JMESZQPN.js.map
376
+ //# sourceMappingURL=claude-pair-runtime-AAHU6VUL.js.map
@@ -55,7 +55,7 @@ import {
55
55
  safeWriteJsonAtomic,
56
56
  setConfigHash,
57
57
  tripClass
58
- } from "../chunk-ESEOTR5J.js";
58
+ } from "../chunk-77YTVCXK.js";
59
59
  import {
60
60
  getProjectDir as getProjectDir2,
61
61
  getReadyTasks,
@@ -111,7 +111,7 @@ import {
111
111
  takeZombieDetection,
112
112
  toOpencodeModel,
113
113
  writeEgressAllowlist
114
- } from "../chunk-Y63W2XP5.js";
114
+ } from "../chunk-5JAUM7J2.js";
115
115
  import {
116
116
  ACCOUNT_ENFORCEMENT_MARKER_FILENAME,
117
117
  AnchorSessionClient,
@@ -192,7 +192,7 @@ import {
192
192
  subagentActivityAgeSeconds,
193
193
  sumTranscriptUsageInWindow,
194
194
  transcriptActivityAgeSeconds
195
- } from "../chunk-VR3VB3FR.js";
195
+ } from "../chunk-SU2J2QRH.js";
196
196
  import {
197
197
  reapOrphanChannelMcps
198
198
  } from "../chunk-XWVM4KPK.js";
@@ -11609,7 +11609,7 @@ var pendingDayRolloverReset = /* @__PURE__ */ new Set();
11609
11609
  var dayRolloverInboundHold = /* @__PURE__ */ new Map();
11610
11610
  var INBOUND_HOLD_EPISODE_GAP_MS = 12e4;
11611
11611
  async function channelInboundActivityAgeSecondsFor(codeName) {
11612
- const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-EII7QAGR.js");
11612
+ const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-APGLAESO.js");
11613
11613
  const newest = newestPendingInboundActivityMtimeMs(dirname10(paneLogPath(codeName)));
11614
11614
  if (newest === null) return null;
11615
11615
  return Math.max(0, Math.floor((Date.now() - newest) / 1e3));
@@ -12219,6 +12219,7 @@ function resolveAgentFramework(codeName) {
12219
12219
  function clearAgentCaches(agentId, codeName) {
12220
12220
  const channelCacheMutated = clearAgentState(agentId, codeName);
12221
12221
  agentChannelTokens.delete(codeName);
12222
+ forgetChannelSyncState(agentId);
12222
12223
  sharedBusyBuckets.reset(codeName);
12223
12224
  stopOpencodeSlackIngest(codeName, log);
12224
12225
  stopOpencodeTelegramIngest(codeName, log);
@@ -12252,7 +12253,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
12252
12253
  var lastVersionCheckAt = 0;
12253
12254
  var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
12254
12255
  var lastResponsivenessProbeAt = 0;
12255
- var agtCliVersion = true ? "0.28.660" : "dev";
12256
+ var agtCliVersion = true ? "0.28.662" : "dev";
12256
12257
  function resolveBrewPath(execFileSync3) {
12257
12258
  try {
12258
12259
  const out = execFileSync3("which", ["brew"], { timeout: 5e3 }).toString().trim();
@@ -13355,6 +13356,60 @@ function saveChannelHashCache2() {
13355
13356
  }
13356
13357
  var channelWriteFailureCounts = /* @__PURE__ */ new Map();
13357
13358
  var CHANNEL_WRITE_FAILURE_ESCALATE_EVERY = 90;
13359
+ var channelSyncFailures = /* @__PURE__ */ new Map();
13360
+ var channelSyncAttemptedSets = /* @__PURE__ */ new Map();
13361
+ function sameChannelSet(a, b) {
13362
+ if (a === void 0) return false;
13363
+ if (a.size !== b.size) return false;
13364
+ for (const v of b) if (!a.has(v)) return false;
13365
+ return true;
13366
+ }
13367
+ function forgetChannelSyncState(agentId) {
13368
+ channelSyncFailures.delete(agentId);
13369
+ channelSyncAttemptedSets.delete(agentId);
13370
+ }
13371
+ var CHANNEL_SYNC_FREE_ATTEMPTS = 3;
13372
+ var CHANNEL_SYNC_MAX_BACKOFF_MS = 5 * 6e4;
13373
+ var CHANNEL_SYNC_STUCK_AFTER_MS = 10 * 6e4;
13374
+ function channelSyncBackoffMs(attempts) {
13375
+ if (attempts <= CHANNEL_SYNC_FREE_ATTEMPTS) return 0;
13376
+ const step = attempts - CHANNEL_SYNC_FREE_ATTEMPTS;
13377
+ const delay = 1e4 * 2 ** (step - 1);
13378
+ return Math.min(delay, CHANNEL_SYNC_MAX_BACKOFF_MS);
13379
+ }
13380
+ function recordChannelSyncFailure(failures, agentId, reason, now) {
13381
+ const prior = failures.get(agentId);
13382
+ const attempts = (prior?.attempts ?? 0) + 1;
13383
+ const next = {
13384
+ attempts,
13385
+ since: prior?.since ?? now,
13386
+ lastReason: reason,
13387
+ loggedAtAttempt: prior?.loggedAtAttempt ?? 0,
13388
+ nextAttemptAt: now + channelSyncBackoffMs(attempts)
13389
+ };
13390
+ failures.set(agentId, next);
13391
+ return next;
13392
+ }
13393
+ function shouldLogChannelSyncFailure(state8) {
13394
+ if (state8.attempts === 1) return true;
13395
+ if (state8.attempts <= CHANNEL_SYNC_FREE_ATTEMPTS) return false;
13396
+ return state8.attempts > state8.loggedAtAttempt;
13397
+ }
13398
+ function stuckChannelSyncs(failures, now, thresholdMs = CHANNEL_SYNC_STUCK_AFTER_MS) {
13399
+ const out = [];
13400
+ for (const [agentId, state8] of failures) {
13401
+ const stuckForMs = now - state8.since;
13402
+ if (stuckForMs < thresholdMs) continue;
13403
+ out.push({
13404
+ agent_id: agentId,
13405
+ attempts: state8.attempts,
13406
+ stuck_for_seconds: Math.floor(stuckForMs / 1e3),
13407
+ reason: state8.lastReason
13408
+ });
13409
+ }
13410
+ out.sort((a, b) => b.stuck_for_seconds - a.stuck_for_seconds);
13411
+ return out;
13412
+ }
13358
13413
  var persistedDeliveryBaseline = createDeliveryBaselineMaps();
13359
13414
  function loadSenderPolicyBaseline2() {
13360
13415
  loadSenderPolicyBaseline(persistedDeliveryBaseline, channelHashCacheDir(), log);
@@ -13562,7 +13617,7 @@ function flushRestartedAgentDiagnostics(hostId, codeNames) {
13562
13617
  if (codeNames.length === 0) return;
13563
13618
  void (async () => {
13564
13619
  try {
13565
- const { collectDiagnostics } = await import("../persistent-session-ADS4LIGF.js");
13620
+ const { collectDiagnostics } = await import("../persistent-session-WOZN2ORO.js");
13566
13621
  await api.post("/host/heartbeat", {
13567
13622
  host_id: hostId,
13568
13623
  agent_diagnostics: collectDiagnostics(codeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor)
@@ -13678,7 +13733,7 @@ async function pollCycleInner() {
13678
13733
  }
13679
13734
  try {
13680
13735
  const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
13681
- const { collectDiagnostics } = await import("../persistent-session-ADS4LIGF.js");
13736
+ const { collectDiagnostics } = await import("../persistent-session-WOZN2ORO.js");
13682
13737
  const diagCodeNames = [...agentState.persistentSessionAgents];
13683
13738
  const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor) : void 0;
13684
13739
  let tailscaleHostname;
@@ -13749,6 +13804,22 @@ async function pollCycleInner() {
13749
13804
  // Omitted (undefined) on hosts that haven't run the assertion
13750
13805
  // (non-claude-code frameworks).
13751
13806
  channels_setting_status: lastManagedSettingsStatus ?? void 0,
13807
+ // ENG-9252: agents whose channel credential sync has failed to converge
13808
+ // for longer than CHANNEL_SYNC_STUCK_AFTER_MS. The API opens/closes a
13809
+ // per-agent alert on the edge, exactly as it does for
13810
+ // `channels_setting_status` above.
13811
+ //
13812
+ // This field is the whole point of the ticket. The retry loop it
13813
+ // reports on ran for over three hours on a customer host and raised
13814
+ // NOTHING: non-convergence moves no heartbeat, no session-health signal
13815
+ // and no restart counter, so every projection an operator would consult
13816
+ // read healthy while the manager span. A bounded retry that is still
13817
+ // silent would have fixed the CPU and left the invisibility.
13818
+ //
13819
+ // ALWAYS SENT, including as an empty array — that is what lets the API
13820
+ // close a resolved alert on the edge. Omitting it when empty would make
13821
+ // "recovered" and "this CLI is too old to report" the same wire value.
13822
+ channel_sync_stuck: stuckChannelSyncs(channelSyncFailures, Date.now()),
13752
13823
  // ENG-6251: capability advertisement — the flags schema version this
13753
13824
  // CLI compiled with, so the admin UI can show flip reach across a
13754
13825
  // mixed-CLI fleet (an older CLI sends an older fingerprint).
@@ -13801,7 +13872,7 @@ async function pollCycleInner() {
13801
13872
  collectPanelessActivityProbes,
13802
13873
  getResponsivenessIntervalMs,
13803
13874
  occupancyQualificationClassifications
13804
- } = await import("../responsiveness-probe-EII7QAGR.js");
13875
+ } = await import("../responsiveness-probe-APGLAESO.js");
13805
13876
  const probeIntervalMs = getResponsivenessIntervalMs();
13806
13877
  if (now - lastResponsivenessProbeAt > probeIntervalMs) {
13807
13878
  const probeCodeNames = [...agentState.persistentSessionAgents];
@@ -13911,7 +13982,7 @@ async function pollCycleInner() {
13911
13982
  collectResponsivenessProbes,
13912
13983
  livePendingInboundOldestAgeSeconds,
13913
13984
  parkPendingInbound
13914
- } = await import("../responsiveness-probe-EII7QAGR.js");
13985
+ } = await import("../responsiveness-probe-APGLAESO.js");
13915
13986
  const { getProjectDir: wedgeProjectDir } = await import("../scheduler-engine-NDP36U7O.js");
13916
13987
  const wedgeNow = /* @__PURE__ */ new Date();
13917
13988
  const liveAgents = agentState.persistentSessionAgents;
@@ -14067,7 +14138,7 @@ async function pollCycleInner() {
14067
14138
  }
14068
14139
  try {
14069
14140
  const { scrapeMcpFailedBannerCount } = await import("../pane-mcp-banner-scraper-JA437JIB.js");
14070
- const { probeSessionAuth } = await import("../session-auth-dead-TY2WU55Z.js");
14141
+ const { probeSessionAuth } = await import("../session-auth-dead-SMMFC3UF.js");
14071
14142
  const observations = [];
14072
14143
  const pendingCacheCommits = [];
14073
14144
  const modelApiErrorReportingOn = hostFlagStore().getBoolean("model-api-error-reporting");
@@ -14678,6 +14749,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
14678
14749
  const adapter = resolveAgentFramework(agent.code_name);
14679
14750
  let agentDir = join36(adapter.getAgentDir(agent.code_name), "provision");
14680
14751
  if (agent.status === "draft" || agent.status === "paused") {
14752
+ forgetChannelSyncState(agent.agent_id);
14681
14753
  if (previousKnownStatus !== agent.status) {
14682
14754
  log(`Agent '${agent.code_name}' is ${agent.status}, skipping provisioning`);
14683
14755
  }
@@ -14881,6 +14953,14 @@ async function processAgent(agent, agentStates, managedToolkits) {
14881
14953
  const previousChannelIds = agentState.knownChannels.get(agent.agent_id);
14882
14954
  const channelsChanged = !previousChannelIds || currentChannelIds.size !== previousChannelIds.size || [...currentChannelIds].some((ch) => !previousChannelIds.has(ch)) || [...previousChannelIds].some((ch) => !currentChannelIds.has(ch));
14883
14955
  let channelConfigConverged = true;
14956
+ let channelConfigFailureReason = "";
14957
+ const attemptedChannelIds = channelSyncAttemptedSets.get(agent.agent_id);
14958
+ const channelSetChangedSinceAttempt = !sameChannelSet(attemptedChannelIds, currentChannelIds);
14959
+ if (attemptedChannelIds !== void 0 && channelSetChangedSinceAttempt && channelSyncFailures.delete(agent.agent_id)) {
14960
+ log(
14961
+ `[channels] channel set changed for '${agent.code_name}' since the last attempt \u2014 clearing the credential-sync backoff and retrying immediately (ENG-9252)`
14962
+ );
14963
+ }
14884
14964
  if (previousChannelIds && channelsChanged && frameworkAdapter.removeChannelCredentials) {
14885
14965
  for (const ch of previousChannelIds) {
14886
14966
  if (!currentChannelIds.has(ch)) {
@@ -14889,6 +14969,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
14889
14969
  log(`Removed ${ch} credentials for '${agent.code_name}'`);
14890
14970
  } catch (err) {
14891
14971
  channelConfigConverged = false;
14972
+ channelConfigFailureReason = `removing ${ch} credentials threw: ${err.message}`;
14892
14973
  log(`Failed to remove ${ch} credentials for '${agent.code_name}': ${err.message}`);
14893
14974
  }
14894
14975
  }
@@ -15152,7 +15233,12 @@ async function processAgent(agent, agentStates, managedToolkits) {
15152
15233
  agentChannelTokens.delete(agent.code_name);
15153
15234
  }
15154
15235
  }
15155
- if (refreshData.channel_configs && frameworkAdapter.writeChannelCredentials) {
15236
+ const channelSyncBackoff = channelSyncFailures.get(agent.agent_id);
15237
+ const channelSyncDeferred = channelSyncBackoff !== void 0 && Date.now() < channelSyncBackoff.nextAttemptAt;
15238
+ if (!channelSyncDeferred) {
15239
+ channelSyncAttemptedSets.set(agent.agent_id, new Set(currentChannelIds));
15240
+ }
15241
+ if (refreshData.channel_configs && frameworkAdapter.writeChannelCredentials && !channelSyncDeferred) {
15156
15242
  if (agent.status === "active") {
15157
15243
  for (const [channelId, entry] of Object.entries(refreshData.channel_configs)) {
15158
15244
  if (quarantinedChannels.has(channelId)) {
@@ -15257,6 +15343,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
15257
15343
  const landed = frameworkAdapter.hasChannelCredentials?.(agent.code_name, channelId) ?? true;
15258
15344
  if (!landed) {
15259
15345
  channelConfigConverged = false;
15346
+ channelConfigFailureReason = `credentials for ${channelId} reported a clean write but did not land on disk (reason=${reason}) \u2014 likely a missing credential field, or the guarded .mcp.json write was rejected by the secret lint / config validator`;
15260
15347
  const attempts = (channelWriteFailureCounts.get(cacheKey) ?? 0) + 1;
15261
15348
  channelWriteFailureCounts.set(cacheKey, attempts);
15262
15349
  if (attempts === 1 || attempts % CHANNEL_WRITE_FAILURE_ESCALATE_EVERY === 0) {
@@ -15274,6 +15361,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
15274
15361
  }
15275
15362
  } catch (err) {
15276
15363
  channelConfigConverged = false;
15364
+ channelConfigFailureReason = `writing ${channelId} credentials threw: ${err.message}`;
15277
15365
  log(`Failed to write channel credentials for '${agent.code_name}/${channelId}': ${err.message}`);
15278
15366
  }
15279
15367
  }
@@ -15287,11 +15375,35 @@ async function processAgent(agent, agentStates, managedToolkits) {
15287
15375
  }
15288
15376
  }
15289
15377
  if (channelConfigConverged) {
15290
- agentState.knownChannels.set(agent.agent_id, currentChannelIds);
15378
+ const ended = channelSyncFailures.get(agent.agent_id);
15379
+ if (ended && !channelSyncDeferred) {
15380
+ channelSyncFailures.delete(agent.agent_id);
15381
+ const stuckForSeconds = Math.floor((Date.now() - ended.since) / 1e3);
15382
+ log(
15383
+ `[channels] Credential sync for '${agent.code_name}' converged after ${ended.attempts} failed attempt(s) over ${stuckForSeconds}s \u2014 recovered (ENG-9252)`
15384
+ );
15385
+ }
15386
+ if (!channelSyncDeferred) {
15387
+ agentState.knownChannels.set(agent.agent_id, currentChannelIds);
15388
+ }
15291
15389
  } else {
15292
- log(`[channels] Credential sync did not converge for '${agent.code_name}' \u2014 leaving diff live for next tick retry`);
15390
+ const state8 = recordChannelSyncFailure(
15391
+ channelSyncFailures,
15392
+ agent.agent_id,
15393
+ channelConfigFailureReason || "reason not recorded",
15394
+ Date.now()
15395
+ );
15396
+ if (shouldLogChannelSyncFailure(state8)) {
15397
+ state8.loggedAtAttempt = state8.attempts;
15398
+ const stuckForSeconds = Math.floor((Date.now() - state8.since) / 1e3);
15399
+ const waitMs = channelSyncBackoffMs(state8.attempts);
15400
+ log(
15401
+ `[channels] Credential sync did not converge for '${agent.code_name}' \u2014 attempt ${state8.attempts}, stuck ${stuckForSeconds}s, next retry in ${Math.round(waitMs / 1e3)}s. Cause: ${state8.lastReason}. Diff left live (ENG-9252).`
15402
+ );
15403
+ }
15293
15404
  }
15294
- const restartDecision = channelConfigConverged ? decideChannelRestart({
15405
+ const channelConfigConvergedThisTick = channelConfigConverged && !channelSyncDeferred;
15406
+ const restartDecision = channelConfigConvergedThisTick ? decideChannelRestart({
15295
15407
  previousChannelIds,
15296
15408
  currentChannelIds,
15297
15409
  sessionMode: refreshData.agent.session_mode,
@@ -15343,7 +15455,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
15343
15455
  writeDmNoticeMarkers
15344
15456
  );
15345
15457
  }
15346
- if (channelConfigConverged) {
15458
+ if (channelConfigConvergedThisTick) {
15347
15459
  const hasSenderPolicyChannel = currentChannelIds.has("slack") || currentChannelIds.has("msteams");
15348
15460
  const senderPolicyForRestartHash = refreshData.sender_policy ?? null;
15349
15461
  const senderPolicyHash = computeSenderPolicyRestartHash(senderPolicyForRestartHash);
@@ -16376,7 +16488,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
16376
16488
  } catch (err) {
16377
16489
  log(`[hot-reload] .mcp.json drift check failed for '${agent.code_name}': ${err.message}`);
16378
16490
  }
16379
- if (channelConfigConverged) {
16491
+ if (channelConfigConvergedThisTick) {
16380
16492
  try {
16381
16493
  checkChannelSecretDriftAndScheduleRestart(agent.code_name, getProjectDir(agent.code_name));
16382
16494
  } catch (err) {
@@ -17700,7 +17812,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
17700
17812
  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}`));
17701
17813
  void (async () => {
17702
17814
  try {
17703
- const { collectDiagnostics } = await import("../persistent-session-ADS4LIGF.js");
17815
+ const { collectDiagnostics } = await import("../persistent-session-WOZN2ORO.js");
17704
17816
  await api.post("/host/heartbeat", {
17705
17817
  host_id: hostId,
17706
17818
  agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor)
@@ -17751,7 +17863,7 @@ async function respawnAgentAfterMcpStop(codeName, reason) {
17751
17863
  }
17752
17864
  try {
17753
17865
  const hostId = await getHostId();
17754
- const { collectDiagnostics } = await import("../persistent-session-ADS4LIGF.js");
17866
+ const { collectDiagnostics } = await import("../persistent-session-WOZN2ORO.js");
17755
17867
  await api.post("/host/heartbeat", {
17756
17868
  host_id: hostId,
17757
17869
  agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor)
@@ -18348,7 +18460,7 @@ async function processClaudePairSessions(agents) {
18348
18460
  killPairSession,
18349
18461
  pairTmuxSession,
18350
18462
  finalizeClaudePairOnboarding
18351
- } = await import("../claude-pair-runtime-JMESZQPN.js");
18463
+ } = await import("../claude-pair-runtime-AAHU6VUL.js");
18352
18464
  for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
18353
18465
  log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
18354
18466
  const killed = await killPairSession(pairTmuxSession(pairId));
@@ -19314,12 +19426,16 @@ process.on("disconnect", () => {
19314
19426
  });
19315
19427
  export {
19316
19428
  BACK_ONLINE_GREETING_GUIDANCE,
19429
+ CHANNEL_SYNC_FREE_ATTEMPTS,
19430
+ CHANNEL_SYNC_MAX_BACKOFF_MS,
19431
+ CHANNEL_SYNC_STUCK_AFTER_MS,
19317
19432
  DAY_ROLLOVER_FORCE_GRACE_MIN,
19318
19433
  DAY_ROLLOVER_INBOUND_DEFER_MAX_MIN,
19319
19434
  DAY_ROLLOVER_INBOUND_GRACE_SEC,
19320
19435
  UntrustworthyToolkitResponseError,
19321
19436
  applyRestartAcks,
19322
19437
  cancelKanbanNoticeOnDrain,
19438
+ channelSyncBackoffMs,
19323
19439
  classifyLazyDayRolloverReset,
19324
19440
  claudeCodeUpgradeMarkerPath,
19325
19441
  claudeCodeUpgradeThrottled,
@@ -19334,6 +19450,7 @@ export {
19334
19450
  extractCharterSlackPeers,
19335
19451
  extractCharterTelegramPeers,
19336
19452
  fetchManagedToolkits,
19453
+ forgetChannelSyncState,
19337
19454
  hasRevokedResiduals,
19338
19455
  inboundHoldMinutes,
19339
19456
  isOlderSemverTuple,
@@ -19342,10 +19459,13 @@ export {
19342
19459
  maybeInjectKanbanCheck,
19343
19460
  maybeProbeClaudeRuntimeAuth,
19344
19461
  maybeUpgradeClaudeCode,
19462
+ recordChannelSyncFailure,
19345
19463
  refreshSkillsIndexInClaudeMd,
19346
19464
  reorderRestartedFirst,
19347
19465
  resolveManagedMcpServerId,
19348
19466
  restartReasonBindsNewMcp,
19467
+ sameChannelSet,
19468
+ shouldLogChannelSyncFailure,
19349
19469
  shouldReapOnRetag,
19350
19470
  shouldReportRestartToAudit,
19351
19471
  shouldSkipRevokedCleanup,
@@ -19353,6 +19473,7 @@ export {
19353
19473
  stampClaudeCodeUpgradeMarker,
19354
19474
  startManager,
19355
19475
  stopManager,
19476
+ stuckChannelSyncs,
19356
19477
  supersededRuntimeImageIds
19357
19478
  };
19358
19479
  //# sourceMappingURL=manager-worker.js.map