@adhdev/daemon-standalone 1.0.58-rc.4 → 1.0.58-rc.6

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/index.js CHANGED
@@ -63,6 +63,7 @@ var require_config_dir = __commonJS({
63
63
  detectOccupiedConfigDir: () => detectOccupiedConfigDir2,
64
64
  formatOccupiedConfigDirWarning: () => formatOccupiedConfigDirWarning2,
65
65
  isCrossTrackConfigDirOverride: () => isCrossTrackConfigDirOverride,
66
+ isTestRuntimeEnv: () => isTestRuntimeEnv,
66
67
  otherTrackConfigDir: () => otherTrackConfigDir,
67
68
  resolveConfigDir: () => resolveConfigDir,
68
69
  resolveConfigLogsDir: () => resolveConfigLogsDir
@@ -104,17 +105,56 @@ var require_config_dir = __commonJS({
104
105
  }
105
106
  var IDENTITY = getTrackIdentity(TRACK);
106
107
  var DEFAULT_CONFIG_DIR_NAME = ".adhdev";
108
+ function isTestRuntimeEnv(env2 = process.env) {
109
+ if (env2.VITEST) return true;
110
+ if (env2.NODE_ENV === "test") return true;
111
+ if (env2.NODE_TEST_CONTEXT) return true;
112
+ return false;
113
+ }
107
114
  function resolveConfigDir(env2 = process.env, homeDir) {
108
115
  const override = env2.ADHDEV_CONFIG_DIR;
109
- if (override && override.trim()) return override.trim();
110
- assertConfigDirPinnedInTestRuntime(env2);
116
+ if (override && override.trim()) {
117
+ const resolved = override.trim();
118
+ assertConfigDirIsolatedInTestRuntime(env2, resolved);
119
+ return resolved;
120
+ }
121
+ assertConfigDirIsolatedInTestRuntime(env2);
111
122
  return (0, import_path2.join)(homeDir ?? (0, import_os2.homedir)(), getTrackIdentity(resolveBuildTrack(env2)).configDirName);
112
123
  }
113
- function assertConfigDirPinnedInTestRuntime(env2) {
124
+ function normalizeConfigPath(p, platform = process.platform) {
125
+ const unified = p.trim().replace(/[\\/]+$/, "").replace(/\\/g, "/");
126
+ return platform === "win32" ? unified.toLowerCase() : unified;
127
+ }
128
+ function liveTrackHomeDirs(homeDir = (0, import_os2.homedir)()) {
129
+ return [
130
+ (0, import_path2.join)(homeDir, getTrackIdentity("stable").configDirName),
131
+ (0, import_path2.join)(homeDir, getTrackIdentity("preview").configDirName)
132
+ ];
133
+ }
134
+ var ORIGINAL_HOME_DIR = typeof process.env.HOME === "string" && process.env.HOME.trim() !== "" ? process.env.HOME.trim() : typeof process.env.USERPROFILE === "string" ? process.env.USERPROFILE.trim() : "";
135
+ function isLiveTrackHomeDir(resolved, homeDir) {
136
+ const needle = normalizeConfigPath(resolved);
137
+ const bases = homeDir !== void 0 ? [homeDir] : [ORIGINAL_HOME_DIR].filter((v) => v !== "");
138
+ return bases.some((base) => liveTrackHomeDirs(base).some((live) => normalizeConfigPath(live) === needle));
139
+ }
140
+ function processLooksLikeNodeTestRunner() {
141
+ return process.execArgv.some((arg) => arg === "--test" || arg.startsWith("--test="));
142
+ }
143
+ function assertConfigDirIsolatedInTestRuntime(env2, resolvedOverride) {
114
144
  if (env2 !== process.env) return;
115
- if (!env2.VITEST && env2.NODE_ENV !== "test") return;
145
+ if (!isTestRuntimeEnv(env2) && !processLooksLikeNodeTestRunner()) return;
146
+ if (resolvedOverride) {
147
+ if (isLiveTrackHomeDir(resolvedOverride)) {
148
+ throw new Error(
149
+ `resolveConfigDir() is pinned to the LIVE ~/.adhdev(-preview) dir in a test runtime: a test inherited or re-assigned ADHDEV_CONFIG_DIR to the developer's real state dir (${resolvedOverride}). Pin ADHDEV_CONFIG_DIR to a tmp dir in test setup, or pass an explicit env/homeDir to resolveConfigDir.`
150
+ );
151
+ }
152
+ return;
153
+ }
154
+ const fallbackDir = (0, import_path2.join)((0, import_os2.homedir)(), getTrackIdentity(resolveBuildTrack(env2)).configDirName);
155
+ if (!isLiveTrackHomeDir(fallbackDir)) return;
116
156
  throw new Error(
117
- "resolveConfigDir() reached the real-home fallback in a test runtime with ADHDEV_CONFIG_DIR unset: a test is about to touch the LIVE ~/.adhdev(-preview) state dir. Pin ADHDEV_CONFIG_DIR to a tmp dir in test setup, or pass an explicit env/homeDir to resolveConfigDir."
157
+ `resolveConfigDir() reached the real-home fallback in a test runtime with ADHDEV_CONFIG_DIR unset: a test is about to touch the LIVE ${fallbackDir} state dir. Pin ADHDEV_CONFIG_DIR to a tmp dir in test setup, or pass an explicit env/homeDir to resolveConfigDir.`
118
158
  );
119
159
  }
120
160
  function resolveConfigLogsDir(env2 = process.env, homeDir) {
@@ -31632,9 +31672,9 @@ var require_streamx = __commonJS({
31632
31672
  }
31633
31673
  });
31634
31674
 
31635
- // ../../node_modules/tar-stream/node_modules/b4a/index.js
31675
+ // ../daemon-core/node_modules/b4a/index.js
31636
31676
  var require_b4a2 = __commonJS({
31637
- "../../node_modules/tar-stream/node_modules/b4a/index.js"(exports2, module2) {
31677
+ "../daemon-core/node_modules/b4a/index.js"(exports2, module2) {
31638
31678
  "use strict";
31639
31679
  function isBuffer(value) {
31640
31680
  return Buffer.isBuffer(value) || value instanceof Uint8Array;
@@ -31790,9 +31830,9 @@ var require_b4a2 = __commonJS({
31790
31830
  }
31791
31831
  });
31792
31832
 
31793
- // ../../node_modules/tar-stream/headers.js
31833
+ // ../daemon-core/node_modules/tar-stream/headers.js
31794
31834
  var require_headers = __commonJS({
31795
- "../../node_modules/tar-stream/headers.js"(exports2) {
31835
+ "../daemon-core/node_modules/tar-stream/headers.js"(exports2) {
31796
31836
  "use strict";
31797
31837
  var b4a = require_b4a2();
31798
31838
  var ZEROS = "0000000000000000000";
@@ -32053,9 +32093,9 @@ var require_headers = __commonJS({
32053
32093
  }
32054
32094
  });
32055
32095
 
32056
- // ../../node_modules/tar-stream/extract.js
32096
+ // ../daemon-core/node_modules/tar-stream/extract.js
32057
32097
  var require_extract = __commonJS({
32058
- "../../node_modules/tar-stream/extract.js"(exports2, module2) {
32098
+ "../daemon-core/node_modules/tar-stream/extract.js"(exports2, module2) {
32059
32099
  "use strict";
32060
32100
  var { Writable, Readable, getStreamError } = require_streamx();
32061
32101
  var FIFO = require_fast_fifo();
@@ -32398,9 +32438,9 @@ var require_extract = __commonJS({
32398
32438
  }
32399
32439
  });
32400
32440
 
32401
- // ../../node_modules/tar-stream/constants.js
32441
+ // ../daemon-core/node_modules/tar-stream/constants.js
32402
32442
  var require_constants = __commonJS({
32403
- "../../node_modules/tar-stream/constants.js"(exports2, module2) {
32443
+ "../daemon-core/node_modules/tar-stream/constants.js"(exports2, module2) {
32404
32444
  "use strict";
32405
32445
  var constants = {
32406
32446
  // just for envs without fs
@@ -32419,9 +32459,9 @@ var require_constants = __commonJS({
32419
32459
  }
32420
32460
  });
32421
32461
 
32422
- // ../../node_modules/tar-stream/pack.js
32462
+ // ../daemon-core/node_modules/tar-stream/pack.js
32423
32463
  var require_pack = __commonJS({
32424
- "../../node_modules/tar-stream/pack.js"(exports2, module2) {
32464
+ "../daemon-core/node_modules/tar-stream/pack.js"(exports2, module2) {
32425
32465
  "use strict";
32426
32466
  var { Readable, Writable, getStreamError } = require_streamx();
32427
32467
  var b4a = require_b4a2();
@@ -32654,9 +32694,9 @@ var require_pack = __commonJS({
32654
32694
  }
32655
32695
  });
32656
32696
 
32657
- // ../../node_modules/tar-stream/index.js
32697
+ // ../daemon-core/node_modules/tar-stream/index.js
32658
32698
  var require_tar_stream = __commonJS({
32659
- "../../node_modules/tar-stream/index.js"(exports2) {
32699
+ "../daemon-core/node_modules/tar-stream/index.js"(exports2) {
32660
32700
  "use strict";
32661
32701
  exports2.extract = require_extract();
32662
32702
  exports2.pack = require_pack();
@@ -32899,9 +32939,9 @@ var require_pump = __commonJS({
32899
32939
  }
32900
32940
  });
32901
32941
 
32902
- // ../../node_modules/tar-fs/index.js
32942
+ // ../daemon-core/node_modules/tar-fs/index.js
32903
32943
  var require_tar_fs = __commonJS({
32904
- "../../node_modules/tar-fs/index.js"(exports2) {
32944
+ "../daemon-core/node_modules/tar-fs/index.js"(exports2) {
32905
32945
  "use strict";
32906
32946
  var tar = require_tar_stream();
32907
32947
  var pump = require_pump();
@@ -36831,10 +36871,10 @@ var require_dist3 = __commonJS({
36831
36871
  }
36832
36872
  function getDaemonBuildInfo() {
36833
36873
  if (cached2) return cached2;
36834
- const commit = readInjected(true ? "388d6e74b391ae9afd94d860aed141063297dca9" : void 0) ?? "unknown";
36835
- const commitShort = readInjected(true ? "388d6e74" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
36836
- const version2 = readInjected(true ? "1.0.58-rc.4" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
36837
- const builtAt = readInjected(true ? "2026-08-23T04:11:22.908Z" : void 0);
36874
+ const commit = readInjected(true ? "671c36c8e29818de2b734954da347d681324d185" : void 0) ?? "unknown";
36875
+ const commitShort = readInjected(true ? "671c36c8" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
36876
+ const version2 = readInjected(true ? "1.0.58-rc.6" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
36877
+ const builtAt = readInjected(true ? "2026-08-23T15:46:11.432Z" : void 0);
36838
36878
  cached2 = builtAt ? { commit, commitShort, version: version2, builtAt } : { commit, commitShort, version: version2 };
36839
36879
  return cached2;
36840
36880
  }
@@ -38030,8 +38070,20 @@ var require_dist3 = __commonJS({
38030
38070
  static buffers = /* @__PURE__ */ new Map();
38031
38071
  static writePromises = /* @__PURE__ */ new Map();
38032
38072
  static flushTimer = null;
38073
+ static pendingBytes = /* @__PURE__ */ new Map();
38074
+ /**
38075
+ * Line/byte ceilings that force a synchronous flush. Sized so an idle daemon
38076
+ * never reaches them (the 50ms timer wins) while a loop-blocking handler
38077
+ * still gets its lines out: the status tick emits on the order of tens of
38078
+ * lines, so 64 lines bounds a stalled window to roughly one tick's worth.
38079
+ */
38080
+ static MAX_PENDING_LINES = 64;
38081
+ static MAX_PENDING_BYTES = 64 * 1024;
38033
38082
  /**
38034
38083
  * Queues data to be written to a file asynchronously in a batch.
38084
+ *
38085
+ * Crossing either pending threshold flushes synchronously before returning,
38086
+ * so a caller on a blocked event loop still lands its line on disk.
38035
38087
  */
38036
38088
  static write(filePath, data) {
38037
38089
  let buf = this.buffers.get(filePath);
@@ -38040,6 +38092,12 @@ var require_dist3 = __commonJS({
38040
38092
  this.buffers.set(filePath, buf);
38041
38093
  }
38042
38094
  buf.push(data);
38095
+ const bytes = (this.pendingBytes.get(filePath) ?? 0) + Buffer.byteLength(data);
38096
+ this.pendingBytes.set(filePath, bytes);
38097
+ if (buf.length >= this.MAX_PENDING_LINES || bytes >= this.MAX_PENDING_BYTES) {
38098
+ this.flushPathSync(filePath);
38099
+ return;
38100
+ }
38043
38101
  if (!this.flushTimer) {
38044
38102
  this.flushTimer = setTimeout(() => {
38045
38103
  this.flushTimer = null;
@@ -38047,9 +38105,35 @@ var require_dist3 = __commonJS({
38047
38105
  }, 50);
38048
38106
  }
38049
38107
  }
38108
+ /**
38109
+ * Synchronously drain every buffered path. Safe to call from shutdown
38110
+ * handlers and from code that has just blocked (or is about to block) the
38111
+ * event loop. Best-effort: never throws.
38112
+ */
38113
+ static flushSync() {
38114
+ if (this.flushTimer) {
38115
+ clearTimeout(this.flushTimer);
38116
+ this.flushTimer = null;
38117
+ }
38118
+ for (const filePath of Array.from(this.buffers.keys())) {
38119
+ this.flushPathSync(filePath);
38120
+ }
38121
+ }
38122
+ /** Append one path's pending buffer with a blocking write. Never throws. */
38123
+ static flushPathSync(filePath) {
38124
+ const buffer = this.buffers.get(filePath);
38125
+ this.buffers.delete(filePath);
38126
+ this.pendingBytes.delete(filePath);
38127
+ if (!buffer || buffer.length === 0) return;
38128
+ try {
38129
+ fs4.appendFileSync(filePath, buffer.join(""), { encoding: "utf-8", mode: 384 });
38130
+ } catch {
38131
+ }
38132
+ }
38050
38133
  static async flushAll() {
38051
38134
  const entries = Array.from(this.buffers.entries());
38052
38135
  this.buffers.clear();
38136
+ this.pendingBytes.clear();
38053
38137
  for (const [filePath, buffer] of entries) {
38054
38138
  const dataToWrite = buffer.join("");
38055
38139
  const doWrite = async () => {
@@ -38126,17 +38210,55 @@ var require_dist3 = __commonJS({
38126
38210
  IDENTITY = getTrackIdentity(TRACK);
38127
38211
  }
38128
38212
  });
38213
+ function isTestRuntimeEnv(env2 = process.env) {
38214
+ if (env2.VITEST) return true;
38215
+ if (env2.NODE_ENV === "test") return true;
38216
+ if (env2.NODE_TEST_CONTEXT) return true;
38217
+ return false;
38218
+ }
38129
38219
  function resolveConfigDir(env2 = process.env, homeDir) {
38130
38220
  const override = env2.ADHDEV_CONFIG_DIR;
38131
- if (override && override.trim()) return override.trim();
38132
- assertConfigDirPinnedInTestRuntime(env2);
38221
+ if (override && override.trim()) {
38222
+ const resolved = override.trim();
38223
+ assertConfigDirIsolatedInTestRuntime(env2, resolved);
38224
+ return resolved;
38225
+ }
38226
+ assertConfigDirIsolatedInTestRuntime(env2);
38133
38227
  return (0, import_path3.join)(homeDir ?? (0, import_os2.homedir)(), getTrackIdentity(resolveBuildTrack(env2)).configDirName);
38134
38228
  }
38135
- function assertConfigDirPinnedInTestRuntime(env2) {
38229
+ function normalizeConfigPath(p, platform10 = process.platform) {
38230
+ const unified = p.trim().replace(/[\\/]+$/, "").replace(/\\/g, "/");
38231
+ return platform10 === "win32" ? unified.toLowerCase() : unified;
38232
+ }
38233
+ function liveTrackHomeDirs(homeDir = (0, import_os2.homedir)()) {
38234
+ return [
38235
+ (0, import_path3.join)(homeDir, getTrackIdentity("stable").configDirName),
38236
+ (0, import_path3.join)(homeDir, getTrackIdentity("preview").configDirName)
38237
+ ];
38238
+ }
38239
+ function isLiveTrackHomeDir(resolved, homeDir) {
38240
+ const needle = normalizeConfigPath(resolved);
38241
+ const bases = homeDir !== void 0 ? [homeDir] : [ORIGINAL_HOME_DIR].filter((v) => v !== "");
38242
+ return bases.some((base) => liveTrackHomeDirs(base).some((live) => normalizeConfigPath(live) === needle));
38243
+ }
38244
+ function processLooksLikeNodeTestRunner() {
38245
+ return process.execArgv.some((arg) => arg === "--test" || arg.startsWith("--test="));
38246
+ }
38247
+ function assertConfigDirIsolatedInTestRuntime(env2, resolvedOverride) {
38136
38248
  if (env2 !== process.env) return;
38137
- if (!env2.VITEST && env2.NODE_ENV !== "test") return;
38249
+ if (!isTestRuntimeEnv(env2) && !processLooksLikeNodeTestRunner()) return;
38250
+ if (resolvedOverride) {
38251
+ if (isLiveTrackHomeDir(resolvedOverride)) {
38252
+ throw new Error(
38253
+ `resolveConfigDir() is pinned to the LIVE ~/.adhdev(-preview) dir in a test runtime: a test inherited or re-assigned ADHDEV_CONFIG_DIR to the developer's real state dir (${resolvedOverride}). Pin ADHDEV_CONFIG_DIR to a tmp dir in test setup, or pass an explicit env/homeDir to resolveConfigDir.`
38254
+ );
38255
+ }
38256
+ return;
38257
+ }
38258
+ const fallbackDir = (0, import_path3.join)((0, import_os2.homedir)(), getTrackIdentity(resolveBuildTrack(env2)).configDirName);
38259
+ if (!isLiveTrackHomeDir(fallbackDir)) return;
38138
38260
  throw new Error(
38139
- "resolveConfigDir() reached the real-home fallback in a test runtime with ADHDEV_CONFIG_DIR unset: a test is about to touch the LIVE ~/.adhdev(-preview) state dir. Pin ADHDEV_CONFIG_DIR to a tmp dir in test setup, or pass an explicit env/homeDir to resolveConfigDir."
38261
+ `resolveConfigDir() reached the real-home fallback in a test runtime with ADHDEV_CONFIG_DIR unset: a test is about to touch the LIVE ${fallbackDir} state dir. Pin ADHDEV_CONFIG_DIR to a tmp dir in test setup, or pass an explicit env/homeDir to resolveConfigDir.`
38140
38262
  );
38141
38263
  }
38142
38264
  function resolveConfigLogsDir(env2 = process.env, homeDir) {
@@ -38166,12 +38288,14 @@ var require_dist3 = __commonJS({
38166
38288
  }
38167
38289
  var import_os2;
38168
38290
  var import_path3;
38291
+ var ORIGINAL_HOME_DIR;
38169
38292
  var init_config_dir = __esm2({
38170
38293
  "src/config/config-dir.ts"() {
38171
38294
  "use strict";
38172
38295
  import_os2 = require("os");
38173
38296
  import_path3 = require("path");
38174
38297
  init_track_identity();
38298
+ ORIGINAL_HOME_DIR = typeof process.env.HOME === "string" && process.env.HOME.trim() !== "" ? process.env.HOME.trim() : typeof process.env.USERPROFILE === "string" ? process.env.USERPROFILE.trim() : "";
38175
38299
  }
38176
38300
  });
38177
38301
  function setLogLevel(level) {
@@ -38831,6 +38955,13 @@ var require_dist3 = __commonJS({
38831
38955
  MACHINE_ID_PREFIX = "mach_";
38832
38956
  }
38833
38957
  });
38958
+ function assertInjectedNetworkFetchInTest(overrides, caller) {
38959
+ if (overrides.fetch) return;
38960
+ if (!isTestRuntimeEnv()) return;
38961
+ throw new Error(
38962
+ `${caller}() in a test runtime without an injected fetch: this would hit a live provider endpoint. Mock the fetcher module, or pass deps.fetch (see test/quota/grok-quota.test.ts).`
38963
+ );
38964
+ }
38834
38965
  function resolveDeps(overrides = {}) {
38835
38966
  return {
38836
38967
  fetch: overrides.fetch ?? ((url2, init) => fetch(url2, init)),
@@ -38858,6 +38989,7 @@ var require_dist3 = __commonJS({
38858
38989
  "src/quota/fetchers/deps.ts"() {
38859
38990
  "use strict";
38860
38991
  import_node_child_process2 = require("child_process");
38992
+ init_config_dir();
38861
38993
  init_config();
38862
38994
  }
38863
38995
  });
@@ -39173,6 +39305,7 @@ var require_dist3 = __commonJS({
39173
39305
  return Number.isNaN(at) ? void 0 : at;
39174
39306
  }
39175
39307
  async function fetchAntigravityQuota2(overrides = {}) {
39308
+ assertInjectedNetworkFetchInTest(overrides, "fetchAntigravityQuota");
39176
39309
  const deps = resolveDeps(overrides);
39177
39310
  const credentialsResult = await readCredentials(deps);
39178
39311
  if (credentialsResult.kind === "unsupported-platform") {
@@ -40795,6 +40928,7 @@ child.on('exit', () => process.exit(0));
40795
40928
  return Number.isNaN(at) ? void 0 : at;
40796
40929
  }
40797
40930
  async function fetchGrokQuota2(overrides = {}) {
40931
+ assertInjectedNetworkFetchInTest(overrides, "fetchGrokQuota");
40798
40932
  const deps = resolveDeps(overrides);
40799
40933
  const credentialsResult = readCredentials2(deps);
40800
40934
  if (credentialsResult.kind === "missing") {
@@ -41034,6 +41168,7 @@ child.on('exit', () => process.exit(0));
41034
41168
  return Number.isNaN(at) ? void 0 : at;
41035
41169
  }
41036
41170
  async function fetchKimiQuota2(overrides = {}) {
41171
+ assertInjectedNetworkFetchInTest(overrides, "fetchKimiQuota");
41037
41172
  const deps = resolveDeps(overrides);
41038
41173
  const credentialsResult = readCredentials3(deps);
41039
41174
  if (credentialsResult.kind === "missing") {
@@ -41389,6 +41524,15 @@ child.on('exit', () => process.exit(0));
41389
41524
  if (cache.size === 0) return void 0;
41390
41525
  return Object.fromEntries(cache);
41391
41526
  }
41527
+ function notifyQuotaCacheChanged() {
41528
+ const listener = quotaCacheChangedListener;
41529
+ if (!listener) return;
41530
+ try {
41531
+ listener();
41532
+ } catch (e) {
41533
+ LOG2.warn("Quota", `Quota cache-change listener failed: ${e?.message || e}`);
41534
+ }
41535
+ }
41392
41536
  function hasFreshlyMeasuredQuota() {
41393
41537
  for (const provider of cache.keys()) {
41394
41538
  if (!hydratedOnly.has(provider)) return true;
@@ -41467,6 +41611,7 @@ child.on('exit', () => process.exit(0));
41467
41611
  }
41468
41612
  const snapshot = readQuotaCache();
41469
41613
  if (snapshot) saveQuotaCache(snapshot);
41614
+ notifyQuotaCacheChanged();
41470
41615
  }
41471
41616
  function cancelFailureRetry(provider) {
41472
41617
  const state = failureRetries.get(provider);
@@ -41532,13 +41677,81 @@ child.on('exit', () => process.exit(0));
41532
41677
  }
41533
41678
  return false;
41534
41679
  }
41680
+ function computeNextWakeDelayMs(fetchers, isEnabled, active, now = Date.now()) {
41681
+ if (!isEnabled) return void 0;
41682
+ let nextAt = Number.POSITIVE_INFINITY;
41683
+ for (const { provider } of fetchers) {
41684
+ if (!isEnabled(provider)) continue;
41685
+ const entry = cache.get(provider);
41686
+ if (!entry) return 0;
41687
+ if (entry.status !== "ok") {
41688
+ const retryAtMs = entry.metadata?.retryAtMs;
41689
+ if (typeof retryAtMs === "number" && (failureRetries.get(provider)?.failures ?? 0) <= QUOTA_FAILURE_MAX_RETRIES) {
41690
+ nextAt = Math.min(nextAt, retryAtMs);
41691
+ }
41692
+ }
41693
+ const updatedAtMs = Number(entry.updatedAt);
41694
+ const dataDueAt = Number.isFinite(updatedAtMs) && updatedAtMs > 0 ? updatedAtMs + QUOTA_ROUTABLE_MAX_AGE_MS : Number.NEGATIVE_INFINITY;
41695
+ const attemptedAt = lastAttemptAt(entry);
41696
+ const attemptDueAt = attemptedAt === void 0 ? Number.NEGATIVE_INFINITY : attemptedAt + QUOTA_ROUTABLE_MAX_AGE_MS;
41697
+ nextAt = Math.min(nextAt, Math.max(dataDueAt, attemptDueAt));
41698
+ if (active) {
41699
+ const ttl = QUOTA_AXIS_TTL_MS[provider];
41700
+ if (Number.isFinite(ttl)) {
41701
+ nextAt = Math.min(nextAt, attemptedAt === void 0 ? now : attemptedAt + ttl);
41702
+ }
41703
+ }
41704
+ }
41705
+ if (!Number.isFinite(nextAt)) return void 0;
41706
+ return Math.max(nextAt - now, 0);
41707
+ }
41535
41708
  function startQuotaRefreshLoop(options) {
41536
41709
  const intervalMs = options.intervalMs ?? QUOTA_REFRESH_INTERVAL_MS;
41537
41710
  const fetchers = options.fetchers ?? REFRESHERS;
41538
41711
  if (options.isEnabled) ambientIsEnabled = options.isEnabled;
41539
41712
  let running = false;
41540
- const timer = setInterval(() => {
41541
- if (running) return;
41713
+ let stopped = false;
41714
+ let timer = null;
41715
+ const scheduleNext = () => {
41716
+ if (stopped) return;
41717
+ if (timer) {
41718
+ clearTimeout(timer);
41719
+ timer = null;
41720
+ }
41721
+ let delayMs = intervalMs;
41722
+ try {
41723
+ let active = false;
41724
+ try {
41725
+ active = options.hasRecentCliActivity();
41726
+ } catch {
41727
+ active = false;
41728
+ }
41729
+ const computed = computeNextWakeDelayMs(fetchers, options.isEnabled, active);
41730
+ if (computed !== void 0) {
41731
+ delayMs = Math.max(computed, MIN_CHAIN_WAKE_DELAY_MS);
41732
+ delayMs = Math.min(delayMs, QUOTA_ROUTABLE_MAX_AGE_MS);
41733
+ if (options.isEnabled && fetchers.some(({ provider }) => !options.isEnabled(provider))) {
41734
+ delayMs = Math.min(delayMs, intervalMs);
41735
+ }
41736
+ }
41737
+ } catch {
41738
+ delayMs = intervalMs;
41739
+ }
41740
+ timer = setTimeout(runWake, delayMs);
41741
+ if (typeof timer.unref === "function") timer.unref();
41742
+ };
41743
+ const rescheduleFromOutside = () => {
41744
+ if (stopped || running) return;
41745
+ scheduleNext();
41746
+ };
41747
+ quotaCacheChangedListener = rescheduleFromOutside;
41748
+ const runWake = () => {
41749
+ timer = null;
41750
+ if (stopped) return;
41751
+ if (running) {
41752
+ scheduleNext();
41753
+ return;
41754
+ }
41542
41755
  let active = false;
41543
41756
  try {
41544
41757
  active = options.hasRecentCliActivity();
@@ -41552,18 +41765,30 @@ child.on('exit', () => process.exit(0));
41552
41765
  return active && isDueByAxisTtl(provider);
41553
41766
  });
41554
41767
  const needsPrune = !!options.isEnabled && fetchers.some(({ provider }) => !options.isEnabled(provider) && cache.has(provider));
41555
- if (due.length === 0 && !needsPrune) return;
41768
+ if (due.length === 0 && !needsPrune) {
41769
+ scheduleNext();
41770
+ return;
41771
+ }
41556
41772
  running = true;
41557
41773
  const probeOnly = new Set(due.map(({ provider }) => provider));
41558
41774
  void refreshQuotaCacheOnce(fetchers, options.isEnabled, { probeOnly }).catch((e) => LOG2.warn("Quota", `Quota refresh tick error: ${e?.message || e}`)).finally(() => {
41559
41775
  running = false;
41776
+ scheduleNext();
41560
41777
  });
41561
- }, intervalMs);
41778
+ };
41779
+ timer = setTimeout(runWake, intervalMs);
41562
41780
  if (typeof timer.unref === "function") timer.unref();
41563
- LOG2.info("Quota", `Quota refresh loop started (interval ${intervalMs}ms, per-axis TTL, idle machines skipped)`);
41781
+ LOG2.info("Quota", `Quota refresh loop started (first wake ${intervalMs}ms, then per-provider expiry chain; per-axis TTL, idle machines skipped)`);
41564
41782
  return {
41565
41783
  stop() {
41566
- clearInterval(timer);
41784
+ stopped = true;
41785
+ if (timer) {
41786
+ clearTimeout(timer);
41787
+ timer = null;
41788
+ }
41789
+ if (quotaCacheChangedListener === rescheduleFromOutside) {
41790
+ quotaCacheChangedListener = void 0;
41791
+ }
41567
41792
  LOG2.info("Quota", "Quota refresh loop stopped");
41568
41793
  }
41569
41794
  };
@@ -41689,12 +41914,14 @@ child.on('exit', () => process.exit(0));
41689
41914
  var REFRESHERS;
41690
41915
  var cache;
41691
41916
  var ambientIsEnabled;
41917
+ var quotaCacheChangedListener;
41692
41918
  var hydratedOnly;
41693
41919
  var hydrated;
41694
41920
  var QUOTA_FAILURE_MAX_RETRIES;
41695
41921
  var failureRetries;
41696
41922
  var QUOTA_ROUTABLE_MAX_AGE_MS;
41697
41923
  var WORKING_STATUSES;
41924
+ var MIN_CHAIN_WAKE_DELAY_MS;
41698
41925
  var bootRefreshInFlight;
41699
41926
  var QUOTA_EVENT_REFRESH_DEBOUNCE_MS;
41700
41927
  var QUOTA_REFRESH_EVENTS;
@@ -41761,6 +41988,7 @@ child.on('exit', () => process.exit(0));
41761
41988
  "no_progress",
41762
41989
  "long_generating"
41763
41990
  ]);
41991
+ MIN_CHAIN_WAKE_DELAY_MS = 1e3;
41764
41992
  bootRefreshInFlight = false;
41765
41993
  QUOTA_EVENT_REFRESH_DEBOUNCE_MS = 6e4;
41766
41994
  QUOTA_REFRESH_EVENTS = /* @__PURE__ */ new Set(["agent:generating_completed", "agent:stopped"]);
@@ -51064,7 +51292,6 @@ The instruction it carried was never delivered to anyone. If it still matters, r
51064
51292
  nodeId: entry.assignedNodeId,
51065
51293
  providerType: entry.assignedProviderType
51066
51294
  } : void 0;
51067
- entry.status = "cancelled";
51068
51295
  entry.cancelledAt = now;
51069
51296
  if (opts?.reason) entry.cancelReason = opts.reason;
51070
51297
  delete entry.parked;
@@ -51076,20 +51303,17 @@ The instruction it carried was never delivered to anyone. If it still matters, r
51076
51303
  entry.dispatchNonce = (entry.dispatchNonce || 0) + 1;
51077
51304
  delete entry.attemptId;
51078
51305
  MeshRuntimeStore.getInstance().updateQueueEntry(entry);
51079
- endTaskDispatchInFlight(meshId, taskId);
51080
51306
  terminalizeSiblingDispatch(meshId, taskId, "queue_task_cancelled");
51081
- try {
51082
- proposeTurnCompletion({
51083
- meshId,
51084
- taskId,
51085
- outcome: "cancelled",
51086
- source: "cancellation",
51087
- reason: opts?.reason ?? "operator_cancel"
51088
- });
51089
- } catch {
51090
- }
51307
+ const commit = commitTaskTerminalAndAdvanceGraph({
51308
+ meshId,
51309
+ taskId,
51310
+ status: "cancelled",
51311
+ sessionId: priorAssignment?.sessionId,
51312
+ source: "cancellation",
51313
+ reason: opts?.reason ?? "operator_cancel"
51314
+ });
51091
51315
  const cascaded = propagateDependencyFailure(meshId, taskId);
51092
- return { entry, cascaded, priorAssignment };
51316
+ return { entry: commit.entry ?? entry, cascaded, priorAssignment };
51093
51317
  });
51094
51318
  if (result) scheduleMissionCloseCandidateCheck(meshId, [result.entry, ...result.cascaded]);
51095
51319
  if (result?.priorAssignment) lastCancelledTaskAssignment.set(`${meshId}::${taskId}`, result.priorAssignment);
@@ -81710,6 +81934,51 @@ ${cleanBody}`;
81710
81934
  return [];
81711
81935
  }
81712
81936
  }
81937
+ async function verifyRemoteBranchContainsCommit(runGit3, submodulePath, commit, branch = "main") {
81938
+ try {
81939
+ await runGit3(submodulePath, ["-c", "protocol.file.allow=always", "fetch", "origin", `refs/heads/${branch}:refs/remotes/origin/${branch}`]);
81940
+ } catch (fetchError) {
81941
+ return { state: "undeterminable", error: fetchError };
81942
+ }
81943
+ const remoteRef = `refs/remotes/origin/${branch}`;
81944
+ try {
81945
+ await runGit3(submodulePath, ["rev-parse", "--verify", "--quiet", `${remoteRef}^{commit}`]);
81946
+ } catch (resolveError) {
81947
+ return { state: "undeterminable", error: resolveError };
81948
+ }
81949
+ try {
81950
+ await runGit3(submodulePath, ["rev-parse", "--verify", "--quiet", `${commit}^{commit}`]);
81951
+ } catch (missingCandidate) {
81952
+ return { state: "absent", error: missingCandidate };
81953
+ }
81954
+ try {
81955
+ await runGit3(submodulePath, ["merge-base", "--is-ancestor", commit, remoteRef]);
81956
+ return { state: "contained" };
81957
+ } catch (ancestryError) {
81958
+ return ancestryError?.code === 1 ? { state: "absent", error: ancestryError } : { state: "undeterminable", error: ancestryError };
81959
+ }
81960
+ }
81961
+ function buildSubmodulePublishRequiredNextStep(entries) {
81962
+ const undeterminable = entries.filter((entry) => entry.remoteMainUndeterminable);
81963
+ const decided = entries.filter((entry) => !entry.remoteMainUndeterminable);
81964
+ const convergeable = decided.filter((entry) => entry.equivalentPublishedCommit);
81965
+ const publishable = decided.filter((entry) => !entry.equivalentPublishedCommit);
81966
+ const parts = [];
81967
+ if (undeterminable.length > 0) {
81968
+ const refs = undeterminable.map((entry) => `${entry.path}@${entry.commit}`).join(", ");
81969
+ parts.push(`Submodule remote main containment could not be determined for (${refs}) \u2014 the submodule remote was not successfully consulted (network, auth, or a missing remote). This is NOT evidence that the commit is unpublished, so do not push it: restore access to the submodule remote and rerun mesh_refine_node to obtain a real verdict.`);
81970
+ }
81971
+ if (convergeable.length > 0) {
81972
+ const refs = convergeable.map((entry) => `${entry.path}: ${entry.commit} \u2192 ${entry.equivalentPublishedCommit}`).join(", ");
81973
+ parts.push(`Converge the submodule gitlink(s) to the already-published equivalent commit(s) (${refs}): a commit with an identical tree already exists on the submodule remote main branch, so publishing the local same-content twin is wrong. Retarget the gitlink to the published commit, commit the root pointer update, then rerun mesh_refine_node.`);
81974
+ }
81975
+ if (publishable.length > 0) {
81976
+ const refs = publishable.map((entry) => `${entry.path}@${entry.commit}`).join(", ");
81977
+ parts.push(`Ask the user for explicit approval to push/publish the unreachable submodule commit(s) (${refs}) to the configured submodule remote main branch, then rerun mesh_refine_node.`);
81978
+ }
81979
+ parts.push("Do not merge the root branch until every submodule gitlink commit is reachable from submodule origin/main.");
81980
+ return parts.join(" ");
81981
+ }
81713
81982
  var fs51;
81714
81983
  var import_node_child_process11;
81715
81984
  var import_path17;
@@ -81795,15 +82064,22 @@ ${cleanBody}`;
81795
82064
  }
81796
82065
  return void 0;
81797
82066
  }
81798
- function isCommitReachableFromRemoteMain(submoduleRepoPath, commit, remoteMainRef) {
81799
- if (!remoteMainRef) return false;
82067
+ function submoduleHasOriginRemote(submoduleRepoPath) {
81800
82068
  try {
81801
- (0, import_node_child_process12.execFileSync)(GIT4, ["merge-base", "--is-ancestor", commit, remoteMainRef], { cwd: submoduleRepoPath, stdio: "ignore" });
81802
- return true;
82069
+ const url2 = (0, import_node_child_process12.execFileSync)(GIT4, ["remote", "get-url", "origin"], {
82070
+ cwd: submoduleRepoPath,
82071
+ encoding: "utf8",
82072
+ stdio: ["ignore", "pipe", "ignore"]
82073
+ });
82074
+ return !!url2.trim();
81803
82075
  } catch {
81804
82076
  return false;
81805
82077
  }
81806
82078
  }
82079
+ function probeCommitReachableFromRemoteMain(submoduleRepoPath, commit, remoteMainRef) {
82080
+ if (!remoteMainRef) return "undeterminable";
82081
+ return probeGitAncestry(submoduleRepoPath, commit, remoteMainRef);
82082
+ }
81807
82083
  function convergeDivergedSubmoduleGitlinks(worktreeRoot, baseRepoRoot, baseHead, branchHead, options = {}) {
81808
82084
  const changed = readChangedGitlinkPaths(worktreeRoot, baseHead, branchHead);
81809
82085
  if (changed.length === 0) {
@@ -81841,9 +82117,12 @@ ${cleanBody}`;
81841
82117
  continue;
81842
82118
  }
81843
82119
  sawDiverged = true;
82120
+ const originConfigured = submoduleHasOriginRemote(submoduleRepoPath);
82121
+ let remoteFetched = true;
81844
82122
  try {
81845
82123
  (0, import_node_child_process12.execFileSync)(GIT4, ["-c", "protocol.file.allow=always", "fetch", "-q", "origin"], { cwd: submoduleRepoPath, stdio: ["ignore", "ignore", "pipe"] });
81846
82124
  } catch {
82125
+ remoteFetched = false;
81847
82126
  }
81848
82127
  const remoteMainRef = resolveSubmoduleRemoteMainRef(submoduleRepoPath);
81849
82128
  const publishedEquivalent = remoteMainRef ? findEquivalentPublishedSubmoduleCommit(submoduleRepoPath, baseCommit, branchCommit, remoteMainRef) : void 0;
@@ -81856,8 +82135,9 @@ ${cleanBody}`;
81856
82135
  resolutions.push({ path: path60, baseCommit, branchCommit, rebasedCommit: publishedEquivalent });
81857
82136
  continue;
81858
82137
  }
81859
- const branchAlreadyPublished = isCommitReachableFromRemoteMain(submoduleRepoPath, branchCommit, remoteMainRef);
81860
- const willMintUnpublishedCommit = !branchAlreadyPublished;
82138
+ const branchPublished = probeCommitReachableFromRemoteMain(submoduleRepoPath, branchCommit, remoteMainRef);
82139
+ const publicationUndeterminable = originConfigured && (branchPublished === "undeterminable" || !remoteFetched);
82140
+ const willMintUnpublishedCommit = branchPublished !== true;
81861
82141
  const wouldConflict = (() => {
81862
82142
  try {
81863
82143
  (0, import_node_child_process12.execFileSync)(GIT4, ["merge-tree", "--write-tree", baseCommit, branchCommit], {
@@ -81870,6 +82150,17 @@ ${cleanBody}`;
81870
82150
  return true;
81871
82151
  }
81872
82152
  })();
82153
+ if (publicationUndeterminable && !wouldConflict) {
82154
+ gitlinks.push({
82155
+ path: path60,
82156
+ baseCommit,
82157
+ branchCommit,
82158
+ action: "publication_undeterminable",
82159
+ remoteMainRef,
82160
+ remoteFetched
82161
+ });
82162
+ return { converged: false, reason: "submodule_publication_undeterminable", resolutions: [], gitlinks };
82163
+ }
81873
82164
  if (willMintUnpublishedCommit && !wouldConflict && options.allowAutoPublishSubmoduleMainCommits !== true) {
81874
82165
  gitlinks.push({
81875
82166
  path: path60,
@@ -81943,12 +82234,18 @@ ${cleanBody}`;
81943
82234
  if (reason === "submodule_publish_required") {
81944
82235
  return describeSubmodulePublishRequired(nodeId, gitlinks);
81945
82236
  }
82237
+ if (reason === "submodule_publication_undeterminable") {
82238
+ return `[Refinery] Could NOT determine whether the branch-side submodule commit(s) are already published for node ${nodeId} \u2014 the submodule remote was not successfully consulted, so refs/remotes/origin/* is stale or absent. Refusing to rebase: minting a submodule commit on absent evidence can synthesize a redundant twin of a commit that is already on origin. The branch was left untouched. NEXT STEP: restore access to the submodule remote and rerun mesh_refine_node \u2014 do NOT publish or rebase on this evidence: ` + gitlinks.filter((g) => g.action === "publication_undeterminable").map((g) => `${g.path} (branch=${(g.branchCommit || "?").slice(0, 12)} base=${(g.baseCommit || "?").slice(0, 12)} remote=${g.remoteMainRef || "unresolved"} fetched=${g.remoteFetched === true})`).join(", ");
82239
+ }
81946
82240
  if (reason === "submodule_commit_unavailable") {
81947
82241
  return `[Refinery] Could NOT determine submodule gitlink divergence for node ${nodeId} \u2014 a gitlink commit is missing from the local submodule object store (auto-converge could not run): ` + gitlinks.filter((g) => g.action === "skipped_commit_unavailable").map((g) => `${g.path} (missing: ${(g.unavailable || []).join("+") || "unknown"}; base=${(g.baseCommit || "?").slice(0, 12)} branch=${(g.branchCommit || "?").slice(0, 12)})`).join(", ");
81948
82242
  }
81949
82243
  return void 0;
81950
82244
  }
81951
82245
  function buildSubmoduleConvergeDeclineDetails(reason, autoPublishEnabled) {
82246
+ if (reason === "submodule_publication_undeterminable") {
82247
+ return { recommendedAction: SUBMODULE_PUBLICATION_UNDETERMINABLE_RECOMMENDED_ACTION };
82248
+ }
81952
82249
  if (reason !== "submodule_publish_required") return {};
81953
82250
  return {
81954
82251
  recommendedAction: SUBMODULE_PUBLISH_REQUIRED_RECOMMENDED_ACTION,
@@ -82042,6 +82339,7 @@ ${cleanBody}`;
82042
82339
  var import_path18;
82043
82340
  var import_node_child_process12;
82044
82341
  var SUBMODULE_PUBLISH_REQUIRED_RECOMMENDED_ACTION;
82342
+ var SUBMODULE_PUBLICATION_UNDETERMINABLE_RECOMMENDED_ACTION;
82045
82343
  var init_mesh_refine_submodule_converge = __esm2({
82046
82344
  "src/mesh/mesh-refine-submodule-converge.ts"() {
82047
82345
  "use strict";
@@ -82050,6 +82348,7 @@ ${cleanBody}`;
82050
82348
  import_node_child_process12 = require("child_process");
82051
82349
  init_mesh_refine_gitlink_utils();
82052
82350
  SUBMODULE_PUBLISH_REQUIRED_RECOMMENDED_ACTION = "Publish the branch-side submodule commit(s) to submodule origin main, then rerun mesh_refine_node. Do NOT retry the rebase: the branch was intentionally left unrewritten because a rebase here would mint a submodule commit the reachability gate must reject.";
82351
+ SUBMODULE_PUBLICATION_UNDETERMINABLE_RECOMMENDED_ACTION = "Restore access to the submodule remote (the publication check could not be run), then rerun mesh_refine_node. Do NOT publish and do NOT retry the rebase on this evidence: it is unknown whether the branch-side commit is already on origin, so minting or pushing here can synthesize a redundant twin of a published commit.";
82053
82352
  }
82054
82353
  });
82055
82354
  function truncateValidationOutput(value) {
@@ -82115,21 +82414,6 @@ ${asText(streams.stderr)}
82115
82414
  ...details || {}
82116
82415
  });
82117
82416
  }
82118
- function buildSubmodulePublishRequiredNextStep(entries) {
82119
- const convergeable = entries.filter((entry) => entry.equivalentPublishedCommit);
82120
- const publishable = entries.filter((entry) => !entry.equivalentPublishedCommit);
82121
- const parts = [];
82122
- if (convergeable.length > 0) {
82123
- const refs = convergeable.map((entry) => `${entry.path}: ${entry.commit} \u2192 ${entry.equivalentPublishedCommit}`).join(", ");
82124
- parts.push(`Converge the submodule gitlink(s) to the already-published equivalent commit(s) (${refs}): a commit with an identical tree already exists on the submodule remote main branch, so publishing the local same-content twin is wrong. Retarget the gitlink to the published commit, commit the root pointer update, then rerun mesh_refine_node.`);
82125
- }
82126
- if (publishable.length > 0) {
82127
- const refs = publishable.map((entry) => `${entry.path}@${entry.commit}`).join(", ");
82128
- parts.push(`Ask the user for explicit approval to push/publish the unreachable submodule commit(s) (${refs}) to the configured submodule remote main branch, then rerun mesh_refine_node.`);
82129
- }
82130
- parts.push("Do not merge the root branch until every submodule gitlink commit is reachable from submodule origin/main.");
82131
- return parts.join(" ");
82132
- }
82133
82417
  function resolveRefineryAutoPublishSubmoduleMainCommits(mesh, workspace) {
82134
82418
  if (mesh?.policy?.allowAutoPublishSubmoduleMainCommits === true) {
82135
82419
  process.stderr.write(
@@ -82848,10 +83132,7 @@ ${mergeTreeErr?.stderr || ""}`;
82848
83132
  });
82849
83133
  return String(stdout || "");
82850
83134
  };
82851
- const verifyRemoteMainContainsCommit = async (submodulePath, commit, branch = "main") => {
82852
- await runGit3(submodulePath, ["-c", "protocol.file.allow=always", "fetch", "origin", `refs/heads/${branch}:refs/remotes/origin/${branch}`]);
82853
- await runGit3(submodulePath, ["merge-base", "--is-ancestor", commit, `refs/remotes/origin/${branch}`]);
82854
- };
83135
+ const verifyRemoteMainContainsCommit = (submodulePath, commit, branch = "main") => verifyRemoteBranchContainsCommit(runGit3, submodulePath, commit, branch);
82855
83136
  const publishCommitToRemoteMain = async (submodulePath, commit, branch = "main") => {
82856
83137
  const refspec = `${commit}:refs/heads/${branch}`;
82857
83138
  const { stdout, stderr } = await execFileAsync7(GIT4, ["push", "origin", refspec], {
@@ -82880,8 +83161,13 @@ ${mergeTreeErr?.stderr || ""}`;
82880
83161
  if (!targetTree) return void 0;
82881
83162
  const candidates = (await runGit3(submodulePath, ["rev-list", "--max-count=100", remoteRef])).split("\n").map((s2) => s2.trim()).filter(Boolean);
82882
83163
  for (const candidate of candidates) {
82883
- const tree = (await runGit3(submodulePath, ["rev-parse", `${candidate}^{tree}`])).trim();
82884
- if (tree === targetTree) return candidate;
83164
+ let tree = "";
83165
+ try {
83166
+ tree = (await runGit3(submodulePath, ["rev-parse", `${candidate}^{tree}`])).trim();
83167
+ } catch {
83168
+ continue;
83169
+ }
83170
+ if (tree && tree === targetTree) return candidate;
82885
83171
  }
82886
83172
  } catch {
82887
83173
  }
@@ -82954,13 +83240,25 @@ ${mergeTreeErr?.stderr || ""}`;
82954
83240
  submodulePath: gitlink.path
82955
83241
  });
82956
83242
  entry.remoteMainBranch = submoduleDefaultBranch;
82957
- try {
82958
- await verifyRemoteMainContainsCommit(submodulePath, gitlink.commit, submoduleDefaultBranch);
83243
+ const verdict = await verifyRemoteMainContainsCommit(submodulePath, gitlink.commit, submoduleDefaultBranch);
83244
+ if (verdict.state === "contained") {
82959
83245
  entry.fetchedFromOrigin = true;
82960
83246
  entry.remoteReachable = true;
82961
83247
  entry.remoteMainReachable = true;
82962
83248
  entry.reachable = true;
82963
- } catch (e) {
83249
+ } else if (verdict.state === "undeterminable") {
83250
+ const e = verdict.error;
83251
+ entry.remoteMainUndeterminable = true;
83252
+ entry.publishRequired = false;
83253
+ const details = truncateValidationOutput(e?.stderr || e?.message || String(e));
83254
+ entry.error = `Submodule remote main reachability for origin/${submoduleDefaultBranch} could not be determined (the remote was not successfully consulted): ${details}. This is not evidence that ${gitlink.commit} is unpublished \u2014 resolve the remote access problem and re-run; Refinery will not publish on an undetermined verdict.`;
83255
+ if (options.allowAutoPublishSubmoduleMainCommits === true) {
83256
+ entry.autoPublishAllowed = true;
83257
+ entry.autoPublishAttempted = false;
83258
+ entry.autoPublishSkippedReason = `remote main containment for origin/${submoduleDefaultBranch} could not be determined, so Refinery will not push \u2014 a failed fetch is not proof the commit is unpublished`;
83259
+ }
83260
+ } else {
83261
+ const e = verdict.error;
82964
83262
  entry.remoteReachable = false;
82965
83263
  entry.remoteMainReachable = false;
82966
83264
  const equivalentPublished = await findEquivalentPublishedCommit(submodulePath, gitlink.commit, `refs/remotes/origin/${submoduleDefaultBranch}`);
@@ -82986,14 +83284,24 @@ ${mergeTreeErr?.stderr || ""}`;
82986
83284
  entry.publishStdout = truncateValidationOutput(publish.stdout);
82987
83285
  entry.publishStderr = truncateValidationOutput(publish.stderr);
82988
83286
  entry.autoPublishSucceeded = true;
82989
- await verifyRemoteMainContainsCommit(submodulePath, gitlink.commit, submoduleDefaultBranch);
82990
- entry.fetchedFromOrigin = true;
82991
- entry.remoteReachable = true;
82992
- entry.remoteMainReachable = true;
82993
- entry.autoPublishVerified = true;
82994
- entry.publishRequired = false;
82995
- entry.reachable = true;
82996
- entry.error = void 0;
83287
+ const postPublish = await verifyRemoteMainContainsCommit(submodulePath, gitlink.commit, submoduleDefaultBranch);
83288
+ if (postPublish.state !== "contained") {
83289
+ entry.autoPublishVerified = false;
83290
+ const postDetails = truncateValidationOutput(
83291
+ postPublish.error?.stderr || postPublish.error?.message || String(postPublish.error)
83292
+ );
83293
+ if (postPublish.state === "undeterminable") entry.remoteMainUndeterminable = true;
83294
+ else entry.remoteMainReachable = false;
83295
+ entry.error = `Submodule auto-publish to origin/${submoduleDefaultBranch} reported success but post-publish verification did not confirm containment (${postPublish.state}): ${postDetails}`;
83296
+ } else {
83297
+ entry.fetchedFromOrigin = true;
83298
+ entry.remoteReachable = true;
83299
+ entry.remoteMainReachable = true;
83300
+ entry.autoPublishVerified = true;
83301
+ entry.publishRequired = false;
83302
+ entry.reachable = true;
83303
+ entry.error = void 0;
83304
+ }
82997
83305
  } catch (publishError) {
82998
83306
  entry.autoPublishSucceeded = false;
82999
83307
  entry.autoPublishVerified = false;
@@ -83031,12 +83339,12 @@ ${mergeTreeErr?.stderr || ""}`;
83031
83339
  autoPublishPolicySource: options.autoPublishPolicySource
83032
83340
  };
83033
83341
  } catch (e) {
83034
- const unreachable = entries.filter((entry) => !entry.reachable).map((entry) => ({ ...entry, publishRequired: true }));
83342
+ const unreachable = entries.filter((entry) => !entry.reachable).map((entry) => ({ ...entry, publishRequired: entry.publishRequired !== false }));
83035
83343
  return {
83036
83344
  status: "failed",
83037
83345
  checked: entries.length,
83038
83346
  unreachable,
83039
- entries: entries.map((entry) => entry.reachable ? entry : { ...entry, publishRequired: true }),
83347
+ entries: entries.map((entry) => entry.reachable ? entry : { ...entry, publishRequired: entry.publishRequired !== false }),
83040
83348
  durationMs: Date.now() - startedAt,
83041
83349
  autoPublishAllowed: options.allowAutoPublishSubmoduleMainCommits === true,
83042
83350
  autoPublishPolicySource: options.autoPublishPolicySource,
@@ -83642,6 +83950,87 @@ ${excerpt}` : "\n--- git output ---\n(none captured)");
83642
83950
  "use strict";
83643
83951
  }
83644
83952
  });
83953
+ async function hasOriginRemote(execFileAsync7, repoRoot, env2) {
83954
+ try {
83955
+ const { stdout } = await execFileAsync7("git", ["remote", "get-url", "origin"], { cwd: repoRoot, encoding: "utf8", env: env2 });
83956
+ return !!stdout.trim();
83957
+ } catch {
83958
+ return false;
83959
+ }
83960
+ }
83961
+ async function probeRefineBaseCas(params) {
83962
+ const { execFileAsync: execFileAsync7, repoRoot, baseBranch, pinnedBaseHead, env: env2 } = params;
83963
+ if (!await hasOriginRemote(execFileAsync7, repoRoot, env2)) {
83964
+ return { state: "no_origin" };
83965
+ }
83966
+ try {
83967
+ await execFileAsync7("git", ["fetch", "origin", baseBranch], { cwd: repoRoot, encoding: "utf8", env: env2 });
83968
+ } catch (e) {
83969
+ const fetchError = e?.message || String(e);
83970
+ return { state: "undeterminable", reason: `git fetch origin ${baseBranch} failed: ${fetchError}`, fetchError };
83971
+ }
83972
+ let liveBaseHead;
83973
+ try {
83974
+ const { stdout } = await execFileAsync7("git", ["rev-parse", `origin/${baseBranch}`], { cwd: repoRoot, encoding: "utf8", env: env2 });
83975
+ liveBaseHead = stdout.trim();
83976
+ } catch (e) {
83977
+ return { state: "undeterminable", reason: `git rev-parse origin/${baseBranch} failed: ${e?.message || String(e)}` };
83978
+ }
83979
+ if (!liveBaseHead) {
83980
+ return { state: "undeterminable", reason: `git rev-parse origin/${baseBranch} produced no SHA` };
83981
+ }
83982
+ return { state: liveBaseHead === pinnedBaseHead ? "unmoved" : "moved", liveBaseHead };
83983
+ }
83984
+ function describeRefineBaseCasStage(cas, pinnedBaseHead) {
83985
+ switch (cas.state) {
83986
+ case "no_origin":
83987
+ return { status: "skipped", detail: { pinnedBaseHead, reason: "no_origin_remote" } };
83988
+ case "undeterminable":
83989
+ return { status: "failed", detail: {
83990
+ pinnedBaseHead,
83991
+ retryable: true,
83992
+ undeterminable: true,
83993
+ reason: cas.reason,
83994
+ ...cas.fetchError ? { fetchError: cas.fetchError } : {}
83995
+ } };
83996
+ case "moved":
83997
+ return { status: "failed", detail: { pinnedBaseHead, retryable: true, liveBaseHead: cas.liveBaseHead } };
83998
+ default:
83999
+ return { status: "passed", detail: { pinnedBaseHead, liveBaseHead: cas.liveBaseHead } };
84000
+ }
84001
+ }
84002
+ function buildRefineBaseCasBlockedResult(params) {
84003
+ const { cas, baseBranch, branch, pinnedBaseHead, validationSummary, patchEquivalence, submoduleReachability, refineStages } = params;
84004
+ const undeterminable = cas.state === "undeterminable";
84005
+ return {
84006
+ success: false,
84007
+ code: undeterminable ? "base_cas_undeterminable" : "base_moved",
84008
+ convergenceStatus: "blocked_review",
84009
+ retryable: true,
84010
+ error: undeterminable ? `Could not verify whether base ${baseBranch} is still at the pinned ${pinnedBaseHead.slice(0, 7)} (${cas.reason}); refusing to merge or push onto an unverified base. Restore access to origin and re-run refine.` : `Base ${baseBranch} advanced from ${pinnedBaseHead.slice(0, 7)} to ${(cas.liveBaseHead || "").slice(0, 7)} after this node was validated; re-run refine to rebase onto and re-validate the new base.`,
84011
+ branch,
84012
+ into: baseBranch,
84013
+ pinnedBaseHead,
84014
+ ...undeterminable ? { baseCasUndeterminable: cas.reason } : { liveBaseHead: cas.liveBaseHead },
84015
+ validationSummary,
84016
+ patchEquivalence,
84017
+ submoduleReachability,
84018
+ refineStages,
84019
+ finalBranchConvergenceState: {
84020
+ branch,
84021
+ baseBranch,
84022
+ merged: false,
84023
+ removed: false,
84024
+ status: "blocked_review",
84025
+ ...undeterminable ? { nextStep: "Restore access to origin (the base compare-and-swap could not run), then re-run refine for this node." } : {}
84026
+ }
84027
+ };
84028
+ }
84029
+ var init_mesh_refine_base_cas = __esm2({
84030
+ "src/mesh/mesh-refine-base-cas.ts"() {
84031
+ "use strict";
84032
+ }
84033
+ });
83645
84034
  function resolveRefineMaxConcurrentJobs(env2 = process.env) {
83646
84035
  const raw = env2[REFINE_MAX_CONCURRENT_JOBS_ENV];
83647
84036
  if (raw === void 0 || raw.trim() === "") return DEFAULT_REFINE_MAX_CONCURRENT_JOBS;
@@ -84986,45 +85375,27 @@ ${hintLines.join("\n")}` : "",
84986
85375
  async function runRefineMergeAndFinalizeLocked(self, ctx) {
84987
85376
  const { meshId, nodeId, args, repoRoot, baseHead, node, branch, baseBranch, sourceNode, validationSummary, patchEquivalence, submoduleReachability, mesh, refineStages, execFileAsync: execFileAsync7 } = ctx;
84988
85377
  const casStarted = Date.now();
84989
- let baseMoved = false;
84990
- let liveBaseHead;
84991
- try {
84992
- await execFileAsync7("git", ["fetch", "origin", baseBranch], { cwd: repoRoot, encoding: "utf8", env: gitChildEnv() });
84993
- const { stdout } = await execFileAsync7("git", ["rev-parse", `origin/${baseBranch}`], { cwd: repoRoot, encoding: "utf8", env: gitChildEnv() });
84994
- liveBaseHead = stdout.trim();
84995
- baseMoved = !!liveBaseHead && liveBaseHead !== baseHead;
84996
- } catch {
84997
- }
84998
- if (baseMoved) {
84999
- recordMeshRefineStage(refineStages, "base_cas", "failed", casStarted, {
85000
- pinnedBaseHead: baseHead,
85001
- liveBaseHead,
85002
- retryable: true
85003
- });
85004
- return { kind: "terminal", result: {
85005
- success: false,
85006
- code: "base_moved",
85007
- convergenceStatus: "blocked_review",
85008
- retryable: true,
85009
- error: `Base ${baseBranch} advanced from ${baseHead.slice(0, 7)} to ${(liveBaseHead || "").slice(0, 7)} after this node was validated; re-run refine to rebase onto and re-validate the new base.`,
85378
+ const cas = await probeRefineBaseCas({
85379
+ execFileAsync: execFileAsync7,
85380
+ repoRoot,
85381
+ baseBranch,
85382
+ pinnedBaseHead: baseHead,
85383
+ env: gitChildEnv()
85384
+ });
85385
+ const casStage = describeRefineBaseCasStage(cas, baseHead);
85386
+ recordMeshRefineStage(refineStages, "base_cas", casStage.status, casStarted, casStage.detail);
85387
+ if (cas.state === "undeterminable" || cas.state === "moved") {
85388
+ return { kind: "terminal", result: buildRefineBaseCasBlockedResult({
85389
+ cas,
85390
+ baseBranch,
85010
85391
  branch,
85011
- into: baseBranch,
85012
85392
  pinnedBaseHead: baseHead,
85013
- liveBaseHead,
85014
85393
  validationSummary,
85015
85394
  patchEquivalence,
85016
85395
  submoduleReachability,
85017
- refineStages,
85018
- finalBranchConvergenceState: {
85019
- branch,
85020
- baseBranch,
85021
- merged: false,
85022
- removed: false,
85023
- status: "blocked_review"
85024
- }
85025
- } };
85396
+ refineStages
85397
+ }) };
85026
85398
  }
85027
- recordMeshRefineStage(refineStages, "base_cas", "passed", casStarted, { pinnedBaseHead: baseHead });
85028
85399
  let mergeResult;
85029
85400
  const mergeStarted = Date.now();
85030
85401
  try {
@@ -85971,9 +86342,10 @@ ${e?.stderr || ""}`;
85971
86342
  init_git_locale();
85972
86343
  init_mesh_node_identity();
85973
86344
  init_mesh_refine_gates();
86345
+ init_mesh_refine_base_cas();
85974
86346
  init_mesh_refine_concurrency();
85975
86347
  init_router_refine_resume();
85976
- RETRYABLE_BASE_MOVEMENT_CODES = /* @__PURE__ */ new Set(["base_moved", "base_locked"]);
86348
+ RETRYABLE_BASE_MOVEMENT_CODES = /* @__PURE__ */ new Set(["base_moved", "base_locked", "base_cas_undeterminable"]);
85977
86349
  }
85978
86350
  });
85979
86351
  var index_exports = {};
@@ -86357,6 +86729,7 @@ ${e?.stderr || ""}`;
86357
86729
  isManagedStatusWorking: () => isManagedStatusWorking,
86358
86730
  isMeshHostOwner: () => isMeshHostOwner,
86359
86731
  isMeshNodeHealthLaunchable: () => isMeshNodeHealthLaunchable,
86732
+ isMeshTestPollution: () => isMeshTestPollution,
86360
86733
  isMissingLiveSessionResult: () => isMissingLiveSessionResult2,
86361
86734
  isOperatingNoteTombstoned: () => isOperatingNoteTombstoned,
86362
86735
  isP2pRelayTransportFailure: () => isP2pRelayTransportFailure,
@@ -86366,6 +86739,8 @@ ${e?.stderr || ""}`;
86366
86739
  isSessionHostLiveRuntime: () => import_session_host_core32.isSessionHostLiveRuntime,
86367
86740
  isSessionHostRecoverySnapshot: () => import_session_host_core32.isSessionHostRecoverySnapshot,
86368
86741
  isSetupComplete: () => isSetupComplete,
86742
+ isSyntheticTestCoordinatorSession: () => isSyntheticTestCoordinatorSession,
86743
+ isSyntheticTestMeshId: () => isSyntheticTestMeshId,
86369
86744
  isTaskReadonly: () => isTaskReadonly,
86370
86745
  isUserFacingChatMessage: () => isUserFacingChatMessage,
86371
86746
  isWeakCompletionEvidence: () => isWeakCompletionEvidence,
@@ -88733,6 +89108,19 @@ ${e?.stderr || ""}`;
88733
89108
  };
88734
89109
  }
88735
89110
  init_mesh_ledger();
89111
+ var SYNTHETIC_MESH_ID_RE = /^mesh_(adopt_|g4dup_|graph_[eg]_)/;
89112
+ var SYNTHETIC_COORDINATOR_SESSIONS = /* @__PURE__ */ new Set(["sess-coord", "sess-A"]);
89113
+ function isSyntheticTestMeshId(meshId) {
89114
+ if (!meshId) return false;
89115
+ return SYNTHETIC_MESH_ID_RE.test(meshId);
89116
+ }
89117
+ function isSyntheticTestCoordinatorSession(sessionId) {
89118
+ if (!sessionId) return false;
89119
+ return SYNTHETIC_COORDINATOR_SESSIONS.has(sessionId);
89120
+ }
89121
+ function isMeshTestPollution(args) {
89122
+ return isSyntheticTestMeshId(args.meshId) || isSyntheticTestCoordinatorSession(args.coordinatorSessionId);
89123
+ }
88736
89124
  var import_fs13 = require("fs");
88737
89125
  var import_path12 = require("path");
88738
89126
  init_config();
@@ -102296,6 +102684,11 @@ ${marker}`,
102296
102684
  var WIN32_SUBMIT_SETTLE_POLL_MS = 120;
102297
102685
  var WIN32_ECHO_PROBE_CHARS = 16;
102298
102686
  var WIN32_ECHO_MAX_WAIT_MS = 2e4;
102687
+ var VERIFIED_SUBMIT_MIN_CHARS = 512;
102688
+ function shouldUseVerifiedSubmit(text, platform10 = process.platform) {
102689
+ if (platform10 === "win32") return true;
102690
+ return text.length >= VERIFIED_SUBMIT_MIN_CHARS;
102691
+ }
102299
102692
  var WIN32_BRACKETED_PASTE_OPEN = "\x1B[200~";
102300
102693
  var WIN32_BRACKETED_PASTE_CLOSE = "\x1B[201~";
102301
102694
  var WIN32_SOFT_NEWLINE = "\x1B[27;2;13~";
@@ -102308,8 +102701,9 @@ ${marker}`,
102308
102701
  function resolveSubmitDelayMs(specBeforeSubmit, text) {
102309
102702
  const lines = countNewlines(text);
102310
102703
  const linesBonus = Math.min(800, lines * 80);
102704
+ const lengthBonus = Math.min(800, Math.floor(text.length / 1e3) * 200);
102311
102705
  const spec = typeof specBeforeSubmit === "number" && specBeforeSubmit > 0 ? specBeforeSubmit : 0;
102312
- return Math.max(spec, SUBMIT_DELAY_FLOOR_MS + linesBonus);
102706
+ return Math.max(spec, SUBMIT_DELAY_FLOOR_MS + linesBonus + lengthBonus);
102313
102707
  }
102314
102708
  var chunkPreservingSurrogates2 = chunkPreservingSurrogates;
102315
102709
  function guessExt(mime) {
@@ -102377,7 +102771,7 @@ ${marker}`,
102377
102771
  * resets the stall reference) or another full stall window lapses. */
102378
102772
  lastRefocusAt = 0;
102379
102773
  /** Timer driving the win32 verification-based submit resend loop (see
102380
- * WIN32_SUBMIT_* and scheduleWin32Submit). Re-arms itself until the FSM
102774
+ * WIN32_SUBMIT_* and scheduleVerifiedSubmit). Re-arms itself until the FSM
102381
102775
  * leaves idle (submitted) or the resend budget is spent. */
102382
102776
  win32SubmitTimer = null;
102383
102777
  /** Wall-clock (ms) of the most recent raw PTY output chunk. Advances on every
@@ -102395,6 +102789,12 @@ ${marker}`,
102395
102789
  * is absorbed by ConPTY the same way a send_message submit CR is, so the confirm
102396
102790
  * must be resent until the modal actually resolves (status leaves 'approval'). */
102397
102791
  win32ModalConfirmTimer = null;
102792
+ /** SUBMIT-SILENT-FAILURE: set when scheduleVerifiedSubmit spent its whole resend
102793
+ * budget without the FSM ever leaving 'idle' — i.e. the body is still sitting
102794
+ * unsent in the composer. Cleared on the next send. Exposed via
102795
+ * lastSubmitUnconfirmed() so a supervisor can distinguish "agent is thinking"
102796
+ * from "the prompt was never actually submitted". */
102797
+ submitUnconfirmed = false;
102398
102798
  currentEval = null;
102399
102799
  stateHistory = [];
102400
102800
  prevStateAt = 0;
@@ -103206,13 +103606,26 @@ ${marker}`,
103206
103606
  this.sendInFlight = true;
103207
103607
  this.sendInFlightAt = Date.now();
103208
103608
  }
103609
+ /** SUBMIT-SILENT-FAILURE: true when the most recent send exhausted its submit
103610
+ * resend budget without the agent ever leaving the composer. A caller seeing
103611
+ * this should treat an apparent 'generating' status as untrustworthy. */
103612
+ lastSubmitUnconfirmed() {
103613
+ return this.submitUnconfirmed;
103614
+ }
103209
103615
  actuallySendMessage(text) {
103210
103616
  const sm = this.spec.send_message;
103617
+ this.submitUnconfirmed = false;
103211
103618
  const perChar = sm.delay_ms_per_char ?? 0;
103212
103619
  const beforeSubmit = resolveSubmitDelayMs(sm.delay_ms_before_submit, text);
103213
103620
  if (process.platform === "win32") {
103214
103621
  this.writeWin32Body(text);
103215
- this.scheduleWin32Submit(sm.submit_key, beforeSubmit, text);
103622
+ this.scheduleVerifiedSubmit(sm.submit_key, beforeSubmit, text);
103623
+ return;
103624
+ }
103625
+ if (perChar === 0 && shouldUseVerifiedSubmit(text)) {
103626
+ this.adapter.send_keys(text);
103627
+ this.markBodyWrite();
103628
+ this.scheduleVerifiedSubmit(sm.submit_key, beforeSubmit, text);
103216
103629
  return;
103217
103630
  }
103218
103631
  if (perChar === 0) {
@@ -103239,7 +103652,7 @@ ${marker}`,
103239
103652
  }
103240
103653
  /** Record a win32 body write so the settle-gate counts it as input activity
103241
103654
  * even before the echo arrives. */
103242
- markWin32Write() {
103655
+ markBodyWrite() {
103243
103656
  this.lastWin32WriteAt = Date.now();
103244
103657
  }
103245
103658
  /** Most recent win32 input activity — a write we issued OR a PTY output chunk
@@ -103264,7 +103677,7 @@ ${marker}`,
103264
103677
  * - 'soft_newline': replace each embedded newline with a non-submitting
103265
103678
  * Shift+Enter (CSI-u) so the body is typed as one multi-line entry.
103266
103679
  * The trailing submit CR is NOT written here — it stays separate and is fired
103267
- * later by scheduleWin32Submit (concern (A)). The bracketed-paste markers are
103680
+ * later by scheduleVerifiedSubmit (concern (A)). The bracketed-paste markers are
103268
103681
  * written as their own atomic segments (never chunked), so chunking can never
103269
103682
  * split ESC[200~ / ESC[201~ mid-sequence regardless of body length.
103270
103683
  */
@@ -103289,7 +103702,7 @@ ${marker}`,
103289
103702
  ];
103290
103703
  }
103291
103704
  if (segments.length <= 1) {
103292
- this.markWin32Write();
103705
+ this.markBodyWrite();
103293
103706
  this.adapter.send_keys(segments[0] ?? text);
103294
103707
  return;
103295
103708
  }
@@ -103297,7 +103710,7 @@ ${marker}`,
103297
103710
  const writeNext = () => {
103298
103711
  this.win32WriteTimer = null;
103299
103712
  if (idx >= segments.length) return;
103300
- this.markWin32Write();
103713
+ this.markBodyWrite();
103301
103714
  this.adapter.send_keys(segments[idx]);
103302
103715
  idx += 1;
103303
103716
  if (idx < segments.length) {
@@ -103327,7 +103740,7 @@ ${marker}`,
103327
103740
  * idle and stop the instant the agent leaves idle (submitted → generating /
103328
103741
  * approval). This preserves the win32 lone-CR-swallow handling.
103329
103742
  */
103330
- scheduleWin32Submit(submitKey, initialDelayMs, body) {
103743
+ scheduleVerifiedSubmit(submitKey, initialDelayMs, body) {
103331
103744
  if (this.win32SubmitTimer) {
103332
103745
  clearTimeout(this.win32SubmitTimer);
103333
103746
  this.win32SubmitTimer = null;
@@ -103346,10 +103759,22 @@ ${marker}`,
103346
103759
  const fire = (attempt) => {
103347
103760
  this.win32SubmitTimer = null;
103348
103761
  this.adapter.send_keys(submitKey);
103349
- if (attempt + 1 >= WIN32_SUBMIT_MAX_RESENDS) return;
103762
+ if (attempt + 1 >= WIN32_SUBMIT_MAX_RESENDS) {
103763
+ if (this.currentStatus() === "idle") {
103764
+ this.submitUnconfirmed = true;
103765
+ LOG2.error(
103766
+ "FsmDriver",
103767
+ `[${this.specTag()}] SUBMIT NOT CONFIRMED after ${WIN32_SUBMIT_MAX_RESENDS} submit-key attempts (len=${body.length}, echoed=${bodyEchoed()}, waited=${Date.now() - startedAt}ms). The message is likely still sitting unsent in the composer \u2014 the agent is NOT working on it.`
103768
+ );
103769
+ }
103770
+ return;
103771
+ }
103350
103772
  this.win32SubmitTimer = setTimeout(() => {
103351
103773
  if (this.currentStatus() !== "idle") {
103352
103774
  this.win32SubmitTimer = null;
103775
+ if (attempt > 0) {
103776
+ LOG2.warn("FsmDriver", `[${this.specTag()}] submit confirmed only after ${attempt + 1} attempts (len=${body.length})`);
103777
+ }
103353
103778
  return;
103354
103779
  }
103355
103780
  fire(attempt + 1);
@@ -103366,6 +103791,10 @@ ${marker}`,
103366
103791
  return;
103367
103792
  }
103368
103793
  if (waited >= WIN32_ECHO_MAX_WAIT_MS) {
103794
+ LOG2.warn(
103795
+ "FsmDriver",
103796
+ `[${this.specTag()}] body never confirmed in composer after ${waited}ms (len=${body.length}) \u2014 firing submit key blind; resend net will verify.`
103797
+ );
103369
103798
  fire(0);
103370
103799
  return;
103371
103800
  }
@@ -103461,7 +103890,7 @@ ${marker}`,
103461
103890
  this.scheduleWin32ModalConfirm(cr);
103462
103891
  }
103463
103892
  /**
103464
- * win32 modal-confirm CR resend loop. Mirrors scheduleWin32Submit's phase-2
103893
+ * win32 modal-confirm CR resend loop. Mirrors scheduleVerifiedSubmit's phase-2
103465
103894
  * verified resend, but gated on still being IN a modal (status 'approval')
103466
103895
  * rather than still idle: the first CR fires immediately, then resends every
103467
103896
  * WIN32_SUBMIT_RESEND_GAP_MS while the FSM is still showing the modal, up to
@@ -104478,7 +104907,7 @@ ${marker}`,
104478
104907
  if (/^[A-Za-z]:$/.test(parts[0])) return { root: `${parts[0]}/`, segments: parts.slice(1) };
104479
104908
  return { root: parts[0], segments: parts.slice(1) };
104480
104909
  }
104481
- function expandDirGlob(template) {
104910
+ function expandDirGlobUncached(template) {
104482
104911
  const { root, segments } = splitTemplateRoot(template);
104483
104912
  let dirs = [root];
104484
104913
  for (const seg of segments) {
@@ -104518,6 +104947,36 @@ ${marker}`,
104518
104947
  }
104519
104948
  return dirs;
104520
104949
  }
104950
+ var GLOB_CACHE_TTL_MS = 3e3;
104951
+ var GLOB_CACHE_MAX_ENTRIES = 512;
104952
+ var GLOB_CACHE_PREFIX = "glob:";
104953
+ var globCache = /* @__PURE__ */ new Map();
104954
+ var globCacheHits = 0;
104955
+ var globCacheMisses = 0;
104956
+ function pruneGlobCache(nowMs) {
104957
+ for (const [key2, entry] of globCache) {
104958
+ if (entry.expiresAtMs <= nowMs) globCache.delete(key2);
104959
+ }
104960
+ while (globCache.size >= GLOB_CACHE_MAX_ENTRIES) {
104961
+ const oldest = globCache.keys().next();
104962
+ if (oldest.done) break;
104963
+ globCache.delete(oldest.value);
104964
+ }
104965
+ }
104966
+ function expandDirGlob(template) {
104967
+ const key2 = `${GLOB_CACHE_PREFIX}${template}`;
104968
+ const now = Date.now();
104969
+ const hit = globCache.get(key2);
104970
+ if (hit && hit.expiresAtMs > now) {
104971
+ globCacheHits += 1;
104972
+ return hit.dirs.slice();
104973
+ }
104974
+ globCacheMisses += 1;
104975
+ const dirs = expandDirGlobUncached(template);
104976
+ pruneGlobCache(now);
104977
+ globCache.set(key2, { dirs, expiresAtMs: now + GLOB_CACHE_TTL_MS });
104978
+ return dirs.slice();
104979
+ }
104521
104980
  function walkAllDirs(root, out) {
104522
104981
  let entries;
104523
104982
  try {
@@ -134631,6 +135090,7 @@ data: ${JSON.stringify(msg.data)}
134631
135090
  }
134632
135091
  var import_node_perf_hooks = require("perf_hooks");
134633
135092
  init_logger();
135093
+ init_async_batch_writer();
134634
135094
  var EVENT_LOOP_MONITOR_INTERVAL_ENV = "ADHDEV_EVENT_LOOP_MONITOR_INTERVAL_MS";
134635
135095
  var EVENT_LOOP_LAG_WARN_ENV = "ADHDEV_EVENT_LOOP_LAG_WARN_MS";
134636
135096
  var DEFAULT_EVENT_LOOP_MONITOR_INTERVAL_MS = 1e4;
@@ -134647,8 +135107,12 @@ data: ${JSON.stringify(msg.data)}
134647
135107
  return parseMs(env2[EVENT_LOOP_LAG_WARN_ENV], DEFAULT_EVENT_LOOP_LAG_WARN_MS);
134648
135108
  }
134649
135109
  function defaultLogFn(level, message) {
134650
- if (level === "warn") LOG2.warn("EventLoop", message);
134651
- else LOG2.debug("EventLoop", message);
135110
+ if (level === "warn") {
135111
+ LOG2.warn("EventLoop", message);
135112
+ AsyncBatchWriter.flushSync();
135113
+ } else {
135114
+ LOG2.debug("EventLoop", message);
135115
+ }
134652
135116
  }
134653
135117
  function startEventLoopMonitor(opts) {
134654
135118
  const intervalMs = opts?.intervalMs ?? resolveEventLoopMonitorIntervalMs();
@@ -134665,6 +135129,8 @@ data: ${JSON.stringify(msg.data)}
134665
135129
  } };
134666
135130
  }
134667
135131
  let expectedTickAt = null;
135132
+ let lastCpu = null;
135133
+ let lastCpuAt = null;
134668
135134
  const timer = setInterval(() => {
134669
135135
  try {
134670
135136
  const now = Date.now();
@@ -134675,9 +135141,21 @@ data: ${JSON.stringify(msg.data)}
134675
135141
  const meanMs = histogram.mean / 1e6;
134676
135142
  histogram.reset();
134677
135143
  const worstMs = Math.max(driftMs, maxMs);
134678
- const message = `event-loop lag: drift=${driftMs.toFixed(0)}ms max=${maxMs.toFixed(0)}ms p99=${p99Ms.toFixed(0)}ms mean=${meanMs.toFixed(1)}ms over ${intervalMs}ms window`;
135144
+ const cpuNow = process.cpuUsage();
135145
+ let cpuPct = null;
135146
+ if (lastCpu !== null && lastCpuAt !== null) {
135147
+ const elapsedMs = now - lastCpuAt;
135148
+ if (elapsedMs > 0) {
135149
+ const usedMs = (cpuNow.user - lastCpu.user + (cpuNow.system - lastCpu.system)) / 1e3;
135150
+ cpuPct = usedMs / elapsedMs * 100;
135151
+ }
135152
+ }
135153
+ lastCpu = cpuNow;
135154
+ lastCpuAt = now;
135155
+ const cpuPart = cpuPct === null ? "" : ` selfCpu=${cpuPct.toFixed(0)}%`;
135156
+ const message = `event-loop lag: drift=${driftMs.toFixed(0)}ms max=${maxMs.toFixed(0)}ms p99=${p99Ms.toFixed(0)}ms mean=${meanMs.toFixed(1)}ms${cpuPart} over ${intervalMs}ms window`;
134679
135157
  if (worstMs >= warnMs) {
134680
- logFn("warn", `${message} \u2014 EXCEEDS ${warnMs}ms: the whole daemon process was frozen/unscheduled (machine saturation), not one slow handler. Expect IPC probe timeouts and reconcile-tick gaps in this window.`);
135158
+ logFn("warn", `${message} \u2014 EXCEEDS ${warnMs}ms. Cause is one of two shapes: high selfCpu \u21D2 this process blocked its own loop (one slow synchronous handler); low selfCpu with high drift \u21D2 the process was unscheduled (machine saturation). Expect IPC probe timeouts and reconcile-tick gaps in this window.`);
134681
135159
  } else {
134682
135160
  logFn("debug", message);
134683
135161
  }