@adhdev/daemon-standalone 1.0.45-rc.8 → 1.0.45-rc.9

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
@@ -37027,10 +37027,10 @@ var require_dist3 = __commonJS({
37027
37027
  }
37028
37028
  function getDaemonBuildInfo() {
37029
37029
  if (cached2) return cached2;
37030
- const commit = readInjected(true ? "d95b1439eb1b062960654db2dd2d523a0831d1eb" : void 0) ?? "unknown";
37031
- const commitShort = readInjected(true ? "d95b1439" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
37032
- const version2 = readInjected(true ? "1.0.45-rc.8" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
37033
- const builtAt = readInjected(true ? "2026-08-12T15:27:41.488Z" : void 0);
37030
+ const commit = readInjected(true ? "6a45bfebc577345264d61b02a71a657bbc313033" : void 0) ?? "unknown";
37031
+ const commitShort = readInjected(true ? "6a45bfeb" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
37032
+ const version2 = readInjected(true ? "1.0.45-rc.9" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
37033
+ const builtAt = readInjected(true ? "2026-08-13T03:05:02.343Z" : void 0);
37034
37034
  cached2 = builtAt ? { commit, commitShort, version: version2, builtAt } : { commit, commitShort, version: version2 };
37035
37035
  return cached2;
37036
37036
  }
@@ -40041,6 +40041,13 @@ child.on('exit', () => process.exit(0));
40041
40041
  metadata: { source: "oauth" }
40042
40042
  };
40043
40043
  }
40044
+ async function readErrorBody(response) {
40045
+ try {
40046
+ return await response.text?.() ?? "";
40047
+ } catch {
40048
+ return "";
40049
+ }
40050
+ }
40044
40051
  function retryAfterMs(header, nowMs) {
40045
40052
  if (!header) {
40046
40053
  return void 0;
@@ -40084,11 +40091,28 @@ child.on('exit', () => process.exit(0));
40084
40091
  },
40085
40092
  signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS2)
40086
40093
  });
40087
- if (response.status === 401 || response.status === 403) {
40094
+ if (response.status === 401) {
40095
+ return quotaFailure(
40096
+ "kimi",
40097
+ "error",
40098
+ "Kimi usage request was rejected (HTTP 401)",
40099
+ { source: "oauth", failureKind: "unauthorized" }
40100
+ );
40101
+ }
40102
+ if (response.status === 403) {
40103
+ const body = await readErrorBody(response);
40104
+ if (USAGE_LIMIT_BODY_PATTERN.test(body)) {
40105
+ return quotaFailure(
40106
+ "kimi",
40107
+ "error",
40108
+ "Kimi usage limit reached (HTTP 403) \u2014 quota refreshes at the next reset/billing cycle",
40109
+ { source: "oauth", failureKind: "quota-exhausted" }
40110
+ );
40111
+ }
40088
40112
  return quotaFailure(
40089
40113
  "kimi",
40090
40114
  "error",
40091
- `Kimi usage request was rejected (HTTP ${response.status})`,
40115
+ "Kimi usage request was rejected (HTTP 403)",
40092
40116
  { source: "oauth", failureKind: "unauthorized" }
40093
40117
  );
40094
40118
  }
@@ -40122,6 +40146,7 @@ child.on('exit', () => process.exit(0));
40122
40146
  var DEFAULT_BASE_URL;
40123
40147
  var REQUEST_TIMEOUT_MS2;
40124
40148
  var EXPIRY_SKEW_SECONDS;
40149
+ var USAGE_LIMIT_BODY_PATTERN;
40125
40150
  var init_kimi = __esm2({
40126
40151
  "src/quota/fetchers/kimi.ts"() {
40127
40152
  "use strict";
@@ -40133,6 +40158,7 @@ child.on('exit', () => process.exit(0));
40133
40158
  DEFAULT_BASE_URL = "https://api.kimi.com/coding/v1";
40134
40159
  REQUEST_TIMEOUT_MS2 = 1e4;
40135
40160
  EXPIRY_SKEW_SECONDS = 5;
40161
+ USAGE_LIMIT_BODY_PATTERN = /usage limit|quota\s*(exhausted|refresh)|billing cycle/i;
40136
40162
  }
40137
40163
  });
40138
40164
  function opencodeCommand(env2) {
@@ -60592,7 +60618,17 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
60592
60618
  const entry = quotaEntryFor(node, providerType);
60593
60619
  if (!entry) return null;
60594
60620
  const { facts, quota } = entry;
60595
- if (quota.status !== "ok") return null;
60621
+ if (quota.status !== "ok") {
60622
+ if (quota.status === "error" && quota.metadata?.failureKind === "quota-exhausted" && isQuotaSnapshotFresh(facts, quota, policy, now)) {
60623
+ return {
60624
+ reason: PROVIDER_QUOTA_EXHAUSTED_SKIP_REASON,
60625
+ window: "unknown",
60626
+ remainingPercent: 0,
60627
+ thresholdPercent: 0
60628
+ };
60629
+ }
60630
+ return null;
60631
+ }
60596
60632
  if (!isQuotaSnapshotFresh(facts, quota, policy, now)) return null;
60597
60633
  const resolved = resolveQuotaRoutingPolicy(policy);
60598
60634
  const session = remainingPercent(quota.session);
@@ -60637,12 +60673,14 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
60637
60673
  }
60638
60674
  var PROVIDER_QUOTA_SESSION_LOW_SKIP_REASON;
60639
60675
  var PROVIDER_QUOTA_WEEKLY_LOW_SKIP_REASON;
60676
+ var PROVIDER_QUOTA_EXHAUSTED_SKIP_REASON;
60640
60677
  var init_mesh_quota_routing = __esm2({
60641
60678
  "src/mesh/mesh-quota-routing.ts"() {
60642
60679
  "use strict";
60643
60680
  init_repo_mesh_types();
60644
60681
  PROVIDER_QUOTA_SESSION_LOW_SKIP_REASON = "provider_quota_session_low";
60645
60682
  PROVIDER_QUOTA_WEEKLY_LOW_SKIP_REASON = "provider_quota_weekly_low";
60683
+ PROVIDER_QUOTA_EXHAUSTED_SKIP_REASON = "provider_quota_exhausted";
60646
60684
  }
60647
60685
  });
60648
60686
  function isAnthropicProvider(providerType) {
@@ -61212,10 +61250,11 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
61212
61250
  // busy counterpart SLOT_MODEL_BUSY_SKIP_REASON is deliberately NOT listed:
61213
61251
  // that one clears on its own when the slot goes idle.
61214
61252
  SLOT_MODEL_ABSENT_SKIP_REASON
61215
- // QUOTA GATE: 'provider_quota_session_low' / 'provider_quota_weekly_low' are
61216
- // deliberately NOT listed either — an exhausted quota window RESETS, so the
61217
- // block self-resolves exactly like the slot-busy case; the task waits in the
61218
- // queue and the coordinator is not paged (mesh-quota-routing.ts).
61253
+ // QUOTA GATE: 'provider_quota_session_low' / 'provider_quota_weekly_low' /
61254
+ // 'provider_quota_exhausted' are deliberately NOT listed either — an
61255
+ // exhausted quota window RESETS, so the block self-resolves exactly like
61256
+ // the slot-busy case; the task waits in the queue and the coordinator is
61257
+ // not paged (mesh-quota-routing.ts).
61219
61258
  ];
61220
61259
  TRANSIENT_TARGET_NODE_BOOTSTRAP_PENDING_REASON = "target_node_bootstrap_pending";
61221
61260
  lastActionableSkipNotified = /* @__PURE__ */ new Map();
@@ -61720,7 +61759,11 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
61720
61759
  }
61721
61760
  const quotaClaimBlock = evaluateProviderQuotaGate(node, providerType, mesh?.policy?.quotaRouting ?? null);
61722
61761
  if (quotaClaimBlock) {
61723
- LOG2.info("MeshQueue", `QUOTA GATE: deferring queue claim for node ${nodeId} (${sessionId}): provider '${providerType}' has ${quotaClaimBlock.remainingPercent.toFixed(1)}% ${quotaClaimBlock.window} quota remaining (< ${quotaClaimBlock.thresholdPercent}% threshold) \u2014 task left pending until the window resets`);
61762
+ if (quotaClaimBlock.reason === PROVIDER_QUOTA_EXHAUSTED_SKIP_REASON) {
61763
+ LOG2.info("MeshQueue", `QUOTA GATE: deferring queue claim for node ${nodeId} (${sessionId}): provider '${providerType}' reported its quota EXHAUSTED \u2014 task left pending until the quota resets`);
61764
+ } else {
61765
+ LOG2.info("MeshQueue", `QUOTA GATE: deferring queue claim for node ${nodeId} (${sessionId}): provider '${providerType}' has ${quotaClaimBlock.remainingPercent.toFixed(1)}% ${quotaClaimBlock.window} quota remaining (< ${quotaClaimBlock.thresholdPercent}% threshold) \u2014 task left pending until the window resets`);
61766
+ }
61724
61767
  return false;
61725
61768
  }
61726
61769
  const inlineBootstrapNode = (() => {
@@ -62465,7 +62508,11 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
62465
62508
  }
62466
62509
  const quotaBlock = evaluateProviderQuotaGate(node, resolved.providerType, mesh?.policy?.quotaRouting ?? null);
62467
62510
  if (quotaBlock) {
62468
- LOG2.info("MeshQueue", `QUOTA GATE: provider '${resolved.providerType}' on node ${nodeId} has ${quotaBlock.remainingPercent.toFixed(1)}% ${quotaBlock.window} quota remaining (< ${quotaBlock.thresholdPercent}% threshold, task ${task.id}); leaving the task queued until the window resets`);
62511
+ if (quotaBlock.reason === PROVIDER_QUOTA_EXHAUSTED_SKIP_REASON) {
62512
+ LOG2.info("MeshQueue", `QUOTA GATE: provider '${resolved.providerType}' on node ${nodeId} reported its quota EXHAUSTED (task ${task.id}); leaving the task queued until the quota resets`);
62513
+ } else {
62514
+ LOG2.info("MeshQueue", `QUOTA GATE: provider '${resolved.providerType}' on node ${nodeId} has ${quotaBlock.remainingPercent.toFixed(1)}% ${quotaBlock.window} quota remaining (< ${quotaBlock.thresholdPercent}% threshold, task ${task.id}); leaving the task queued until the window resets`);
62515
+ }
62469
62516
  markSkip(nodeId, quotaBlock.reason, { providerType: resolved.providerType });
62470
62517
  continue;
62471
62518
  }
@@ -75563,6 +75610,9 @@ ${cont}` : cont;
75563
75610
  var import_session_host_core8;
75564
75611
  var missingBackgroundSourceWarned;
75565
75612
  var FORCE_SUBMIT_SETTLE_MS;
75613
+ var WIN32_INJECT_ENTER_MAX_RETRIES;
75614
+ var WIN32_INJECT_ENTER_RETRY_DELAY_MS;
75615
+ var WIN32_INJECT_COMPOSER_TAIL_LINES;
75566
75616
  var ProviderCliAdapter;
75567
75617
  var init_provider_cli_adapter = __esm2({
75568
75618
  "src/cli-adapters/provider-cli-adapter.ts"() {
@@ -75589,6 +75639,9 @@ ${cont}` : cont;
75589
75639
  init_provider_cli_shared();
75590
75640
  missingBackgroundSourceWarned = /* @__PURE__ */ new Set();
75591
75641
  FORCE_SUBMIT_SETTLE_MS = 150;
75642
+ WIN32_INJECT_ENTER_MAX_RETRIES = 2;
75643
+ WIN32_INJECT_ENTER_RETRY_DELAY_MS = 300;
75644
+ WIN32_INJECT_COMPOSER_TAIL_LINES = 8;
75592
75645
  ProviderCliAdapter = class _ProviderCliAdapter {
75593
75646
  constructor(provider, workingDir, extraArgs = [], extraEnv = {}, transportFactory = new NodePtyTransportFactory(), owningSessionId) {
75594
75647
  this.extraArgs = extraArgs;
@@ -75736,6 +75789,9 @@ ${cont}` : cont;
75736
75789
  pendingOutboundStaleTimer = null;
75737
75790
  // Submit retry timer — PTY-level, not state machine
75738
75791
  submitRetryTimer = null;
75792
+ // WIN32-INJECT-ENTER-RETRY: pending bare-ENTER resend for a mesh_send_keys
75793
+ // injection whose submit may have been swallowed by win32 ConPTY.
75794
+ injectEnterRetryTimer = null;
75739
75795
  // PTY-WRITE-SERIALIZE: a single per-session tail promise that serializes every
75740
75796
  // PTY write. Each writeToPty() call chains its actual write after the previous
75741
75797
  // one and returns a promise that resolves only after ITS write completes, so
@@ -76295,6 +76351,10 @@ ${lastSnapshot}`;
76295
76351
  clearTimeout(this.submitRetryTimer);
76296
76352
  this.submitRetryTimer = null;
76297
76353
  }
76354
+ if (this.injectEnterRetryTimer) {
76355
+ clearTimeout(this.injectEnterRetryTimer);
76356
+ this.injectEnterRetryTimer = null;
76357
+ }
76298
76358
  if (this.pendingOutputParseTimer) {
76299
76359
  clearTimeout(this.pendingOutputParseTimer);
76300
76360
  this.pendingOutputParseTimer = null;
@@ -77109,6 +77169,10 @@ ${lastSnapshot}`;
77109
77169
  clearTimeout(this.submitRetryTimer);
77110
77170
  this.submitRetryTimer = null;
77111
77171
  }
77172
+ if (this.injectEnterRetryTimer) {
77173
+ clearTimeout(this.injectEnterRetryTimer);
77174
+ this.injectEnterRetryTimer = null;
77175
+ }
77112
77176
  this.engine.onTurnStarted(turnScope);
77113
77177
  this.engine.submitRetryPromptSnippet = extractPromptRetrySnippet(text);
77114
77178
  const normalizedPromptSnippet = normalizePromptText(this.engine.submitRetryPromptSnippet);
@@ -77672,7 +77736,17 @@ ${lastSnapshot}`;
77672
77736
  LOG2.warn("CLI", `[${this.cliType}] send_keys refused (actionable_modal): keys=${encoded.keys.join(",")} \u2014 use mesh_approve`);
77673
77737
  return { ok: false, refused: "actionable_modal", keys: encoded.keys, hasDestructive: encoded.hasDestructive };
77674
77738
  }
77739
+ if (this.injectEnterRetryTimer) {
77740
+ clearTimeout(this.injectEnterRetryTimer);
77741
+ this.injectEnterRetryTimer = null;
77742
+ }
77675
77743
  await this.writeToPty(encoded.sequence);
77744
+ if (process.platform === "win32" && encoded.submits) {
77745
+ const snippet2 = extractPromptRetrySnippet(
77746
+ items.map((it) => "text" in it ? it.text : "").join("\n")
77747
+ );
77748
+ if (snippet2) this.scheduleWin32InjectEnterRetry(snippet2, 1);
77749
+ }
77676
77750
  LOG2.info("CLI", `[${this.cliType}] send_keys injected keys=${encoded.keys.join(",") || "(text-only)"} bytes=${Buffer.byteLength(encoded.sequence, "utf8")} destructive=${encoded.hasDestructive}`);
77677
77751
  return {
77678
77752
  ok: true,
@@ -77689,6 +77763,30 @@ ${lastSnapshot}`;
77689
77763
  const str2 = Buffer.isBuffer(data) ? data.toString("utf8") : data;
77690
77764
  await this.writeToPty(str2);
77691
77765
  }
77766
+ /**
77767
+ * WIN32-INJECT-ENTER-RETRY: resend the bare submit key while the injected
77768
+ * text still stands in the composer (bottom viewport lines). Stops the
77769
+ * instant the text leaves that region — proof the submit was consumed —
77770
+ * so a delayed (not lost) original ENTER is never doubled. Bounded by
77771
+ * WIN32_INJECT_ENTER_MAX_RETRIES; see the constants' comment for the
77772
+ * rationale. Never logs the snippet (it is user text).
77773
+ */
77774
+ scheduleWin32InjectEnterRetry(snippet2, attempt) {
77775
+ this.injectEnterRetryTimer = setTimeout(() => {
77776
+ this.injectEnterRetryTimer = null;
77777
+ if (!this.ptyProcess) return;
77778
+ const screenLines = this.terminalScreen.getText().split("\n");
77779
+ const composerRegion = screenLines.slice(-WIN32_INJECT_COMPOSER_TAIL_LINES).join("\n");
77780
+ if (!promptLikelyVisible(composerRegion, snippet2)) return;
77781
+ LOG2.info("CLI", `[${this.cliType}] send_keys ENTER retry (attempt ${attempt}/${WIN32_INJECT_ENTER_MAX_RETRIES}): injected text still in composer`);
77782
+ void this.writeToPty(MESH_SEND_KEY_ENCODING.ENTER).catch((error48) => {
77783
+ LOG2.warn("CLI", `[${this.cliType}] send_keys ENTER retry write failed: ${error48?.message || error48}`);
77784
+ });
77785
+ if (attempt < WIN32_INJECT_ENTER_MAX_RETRIES) {
77786
+ this.scheduleWin32InjectEnterRetry(snippet2, attempt + 1);
77787
+ }
77788
+ }, WIN32_INJECT_ENTER_RETRY_DELAY_MS);
77789
+ }
77692
77790
  resolveModal(buttonIndex) {
77693
77791
  this.engine.resolveModal(buttonIndex);
77694
77792
  }
@@ -113434,8 +113532,19 @@ ${asText(streams.stderr)}
113434
113532
  });
113435
113533
  }
113436
113534
  function buildSubmodulePublishRequiredNextStep(entries) {
113437
- const refs = entries.map((entry) => `${entry.path}@${entry.commit}`).join(", ");
113438
- return `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. Do not merge the root branch until every submodule gitlink commit is reachable from submodule origin/main.`;
113535
+ const convergeable = entries.filter((entry) => entry.equivalentPublishedCommit);
113536
+ const publishable = entries.filter((entry) => !entry.equivalentPublishedCommit);
113537
+ const parts = [];
113538
+ if (convergeable.length > 0) {
113539
+ const refs = convergeable.map((entry) => `${entry.path}: ${entry.commit} \u2192 ${entry.equivalentPublishedCommit}`).join(", ");
113540
+ 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.`);
113541
+ }
113542
+ if (publishable.length > 0) {
113543
+ const refs = publishable.map((entry) => `${entry.path}@${entry.commit}`).join(", ");
113544
+ 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.`);
113545
+ }
113546
+ parts.push("Do not merge the root branch until every submodule gitlink commit is reachable from submodule origin/main.");
113547
+ return parts.join(" ");
113439
113548
  }
113440
113549
  function resolveRefineryAutoPublishSubmoduleMainCommits(mesh, workspace) {
113441
113550
  if (mesh?.policy?.allowAutoPublishSubmoduleMainCommits === true) {
@@ -113989,6 +114098,47 @@ ${mergeTreeErr?.stderr || ""}`;
113989
114098
  return false;
113990
114099
  }
113991
114100
  }
114101
+ function resolveSubmoduleRemoteMainRef(submoduleRepoPath) {
114102
+ try {
114103
+ const sym = (0, import_node_child_process9.execFileSync)(GIT3, ["symbolic-ref", "-q", "refs/remotes/origin/HEAD"], { cwd: submoduleRepoPath, encoding: "utf8" }).trim();
114104
+ if (sym) return sym;
114105
+ } catch {
114106
+ }
114107
+ for (const branch of ["main", "master"]) {
114108
+ try {
114109
+ (0, import_node_child_process9.execFileSync)(GIT3, ["rev-parse", "--verify", "-q", `refs/remotes/origin/${branch}`], { cwd: submoduleRepoPath, stdio: ["ignore", "pipe", "pipe"] });
114110
+ return `refs/remotes/origin/${branch}`;
114111
+ } catch {
114112
+ }
114113
+ }
114114
+ return void 0;
114115
+ }
114116
+ function findEquivalentPublishedSubmoduleCommit(submoduleRepoPath, baseCommit, branchCommit, remoteRef) {
114117
+ try {
114118
+ const mergeTreeOut = (0, import_node_child_process9.execFileSync)(GIT3, ["merge-tree", "--write-tree", baseCommit, branchCommit], {
114119
+ cwd: submoduleRepoPath,
114120
+ encoding: "utf8",
114121
+ stdio: ["ignore", "pipe", "pipe"]
114122
+ });
114123
+ const mergedTree = mergeTreeOut.trim().split(/\s+/)[0] || "";
114124
+ if (!mergedTree) return void 0;
114125
+ const candidates = (0, import_node_child_process9.execFileSync)(GIT3, ["rev-list", "--max-count=100", remoteRef, "--not", baseCommit], {
114126
+ cwd: submoduleRepoPath,
114127
+ encoding: "utf8"
114128
+ }).split("\n").map((s2) => s2.trim()).filter(Boolean);
114129
+ for (const candidate of candidates) {
114130
+ try {
114131
+ (0, import_node_child_process9.execFileSync)(GIT3, ["merge-base", "--is-ancestor", baseCommit, candidate], { cwd: submoduleRepoPath, stdio: "ignore" });
114132
+ } catch {
114133
+ continue;
114134
+ }
114135
+ const tree = (0, import_node_child_process9.execFileSync)(GIT3, ["rev-parse", `${candidate}^{tree}`], { cwd: submoduleRepoPath, encoding: "utf8" }).trim();
114136
+ if (tree === mergedTree) return candidate;
114137
+ }
114138
+ } catch {
114139
+ }
114140
+ return void 0;
114141
+ }
113992
114142
  function ensureSubmoduleCommitLocal(submoduleRepoPath, baseSubmoduleRepoPath, commit) {
113993
114143
  if (!commit) return;
113994
114144
  try {
@@ -114025,6 +114175,21 @@ ${mergeTreeErr?.stderr || ""}`;
114025
114175
  continue;
114026
114176
  }
114027
114177
  sawDiverged = true;
114178
+ try {
114179
+ (0, import_node_child_process9.execFileSync)(GIT3, ["-c", "protocol.file.allow=always", "fetch", "-q", "origin"], { cwd: submoduleRepoPath, stdio: ["ignore", "ignore", "pipe"] });
114180
+ } catch {
114181
+ }
114182
+ const remoteMainRef = resolveSubmoduleRemoteMainRef(submoduleRepoPath);
114183
+ const publishedEquivalent = remoteMainRef ? findEquivalentPublishedSubmoduleCommit(submoduleRepoPath, baseCommit, branchCommit, remoteMainRef) : void 0;
114184
+ if (publishedEquivalent) {
114185
+ try {
114186
+ (0, import_node_child_process9.execFileSync)(GIT3, ["checkout", "-q", "--detach", publishedEquivalent], { cwd: submoduleRepoPath, stdio: ["ignore", "ignore", "pipe"] });
114187
+ } catch {
114188
+ }
114189
+ gitlinks.push({ path: path54, baseCommit, branchCommit, rebasedCommit: publishedEquivalent, action: "converged_to_published" });
114190
+ resolutions.push({ path: path54, baseCommit, branchCommit, rebasedCommit: publishedEquivalent });
114191
+ continue;
114192
+ }
114028
114193
  let rebasedCommit;
114029
114194
  try {
114030
114195
  (0, import_node_child_process9.execFileSync)(GIT3, ["checkout", "-q", "--detach", branchCommit], { cwd: submoduleRepoPath, stdio: ["ignore", "ignore", "pipe"] });
@@ -114422,6 +114587,19 @@ ${mergeTreeErr?.stderr || ""}`;
114422
114587
  await runGit3(submodulePath, ["cat-file", "-e", `${commit}^{commit}`]);
114423
114588
  return true;
114424
114589
  };
114590
+ const findEquivalentPublishedCommit = async (submodulePath, commit, remoteRef) => {
114591
+ try {
114592
+ const targetTree = (await runGit3(submodulePath, ["rev-parse", `${commit}^{tree}`])).trim();
114593
+ if (!targetTree) return void 0;
114594
+ const candidates = (await runGit3(submodulePath, ["rev-list", "--max-count=100", remoteRef])).split("\n").map((s2) => s2.trim()).filter(Boolean);
114595
+ for (const candidate of candidates) {
114596
+ const tree = (await runGit3(submodulePath, ["rev-parse", `${candidate}^{tree}`])).trim();
114597
+ if (tree === targetTree) return candidate;
114598
+ }
114599
+ } catch {
114600
+ }
114601
+ return void 0;
114602
+ };
114425
114603
  const treeOutput = await runGit3(repoRoot, ["ls-tree", "-r", "-z", mergedTree]);
114426
114604
  const gitlinks = treeOutput.split("\0").filter(Boolean).map((record2) => {
114427
114605
  const match = /^160000\s+commit\s+([0-9a-f]{40})\t(.+)$/.exec(record2);
@@ -114455,11 +114633,7 @@ ${mergeTreeErr?.stderr || ""}`;
114455
114633
  entry.localReachable = false;
114456
114634
  if (options.allowAutoPublishSubmoduleMainCommits === true && options.worktreeRoot) {
114457
114635
  try {
114458
- const imported = await importCommitFromWorktreeSubmodule(
114459
- submodulePath,
114460
- (0, import_path17.resolve)(options.worktreeRoot, gitlink.path),
114461
- gitlink.commit
114462
- );
114636
+ const imported = await importCommitFromWorktreeSubmodule(submodulePath, (0, import_path17.resolve)(options.worktreeRoot, gitlink.path), gitlink.commit);
114463
114637
  if (imported) {
114464
114638
  entry.localReachable = true;
114465
114639
  entry.importedFromWorktree = true;
@@ -114502,36 +114676,48 @@ ${mergeTreeErr?.stderr || ""}`;
114502
114676
  } catch (e) {
114503
114677
  entry.remoteReachable = false;
114504
114678
  entry.remoteMainReachable = false;
114505
- entry.publishRequired = true;
114506
- const details = truncateValidationOutput(e?.stderr || e?.message || String(e));
114507
- entry.error = `Submodule remote main reachability check failed for origin/${submoduleDefaultBranch}: ${details}`;
114508
- if (options.allowAutoPublishSubmoduleMainCommits === true && entry.localReachable === true) {
114509
- entry.autoPublishAllowed = true;
114510
- entry.autoPublishAttempted = true;
114511
- try {
114512
- const publish = await publishCommitToRemoteMain(submodulePath, gitlink.commit, submoduleDefaultBranch);
114513
- entry.autoPublishRefspec = publish.refspec;
114514
- entry.publishStdout = truncateValidationOutput(publish.stdout);
114515
- entry.publishStderr = truncateValidationOutput(publish.stderr);
114516
- entry.autoPublishSucceeded = true;
114517
- await verifyRemoteMainContainsCommit(submodulePath, gitlink.commit, submoduleDefaultBranch);
114518
- entry.fetchedFromOrigin = true;
114519
- entry.remoteReachable = true;
114520
- entry.remoteMainReachable = true;
114521
- entry.autoPublishVerified = true;
114522
- entry.publishRequired = false;
114523
- entry.reachable = true;
114524
- entry.error = void 0;
114525
- } catch (publishError) {
114526
- entry.autoPublishSucceeded = false;
114527
- entry.autoPublishVerified = false;
114528
- const publishDetails = truncateValidationOutput(publishError?.stderr || publishError?.message || String(publishError));
114529
- entry.error = `Submodule auto-publish to origin/${submoduleDefaultBranch} failed or could not be verified: ${publishDetails}`;
114679
+ const equivalentPublished = await findEquivalentPublishedCommit(submodulePath, gitlink.commit, `refs/remotes/origin/${submoduleDefaultBranch}`);
114680
+ if (equivalentPublished) {
114681
+ entry.equivalentPublishedCommit = equivalentPublished;
114682
+ entry.publishRequired = false;
114683
+ entry.error = `Submodule commit ${gitlink.commit} is not reachable from origin/${submoduleDefaultBranch}, but an equivalent commit ${equivalentPublished} (identical tree) is already published there; converge the gitlink to the published commit instead of publishing a same-content twin.`;
114684
+ if (options.allowAutoPublishSubmoduleMainCommits === true) {
114685
+ entry.autoPublishAllowed = true;
114686
+ entry.autoPublishAttempted = false;
114687
+ entry.autoPublishSkippedReason = `an equivalent commit (${equivalentPublished}) is already published on origin/${submoduleDefaultBranch}; publishing a same-content twin is wrong \u2014 converge the gitlink to the published commit instead`;
114688
+ }
114689
+ } else {
114690
+ entry.publishRequired = true;
114691
+ const details = truncateValidationOutput(e?.stderr || e?.message || String(e));
114692
+ entry.error = `Submodule remote main reachability check failed for origin/${submoduleDefaultBranch}: ${details}`;
114693
+ if (options.allowAutoPublishSubmoduleMainCommits === true && entry.localReachable === true) {
114694
+ entry.autoPublishAllowed = true;
114695
+ entry.autoPublishAttempted = true;
114696
+ try {
114697
+ const publish = await publishCommitToRemoteMain(submodulePath, gitlink.commit, submoduleDefaultBranch);
114698
+ entry.autoPublishRefspec = publish.refspec;
114699
+ entry.publishStdout = truncateValidationOutput(publish.stdout);
114700
+ entry.publishStderr = truncateValidationOutput(publish.stderr);
114701
+ entry.autoPublishSucceeded = true;
114702
+ await verifyRemoteMainContainsCommit(submodulePath, gitlink.commit, submoduleDefaultBranch);
114703
+ entry.fetchedFromOrigin = true;
114704
+ entry.remoteReachable = true;
114705
+ entry.remoteMainReachable = true;
114706
+ entry.autoPublishVerified = true;
114707
+ entry.publishRequired = false;
114708
+ entry.reachable = true;
114709
+ entry.error = void 0;
114710
+ } catch (publishError) {
114711
+ entry.autoPublishSucceeded = false;
114712
+ entry.autoPublishVerified = false;
114713
+ const publishDetails = truncateValidationOutput(publishError?.stderr || publishError?.message || String(publishError));
114714
+ entry.error = `Submodule auto-publish to origin/${submoduleDefaultBranch} failed or could not be verified: ${publishDetails}`;
114715
+ }
114716
+ } else if (options.allowAutoPublishSubmoduleMainCommits === true) {
114717
+ entry.autoPublishAllowed = true;
114718
+ entry.autoPublishAttempted = false;
114719
+ entry.autoPublishSkippedReason = entry.autoPublishSkippedReason || `candidate commit is not reachable in the source checkout or worktree submodule, so Refinery cannot push it to origin/${submoduleDefaultBranch}`;
114530
114720
  }
114531
- } else if (options.allowAutoPublishSubmoduleMainCommits === true) {
114532
- entry.autoPublishAllowed = true;
114533
- entry.autoPublishAttempted = false;
114534
- entry.autoPublishSkippedReason = entry.autoPublishSkippedReason || `candidate commit is not reachable in the source checkout or worktree submodule, so Refinery cannot push it to origin/${submoduleDefaultBranch}`;
114535
114721
  }
114536
114722
  }
114537
114723
  } catch (e) {
@@ -115100,18 +115286,49 @@ ${mergeTreeErr?.stderr || ""}`;
115100
115286
  const resolved = await refineResolveRefsStage(self, meshId, nodeId, args, refineStages);
115101
115287
  if (resolved.kind === "terminal") return resolved.result;
115102
115288
  const ctx = resolved.ctx;
115103
- const syncBase = await refineSyncBaseStage(self, ctx);
115104
- if (syncBase.kind === "terminal") return syncBase.result;
115105
- const validation = await refineValidationStage(self, ctx);
115106
- if (validation.kind === "terminal") return validation.result;
115107
- const patchEquivalence = await refinePatchEquivalenceStage(self, ctx);
115108
- if (patchEquivalence.kind === "terminal") return patchEquivalence.result;
115109
- const submoduleReachability = await refineSubmoduleReachabilityStage(self, ctx);
115110
- if (submoduleReachability.kind === "terminal") return submoduleReachability.result;
115111
- const effectiveDiff = await refineEffectiveDiffStage(self, ctx);
115112
- if (effectiveDiff.kind === "terminal") return effectiveDiff.result;
115113
- const merge3 = await refineMergeAndFinalizeStage(self, ctx);
115114
- return merge3.result;
115289
+ const leaseKey = `${ctx.repoRoot}::${ctx.baseBranch}`;
115290
+ const leaseHolder = buildRefineJobKey(self, meshId, nodeId);
115291
+ if (self.refineBaseLeases.has(leaseKey) && self.refineBaseLeases.get(leaseKey) !== leaseHolder) {
115292
+ recordMeshRefineStage(refineStages, "base_lease", "skipped", Date.now(), {
115293
+ leaseKey,
115294
+ heldBy: self.refineBaseLeases.get(leaseKey),
115295
+ retryable: true
115296
+ });
115297
+ return {
115298
+ success: false,
115299
+ code: "base_locked",
115300
+ convergenceStatus: "blocked_review",
115301
+ retryable: true,
115302
+ error: `Another refine holds the base lease for ${ctx.baseBranch} in this repo; retry after it completes.`,
115303
+ branch: ctx.branch,
115304
+ into: ctx.baseBranch,
115305
+ refineStages,
115306
+ finalBranchConvergenceState: {
115307
+ branch: ctx.branch,
115308
+ baseBranch: ctx.baseBranch,
115309
+ merged: false,
115310
+ removed: false,
115311
+ status: "blocked_review"
115312
+ }
115313
+ };
115314
+ }
115315
+ self.refineBaseLeases.set(leaseKey, leaseHolder);
115316
+ try {
115317
+ const syncBase = await refineSyncBaseStage(self, ctx);
115318
+ if (syncBase.kind === "terminal") return syncBase.result;
115319
+ const validation = await refineValidationStage(self, ctx);
115320
+ if (validation.kind === "terminal") return validation.result;
115321
+ const patchEquivalence = await refinePatchEquivalenceStage(self, ctx);
115322
+ if (patchEquivalence.kind === "terminal") return patchEquivalence.result;
115323
+ const submoduleReachability = await refineSubmoduleReachabilityStage(self, ctx);
115324
+ if (submoduleReachability.kind === "terminal") return submoduleReachability.result;
115325
+ const effectiveDiff = await refineEffectiveDiffStage(self, ctx);
115326
+ if (effectiveDiff.kind === "terminal") return effectiveDiff.result;
115327
+ const merge3 = await refineMergeAndFinalizeStage(self, ctx);
115328
+ return merge3.result;
115329
+ } finally {
115330
+ if (self.refineBaseLeases.get(leaseKey) === leaseHolder) self.refineBaseLeases.delete(leaseKey);
115331
+ }
115115
115332
  } catch (e) {
115116
115333
  return { success: false, error: e.message, refineStages };
115117
115334
  }
@@ -115631,6 +115848,7 @@ ${tail}` : ""
115631
115848
  unreachable: submoduleReachability.unreachable.map((entry) => ({
115632
115849
  path: entry.path,
115633
115850
  commit: entry.commit,
115851
+ equivalentPublishedCommit: entry.equivalentPublishedCommit,
115634
115852
  publishRequired: entry.publishRequired === true,
115635
115853
  autoPublishAllowed: entry.autoPublishAllowed,
115636
115854
  autoPublishAttempted: entry.autoPublishAttempted,
@@ -115649,15 +115867,23 @@ ${tail}` : ""
115649
115867
  });
115650
115868
  if (submoduleReachability.status === "failed") {
115651
115869
  const nextStep = buildSubmodulePublishRequiredNextStep(submoduleReachability.unreachable);
115870
+ const convergeToPublished = submoduleReachability.unreachable.length > 0 && submoduleReachability.unreachable.every((entry) => !!entry.equivalentPublishedCommit);
115871
+ const blockedReason = convergeToPublished ? "submodule_converge_to_published" : "submodule_publish_required";
115652
115872
  return { kind: "terminal", result: {
115653
115873
  success: false,
115654
115874
  code: "submodule_reachability_failed",
115655
115875
  convergenceStatus: "blocked_review",
115656
- publishRequired: true,
115657
- blockedReason: "submodule_publish_required",
115658
- error: "Refinery submodule reachability preflight failed because one or more submodule gitlink commits are not reachable from their configured remote main branch; merge/refine cleanup was not attempted.",
115876
+ publishRequired: !convergeToPublished,
115877
+ ...convergeToPublished ? { convergeToPublished: true } : {},
115878
+ blockedReason,
115879
+ error: convergeToPublished ? "Refinery submodule reachability preflight found submodule gitlink commit(s) that are not reachable from their configured remote main branch, but each has an equivalent commit (identical tree) already published there; converge the gitlink(s) to the published commit(s) instead of publishing same-content twins. Merge/refine cleanup was not attempted." : "Refinery submodule reachability preflight failed because one or more submodule gitlink commits are not reachable from their configured remote main branch; merge/refine cleanup was not attempted.",
115659
115880
  nextStep,
115660
- nextSteps: [
115881
+ nextSteps: convergeToPublished ? [
115882
+ "Do NOT publish the local submodule commit(s): an equivalent commit (identical tree) is already published on the submodule remote main branch for every unreachable gitlink.",
115883
+ "Retarget each submodule gitlink to the already-published equivalent commit shown in the evidence (equivalentPublishedCommit), commit the root pointer update, and push the submodule checkout to that commit.",
115884
+ "Rerun mesh_refine_node after the gitlink points at the published commit.",
115885
+ "Do not merge the root branch until every submodule gitlink commit is reachable from submodule origin/main."
115886
+ ] : [
115661
115887
  "Ask the user for explicit approval before pushing or publishing any submodule commit.",
115662
115888
  "Push/publish each unreachable submodule commit to the configured submodule remote main branch shown in the evidence.",
115663
115889
  "Rerun mesh_refine_node after remote reachability is confirmed.",
@@ -115666,6 +115892,7 @@ ${tail}` : ""
115666
115892
  unreachableSubmoduleCommits: submoduleReachability.unreachable.map((entry) => ({
115667
115893
  path: entry.path,
115668
115894
  commit: entry.commit,
115895
+ equivalentPublishedCommit: entry.equivalentPublishedCommit,
115669
115896
  remote: entry.remote,
115670
115897
  remoteUrl: entry.remoteUrl,
115671
115898
  remoteReachable: entry.remoteReachable,
@@ -115694,7 +115921,7 @@ ${tail}` : ""
115694
115921
  patchEquivalence: "passed",
115695
115922
  submoduleReachability: "failed",
115696
115923
  status: "blocked_review",
115697
- reason: "submodule_publish_required",
115924
+ reason: blockedReason,
115698
115925
  nextStep
115699
115926
  }
115700
115927
  } };
@@ -115811,7 +116038,8 @@ ${hintLines.join("\n")}` : "",
115811
116038
  const { meshId, nodeId, args, repoRoot, baseHead, node, branch, baseBranch, sourceNode, validationSummary, patchEquivalence, submoduleReachability, mesh, refineStages, execFileAsync: execFileAsync6 } = ctx;
115812
116039
  const leaseKey = `${repoRoot}::${baseBranch}`;
115813
116040
  const leaseHolder = buildRefineJobKey(self, meshId, nodeId);
115814
- if (self.refineBaseLeases.has(leaseKey) && self.refineBaseLeases.get(leaseKey) !== leaseHolder) {
116041
+ const alreadyHeld = self.refineBaseLeases.get(leaseKey) === leaseHolder;
116042
+ if (!alreadyHeld && self.refineBaseLeases.has(leaseKey)) {
115815
116043
  recordMeshRefineStage(refineStages, "base_lease", "skipped", Date.now(), {
115816
116044
  leaseKey,
115817
116045
  heldBy: self.refineBaseLeases.get(leaseKey),
@@ -115838,11 +116066,11 @@ ${hintLines.join("\n")}` : "",
115838
116066
  }
115839
116067
  } };
115840
116068
  }
115841
- self.refineBaseLeases.set(leaseKey, leaseHolder);
116069
+ if (!alreadyHeld) self.refineBaseLeases.set(leaseKey, leaseHolder);
115842
116070
  try {
115843
116071
  return await runRefineMergeAndFinalizeLocked(self, ctx);
115844
116072
  } finally {
115845
- if (self.refineBaseLeases.get(leaseKey) === leaseHolder) self.refineBaseLeases.delete(leaseKey);
116073
+ if (!alreadyHeld && self.refineBaseLeases.get(leaseKey) === leaseHolder) self.refineBaseLeases.delete(leaseKey);
115846
116074
  }
115847
116075
  }
115848
116076
  async function runRefineMergeAndFinalizeLocked(self, ctx) {