omnius 1.0.556 → 1.0.558

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
@@ -9349,9 +9349,9 @@ function normalizeCameraRotationDegrees(value2) {
9349
9349
  const raw = String(value2).trim().toLowerCase();
9350
9350
  if (!raw)
9351
9351
  return 0;
9352
- const numeric = Number(raw.replace(/deg(?:rees)?$/i, ""));
9353
- if (Number.isFinite(numeric))
9354
- return normalizeCameraRotationDegrees(numeric);
9352
+ const numeric2 = Number(raw.replace(/deg(?:rees)?$/i, ""));
9353
+ if (Number.isFinite(numeric2))
9354
+ return normalizeCameraRotationDegrees(numeric2);
9355
9355
  if (["none", "off", "upright", "normal", "0"].includes(raw))
9356
9356
  return 0;
9357
9357
  if (["cw", "clockwise", "right", "rotate-cw", "rotate_cw", "90"].includes(raw))
@@ -14857,14 +14857,14 @@ var init_file_edit = __esm({
14857
14857
  },
14858
14858
  expected_hash: {
14859
14859
  type: "string",
14860
- description: "SHA-256 from the most recent file_read for this file. The runner refuses unverified exact replacements that omit or mismatch this hash."
14860
+ description: "Optional SHA-256 from file_read. When present, the edit is compare-and-swap protected against concurrent file changes; otherwise old_string must match current file text exactly."
14861
14861
  },
14862
14862
  dry_run: {
14863
14863
  type: "boolean",
14864
14864
  description: "Validate the edit and preview the diff without modifying disk."
14865
14865
  }
14866
14866
  },
14867
- required: ["path", "expected_hash"],
14867
+ required: ["path"],
14868
14868
  allOf: [
14869
14869
  { anyOf: [{ required: ["old_string"] }, { required: ["old_string_base64"] }] },
14870
14870
  { anyOf: [{ required: ["new_string"] }, { required: ["new_string_base64"] }] }
@@ -26877,6 +26877,16 @@ function isRetirableEvidence(message2, minChars) {
26877
26877
  }
26878
26878
  function foldEvidenceOutcome(message2) {
26879
26879
  const text2 = message2.content;
26880
+ const admissionBlock = text2.match(RUNTIME_ADMISSION_BLOCK);
26881
+ if (admissionBlock) {
26882
+ const after = text2.slice((admissionBlock.index ?? 0) + admissionBlock[0].length);
26883
+ const reason = after.split("\n").map((line) => line.trim()).find((line) => line.length > 0 && !/^\w+=/.test(line));
26884
+ return `runtime admission: ${admissionBlock[0]}${reason ? ` — ${reason.slice(0, 160)}` : ""}`;
26885
+ }
26886
+ const runtimeException = text2.match(RUNTIME_EXCEPTION_LINE);
26887
+ if (runtimeException) {
26888
+ return `runtime exception: ${runtimeException[0].trim().slice(0, 220)}`;
26889
+ }
26880
26890
  const diag = extractDiagnosticSymbols(text2);
26881
26891
  if (diag.count > 0) {
26882
26892
  const syms = diag.symbols.slice(0, 6);
@@ -26938,12 +26948,14 @@ function retireStaleEvidence(messages2, options2) {
26938
26948
  });
26939
26949
  return { messages: out, retiredCount, reclaimedChars };
26940
26950
  }
26941
- var DIAG_LINE, QUOTED_SYMBOL, EVIDENCE_MARKERS;
26951
+ var DIAG_LINE, QUOTED_SYMBOL, RUNTIME_ADMISSION_BLOCK, RUNTIME_EXCEPTION_LINE, EVIDENCE_MARKERS;
26942
26952
  var init_evidence_retirement = __esm({
26943
26953
  "packages/memory/dist/evidence-retirement.js"() {
26944
26954
  "use strict";
26945
26955
  DIAG_LINE = /\berror\b\s*:/i;
26946
26956
  QUOTED_SYMBOL = /['"`]([A-Za-z_][A-Za-z0-9_:.<>]{1,80})['"`]/g;
26957
+ RUNTIME_ADMISSION_BLOCK = /\[(?:COMPILE ERROR FIX LOOP BLOCKED|EXPLORATION ADMISSION BLOCK|PARENT(?:\s+[^\]]*)?\s+BLOCK(?:ED)?|FOCUS SUPERVISOR BLOCK|STEERING RECONCILIATION REQUIRED|STALE EDIT LOOP BLOCKED|FULL FILE WRITE LOOP BLOCKED)[^\]]*\]/i;
26958
+ RUNTIME_EXCEPTION_LINE = /^\s*(?:[A-Za-z_][\w.]*?(?:Error|Exception)|AssertionError)\s*:\s*(.+)$/m;
26947
26959
  EVIDENCE_MARKERS = [
26948
26960
  "[SHELL TRANSCRIPT]",
26949
26961
  "[FILE CONTEXT",
@@ -29466,10 +29478,10 @@ var init_batch_edit = __esm({
29466
29478
  },
29467
29479
  expected_hash: {
29468
29480
  type: "string",
29469
- description: "SHA-256 from the most recent file_read for this file. All edits for a file must use the same verified hash."
29481
+ description: "Optional SHA-256 from file_read. When supplied, all edits for a file must use the same value and the atomic batch checks it before writing."
29470
29482
  }
29471
29483
  },
29472
- required: ["path", "expected_hash"],
29484
+ required: ["path"],
29473
29485
  allOf: [
29474
29486
  { anyOf: [{ required: ["old_string"] }, { required: ["old_string_base64"] }] },
29475
29487
  { anyOf: [{ required: ["new_string"] }, { required: ["new_string_base64"] }] }
@@ -62146,12 +62158,12 @@ var init_mock_stream = __esm({
62146
62158
  });
62147
62159
 
62148
62160
  // ../node_modules/unlimited-timeout/index.js
62149
- function setTimeout2(callback, delay4, ...arguments_) {
62161
+ function setTimeout2(callback, delay5, ...arguments_) {
62150
62162
  if (typeof callback !== "function") {
62151
62163
  throw new TypeError("Expected callback to be a function");
62152
62164
  }
62153
- delay4 ??= 0;
62154
- delay4 = Number(delay4);
62165
+ delay5 ??= 0;
62166
+ delay5 = Number(delay5);
62155
62167
  let shouldUnref = false;
62156
62168
  const timeout2 = {
62157
62169
  [brandSymbol]: true,
@@ -62168,13 +62180,13 @@ function setTimeout2(callback, delay4, ...arguments_) {
62168
62180
  return timeout2;
62169
62181
  }
62170
62182
  };
62171
- if (delay4 === Number.POSITIVE_INFINITY || delay4 > Number.MAX_SAFE_INTEGER) {
62183
+ if (delay5 === Number.POSITIVE_INFINITY || delay5 > Number.MAX_SAFE_INTEGER) {
62172
62184
  return timeout2;
62173
62185
  }
62174
- if (!Number.isFinite(delay4) || delay4 < 0) {
62175
- delay4 = 0;
62186
+ if (!Number.isFinite(delay5) || delay5 < 0) {
62187
+ delay5 = 0;
62176
62188
  }
62177
- const targetTime = performance.now() + delay4;
62189
+ const targetTime = performance.now() + delay5;
62178
62190
  const schedule = (remainingDelay) => {
62179
62191
  if (timeout2.cleared) {
62180
62192
  return;
@@ -62199,7 +62211,7 @@ function setTimeout2(callback, delay4, ...arguments_) {
62199
62211
  }
62200
62212
  }
62201
62213
  };
62202
- schedule(delay4);
62214
+ schedule(delay5);
62203
62215
  return timeout2;
62204
62216
  }
62205
62217
  function clearTimeout2(timeout2) {
@@ -72204,15 +72216,15 @@ var init_dist3 = __esm({
72204
72216
  const activeTicksCount = this.#getActiveTicksCount();
72205
72217
  if (activeTicksCount >= this.#intervalCap) {
72206
72218
  const oldestTick = this.#strictTicks[this.#strictTicksStartIndex];
72207
- const delay4 = this.#interval - (now2 - oldestTick);
72208
- this.#createIntervalTimeout(delay4);
72219
+ const delay5 = this.#interval - (now2 - oldestTick);
72220
+ this.#createIntervalTimeout(delay5);
72209
72221
  return true;
72210
72222
  }
72211
72223
  return false;
72212
72224
  }
72213
72225
  if (this.#intervalId === void 0) {
72214
- const delay4 = this.#intervalEnd - now2;
72215
- if (delay4 < 0) {
72226
+ const delay5 = this.#intervalEnd - now2;
72227
+ if (delay5 < 0) {
72216
72228
  if (this.#lastExecutionTime > 0) {
72217
72229
  const timeSinceLastExecution = now2 - this.#lastExecutionTime;
72218
72230
  if (timeSinceLastExecution < this.#interval) {
@@ -72222,19 +72234,19 @@ var init_dist3 = __esm({
72222
72234
  }
72223
72235
  this.#intervalCount = this.#carryoverIntervalCount ? this.#pending : 0;
72224
72236
  } else {
72225
- this.#createIntervalTimeout(delay4);
72237
+ this.#createIntervalTimeout(delay5);
72226
72238
  return true;
72227
72239
  }
72228
72240
  }
72229
72241
  return false;
72230
72242
  }
72231
- #createIntervalTimeout(delay4) {
72243
+ #createIntervalTimeout(delay5) {
72232
72244
  if (this.#timeoutId !== void 0) {
72233
72245
  return;
72234
72246
  }
72235
72247
  this.#timeoutId = setTimeout(() => {
72236
72248
  this.#onResumeInterval();
72237
- }, delay4);
72249
+ }, delay5);
72238
72250
  }
72239
72251
  #clearIntervalTimer() {
72240
72252
  if (this.#intervalId) {
@@ -84795,8 +84807,8 @@ function validateKeyName(name10) {
84795
84807
  async function randomDelay() {
84796
84808
  const min = 200;
84797
84809
  const max = 1e3;
84798
- const delay4 = Math.random() * (max - min) + min;
84799
- await new Promise((resolve82) => setTimeout(resolve82, delay4));
84810
+ const delay5 = Math.random() * (max - min) + min;
84811
+ await new Promise((resolve82) => setTimeout(resolve82, delay5));
84800
84812
  }
84801
84813
  function DsName(name10) {
84802
84814
  return new Key(keyPrefix + name10);
@@ -97999,13 +98011,13 @@ var require_lazy_helpers = __commonJS({
97999
98011
  }
98000
98012
  };
98001
98013
  exports.DelayedConstructor = DelayedConstructor;
98002
- function delay4(wrappedConstructor) {
98014
+ function delay5(wrappedConstructor) {
98003
98015
  if (typeof wrappedConstructor === "undefined") {
98004
98016
  throw new Error("Attempt to `delay` undefined. Constructor must be wrapped in a callback");
98005
98017
  }
98006
98018
  return new DelayedConstructor(wrappedConstructor);
98007
98019
  }
98008
- exports.delay = delay4;
98020
+ exports.delay = delay5;
98009
98021
  }
98010
98022
  });
98011
98023
 
@@ -103023,12 +103035,12 @@ var require_x509_cjs = __commonJS({
103023
103035
  var require_crypto = __commonJS({
103024
103036
  "../node_modules/acme-client/src/crypto/index.js"(exports) {
103025
103037
  var net5 = __require("net");
103026
- var { promisify: promisify9 } = __require("util");
103038
+ var { promisify: promisify10 } = __require("util");
103027
103039
  var crypto14 = __require("crypto");
103028
103040
  var asn1js4 = require_build2();
103029
103041
  var x5093 = require_x509_cjs();
103030
- var randomInt2 = promisify9(crypto14.randomInt);
103031
- var generateKeyPair2 = promisify9(crypto14.generateKeyPair);
103042
+ var randomInt2 = promisify10(crypto14.randomInt);
103043
+ var generateKeyPair2 = promisify10(crypto14.generateKeyPair);
103032
103044
  x5093.cryptoProvider.set(crypto14.webcrypto);
103033
103045
  var subjectAltNameOID = "2.5.29.17";
103034
103046
  var alpnAcmeIdentifierOID = "1.3.6.1.5.5.7.1.31";
@@ -137873,9 +137885,9 @@ var require_lib = __commonJS({
137873
137885
  var require_forge2 = __commonJS({
137874
137886
  "../node_modules/acme-client/src/crypto/forge.js"(exports) {
137875
137887
  var net5 = __require("net");
137876
- var { promisify: promisify9 } = __require("util");
137888
+ var { promisify: promisify10 } = __require("util");
137877
137889
  var forge = require_lib();
137878
- var generateKeyPair2 = promisify9(forge.pki.rsa.generateKeyPair);
137890
+ var generateKeyPair2 = promisify10(forge.pki.rsa.generateKeyPair);
137879
137891
  function forgeObjectFromPem(input) {
137880
137892
  const msg = forge.pem.decode(input)[0];
137881
137893
  let result;
@@ -142419,9 +142431,9 @@ var require_timers = __commonJS({
142419
142431
  * before the specified function or code is executed.
142420
142432
  * @param {*} arg
142421
142433
  */
142422
- constructor(callback, delay4, arg) {
142434
+ constructor(callback, delay5, arg) {
142423
142435
  this._onTimeout = callback;
142424
- this._idleTimeout = delay4;
142436
+ this._idleTimeout = delay5;
142425
142437
  this._timerArg = arg;
142426
142438
  this.refresh();
142427
142439
  }
@@ -142466,8 +142478,8 @@ var require_timers = __commonJS({
142466
142478
  * when the timer expires.
142467
142479
  * @returns {NodeJS.Timeout|FastTimer}
142468
142480
  */
142469
- setTimeout(callback, delay4, arg) {
142470
- return delay4 <= RESOLUTION_MS ? setTimeout(callback, delay4, arg) : new FastTimer(callback, delay4, arg);
142481
+ setTimeout(callback, delay5, arg) {
142482
+ return delay5 <= RESOLUTION_MS ? setTimeout(callback, delay5, arg) : new FastTimer(callback, delay5, arg);
142471
142483
  },
142472
142484
  /**
142473
142485
  * The clearTimeout method cancels an instantiated Timer previously created
@@ -142493,8 +142505,8 @@ var require_timers = __commonJS({
142493
142505
  * when the timer expires.
142494
142506
  * @returns {FastTimer}
142495
142507
  */
142496
- setFastTimeout(callback, delay4, arg) {
142497
- return new FastTimer(callback, delay4, arg);
142508
+ setFastTimeout(callback, delay5, arg) {
142509
+ return new FastTimer(callback, delay5, arg);
142498
142510
  },
142499
142511
  /**
142500
142512
  * The clearTimeout method cancels an instantiated FastTimer previously
@@ -142520,8 +142532,8 @@ var require_timers = __commonJS({
142520
142532
  * @deprecated
142521
142533
  * @param {number} [delay=0] The delay in milliseconds to add to the now value.
142522
142534
  */
142523
- tick(delay4 = 0) {
142524
- fastNow += delay4 - RESOLUTION_MS + 1;
142535
+ tick(delay5 = 0) {
142536
+ fastNow += delay5 - RESOLUTION_MS + 1;
142525
142537
  onTick();
142526
142538
  onTick();
142527
142539
  },
@@ -148914,21 +148926,21 @@ var require_client_h1 = __commonJS({
148914
148926
  this.connection = "";
148915
148927
  this.maxResponseSize = client[kMaxResponseSize];
148916
148928
  }
148917
- setTimeout(delay4, type) {
148918
- if (delay4 !== this.timeoutValue || type & USE_FAST_TIMER ^ this.timeoutType & USE_FAST_TIMER) {
148929
+ setTimeout(delay5, type) {
148930
+ if (delay5 !== this.timeoutValue || type & USE_FAST_TIMER ^ this.timeoutType & USE_FAST_TIMER) {
148919
148931
  if (this.timeout) {
148920
148932
  timers.clearTimeout(this.timeout);
148921
148933
  this.timeout = null;
148922
148934
  }
148923
- if (delay4) {
148935
+ if (delay5) {
148924
148936
  if (type & USE_FAST_TIMER) {
148925
- this.timeout = timers.setFastTimeout(onParserTimeout, delay4, new WeakRef(this));
148937
+ this.timeout = timers.setFastTimeout(onParserTimeout, delay5, new WeakRef(this));
148926
148938
  } else {
148927
- this.timeout = setTimeout(onParserTimeout, delay4, new WeakRef(this));
148939
+ this.timeout = setTimeout(onParserTimeout, delay5, new WeakRef(this));
148928
148940
  this.timeout?.unref();
148929
148941
  }
148930
148942
  }
148931
- this.timeoutValue = delay4;
148943
+ this.timeoutValue = delay5;
148932
148944
  } else if (this.timeout) {
148933
148945
  if (this.timeout.refresh) {
148934
148946
  this.timeout.refresh();
@@ -154794,7 +154806,7 @@ var require_mock_utils = __commonJS({
154794
154806
  if (mockDispatch2.data.callback) {
154795
154807
  mockDispatch2.data = { ...mockDispatch2.data, ...mockDispatch2.data.callback(opts) };
154796
154808
  }
154797
- const { data: { statusCode, data, headers, trailers, error }, delay: delay4, persist: persist4 } = mockDispatch2;
154809
+ const { data: { statusCode, data, headers, trailers, error }, delay: delay5, persist: persist4 } = mockDispatch2;
154798
154810
  const { timesInvoked, times } = mockDispatch2;
154799
154811
  mockDispatch2.consumed = !persist4 && timesInvoked >= times;
154800
154812
  mockDispatch2.pending = timesInvoked < times;
@@ -154817,11 +154829,11 @@ var require_mock_utils = __commonJS({
154817
154829
  handler.onError(err);
154818
154830
  }
154819
154831
  handler.onConnect?.(abort, null);
154820
- if (typeof delay4 === "number" && delay4 > 0) {
154832
+ if (typeof delay5 === "number" && delay5 > 0) {
154821
154833
  timer = setTimeout(() => {
154822
154834
  timer = null;
154823
154835
  handleReply(this[kDispatches]);
154824
- }, delay4);
154836
+ }, delay5);
154825
154837
  } else {
154826
154838
  handleReply(this[kDispatches]);
154827
154839
  }
@@ -155101,7 +155113,7 @@ var require_mock_interceptor = __commonJS({
155101
155113
  var require_mock_client = __commonJS({
155102
155114
  "../node_modules/undici/lib/mock/mock-client.js"(exports, module) {
155103
155115
  "use strict";
155104
- var { promisify: promisify9 } = __require("node:util");
155116
+ var { promisify: promisify10 } = __require("node:util");
155105
155117
  var Client2 = require_client2();
155106
155118
  var { buildMockDispatch } = require_mock_utils();
155107
155119
  var {
@@ -155149,7 +155161,7 @@ var require_mock_client = __commonJS({
155149
155161
  this[kDispatches] = [];
155150
155162
  }
155151
155163
  async [kClose]() {
155152
- await promisify9(this[kOriginalClose])();
155164
+ await promisify10(this[kOriginalClose])();
155153
155165
  this[kConnected] = 0;
155154
155166
  this[kMockAgent][Symbols.kClients].delete(this[kOrigin]);
155155
155167
  }
@@ -155362,7 +155374,7 @@ var require_mock_call_history = __commonJS({
155362
155374
  var require_mock_pool = __commonJS({
155363
155375
  "../node_modules/undici/lib/mock/mock-pool.js"(exports, module) {
155364
155376
  "use strict";
155365
- var { promisify: promisify9 } = __require("node:util");
155377
+ var { promisify: promisify10 } = __require("node:util");
155366
155378
  var Pool = require_pool();
155367
155379
  var { buildMockDispatch } = require_mock_utils();
155368
155380
  var {
@@ -155410,7 +155422,7 @@ var require_mock_pool = __commonJS({
155410
155422
  this[kDispatches] = [];
155411
155423
  }
155412
155424
  async [kClose]() {
155413
- await promisify9(this[kOriginalClose])();
155425
+ await promisify10(this[kOriginalClose])();
155414
155426
  this[kConnected] = 0;
155415
155427
  this[kMockAgent][Symbols.kClients].delete(this[kOrigin]);
155416
155428
  }
@@ -288327,9 +288339,9 @@ function inferHoleRadius(lower) {
288327
288339
  function inferHoleCount(lower) {
288328
288340
  if (!/hole|bolt|mount|screw|fastener/.test(lower))
288329
288341
  return 0;
288330
- const numeric = lower.match(/\b(\d{1,2})\s*(?:x\s*)?(?:corner\s*)?(?:mounting\s*)?(?:holes?|bolts?|screws?|fasteners?)\b/);
288331
- if (numeric)
288332
- return clampInteger(Number(numeric[1]), 0, 16, 4);
288342
+ const numeric2 = lower.match(/\b(\d{1,2})\s*(?:x\s*)?(?:corner\s*)?(?:mounting\s*)?(?:holes?|bolts?|screws?|fasteners?)\b/);
288343
+ if (numeric2)
288344
+ return clampInteger(Number(numeric2[1]), 0, 16, 4);
288333
288345
  const wordCounts = {
288334
288346
  one: 1,
288335
288347
  two: 2,
@@ -289570,12 +289582,12 @@ ${plan.notes.map((n2) => `- ${n2}`).join("\n")}`,
289570
289582
  durationMs: Date.now() - t0
289571
289583
  };
289572
289584
  }
289573
- const delay4 = Math.min(BASE_DELAY * Math.pow(2, attempt - 1), MAX_BACKOFF);
289585
+ const delay5 = Math.min(BASE_DELAY * Math.pow(2, attempt - 1), MAX_BACKOFF);
289574
289586
  this.emitProgress({
289575
289587
  stage: "generate",
289576
- message: `Attempt ${attempt} ${msg.includes("timed out") ? "timed out" : "backend unavailable"}, retrying in ${Math.round(delay4 / 1e3)}s...`
289588
+ message: `Attempt ${attempt} ${msg.includes("timed out") ? "timed out" : "backend unavailable"}, retrying in ${Math.round(delay5 / 1e3)}s...`
289577
289589
  });
289578
- await new Promise((r2) => setTimeout(r2, delay4));
289590
+ await new Promise((r2) => setTimeout(r2, delay5));
289579
289591
  }
289580
289592
  }
289581
289593
  let result = {};
@@ -298094,6 +298106,9 @@ function validateCardTransition(from3, to) {
298094
298106
  return { valid: true, message: "transition allowed" };
298095
298107
  }
298096
298108
  function verifyCardEvidence(card) {
298109
+ const declaredVerifierEvidence = verifyDeclaredVerifierEvidence(card);
298110
+ if (!declaredVerifierEvidence.valid)
298111
+ return declaredVerifierEvidence;
298097
298112
  const compileEvidence = verifyCompileCardEvidence(card);
298098
298113
  if (!compileEvidence.valid)
298099
298114
  return compileEvidence;
@@ -298115,6 +298130,13 @@ function verifyCardEvidence(card) {
298115
298130
  });
298116
298131
  return { valid: missing.length === 0, missing };
298117
298132
  }
298133
+ function verifyDeclaredVerifierEvidence(card) {
298134
+ const verifier = normalizeCommandText(card.verifierCommand ?? "");
298135
+ if (!verifier)
298136
+ return { valid: true, missing: [] };
298137
+ const hasExactLiveCommand = card.evidence.some((evidence) => evidence.kind === "tool_result" && normalizeCommandText(evidence.command ?? "") === verifier);
298138
+ return hasExactLiveCommand ? { valid: true, missing: [] } : { valid: false, missing: [`live verifier output: ${card.verifierCommand}`] };
298139
+ }
298118
298140
  function verifyCompileCardEvidence(card) {
298119
298141
  if (!card.diagnosticFingerprint && !card.id.startsWith("compile-")) {
298120
298142
  return { valid: true, missing: [] };
@@ -491768,14 +491790,14 @@ ${content}
491768
491790
  function getOrganizeImportsUnicodeStringComparer(ignoreCase, preferences) {
491769
491791
  const resolvedLocale = getOrganizeImportsLocale(preferences);
491770
491792
  const caseFirst = preferences.organizeImportsCaseFirst ?? false;
491771
- const numeric = preferences.organizeImportsNumericCollation ?? false;
491793
+ const numeric2 = preferences.organizeImportsNumericCollation ?? false;
491772
491794
  const accents = preferences.organizeImportsAccentCollation ?? true;
491773
491795
  const sensitivity = ignoreCase ? accents ? "accent" : "base" : accents ? "variant" : "case";
491774
491796
  const collator = new Intl.Collator(resolvedLocale, {
491775
491797
  usage: "sort",
491776
491798
  caseFirst: caseFirst || "false",
491777
491799
  sensitivity,
491778
- numeric
491800
+ numeric: numeric2
491779
491801
  });
491780
491802
  return collator.compare;
491781
491803
  }
@@ -502591,12 +502613,12 @@ ${options2.prefix}` : "\n" : options2.prefix
502591
502613
  * of the new one. (Note that the amount of time the canceled operation had been
502592
502614
  * waiting does not affect the amount of time that the new operation waits.)
502593
502615
  */
502594
- schedule(operationId, delay4, cb) {
502616
+ schedule(operationId, delay5, cb) {
502595
502617
  const pendingTimeout = this.pendingTimeouts.get(operationId);
502596
502618
  if (pendingTimeout) {
502597
502619
  this.host.clearTimeout(pendingTimeout);
502598
502620
  }
502599
- this.pendingTimeouts.set(operationId, this.host.setTimeout(_ThrottledOperations.run, delay4, operationId, this, cb));
502621
+ this.pendingTimeouts.set(operationId, this.host.setTimeout(_ThrottledOperations.run, delay5, operationId, this, cb));
502600
502622
  if (this.logger) {
502601
502623
  this.logger.info(`Scheduled: ${operationId}${pendingTimeout ? ", Cancelled earlier one" : ""}`);
502602
502624
  }
@@ -502616,9 +502638,9 @@ ${options2.prefix}` : "\n" : options2.prefix
502616
502638
  }
502617
502639
  };
502618
502640
  var GcTimer = class _GcTimer {
502619
- constructor(host, delay4, logger2) {
502641
+ constructor(host, delay5, logger2) {
502620
502642
  this.host = host;
502621
- this.delay = delay4;
502643
+ this.delay = delay5;
502622
502644
  this.logger = logger2;
502623
502645
  }
502624
502646
  scheduleCollect() {
@@ -512967,12 +512989,12 @@ Project '${project.projectName}' (${ProjectKind[project.projectKind]}) ${counter
512967
512989
  const project = this.projectService.tryGetDefaultProjectForFile(fileName);
512968
512990
  return project && { fileName, project };
512969
512991
  }
512970
- getDiagnostics(next, delay4, fileArgs) {
512992
+ getDiagnostics(next, delay5, fileArgs) {
512971
512993
  if (this.suppressDiagnosticEvents) {
512972
512994
  return;
512973
512995
  }
512974
512996
  if (fileArgs.length > 0) {
512975
- this.updateErrorCheck(next, fileArgs, delay4);
512997
+ this.updateErrorCheck(next, fileArgs, delay5);
512976
512998
  }
512977
512999
  }
512978
513000
  change(args) {
@@ -513372,7 +513394,7 @@ Additional information: BADCLIENT: Bad error code, ${badCode} not found in range
513372
513394
  const spans = languageService.getBraceMatchingAtPosition(file, position);
513373
513395
  return !spans ? void 0 : simplifiedResult ? spans.map((span) => toProtocolTextSpan(span, scriptInfo)) : spans;
513374
513396
  }
513375
- getDiagnosticsForProject(next, delay4, fileName) {
513397
+ getDiagnosticsForProject(next, delay5, fileName) {
513376
513398
  if (this.suppressDiagnosticEvents) {
513377
513399
  return;
513378
513400
  }
@@ -513417,7 +513439,7 @@ Additional information: BADCLIENT: Bad error code, ${badCode} not found in range
513417
513439
  this.updateErrorCheck(
513418
513440
  next,
513419
513441
  checkList,
513420
- delay4,
513442
+ delay5,
513421
513443
  /*requireOpen*/
513422
513444
  false
513423
513445
  );
@@ -514947,7 +514969,7 @@ var require_commonjs2 = __commonJS({
514947
514969
  var commaPattern = /\\,/g;
514948
514970
  var periodPattern = /\\\./g;
514949
514971
  exports.EXPANSION_MAX = 1e5;
514950
- function numeric(str) {
514972
+ function numeric2(str) {
514951
514973
  return !isNaN(str) ? parseInt(str, 10) : str.charCodeAt(0);
514952
514974
  }
514953
514975
  function escapeBraces(str) {
@@ -515037,10 +515059,10 @@ var require_commonjs2 = __commonJS({
515037
515059
  }
515038
515060
  let N;
515039
515061
  if (isSequence && n2[0] !== void 0 && n2[1] !== void 0) {
515040
- const x = numeric(n2[0]);
515041
- const y = numeric(n2[1]);
515062
+ const x = numeric2(n2[0]);
515063
+ const y = numeric2(n2[1]);
515042
515064
  const width = Math.max(n2[0].length, n2[1].length);
515043
- let incr = n2.length === 3 && n2[2] !== void 0 ? Math.max(Math.abs(numeric(n2[2])), 1) : 1;
515065
+ let incr = n2.length === 3 && n2[2] !== void 0 ? Math.max(Math.abs(numeric2(n2[2])), 1) : 1;
515044
515066
  let test = lte;
515045
515067
  const reverse = y < x;
515046
515068
  if (reverse) {
@@ -563021,8 +563043,8 @@ var init_VllmBackend = __esm({
563021
563043
  const errorText = await response.text().catch(() => "");
563022
563044
  const isRetryable = response.status >= 500 || response.status === 429;
563023
563045
  if (isRetryable && attempt < this.maxRetries) {
563024
- const delay4 = Math.min(100 * Math.pow(2, attempt), 2e3);
563025
- await new Promise((r2) => setTimeout(r2, delay4));
563046
+ const delay5 = Math.min(100 * Math.pow(2, attempt), 2e3);
563047
+ await new Promise((r2) => setTimeout(r2, delay5));
563026
563048
  return this.postWithRetry(path16, body, attempt + 1);
563027
563049
  }
563028
563050
  throw new Error(`vLLM POST ${path16} failed with HTTP ${response.status}: ${errorText}`);
@@ -563032,8 +563054,8 @@ var init_VllmBackend = __esm({
563032
563054
  clearTimeout(timer);
563033
563055
  const isNetworkError2 = err instanceof TypeError || err instanceof Error && err.name === "AbortError";
563034
563056
  if (isNetworkError2 && attempt < this.maxRetries) {
563035
- const delay4 = Math.min(100 * Math.pow(2, attempt), 2e3);
563036
- await new Promise((r2) => setTimeout(r2, delay4));
563057
+ const delay5 = Math.min(100 * Math.pow(2, attempt), 2e3);
563058
+ await new Promise((r2) => setTimeout(r2, delay5));
563037
563059
  return this.postWithRetry(path16, body, attempt + 1);
563038
563060
  }
563039
563061
  throw err;
@@ -563281,8 +563303,8 @@ var init_OllamaBackend = __esm({
563281
563303
  const errorText = await response.text().catch(() => "");
563282
563304
  const isRetryable = response.status >= 500 || response.status === 429;
563283
563305
  if (isRetryable && attempt < this.maxRetries) {
563284
- const delay4 = Math.min(100 * Math.pow(2, attempt), 2e3);
563285
- await new Promise((r2) => setTimeout(r2, delay4));
563306
+ const delay5 = Math.min(100 * Math.pow(2, attempt), 2e3);
563307
+ await new Promise((r2) => setTimeout(r2, delay5));
563286
563308
  return this.postWithRetry(path16, body, attempt + 1);
563287
563309
  }
563288
563310
  throw new Error(`Ollama POST ${path16} failed with HTTP ${response.status}: ${errorText}`);
@@ -563292,8 +563314,8 @@ var init_OllamaBackend = __esm({
563292
563314
  clearTimeout(timer);
563293
563315
  const isNetworkError2 = err instanceof TypeError || err instanceof Error && err.name === "AbortError";
563294
563316
  if (isNetworkError2 && attempt < this.maxRetries) {
563295
- const delay4 = Math.min(100 * Math.pow(2, attempt), 2e3);
563296
- await new Promise((r2) => setTimeout(r2, delay4));
563317
+ const delay5 = Math.min(100 * Math.pow(2, attempt), 2e3);
563318
+ await new Promise((r2) => setTimeout(r2, delay5));
563297
563319
  return this.postWithRetry(path16, body, attempt + 1);
563298
563320
  }
563299
563321
  throw err;
@@ -565670,9 +565692,9 @@ var init_verifierRunner = __esm({
565670
565692
  async executeTests(patch, repoRoot) {
565671
565693
  if (patch.testsToRun.length === 0)
565672
565694
  return "(no tests specified)";
565673
- const { execFile: execFile11 } = await import("node:child_process");
565674
- const { promisify: promisify9 } = await import("node:util");
565675
- const execFileAsync6 = promisify9(execFile11);
565695
+ const { execFile: execFile12 } = await import("node:child_process");
565696
+ const { promisify: promisify10 } = await import("node:util");
565697
+ const execFileAsync7 = promisify10(execFile12);
565676
565698
  const outputs = [];
565677
565699
  const workDir = this.options.workingDir || repoRoot;
565678
565700
  for (const cmd of patch.testsToRun.slice(0, 3)) {
@@ -565681,7 +565703,7 @@ var init_verifierRunner = __esm({
565681
565703
  const [bin, ...args] = parts;
565682
565704
  if (!bin)
565683
565705
  continue;
565684
- const { stdout, stderr } = await execFileAsync6(bin, args, {
565706
+ const { stdout, stderr } = await execFileAsync7(bin, args, {
565685
565707
  cwd: workDir,
565686
565708
  timeout: 15e3,
565687
565709
  maxBuffer: 1024 * 1024
@@ -574071,15 +574093,19 @@ function buildTrajectoryCheckpoint(input) {
574071
574093
  const latestFailure = [...observations].reverse().find((item) => item.type === "tool_result" && item.success === false || item.type === "error");
574072
574094
  const failureText = sanitizeTrajectoryText(latestFailure?.content, 300);
574073
574095
  const fallbackFailure = input.recentFailures?.at(-1);
574096
+ const failureTurn = Math.max(typeof latestFailure?.turn === "number" ? latestFailure.turn : -1, typeof fallbackFailure?.turn === "number" ? fallbackFailure.turn : -1);
574097
+ const verifiedFailureRecovery = input.lastVerifier?.passed === true && typeof input.lastVerifier.turn === "number" && input.lastVerifier.turn > failureTurn;
574074
574098
  const combinedFailure = [
574075
- failureText,
574076
- sanitizeTrajectoryText(fallbackFailure?.error || fallbackFailure?.output, 300)
574099
+ ...verifiedFailureRecovery ? [] : [
574100
+ failureText,
574101
+ sanitizeTrajectoryText(fallbackFailure?.error || fallbackFailure?.output, 300)
574102
+ ]
574077
574103
  ].filter(Boolean).join(" ");
574078
574104
  const focus = sanitizeTrajectoryText(input.focusDirective, 300);
574079
574105
  const targetPath = inferTargetPath(combinedFailure || outcomeText || focus) ?? latestFailure?.targetPath ?? mostRecentTargetForTool(observations, latestFailure?.toolName);
574080
574106
  const targetFreshness = targetPath ? input.evidenceFreshness?.(targetPath) ?? "unknown" : "unknown";
574081
574107
  const modifiedFiles = Array.from(state.modifiedFiles).slice(-3);
574082
- const fullWriteIssue = (latestFailure?.toolName === "file_write" || fallbackFailure?.tool === "file_write" || /file_write/i.test(combinedFailure)) && /FULL FILE (?:WRITE LOOP BLOCKED|REWRITE CONTRACT)|overwrite(?:=true)?|expected_hash|Refusing to overwrite existing file/i.test(combinedFailure);
574108
+ const fullWriteIssue = !verifiedFailureRecovery && (latestFailure?.toolName === "file_write" || fallbackFailure?.tool === "file_write" || /file_write/i.test(combinedFailure)) && /FULL FILE (?:WRITE LOOP BLOCKED|REWRITE CONTRACT)|overwrite(?:=true)?|expected_hash|Refusing to overwrite existing file/i.test(combinedFailure);
574083
574109
  const fullWriteRecoveredByMutation = fullWriteIssue && Boolean(targetPath) && modifiedFiles.some(([path16]) => sameProjectPath(path16, targetPath)) && typeof latestFailure?.turn === "number" && typeof input.lastMutationTurn === "number" && input.lastMutationTurn > latestFailure.turn;
574084
574110
  const explicitBlock = /(?:permission denied|needs user input|ask_user|cannot proceed|external dependency|\[.*BLOCKED\])/i.test(combinedFailure);
574085
574111
  const hasRecentFailure = Boolean(combinedFailure);
@@ -578615,17 +578641,12 @@ var init_context_fabric = __esm({
578615
578641
  "Scope: runtime state for the next action. Do not quote or re-emit this frame. Prior evidence is orientation; execute a narrow file_read or the declared verifier whenever current text/hash or post-mutation proof is required."
578616
578642
  ].filter(Boolean);
578617
578643
  let content = [...header, "", ...sectionLines].join("\n").trim();
578618
- const controlChars = included.filter(isControlSignal).reduce((sum2, signal) => sum2 + signal.content.length, 0);
578619
- const evidenceChars = included.filter(isEvidenceSignal).reduce((sum2, signal) => sum2 + signal.content.length, 0);
578620
- const controlToEvidenceRatio = Number((controlChars / Math.max(1, evidenceChars)).toFixed(3));
578644
+ let visibleIncluded = [...included];
578645
+ let controlChars = 0;
578646
+ let evidenceChars = 0;
578647
+ let controlToEvidenceRatio = 0;
578621
578648
  const qualityWarnings = [];
578622
578649
  const maxControlRatio = options2.maxControlToEvidenceRatio ?? 0.45;
578623
- if (controlToEvidenceRatio > maxControlRatio) {
578624
- qualityWarnings.push(`control_context_ratio_high:${controlToEvidenceRatio}`);
578625
- }
578626
- const activeFrameCount = (content.match(/\[ACTIVE CONTEXT FRAME\]/g) ?? []).length;
578627
- if (activeFrameCount > 1)
578628
- qualityWarnings.push(`active_frame_count:${activeFrameCount}`);
578629
578650
  if (sectionLines.length === 0) {
578630
578651
  return {
578631
578652
  content: null,
@@ -578661,6 +578682,21 @@ var init_context_fabric = __esm({
578661
578682
  dropped.push(signal);
578662
578683
  }
578663
578684
  }
578685
+ visibleIncluded = included.filter((signal) => content.includes(signal.content));
578686
+ for (const signal of included) {
578687
+ if (!visibleIncluded.includes(signal) && !dropped.includes(signal)) {
578688
+ dropped.push(signal);
578689
+ }
578690
+ }
578691
+ controlChars = visibleIncluded.filter(isControlSignal).reduce((sum2, signal) => sum2 + signal.content.length, 0);
578692
+ evidenceChars = visibleIncluded.filter(isEvidenceSignal).reduce((sum2, signal) => sum2 + signal.content.length, 0);
578693
+ controlToEvidenceRatio = Number((controlChars / Math.max(1, evidenceChars)).toFixed(3));
578694
+ if (controlToEvidenceRatio > maxControlRatio) {
578695
+ qualityWarnings.push(`control_context_ratio_high:${controlToEvidenceRatio}`);
578696
+ }
578697
+ const activeFrameCount = (content.match(/\[ACTIVE CONTEXT FRAME\]/g) ?? []).length;
578698
+ if (activeFrameCount > 1)
578699
+ qualityWarnings.push(`active_frame_count:${activeFrameCount}`);
578664
578700
  if (options2.includeDiagnostics) {
578665
578701
  content += `
578666
578702
 
@@ -578669,7 +578705,7 @@ context_fabric: included=${included.length} dropped=${dropped.length} truncated=
578669
578705
  return {
578670
578706
  content,
578671
578707
  diagnostics: {
578672
- includedSignals: included.length,
578708
+ includedSignals: visibleIncluded.length,
578673
578709
  droppedSignals: dropped.length + droppedByAdmission.length,
578674
578710
  hiddenSignals: hidden.length,
578675
578711
  semanticDedupedSignals,
@@ -578678,7 +578714,7 @@ context_fabric: included=${included.length} dropped=${dropped.length} truncated=
578678
578714
  truncatedSignals,
578679
578715
  estimatedTokens: estimateTokens2(content),
578680
578716
  totalChars: content.length,
578681
- semanticChunkCount: included.filter((signal) => signal.kind === "semantic_chunk").length,
578717
+ semanticChunkCount: visibleIncluded.filter((signal) => signal.kind === "semantic_chunk").length,
578682
578718
  controlChars,
578683
578719
  evidenceChars,
578684
578720
  controlToEvidenceRatio,
@@ -578686,7 +578722,7 @@ context_fabric: included=${included.length} dropped=${dropped.length} truncated=
578686
578722
  ...metadataReports,
578687
578723
  sections: sectionDiagnostics
578688
578724
  },
578689
- included,
578725
+ included: visibleIncluded,
578690
578726
  dropped: [...dropped, ...droppedByAdmission, ...hidden]
578691
578727
  };
578692
578728
  }
@@ -578710,7 +578746,7 @@ function isAdmittedFileReadMessage(message2) {
578710
578746
  function isProtectedControllerMessage(message2) {
578711
578747
  return isControllerStateMessage(message2) || isActionGroundTruthMessage(message2) || isActiveSteeringMessage(message2);
578712
578748
  }
578713
- function modelFacingMessageCap(message2) {
578749
+ function modelFacingMessageCapWithLimits(message2, limits) {
578714
578750
  if (isControllerStateMessage(message2)) {
578715
578751
  return MODEL_FACING_CONTROLLER_STATE_CHAR_CAP;
578716
578752
  }
@@ -578721,12 +578757,12 @@ function modelFacingMessageCap(message2) {
578721
578757
  return Math.max(MODEL_FACING_ACTION_GROUND_TRUTH_CHAR_CAP, 7e3);
578722
578758
  }
578723
578759
  if (isAdmittedFileReadMessage(message2)) {
578724
- return MODEL_FACING_ADMITTED_FILE_READ_CHAR_CAP;
578760
+ return limits.admittedFileReadChars ?? MODEL_FACING_ADMITTED_FILE_READ_CHAR_CAP;
578725
578761
  }
578726
578762
  if (message2.role === "tool")
578727
- return MODEL_FACING_TOOL_CHAR_CAP;
578763
+ return limits.toolChars ?? MODEL_FACING_TOOL_CHAR_CAP;
578728
578764
  if (message2.role === "system")
578729
- return MODEL_FACING_SYSTEM_CHAR_CAP;
578765
+ return limits.systemChars ?? MODEL_FACING_SYSTEM_CHAR_CAP;
578730
578766
  return messageText(message2.content).length;
578731
578767
  }
578732
578768
  function stripLegacyRuntimeControlFragments(content) {
@@ -578736,18 +578772,18 @@ function stripLegacyRuntimeControlFragments(content) {
578736
578772
  out = pieces.map((piece) => LEGACY_RUNTIME_CONTROL_FRAGMENT_RE.test(piece) ? "" : piece).join("");
578737
578773
  return collapseWhitespace(out);
578738
578774
  }
578739
- function splitOversizedSystemMessages(messages2) {
578775
+ function splitOversizedSystemMessages(messages2, systemCharCap = MODEL_FACING_SYSTEM_CHAR_CAP) {
578740
578776
  const out = [];
578741
578777
  for (const message2 of messages2) {
578742
- if (message2.role !== "system" || typeof message2.content !== "string" || isProtectedControllerMessage(message2) || message2.content.length <= MODEL_FACING_SYSTEM_CHAR_CAP) {
578778
+ if (message2.role !== "system" || typeof message2.content !== "string" || isProtectedControllerMessage(message2) || message2.content.length <= systemCharCap) {
578743
578779
  out.push(message2);
578744
578780
  continue;
578745
578781
  }
578746
578782
  let remaining = message2.content.trim();
578747
- while (remaining.length > MODEL_FACING_SYSTEM_CHAR_CAP) {
578748
- const window2 = remaining.slice(0, MODEL_FACING_SYSTEM_CHAR_CAP);
578783
+ while (remaining.length > systemCharCap) {
578784
+ const window2 = remaining.slice(0, systemCharCap);
578749
578785
  const boundary = Math.max(window2.lastIndexOf("\n\n"), window2.lastIndexOf("\n"));
578750
- const cut = boundary >= Math.floor(MODEL_FACING_SYSTEM_CHAR_CAP * 0.5) ? boundary : MODEL_FACING_SYSTEM_CHAR_CAP;
578786
+ const cut = boundary >= Math.floor(systemCharCap * 0.5) ? boundary : systemCharCap;
578751
578787
  const chunk = remaining.slice(0, cut).trim();
578752
578788
  if (chunk)
578753
578789
  out.push({ ...message2, content: chunk });
@@ -578761,17 +578797,17 @@ function splitOversizedSystemMessages(messages2) {
578761
578797
  function isCurrentGoalMessage(message2) {
578762
578798
  return typeof message2.content === "string" && message2.content.includes("[CURRENT USER GOAL]");
578763
578799
  }
578764
- function applyModelFacingBudget(messages2, preserveFirstSystem) {
578800
+ function applyModelFacingBudget(messages2, preserveFirstSystem, limits = {}) {
578765
578801
  const reservedTransaction = latestResolvedToolTransaction(messages2);
578766
- const reservedChars = [...reservedTransaction].reduce((sum2, index) => sum2 + modelFacingReservedChars(messages2[index]), 0);
578767
- let remaining = Math.max(0, MODEL_FACING_CONTEXT_CHAR_BUDGET - reservedChars);
578802
+ const reservedChars = [...reservedTransaction].reduce((sum2, index) => sum2 + modelFacingReservedChars(messages2[index], limits), 0);
578803
+ let remaining = Math.max(0, (limits.contextChars ?? MODEL_FACING_CONTEXT_CHAR_BUDGET) - reservedChars);
578768
578804
  const kept = [];
578769
578805
  for (let index = 0; index < messages2.length; index++) {
578770
578806
  const message2 = messages2[index];
578771
578807
  const content = messageText(message2.content);
578772
578808
  const isReservedTransactionMessage = reservedTransaction.has(index);
578773
578809
  const isPriorityIntent = message2.role === "user" || isCurrentGoalMessage(message2) || isActiveSteeringMessage(message2);
578774
- const perMessageCap = modelFacingMessageCap(message2);
578810
+ const perMessageCap = modelFacingMessageCapWithLimits(message2, limits);
578775
578811
  const isProtectedController = isProtectedControllerMessage(message2);
578776
578812
  const allowed = isReservedTransactionMessage ? perMessageCap : isPriorityIntent ? content.length : isProtectedController ? perMessageCap : Math.min(remaining, perMessageCap);
578777
578813
  if (!isReservedTransactionMessage && !isPriorityIntent && !isProtectedController && allowed <= 0) {
@@ -578882,9 +578918,9 @@ function latestResolvedToolTransaction(messages2) {
578882
578918
  }
578883
578919
  return /* @__PURE__ */ new Set();
578884
578920
  }
578885
- function modelFacingReservedChars(message2) {
578921
+ function modelFacingReservedChars(message2, limits = {}) {
578886
578922
  const content = messageText(message2.content);
578887
- const cap = modelFacingMessageCap(message2);
578923
+ const cap = modelFacingMessageCapWithLimits(message2, limits);
578888
578924
  return Math.min(content.length, cap);
578889
578925
  }
578890
578926
  function retireLinkedAssistantReadIntents(messages2) {
@@ -578906,6 +578942,64 @@ function retireLinkedAssistantReadIntents(messages2) {
578906
578942
  return { ...message2, content: ASSISTANT_READ_INTENT_RETIRED_MARKER };
578907
578943
  });
578908
578944
  }
578945
+ function retireHistoricalAssistantNarratives(messages2) {
578946
+ const resolvedToolCallIds = new Set(messages2.filter((message2) => message2.role === "tool").map(linkedToolCallId).filter((id2) => id2 !== null));
578947
+ const newestTransaction = latestResolvedToolTransaction(messages2);
578948
+ const keepFreeform = /* @__PURE__ */ new Set();
578949
+ let freeformSlots = 1;
578950
+ const assistantControllerRecap = /(?:\[?(?:controller state v1|active context frame|trajectory checkpoint|branch-extract(?: v\d+)?|recent action ground truth)\]?|\b(?:controller|admin)\s+(?:directive|state|summary|recap|reflection)\b|\b(?:verifier|compile)\s+(?:is\s+)?locked\b|\b(?:read tool|read wrapper)\s+(?:is|was)\s+(?:contaminated|untrusted)\b|\b(?:failure|recovery|doom)[ -]?(?:loop|recap|summary)\b)/i;
578951
+ for (let index = messages2.length - 1; index >= 0; index--) {
578952
+ const message2 = messages2[index];
578953
+ if (message2.role !== "assistant" || typeof message2.content !== "string" || toolCallIds(message2).length > 0 || !message2.content.trim() || assistantControllerRecap.test(message2.content)) {
578954
+ continue;
578955
+ }
578956
+ if (freeformSlots-- > 0)
578957
+ keepFreeform.add(index);
578958
+ }
578959
+ return messages2.map((message2, index) => {
578960
+ if (message2.role !== "assistant" || typeof message2.content !== "string") {
578961
+ return message2;
578962
+ }
578963
+ if (assistantControllerRecap.test(message2.content)) {
578964
+ return { ...message2, content: "" };
578965
+ }
578966
+ const callIds = toolCallIds(message2);
578967
+ if (callIds.length > 0) {
578968
+ const allResolved = callIds.every((id2) => resolvedToolCallIds.has(id2));
578969
+ if (allResolved && !newestTransaction.has(index)) {
578970
+ return { ...message2, content: "" };
578971
+ }
578972
+ return message2;
578973
+ }
578974
+ if (!keepFreeform.has(index))
578975
+ return { ...message2, content: "" };
578976
+ return message2;
578977
+ });
578978
+ }
578979
+ function retireHistoricalRunEvidence(messages2) {
578980
+ const retainedByBucket = /* @__PURE__ */ new Map();
578981
+ const limitByBucket = {
578982
+ discovery: 3,
578983
+ mutation: 2,
578984
+ verification: 1
578985
+ };
578986
+ const out = [...messages2];
578987
+ for (let index = out.length - 1; index >= 0; index--) {
578988
+ const message2 = out[index];
578989
+ if (message2.role !== "system" || typeof message2.content !== "string" || !message2.content.includes("[RUN EVIDENCE]")) {
578990
+ continue;
578991
+ }
578992
+ const text2 = message2.content.toLowerCase();
578993
+ const bucket = /\b(?:file_edit|file_write|patch|apply_patch)\b/.test(text2) ? "mutation" : /\b(?:shell|verifier|compile|build|test)\b/.test(text2) ? "verification" : "discovery";
578994
+ const retained = retainedByBucket.get(bucket) ?? 0;
578995
+ if (retained >= limitByBucket[bucket]) {
578996
+ out[index] = { ...message2, content: "" };
578997
+ continue;
578998
+ }
578999
+ retainedByBucket.set(bucket, retained + 1);
579000
+ }
579001
+ return out.filter((message2) => message2.role !== "system" || typeof message2.content !== "string" || message2.content.trim());
579002
+ }
578909
579003
  function runtimeControlSemanticKey(content) {
578910
579004
  const normalized = content.replace(/\s+/g, " ").trim().toLowerCase();
578911
579005
  if (!normalized)
@@ -578969,9 +579063,13 @@ function hasAssistantPayload(message2) {
578969
579063
  }
578970
579064
  function staleToolFailureKey(content) {
578971
579065
  const text2 = content.replace(/\s+/g, " ").trim();
578972
- if (!/(FAILED:|failed again|doom-loop|result compacted|Earlier read of .* cleared)/i.test(text2)) {
579066
+ const runtimeBlock = text2.match(/\[(COMPILE ERROR FIX LOOP BLOCKED|EXPLORATION ADMISSION BLOCK|PARENT(?:\s+[^\]]*)?\s+BLOCK(?:ED)?|FOCUS SUPERVISOR BLOCK|STEERING RECONCILIATION REQUIRED|STALE EDIT LOOP BLOCKED|FULL FILE WRITE LOOP BLOCKED)[^\]]*\]/i);
579067
+ if (!/(FAILED:|failed again|doom-loop|result compacted|Earlier read of .* cleared)/i.test(text2) && !runtimeBlock) {
578973
579068
  return null;
578974
579069
  }
579070
+ if (runtimeBlock) {
579071
+ return `runtime-block|${runtimeBlock[1].toLowerCase().replace(/\s+/g, "-")}`;
579072
+ }
578975
579073
  const tool = text2.match(/^\[?([a-zA-Z_][a-zA-Z0-9_]*)\(/)?.[1] ?? "tool";
578976
579074
  const path16 = text2.match(/"path"\s*:\s*"([^"]+)"/)?.[1] ?? text2.match(/Earlier read of ([^ ]+) cleared/)?.[1] ?? "";
578977
579075
  const family = text2.match(/FAILED:\s*\[([^\]\n]+)/i)?.[1] ?? text2.match(/(doom-loop[^.]+)/i)?.[1] ?? text2.match(/(Earlier read of [^ ]+ cleared)/i)?.[1] ?? "failure";
@@ -579003,6 +579101,12 @@ function retireDuplicateToolFailures(messages2) {
579003
579101
  }
579004
579102
  function prepareModelFacingApiMessages(input) {
579005
579103
  const preserveFirstSystem = input.preserveFirstSystem !== false;
579104
+ const limits = {
579105
+ contextChars: input.contextBudgetChars,
579106
+ systemChars: input.systemMessageChars,
579107
+ toolChars: input.toolMessageChars,
579108
+ admittedFileReadChars: input.admittedFileReadChars
579109
+ };
579006
579110
  const sanitized = [];
579007
579111
  const withoutLegacyControl = input.messages.flatMap((message2) => {
579008
579112
  if (message2.role !== "system" || typeof message2.content !== "string" || isProtectedControllerMessage(message2)) {
@@ -579011,7 +579115,7 @@ function prepareModelFacingApiMessages(input) {
579011
579115
  const stripped = stripLegacyRuntimeControlFragments(message2.content);
579012
579116
  return stripped ? [{ ...message2, content: stripped }] : [];
579013
579117
  });
579014
- const independentlyBounded = splitOversizedSystemMessages(withoutLegacyControl);
579118
+ const independentlyBounded = splitOversizedSystemMessages(withoutLegacyControl, limits.systemChars);
579015
579119
  for (let index = 0; index < independentlyBounded.length; index++) {
579016
579120
  const rawMessage = independentlyBounded[index];
579017
579121
  const message2 = {
@@ -579070,7 +579174,7 @@ function prepareModelFacingApiMessages(input) {
579070
579174
  }
579071
579175
  seenSystemKeys.add(key);
579072
579176
  }
579073
- const deduped = retireDuplicateToolFailures(epochScoped.filter((_message, index) => keep[index]));
579177
+ const deduped = retireDuplicateToolFailures(retireHistoricalRunEvidence(epochScoped.filter((_message, index) => keep[index])));
579074
579178
  if (!hasUserMessage(deduped) && !hasConcreteGoalMessage(deduped)) {
579075
579179
  const goal = deriveCurrentGoal({
579076
579180
  explicitGoal: input.currentGoal,
@@ -579088,7 +579192,8 @@ function prepareModelFacingApiMessages(input) {
579088
579192
  const insertAt = preserveFirstSystem && deduped[0]?.role === "system" ? 1 : 0;
579089
579193
  deduped.splice(insertAt, 0, goalMessage);
579090
579194
  }
579091
- return retireLinkedAssistantReadIntents(applyModelFacingBudget(deduped, preserveFirstSystem));
579195
+ const historyPruned = retireHistoricalAssistantNarratives(retireLinkedAssistantReadIntents(deduped));
579196
+ return applyModelFacingBudget(historyPruned, preserveFirstSystem, limits).filter((message2) => message2.role !== "assistant" || hasAssistantPayload(message2));
579092
579197
  }
579093
579198
  function deriveCurrentGoal(input) {
579094
579199
  const explicit = sanitizeModelVisibleContextText(input.explicitGoal ?? "");
@@ -579275,9 +579380,9 @@ var init_evidenceLedger = __esm({
579275
579380
  const { path: path16, content, range, fileVersion, turn } = input;
579276
579381
  if (!path16 || !content)
579277
579382
  return;
579278
- const built = buildExtract(content);
579279
- if (input.fidelity)
579280
- built.fidelity = input.fidelity;
579383
+ const built = input.fidelity === "full" ? { text: content, fidelity: "full" } : buildExtract(content);
579384
+ if (input.fidelity === "extract")
579385
+ built.fidelity = "extract";
579281
579386
  const existing = this.entries.get(path16);
579282
579387
  if (existing && existing.readVersion === fileVersion && !existing.stale) {
579283
579388
  const keepNew = input.fidelity === "extract" || built.text.length >= existing.content.length;
@@ -580863,7 +580968,7 @@ ${input.error}`;
580863
580968
  diagnoses.add("tool-failure");
580864
580969
  if (input.failureKind)
580865
580970
  diagnoses.add(input.failureKind);
580866
- if (out.includes("[FOCUS SUPERVISOR BLOCK]")) {
580971
+ if (!input.success && out.includes("[FOCUS SUPERVISOR BLOCK]")) {
580867
580972
  diagnoses.add("focus-supervisor-block");
580868
580973
  }
580869
580974
  if (input.toolName === "task_status" && /Task not found/i.test(out)) {
@@ -581797,7 +581902,7 @@ var init_focusSupervisor = __esm({
581797
581902
  this.expireDirectiveIfNeeded(this.lastObservedTurn);
581798
581903
  if (!this.enabled || !this.directive)
581799
581904
  return null;
581800
- if (this.modelTier === "large")
581905
+ if (this.modelTier !== "small")
581801
581906
  return null;
581802
581907
  const d2 = this.directive;
581803
581908
  return [
@@ -582178,13 +582283,10 @@ var init_focusSupervisor = __esm({
582178
582283
  return true;
582179
582284
  if (this.mode === "off")
582180
582285
  return false;
582181
- if (this.modelTier === "small" || this.modelTier === "medium")
582286
+ if (this.modelTier === "small")
582182
582287
  return true;
582183
- if (!context2)
582184
- return false;
582185
- const pressure = context2.pressureRatio ?? 0;
582186
- const ratio = context2.signalToNoiseRatio;
582187
- return pressure >= 0.85 || ratio !== void 0 && ratio < 1.2;
582288
+ void context2;
582289
+ return false;
582188
582290
  }
582189
582291
  hasLowSignalContext(context2) {
582190
582292
  if (!context2)
@@ -584658,12 +584760,12 @@ var init_completion_resolution_verifier = __esm({
584658
584760
  import { createHash as createHash33 } from "node:crypto";
584659
584761
  function buildBranchExtractionBrief(input) {
584660
584762
  const path16 = cleanBriefText(input.path, 320) || "the requested file";
584661
- const intent = firstBriefText([
584763
+ const intent = fileLocalDiscoveryQuestion(firstBriefText([
584662
584764
  input.assistantIntent,
584663
584765
  input.trajectoryNextAction,
584664
584766
  input.currentStep
584665
- ]);
584666
- const openQuestion = cleanBriefText(input.trajectoryOpenQuestion, 280);
584767
+ ]), path16);
584768
+ const openQuestion = fileLocalDiscoveryQuestion(cleanBriefText(input.trajectoryOpenQuestion, 280), path16);
584667
584769
  const focus = openQuestion || intent;
584668
584770
  const goalAnchor = cleanBriefText(input.goalAnchor || input.currentStep || input.trajectoryAssessment || intent, 320);
584669
584771
  const request = openQuestion ? `Determine the exact file-local facts in ${path16} that answer this unresolved agent question: ${openQuestion}` : intent ? `Identify the exact file-local facts in ${path16} that the active agent needs before it can ${asActionClause(intent)}.` : `Identify the exact declarations, behavior, and configuration in ${path16} needed to choose the next narrow action.`;
@@ -584677,11 +584779,12 @@ function buildBranchExtractionBrief(input) {
584677
584779
  input.recentFailure ? `Recent unresolved evidence: ${cleanBriefText(input.recentFailure, 320)}` : ""
584678
584780
  ]);
584679
584781
  const returnContract = focus ? `Return only the exact declarations, values, behavior, and line spans that resolve: ${focus}` : "Return only the exact declarations, values, behavior, and line spans needed for the next safe action.";
584782
+ const relatedFailure = fileLocalFailureForPath(input.recentFailure, path16);
584680
584783
  const requirementQuestions = uniqueBriefLines([
584681
584784
  openQuestion,
584682
584785
  intent,
584683
- input.currentStep && input.currentStep !== intent ? input.currentStep : "",
584684
- input.recentFailure ? `Which file-local declaration, value, or behavior explains this unresolved failure: ${cleanBriefText(input.recentFailure, 260)}` : ""
584786
+ input.currentStep && input.currentStep !== intent ? fileLocalDiscoveryQuestion(input.currentStep, path16) : "",
584787
+ relatedFailure ? `Which file-local declaration, value, or behavior explains this unresolved failure: ${relatedFailure}` : ""
584685
584788
  ]).slice(0, 3);
584686
584789
  if (requirementQuestions.length === 0) {
584687
584790
  requirementQuestions.push(`Which declarations, values, and behavior in this file are required for the next narrow action?`);
@@ -584689,7 +584792,10 @@ function buildBranchExtractionBrief(input) {
584689
584792
  const requirements = requirementQuestions.map((question, index) => ({
584690
584793
  id: `R${index + 1}`,
584691
584794
  question,
584692
- required: index === 0 || requirementQuestions.length === 1,
584795
+ // A declared discovery question is never decorative. The branch may
584796
+ // return a justified partial result, but it cannot call its contract
584797
+ // complete until every listed requirement has anchored evidence.
584798
+ required: true,
584693
584799
  expectedEvidence: "Exact source declarations, literal values, control/configuration behavior, and their line anchors.",
584694
584800
  searchTerms: queryTerms(question).slice(0, 16)
584695
584801
  }));
@@ -584704,7 +584810,7 @@ function buildBranchExtractionBrief(input) {
584704
584810
  query: cleanBriefText(retrievalQuery, 700),
584705
584811
  requirements,
584706
584812
  completionCriteria: [
584707
- "Every required requirement is either supported by an exact anchored segment or explicitly marked unresolved.",
584813
+ "Every declared requirement is either supported by an exact anchored segment or has an explicit source-based unresolved reason and deterministic recovery action.",
584708
584814
  "Every returned factual claim names its source line span; discontiguous evidence remains separate.",
584709
584815
  "Stop when the contract is satisfied, no new query/range is available, or the bounded search budget is exhausted."
584710
584816
  ],
@@ -584774,6 +584880,28 @@ function uniqueBriefLines(values) {
584774
584880
  function asActionClause(value2) {
584775
584881
  return cleanBriefText(value2, 320).replace(/^to\s+/i, "").replace(/[.?!]+$/, "").replace(/^([A-Z])/, (match) => match.toLowerCase());
584776
584882
  }
584883
+ function fileLocalDiscoveryQuestion(value2, path16) {
584884
+ const clean5 = cleanBriefText(value2, 320);
584885
+ if (!clean5)
584886
+ return "";
584887
+ if (/^(?:exploring|editing|reading|verifying|current|next(?:_valid)?_action)\s*:/i.test(clean5) || /\b(?:controller state|branch-extract|active context frame|file_read block|runtime repair|recovery required)\b/i.test(clean5)) {
584888
+ return "";
584889
+ }
584890
+ const referencedPaths = clean5.match(/[\w./-]+\.(?:[cm]?[jt]sx?|py|cpp|cxx|h(?:pp)?|md|json|yaml|yml)/g) ?? [];
584891
+ const targetBase = path16.split("/").pop() ?? path16;
584892
+ if (referencedPaths.length > 0 && !referencedPaths.some((candidate) => candidate === targetBase || path16.endsWith(candidate))) {
584893
+ return "";
584894
+ }
584895
+ return clean5;
584896
+ }
584897
+ function fileLocalFailureForPath(value2, path16) {
584898
+ const clean5 = fileLocalDiscoveryQuestion(value2, path16);
584899
+ if (!clean5)
584900
+ return "";
584901
+ const targetBase = path16.split("/").pop() ?? path16;
584902
+ const mentionsTarget = clean5.includes(targetBase) || clean5.includes(path16);
584903
+ return mentionsTarget || !/[\w./-]+\.(?:[cm]?[jt]sx?|py|cpp|cxx|h(?:pp)?)/.test(clean5) ? clean5 : "";
584904
+ }
584777
584905
  function selectWindows(lines, terms2) {
584778
584906
  const matched = [];
584779
584907
  for (let i2 = 0; i2 < lines.length; i2++) {
@@ -585019,6 +585147,44 @@ function deterministicSegments(input) {
585019
585147
  });
585020
585148
  return { segments, satisfied: [...satisfied], rounds };
585021
585149
  }
585150
+ function buildRequirementCoverage(input) {
585151
+ return input.requirements.map((requirement) => {
585152
+ const anchors = input.segments.filter((segment) => segment.requirementIds.includes(requirement.id)).map((segment) => ({
585153
+ startLine: segment.anchor.startLine,
585154
+ endLine: segment.anchor.endLine
585155
+ }));
585156
+ if (anchors.length > 0) {
585157
+ return {
585158
+ id: requirement.id,
585159
+ question: requirement.question,
585160
+ status: "satisfied",
585161
+ anchors
585162
+ };
585163
+ }
585164
+ const terms2 = queryTerms(requirement.question);
585165
+ const candidateIndex = input.lines.findIndex((line) => {
585166
+ const lower = line.toLowerCase();
585167
+ return terms2.some((term) => lower.includes(term));
585168
+ });
585169
+ const reason = candidateIndex >= 0 ? "A candidate source line was found, but no bounded, line-anchored segment established the declared requirement." : terms2.length > 0 ? "None of the requirement's discriminating search terms occurred in the selected source range." : "The requirement had no discriminating file-local search term after normalization.";
585170
+ const recovery = candidateIndex >= 0 ? `file_read({"path":${JSON.stringify(input.path)},"offset":${input.sourceLineOffset + Math.max(1, candidateIndex - 3)},"limit":12,"mode":"full"})` : `grep_search({"pattern":${JSON.stringify(terms2[0] ?? requirement.question.slice(0, 80))},"path":${JSON.stringify(input.path)}})`;
585171
+ return {
585172
+ id: requirement.id,
585173
+ question: requirement.question,
585174
+ status: "unresolved",
585175
+ anchors: [],
585176
+ reason,
585177
+ recovery
585178
+ };
585179
+ });
585180
+ }
585181
+ function renderBranchRequirementCoverage(evidence) {
585182
+ return [
585183
+ `[REQUIREMENT COVERAGE]`,
585184
+ ...evidence.requirementCoverage.map((coverage) => coverage.status === "satisfied" ? `- ${coverage.id} satisfied anchors=${coverage.anchors.map((anchor) => `L${anchor.startLine}-L${anchor.endLine}`).join(",")}` : `- ${coverage.id} unresolved reason=${coverage.reason ?? "no bounded anchor returned"} recovery=${coverage.recovery ?? "narrow the source query"}`),
585185
+ `branch_contract=${evidence.contractComplete ? "complete" : "partial"}`
585186
+ ];
585187
+ }
585022
585188
  async function extractEvidence(opts) {
585023
585189
  const { path: path16, content, fileVersion, backend } = opts;
585024
585190
  const sourceLineOffset = Math.max(0, Math.floor(opts.sourceLineOffset ?? 0));
@@ -585051,12 +585217,19 @@ async function extractEvidence(opts) {
585051
585217
  brief,
585052
585218
  maxSegments
585053
585219
  });
585054
- const requiredIds = requirements.filter((requirement) => requirement.required).map((requirement) => requirement.id);
585220
+ const requiredIds = requirements.map((requirement) => requirement.id);
585055
585221
  const deterministicSatisfied = new Set(deterministic.satisfied);
585056
585222
  const deterministicComplete = deterministic.segments.length > 0 && requiredIds.every((id2) => deterministicSatisfied.has(id2));
585057
585223
  if (deterministicComplete && !backend) {
585058
585224
  const claim = renderSegments(deterministic.segments, maxInjectedChars);
585059
585225
  const legacySpan = legacyContiguousSpan(deterministic.segments);
585226
+ const requirementCoverage2 = buildRequirementCoverage({
585227
+ requirements,
585228
+ segments: deterministic.segments,
585229
+ lines,
585230
+ path: path16,
585231
+ sourceLineOffset
585232
+ });
585060
585233
  return {
585061
585234
  path: path16,
585062
585235
  query,
@@ -585068,8 +585241,10 @@ async function extractEvidence(opts) {
585068
585241
  exploredLines: lines.length,
585069
585242
  injectedChars: claim.length,
585070
585243
  segments: deterministic.segments,
585071
- satisfiedRequirementIds: [...deterministicSatisfied],
585072
- unresolvedRequirementIds: requirements.map((requirement) => requirement.id).filter((id2) => !deterministicSatisfied.has(id2)),
585244
+ satisfiedRequirementIds: requirementCoverage2.filter((coverage) => coverage.status === "satisfied").map((coverage) => coverage.id),
585245
+ unresolvedRequirementIds: requirementCoverage2.filter((coverage) => coverage.status === "unresolved").map((coverage) => coverage.id),
585246
+ requirementCoverage: requirementCoverage2,
585247
+ contractComplete: requirementCoverage2.every((coverage) => coverage.status === "satisfied"),
585073
585248
  provenance: {
585074
585249
  contentHash: contentHash2,
585075
585250
  byteCount,
@@ -585177,14 +585352,16 @@ async function extractEvidence(opts) {
585177
585352
  if (semanticSegment && !segments.some((segment) => rangesOverlap(segment.anchor, semanticSegment.anchor))) {
585178
585353
  segments.push(semanticSegment);
585179
585354
  }
585180
- const satisfied = new Set(deterministic.satisfied);
585181
- for (const segment of segments) {
585182
- for (const id2 of segment.requirementIds)
585183
- satisfied.add(id2);
585184
- }
585185
585355
  if (segments.length > 0) {
585186
585356
  const claim = renderSegments(segments, maxInjectedChars);
585187
585357
  const legacySpan = legacyContiguousSpan(segments);
585358
+ const requirementCoverage2 = buildRequirementCoverage({
585359
+ requirements,
585360
+ segments,
585361
+ lines,
585362
+ path: path16,
585363
+ sourceLineOffset
585364
+ });
585188
585365
  return {
585189
585366
  path: path16,
585190
585367
  query,
@@ -585196,8 +585373,10 @@ async function extractEvidence(opts) {
585196
585373
  exploredLines: Math.min(lines.length, parsedWindows.reduce((sum2, window2) => sum2 + (window2.end - window2.start + 1), 0) || lines.length),
585197
585374
  injectedChars: claim.length,
585198
585375
  segments,
585199
- satisfiedRequirementIds: [...satisfied],
585200
- unresolvedRequirementIds: requirements.map((requirement) => requirement.id).filter((id2) => !satisfied.has(id2)),
585376
+ satisfiedRequirementIds: requirementCoverage2.filter((coverage) => coverage.status === "satisfied").map((coverage) => coverage.id),
585377
+ unresolvedRequirementIds: requirementCoverage2.filter((coverage) => coverage.status === "unresolved").map((coverage) => coverage.id),
585378
+ requirementCoverage: requirementCoverage2,
585379
+ contractComplete: requirementCoverage2.every((coverage) => coverage.status === "satisfied"),
585201
585380
  provenance: {
585202
585381
  contentHash: contentHash2,
585203
585382
  byteCount,
@@ -585234,6 +585413,13 @@ async function extractEvidence(opts) {
585234
585413
  matches: 1
585235
585414
  });
585236
585415
  }
585416
+ const requirementCoverage = buildRequirementCoverage({
585417
+ requirements,
585418
+ segments: [structuralSegment],
585419
+ lines,
585420
+ path: path16,
585421
+ sourceLineOffset
585422
+ });
585237
585423
  return {
585238
585424
  path: path16,
585239
585425
  query,
@@ -585246,7 +585432,9 @@ async function extractEvidence(opts) {
585246
585432
  injectedChars: Math.min(structuralClaim.length, maxInjectedChars),
585247
585433
  segments: [structuralSegment],
585248
585434
  satisfiedRequirementIds: [],
585249
- unresolvedRequirementIds: requirements.map((requirement) => requirement.id),
585435
+ unresolvedRequirementIds: requirementCoverage.map((coverage) => coverage.id),
585436
+ requirementCoverage,
585437
+ contractComplete: false,
585250
585438
  provenance: {
585251
585439
  contentHash: contentHash2,
585252
585440
  byteCount,
@@ -585668,16 +585856,32 @@ var init_contextEngine = __esm({
585668
585856
  let evidenceDropped = 0;
585669
585857
  if (allowCompaction && budget && before > budget) {
585670
585858
  const overhead = estimateTokens3([...evidence, ...hints, ...contract]);
585671
- const retained = [];
585672
- let used = overhead;
585673
- for (const message2 of [...input.messages].reverse()) {
585859
+ const lastUserIndex = input.messages.map((message2, index) => message2.role === "user" ? index : -1).filter((index) => index >= 0).at(-1);
585860
+ const lastTransactionStart = Math.max(0, input.messages.length - 3);
585861
+ const protectedIndexes = /* @__PURE__ */ new Set();
585862
+ for (let index = lastTransactionStart; index < input.messages.length; index++) {
585863
+ protectedIndexes.add(index);
585864
+ }
585865
+ if (lastUserIndex !== void 0)
585866
+ protectedIndexes.add(lastUserIndex);
585867
+ input.messages.forEach((message2, index) => {
585868
+ if (message2.role === "system" && /\[(?:ACTIVE USER STEERING|CONTROLLER STATE v1|RECENT ACTION GROUND TRUTH|EXPLORATION ADMISSION BLOCK|COMPILE ERROR FIX LOOP BLOCKED|BRANCH-EXTRACT)/.test(message2.content)) {
585869
+ protectedIndexes.add(index);
585870
+ }
585871
+ });
585872
+ const retainedIndexes = new Set(protectedIndexes);
585873
+ let used = overhead + [...protectedIndexes].reduce((sum2, index) => sum2 + estimateTokens3([input.messages[index]]), 0);
585874
+ for (let index = input.messages.length - 1; index >= 0; index--) {
585875
+ if (retainedIndexes.has(index))
585876
+ continue;
585877
+ const message2 = input.messages[index];
585674
585878
  const cost = estimateTokens3([message2]);
585675
585879
  if (used + cost > budget)
585676
585880
  continue;
585677
- retained.push(message2);
585881
+ retainedIndexes.add(index);
585678
585882
  used += cost;
585679
585883
  }
585680
- compactedMessages = retained.reverse();
585884
+ compactedMessages = input.messages.filter((_message, index) => retainedIndexes.has(index));
585681
585885
  compacted = compactedMessages.length !== input.messages.length;
585682
585886
  evidenceDropped = 0;
585683
585887
  }
@@ -587812,6 +588016,13 @@ function stripShellQuotedSegments(command) {
587812
588016
  }
587813
588017
  return out;
587814
588018
  }
588019
+ function isCompilerLikeVerifierCommand(command) {
588020
+ const normalized = command.toLowerCase();
588021
+ return /\b(?:pio|platformio|tsc|gcc|g\+\+|clang\+\+?|clang|cargo\s+(?:build|check)|go\s+(?:build|test)|javac|gradle|mvn|msbuild|dotnet\s+build|python(?:3)?\s+-m\s+(?:py_compile|compileall)|mypy|pyright)\b/.test(normalized);
588022
+ }
588023
+ function isRecoveryCriticalRuntimeOutcome(content) {
588024
+ return /\[(?:COMPILE ERROR FIX LOOP BLOCKED|EXPLORATION ADMISSION BLOCK|PARENT(?:\s+[^\]]*)?\s+BLOCK(?:ED)?|FOCUS SUPERVISOR BLOCK|STEERING RECONCILIATION REQUIRED|STALE EDIT LOOP BLOCKED|FULL FILE WRITE LOOP BLOCKED)\b/i.test(content);
588025
+ }
587815
588026
  function parsePersistentMemoryMode(value2) {
587816
588027
  if (value2 === "full" || value2 === "deferred" || value2 === "off")
587817
588028
  return value2;
@@ -589191,9 +589402,6 @@ var init_agenticRunner = __esm({
589191
589402
  _branchEvidenceCache = /* @__PURE__ */ new Map();
589192
589403
  /** Latest curated node per canonical path for safe post-compaction recovery. */
589193
589404
  _branchEvidenceByPath = /* @__PURE__ */ new Map();
589194
- /** Exact read fingerprints resolved from canonical evidence, not a fresh tool call. */
589195
- _resolvedReadEvidence = /* @__PURE__ */ new Map();
589196
- _deterministicNarrowReadFallbacks = /* @__PURE__ */ new Set();
589197
589405
  // OBS-1: durable "current observed state" for non-file_read tool outputs
589198
589406
  // (shell/web_fetch/list_directory/…). EvidenceLedger's counterpart for the
589199
589407
  // observation channels that were previously invisible after compaction —
@@ -589221,6 +589429,9 @@ var init_agenticRunner = __esm({
589221
589429
  /** Auto-delegation: directive ids we've already auto-delegated for (once each). */
589222
589430
  _autoDelegatedDirectiveIds = /* @__PURE__ */ new Set();
589223
589431
  _compileFixLoop = null;
589432
+ /** A verifier produced a concrete card; the next parent tool slot is an
589433
+ * orchestrator-owned isolated fixer, not another model-chosen broad edit. */
589434
+ _pendingCompileDelegationCardId = null;
589224
589435
  _declaredVerifierCommand = null;
589225
589436
  _lastDeclaredVerifierOutput = null;
589226
589437
  _lastDeclaredVerifierDiagnostics = [];
@@ -591177,9 +591388,18 @@ Your hypotheses MUST address this specific error, not generic causes.
591177
591388
  }
591178
591389
  }
591179
591390
  _prepareModelFacingMessages(messages2, _turn) {
591391
+ const tier = this.options.modelTier ?? "large";
591392
+ const contextWindow = this.options.contextWindowSize ?? 0;
591393
+ const contextBudgetChars = contextWindow > 0 ? Math.max(48e3, Math.min(384e3, Math.floor(contextWindow * 4 * 0.7))) : tier === "large" ? 16e4 : tier === "medium" ? 96e3 : 48e3;
591394
+ const systemMessageChars = Math.max(8e3, Math.min(32e3, Math.floor(contextBudgetChars * 0.16)));
591395
+ const toolMessageChars = Math.max(6e3, Math.min(64e3, Math.floor(contextBudgetChars * 0.25)));
591180
591396
  const prepared = prepareModelFacingApiMessages({
591181
591397
  messages: messages2,
591182
- currentGoal: this._taskState.originalGoal || this._taskState.goal || this._taskState.currentStep || this._taskState.nextAction || ""
591398
+ currentGoal: this._taskState.originalGoal || this._taskState.goal || this._taskState.currentStep || this._taskState.nextAction || "",
591399
+ contextBudgetChars,
591400
+ systemMessageChars,
591401
+ toolMessageChars,
591402
+ admittedFileReadChars: Math.min(128e3, contextBudgetChars)
591183
591403
  });
591184
591404
  const withCurrentUserIntent = sanitizeHistoryThink(prepared);
591185
591405
  if (!withCurrentUserIntent.some((message2) => message2.role === "user")) {
@@ -591459,6 +591679,8 @@ ${currentIntent.trim().slice(0, 6e3)}`,
591459
591679
  * from main-loop fires in the status emit (e.g. "bf-cycle 2").
591460
591680
  */
591461
591681
  _runReg61Check(turn, toolCallLog, messages2, cycleLabel) {
591682
+ if ((this.options.modelTier ?? "large") !== "small")
591683
+ return;
591462
591684
  const REG61_TURN_FLOOR = 4;
591463
591685
  const REG61_MIN_READS = 3;
591464
591686
  const REG61_NO_WRITE_GAP = 5;
@@ -591579,7 +591801,7 @@ Pick the SMALLEST concrete deliverable from the spec — typically the project e
591579
591801
  const _editPath = _editPaths.find((p2) => !this._decomp2MainContextFiles.has(p2)) ?? "";
591580
591802
  if (!_editPath)
591581
591803
  return null;
591582
- const _hardBlock = process.env["OMNIUS_ENABLE_DECOMP2_HARD_BLOCK"] === "1";
591804
+ const _hardBlock = this._enforcesStrictActionBoundaries() && process.env["OMNIUS_ENABLE_DECOMP2_HARD_BLOCK"] === "1";
591583
591805
  this.emit({
591584
591806
  type: "status",
591585
591807
  content: _hardBlock ? `DECOMP-2 NEW-FILE BLOCK — rejected ${tc.name}('${_editPath}') at turn ${turn}; gate stays active until sub_agent succeeds` : `DECOMP-2 NEW-FILE WARN — ${tc.name}('${_editPath}') at turn ${turn} would have been blocked (${this._decomp2MainContextFiles.size} files edited without sub_agent); proceeding anyway`,
@@ -592078,7 +592300,7 @@ Pick the SMALLEST concrete deliverable from the spec — typically the project e
592078
592300
  return this._declaredVerifierCommand;
592079
592301
  }
592080
592302
  const diagnostics = parseCompilerDiagnostics(output);
592081
- if (diagnostics.length > 0 && !commandIsPureReadOnlyPipeline(trimmed)) {
592303
+ if (diagnostics.length > 0 && isCompilerLikeVerifierCommand(trimmed) && !commandIsPureReadOnlyPipeline(trimmed)) {
592082
592304
  const latched = stripVerifierFallbackSuffix(trimmed);
592083
592305
  return latched || trimmed;
592084
592306
  }
@@ -592187,7 +592409,7 @@ ${extras.join("\n")}`;
592187
592409
  verifierResultSignature,
592188
592410
  verifierStasisCount,
592189
592411
  verifierStasisBlocked: verifierStasisCount >= 3 && !(input.success && diagnostics.length === 0),
592190
- prerequisiteRecoverySignature: void 0
592412
+ prerequisiteRecoverySignatures: []
592191
592413
  };
592192
592414
  if (this._compileFixLoop.verifierStasisBlocked) {
592193
592415
  this.emit({
@@ -592227,6 +592449,9 @@ ${extras.join("\n")}`;
592227
592449
  this._compileFixLoop.cards = this._compileFixLoop.cards.map((card) => card.id === top.id ? top : card);
592228
592450
  this._mirrorCompileFixCardAssigned(top, input.turn);
592229
592451
  }
592452
+ if (this._enforcesStrictActionBoundaries() && !this.options.subAgent && this.tools.has("sub_agent")) {
592453
+ this._pendingCompileDelegationCardId = top.id;
592454
+ }
592230
592455
  this.emit({
592231
592456
  type: "status",
592232
592457
  content: `compile_error_fix_loop_started: verifierCommand=${verifierCommand}; cardId=${top.id}; diagnosticFingerprint=${top.diagnostic.fingerprint}; afterDiagnosticCount=${diagnostics.length}`,
@@ -592437,7 +592662,7 @@ ${extras.join("\n")}`;
592437
592662
  state.lastMutationTurn = turn;
592438
592663
  state.verifierStasisCount = 0;
592439
592664
  state.verifierStasisBlocked = false;
592440
- state.prerequisiteRecoverySignature = void 0;
592665
+ state.prerequisiteRecoverySignatures = [];
592441
592666
  this._focusSupervisor?.markCompletionBlocked({
592442
592667
  turn,
592443
592668
  reason: "A source mutation invalidated the declared verifier; verifier evidence now owns the active focus.",
@@ -592480,12 +592705,23 @@ ${extras.join("\n")}`;
592480
592705
  return owned.some((ownedPath) => this._pathsOverlapForVerifier(pathValue, ownedPath)) || artifacts.some((artifactPath) => this._pathsOverlapForVerifier(pathValue, artifactPath)) || /\.(ts|tsx|js|jsx|mjs|cjs|py|go|rs|java|kt|c|cc|cpp|cxx|h|hpp|hh|hxx|ino)$/i.test(pathValue);
592481
592706
  });
592482
592707
  }
592708
+ /**
592709
+ * Action rails are an explicitly opt-in diagnostic experiment, never a
592710
+ * normal-model policy. They created deadlocks by denying the very reads and
592711
+ * edits needed to revise a hypothesis. Evidence and the tools' own atomic
592712
+ * checks remain available without a controller admission gate.
592713
+ */
592714
+ _enforcesStrictActionBoundaries() {
592715
+ return process.env["OMNIUS_ENABLE_EXPERIMENTAL_ACTION_GATES"] === "1";
592716
+ }
592483
592717
  /** Consecutive preflight blocks before the gate yields instead of blocking. */
592484
592718
  static COMPILE_FIX_GATE_YIELD_AFTER = 3;
592485
592719
  _compileFixLoopPreflightBlock(toolName, args, turn, shellLikelyMutatesFilesystem) {
592486
592720
  const state = this._compileFixLoop;
592487
592721
  if (!state?.active)
592488
592722
  return null;
592723
+ if (!this._enforcesStrictActionBoundaries())
592724
+ return null;
592489
592725
  const action = compileFixLoopNextRequiredAction(state);
592490
592726
  const verifierLocked = action === "run_declared_verifier" || state.verifierStasisBlocked === true;
592491
592727
  if (!verifierLocked)
@@ -592503,7 +592739,7 @@ ${extras.join("\n")}`;
592503
592739
  `lastVerifierRunTurn=${state.lastVerifierRunTurn}`,
592504
592740
  `stasisRounds=${state.verifierStasisCount ?? 0}`,
592505
592741
  `blockedTool=${toolName} consecutiveBlocks=${streak}`,
592506
- `Allowed next actions: the declared verifier; one narrow prerequisite read of an owned file; or a scoped source fix that changes verifier inputs.`
592742
+ `Allowed next actions: the declared verifier; up to three distinct bounded prerequisite reads/searches; or a scoped source fix that changes verifier inputs.`
592507
592743
  ].join("\n")
592508
592744
  };
592509
592745
  };
@@ -592527,16 +592763,17 @@ ${extras.join("\n")}`;
592527
592763
  "file_explore"
592528
592764
  ]);
592529
592765
  if (readLike.has(toolName)) {
592530
- const target = String(args["path"] ?? args["file"] ?? args["file_path"] ?? "");
592531
- const owned = state.cards.flatMap((card) => card.ownedFiles);
592532
- const scoped = target.length > 0 && owned.some((path16) => this._pathsOverlapForVerifier(target, path16));
592533
592766
  const signature = `${toolName}:${this._buildExactArgsKey(args)}`;
592534
- if (scoped && state.prerequisiteRecoverySignature !== signature) {
592535
- state.prerequisiteRecoverySignature = signature;
592767
+ const prior = state.prerequisiteRecoverySignatures ?? [];
592768
+ const target = String(args["path"] ?? args["file"] ?? args["file_path"] ?? "").trim();
592769
+ const pattern = String(args["pattern"] ?? "").trim();
592770
+ const explicitBoundedRecovery = toolName === "file_read" && target.length > 0 || toolName === "grep_search" && (target.length > 0 || pattern.length > 0) || toolName === "find_files" && pattern.length > 0 || toolName === "list_directory" && target.length > 0 || toolName === "file_explore" && target.length > 0;
592771
+ if (explicitBoundedRecovery && !prior.includes(signature) && prior.length < 3) {
592772
+ state.prerequisiteRecoverySignatures = [...prior, signature];
592536
592773
  state.preflightBlockStreak = 0;
592537
592774
  return null;
592538
592775
  }
592539
- return blocked(scoped ? "The one prerequisite-recovery read has already been used; act on its evidence instead of reading again." : "Prerequisite recovery must be a narrow read of a compile-card owned file.");
592776
+ return blocked(prior.includes(signature) ? "This exact prerequisite recovery was already admitted; use its evidence or change the path/range/pattern." : prior.length >= 3 ? "The bounded prerequisite-recovery budget is exhausted; synthesize the three fresh observations before another read." : "Prerequisite recovery must name a file path or search pattern; broad unscoped exploration is not admitted while verifier evidence is locked.");
592540
592777
  }
592541
592778
  if (this._isProjectEditTool(toolName)) {
592542
592779
  const targetPaths = this._extractToolTargetPaths(toolName, args);
@@ -592959,6 +593196,8 @@ ${result.output ?? ""}`;
592959
593196
  return openTodoLeaves(todos);
592960
593197
  }
592961
593198
  _todoExpansionRequiredBlocker(toolName) {
593199
+ if (!this._enforcesStrictActionBoundaries())
593200
+ return null;
592962
593201
  if (!this._todoWriteAvailable())
592963
593202
  return null;
592964
593203
  if (toolName === "todo_write" || toolName === "todo_read")
@@ -596372,6 +596611,9 @@ ${blob}
596372
596611
  }
596373
596612
  microcompact(messages2, recentToolResults) {
596374
596613
  const tier = this.options.modelTier ?? "large";
596614
+ if (tier !== "small" && process.env["OMNIUS_ENABLE_AGGRESSIVE_MICROCOMPACTION"] !== "1") {
596615
+ return;
596616
+ }
596375
596617
  let keepResults = tier === "small" ? 6 : tier === "medium" ? 10 : 20;
596376
596618
  const idleGapMs = Date.now() - this._lastAssistantTimestamp;
596377
596619
  const IDLE_THRESHOLD_MS = 5 * 6e4;
@@ -597586,57 +597828,28 @@ ${notice}`;
597586
597828
  }
597587
597829
  }
597588
597830
  _canonicalReadEvidencePayload(canonicalPath, contentHash2) {
597831
+ const evidence = this._evidenceLedger.get(canonicalPath);
597832
+ if (evidence && !evidence.stale && evidence.contentHash === contentHash2 && evidence.fidelity === "full" && this._mustHonorExplicitFullFileRead(Buffer.byteLength(evidence.content, "utf8"), evidence.content.split("\n").length, this._branchRoutingContextWindow())) {
597833
+ return evidence.content;
597834
+ }
597589
597835
  const branch = this._branchEvidenceByPath.get(canonicalPath);
597590
- if (branch && branch.contentHash === contentHash2 && branch.taskEpoch === this._taskEpoch) {
597836
+ if (branch && branch.contentHash === contentHash2 && branch.taskEpoch === this._taskEpoch && branch.contractComplete) {
597591
597837
  return branch.output;
597592
597838
  }
597593
597839
  return null;
597594
597840
  }
597595
597841
  _rehydrateResolvedReadEvidence(input) {
597596
- const previous = this._resolvedReadEvidence.get(input.fingerprint);
597597
- const handle2 = previous?.handle ?? `evidence:${input.canonicalPath}:${input.contentHash.slice(0, 16)}`;
597598
- this._resolvedReadEvidence.set(input.fingerprint, {
597599
- state: "resolved_from_cache",
597600
- handle: handle2,
597601
- path: input.canonicalPath,
597602
- contentHash: input.contentHash,
597603
- resolvedTurn: input.turn,
597604
- consumed: false
597605
- });
597606
597842
  return [
597607
597843
  "[REHYDRATED_FILE_EVIDENCE]",
597608
- `handle=${handle2}`,
597609
- "fingerprint_state=resolved_from_cache",
597610
597844
  `path=${input.canonicalPath}`,
597845
+ "source=canonical_branch_cache",
597611
597846
  `sha256=${input.contentHash}`,
597612
- "Facts below are canonical current-run evidence. Consume these facts in the next decision; do not repeat the identical read.",
597847
+ "This is an unchanged, complete branch extraction. A later file_read may still execute whenever current source or broader coverage is needed.",
597613
597848
  "[CANONICAL_FACTS]",
597614
597849
  input.payload.slice(0, 7e3),
597615
597850
  "[/CANONICAL_FACTS]"
597616
597851
  ].join("\n");
597617
597852
  }
597618
- _rejectRepeatedResolvedRead(tc, messages2) {
597619
- if (tc.name !== "file_read") {
597620
- for (const state2 of this._resolvedReadEvidence.values()) {
597621
- state2.consumed = true;
597622
- }
597623
- return null;
597624
- }
597625
- const fingerprint = this._buildToolFingerprint(tc.name, tc.arguments);
597626
- const state = this._resolvedReadEvidence.get(fingerprint);
597627
- if (!state)
597628
- return null;
597629
- const latestAssistant = [...messages2].reverse().find((message2) => message2.role === "assistant" && typeof message2.content === "string");
597630
- if (latestAssistant && typeof latestAssistant.content === "string" && latestAssistant.content.includes(state.handle)) {
597631
- state.consumed = true;
597632
- }
597633
- return [
597634
- "[REPEATED_READ_REJECTED]",
597635
- `handle=${state.handle}`,
597636
- `fingerprint_state=${state.state}`,
597637
- state.consumed ? "The evidence handle was acknowledged, but an identical read cannot add facts. Change file/range/query scope or take the evidence-backed next action." : "Consume the rehydrated evidence handle in your next decision before requesting another read. Change file/range/query scope if a different fact is required."
597638
- ].join("\n");
597639
- }
597640
597853
  async _drainPendingSteeringMessages(messages2, turn) {
597641
597854
  this.drainPendingRuntimeGuidance(turn);
597642
597855
  const pending2 = this.pendingSteeringInputs.filter((record) => (record.state === "queued" || record.state === "acknowledged") && (!record.taskEpoch || record.taskEpoch === this._taskEpoch));
@@ -598026,6 +598239,27 @@ The steering reconciliation was emitted this turn. Wait for the next model decis
598026
598239
  const value2 = String(args["mode"] ?? "auto").trim().toLowerCase();
598027
598240
  return value2 === "full" || value2 === "extract" ? value2 : "auto";
598028
598241
  }
598242
+ /**
598243
+ * A small canonical source file is more useful as a complete first-class
598244
+ * read than as a one-line branch extract. In particular, a stale/noisy
598245
+ * resident-context estimate must not turn a 36-line file into a curated
598246
+ * wrapper merely because computed headroom is momentarily zero. This cap is
598247
+ * deliberately far below ordinary tool output limits and is still subject to
598248
+ * normal model-facing budgeting on the next request.
598249
+ */
598250
+ _mustInlineSmallFileRead(selectedBytes, selectedLines) {
598251
+ return selectedBytes <= 8e3 && selectedLines <= 200;
598252
+ }
598253
+ /**
598254
+ * `mode:"full"` is a first-class model choice, not a request for a wrapper.
598255
+ * Honor it for a bounded source body that still leaves normal output room;
598256
+ * truly overwhelming files continue through the isolated extractor.
598257
+ */
598258
+ _mustHonorExplicitFullFileRead(selectedBytes, selectedLines, contextWindow) {
598259
+ const projected = estimateFileReadInjectionTokens(selectedBytes, selectedLines);
598260
+ const cap = Math.max(4096, Math.min(8192, Math.floor(Math.max(0, contextWindow) * 0.15)));
598261
+ return selectedBytes <= 32e3 && selectedLines <= 800 && projected <= cap;
598262
+ }
598029
598263
  /**
598030
598264
  * Route using the same sanitized, model-facing request shape that will be
598031
598265
  * sent after the tool turn—not the unreduced historical transcript. Using
@@ -598135,7 +598369,10 @@ The steering reconciliation was emitted this turn. Wait for the next model decis
598135
598369
  });
598136
598370
  const requestedMode = this._fileReadMode(input.args);
598137
598371
  const explicitExtraction = requestedMode === "extract";
598138
- if (!decision2.branch && !explicitExtraction) {
598372
+ const explicitFull = requestedMode === "full";
598373
+ const inlineSmallRead = this._mustInlineSmallFileRead(selectedBytes, selectedLines.length);
598374
+ const honorFull = explicitFull && this._mustHonorExplicitFullFileRead(selectedBytes, selectedLines.length, contextWindow);
598375
+ if ((!decision2.branch || inlineSmallRead || honorFull) && !explicitExtraction) {
598139
598376
  input.batchBudget.inlineTokens += decision2.projectedReadTokens;
598140
598377
  input.batchBudget.reservations.set(input.callId, decision2.projectedReadTokens);
598141
598378
  return null;
@@ -598155,7 +598392,7 @@ The steering reconciliation was emitted this turn. Wait for the next model decis
598155
598392
  const branchRequestId = `branch:${this._taskEpoch}:${_createHash("sha256").update(`${canonicalPath}|${fullHash}|${offset ?? 0}:${limit ?? "EOF"}|${contractFingerprint}`).digest("hex").slice(0, 20)}`;
598156
598393
  const cacheKey = `${this._taskEpoch}|${canonicalPath}|${fullHash}|${offset ?? 0}:${limit ?? "EOF"}|${contractFingerprint}`;
598157
598394
  const cached2 = this._branchEvidenceCache.get(cacheKey);
598158
- if (cached2) {
598395
+ if (cached2?.contractComplete) {
598159
598396
  const fingerprint = this._buildToolFingerprint(input.toolName, input.args);
598160
598397
  const rehydrated = this._rehydrateResolvedReadEvidence({
598161
598398
  fingerprint,
@@ -598167,7 +598404,7 @@ The steering reconciliation was emitted this turn. Wait for the next model decis
598167
598404
  this.emit({
598168
598405
  type: "status",
598169
598406
  toolName: input.toolName,
598170
- content: `Branch-extract cache rehydrated: ${rawPath} sha256=${fullHash.slice(0, 12)} contract=${contractFingerprint} fingerprint_state=resolved_from_cache`,
598407
+ content: `Complete branch extraction reused: ${rawPath} sha256=${fullHash.slice(0, 12)} contract=${contractFingerprint}`,
598171
598408
  turn: input.turn,
598172
598409
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
598173
598410
  });
@@ -598195,7 +598432,9 @@ The steering reconciliation was emitted this turn. Wait for the next model decis
598195
598432
  sourceRange: {
598196
598433
  startLine: startIndex + 1,
598197
598434
  endLine: startIndex + Math.max(1, selectedLines.length)
598198
- }
598435
+ },
598436
+ contractComplete: cached2.contractComplete,
598437
+ unresolvedRequirementIds: cached2.unresolvedRequirementIds
598199
598438
  }
598200
598439
  };
598201
598440
  }
@@ -598211,23 +598450,23 @@ The steering reconciliation was emitted this turn. Wait for the next model decis
598211
598450
  backend: extractionBackend,
598212
598451
  timeoutMs: 3e4
598213
598452
  });
598453
+ const requirementCoverage = renderBranchRequirementCoverage(ev);
598214
598454
  const verboseOutput = [
598215
598455
  `[BRANCH-EXTRACT v2] path=${rawPath}`,
598216
598456
  `[VERIFIED_RUNTIME_FILE_READ] request_id=${branchRequestId} task_epoch=${this._taskEpoch}`,
598217
598457
  `routing=${explicitExtraction ? "manual" : "mandatory"} reasons=${decision2.reasons.join(",") || "explicit_extract"} projected_read_tokens=${decision2.projectedReadTokens} fraction_limit_tokens=${decision2.fractionLimitTokens} available_headroom_tokens=${decision2.availableHeadroomTokens}`,
598218
598458
  `source=sha256:${fullHash} selected_lines=${selectedLines.length} selected_bytes=${selectedBytes}${hasRange ? ` range=${offset ?? 1}:${limit ?? "EOF"}` : " range=whole"}`,
598219
- `[DISCOVERY CONTRACT]`,
598220
- `Goal anchor: ${branchBrief.discoveryContract?.goalAnchor ?? this._taskState.currentStep}`,
598221
- `Request: ${branchBrief.request}`,
598222
- `Required discoveries:`,
598459
+ `[EXTRACTION CONTRACT]`,
598460
+ `Task: ${branchBrief.discoveryContract?.goalAnchor ?? this._taskState.currentStep}`,
598461
+ `Question: ${branchBrief.request}`,
598462
+ `Requirements:`,
598223
598463
  ...(branchBrief.discoveryContract?.requirements ?? []).map((requirement) => `- ${requirement.id}${requirement.required ? " [required]" : ""}: ${requirement.question}`),
598224
598464
  `Stop conditions: ${(branchBrief.discoveryContract?.completionCriteria ?? []).join(" | ")}`,
598225
598465
  `[CURATED SEGMENTS]`,
598226
598466
  ev.claim,
598227
- `satisfied=${ev.satisfiedRequirementIds.join(",") || "none"}`,
598228
- `unresolved=${ev.unresolvedRequirementIds.join(",") || "none"}`,
598467
+ ...requirementCoverage,
598229
598468
  `provenance=content:${ev.provenance.contentHash} searches:${ev.provenance.searchRounds.length} ranges:${ev.provenance.exploredRanges.map((range) => `L${range.startLine}-L${range.endLine}`).join(",")}`,
598230
- `Contract: use these anchors as evidence. If a required item remains unresolved, issue one narrow grep_search or bounded file_read for that item. Do not use shell/cat to bypass context routing; file_read(mode="full") remains available when live admission permits it.`
598469
+ ev.contractComplete ? `Coverage: complete; every declared requirement has anchored evidence.` : `Coverage: partial; unresolved requirements include their source-based reason and suggested next evidence query. This extract is advisory and does not restrict other tool calls.`
598231
598470
  ].join("\n");
598232
598471
  const outputBudgetChars = Math.max(800, decision2.fractionLimitTokens * 4);
598233
598472
  let output = verboseOutput;
@@ -598237,13 +598476,13 @@ The steering reconciliation was emitted this turn. Wait for the next model decis
598237
598476
  `[BRANCH-EXTRACT v2] path=${rawPath} sha256=${fullHash}`,
598238
598477
  `[VERIFIED_RUNTIME_FILE_READ] request_id=${branchRequestId} task_epoch=${this._taskEpoch}`,
598239
598478
  `routing=${decision2.reasons.join(",")} projected=${decision2.projectedReadTokens}/${contextWindow}t limit=${decision2.fractionLimitTokens}t`,
598240
- `[DISCOVERY CONTRACT] required=${required || "next narrow file-local fact"}`,
598479
+ `[EXTRACTION CONTRACT] required=${required || "next narrow file-local fact"}`,
598241
598480
  `[CURATED SEGMENTS]`
598242
598481
  ].join("\n");
598243
598482
  const suffix = [
598244
- `unresolved=${ev.unresolvedRequirementIds.join(",") || "none"}`,
598483
+ ...requirementCoverage,
598245
598484
  `anchors=${ev.provenance.exploredRanges.map((range) => `L${range.startLine}-L${range.endLine}`).join(",")}`,
598246
- `Do not whole-read again; act on these anchors or issue one narrower search.`
598485
+ ev.contractComplete ? `All declared requirements are grounded; act on these anchors.` : `PARTIAL contract: execute the listed bounded recovery before relying on an unresolved requirement.`
598247
598486
  ].join("\n");
598248
598487
  const claimBudget = Math.max(120, outputBudgetChars - prefix.length - suffix.length - 2);
598249
598488
  output = `${prefix}
@@ -598257,13 +598496,19 @@ ${suffix}`.slice(0, outputBudgetChars);
598257
598496
  sourceBytes: stat9.size,
598258
598497
  createdAt: Date.now(),
598259
598498
  taskEpoch: this._taskEpoch,
598260
- requestId: branchRequestId
598499
+ requestId: branchRequestId,
598500
+ contractComplete: ev.contractComplete,
598501
+ unresolvedRequirementIds: ev.unresolvedRequirementIds,
598502
+ unresolvedRecoveries: ev.requirementCoverage.filter((coverage) => coverage.status === "unresolved").map((coverage) => `${coverage.id}: ${coverage.recovery ?? "narrow recovery required"}`)
598261
598503
  });
598262
598504
  this._branchEvidenceByPath.set(canonicalPath, {
598263
598505
  output,
598264
598506
  contentHash: fullHash,
598265
598507
  mtimeMs: stat9.mtimeMs,
598266
- taskEpoch: this._taskEpoch
598508
+ taskEpoch: this._taskEpoch,
598509
+ contractComplete: ev.contractComplete,
598510
+ unresolvedRequirementIds: ev.unresolvedRequirementIds,
598511
+ unresolvedRecoveries: ev.requirementCoverage.filter((coverage) => coverage.status === "unresolved").map((coverage) => `${coverage.id}: ${coverage.recovery ?? "narrow recovery required"}`)
598267
598512
  });
598268
598513
  if (explicitExtraction) {
598269
598514
  const evicted = this._evictInlineReadArtifacts(input.messages, canonicalPath, fullHash, "verified_branch_extract");
@@ -598306,7 +598551,9 @@ ${suffix}`.slice(0, outputBudgetChars);
598306
598551
  sourceRange: {
598307
598552
  startLine: startIndex + 1,
598308
598553
  endLine: startIndex + Math.max(1, selectedLines.length)
598309
- }
598554
+ },
598555
+ contractComplete: ev.contractComplete,
598556
+ unresolvedRequirementIds: ev.unresolvedRequirementIds
598310
598557
  }
598311
598558
  };
598312
598559
  }
@@ -598337,7 +598584,10 @@ ${suffix}`.slice(0, outputBudgetChars);
598337
598584
  safeContextTokens: this.contextLimits().compactionThreshold
598338
598585
  });
598339
598586
  const explicitExtraction = this._fileReadMode(input.args) === "extract";
598340
- if (!decision2.branch && !explicitExtraction) {
598587
+ const explicitFull = this._fileReadMode(input.args) === "full";
598588
+ const inlineSmallRead = this._mustInlineSmallFileRead(Buffer.byteLength(input.result.output, "utf8"), lines.length);
598589
+ const honorFull = explicitFull && this._mustHonorExplicitFullFileRead(Buffer.byteLength(input.result.output, "utf8"), lines.length, contextWindow);
598590
+ if ((!decision2.branch || inlineSmallRead || honorFull) && !explicitExtraction) {
598341
598591
  if (reservedForThisCall === 0) {
598342
598592
  input.batchBudget.inlineTokens += decision2.projectedReadTokens;
598343
598593
  input.batchBudget.reservations.set(input.callId, decision2.projectedReadTokens);
@@ -598366,15 +598616,17 @@ ${suffix}`.slice(0, outputBudgetChars);
598366
598616
  backend: process.env["OMNIUS_DISABLE_BRANCH_EXTRACT"] === "1" ? void 0 : this._auxInferenceBackend(),
598367
598617
  timeoutMs: 3e4
598368
598618
  });
598619
+ const requirementCoverage = renderBranchRequirementCoverage(ev);
598369
598620
  const output = [
598370
598621
  `[BRANCH-EXTRACT v2] path=${path16}`,
598371
598622
  `[VERIFIED_RUNTIME_FILE_READ] request_id=branch:${this._taskEpoch}:${input.callId} task_epoch=${this._taskEpoch}`,
598372
598623
  `routing=${explicitExtraction ? "manual" : "post-execution-failsafe"} reasons=${decision2.reasons.join(",") || "explicit_extract"} projected_read_tokens=${decision2.projectedReadTokens}`,
598373
- `[DISCOVERY CONTRACT] ${brief.request}`,
598624
+ `[EXTRACTION CONTRACT] ${brief.request}`,
598374
598625
  `[CURATED SEGMENTS]`,
598375
598626
  ev.claim,
598376
- `unresolved=${ev.unresolvedRequirementIds.join(",") || "none"}`,
598377
- `provenance=content:${ev.provenance.contentHash} ranges:${ev.provenance.exploredRanges.map((range) => `L${range.startLine}-L${range.endLine}`).join(",")}`
598627
+ ...requirementCoverage,
598628
+ `provenance=content:${ev.provenance.contentHash} ranges:${ev.provenance.exploredRanges.map((range) => `L${range.startLine}-L${range.endLine}`).join(",")}`,
598629
+ ev.contractComplete ? "Coverage: complete; all declared requirements are grounded." : "Coverage: partial; unresolved requirements include a source-based recovery suggestion. This extract is advisory and does not restrict other tool calls."
598378
598630
  ].join("\n").slice(0, Math.max(800, decision2.fractionLimitTokens * 4));
598379
598631
  return {
598380
598632
  ...input.result,
@@ -598397,7 +598649,9 @@ ${suffix}`.slice(0, outputBudgetChars);
598397
598649
  sourceRange: {
598398
598650
  startLine: 1,
598399
598651
  endLine: Math.max(1, lines.length)
598400
- }
598652
+ },
598653
+ contractComplete: ev.contractComplete,
598654
+ unresolvedRequirementIds: ev.unresolvedRequirementIds
598401
598655
  }
598402
598656
  };
598403
598657
  }
@@ -599082,6 +599336,7 @@ Respond with the assessment and take the selected evidence-backed action.`;
599082
599336
  this._completionLedger = null;
599083
599337
  this._focusTerminalLedgerRecorded = false;
599084
599338
  this._compileFixLoop = null;
599339
+ this._pendingCompileDelegationCardId = null;
599085
599340
  this._declaredVerifierCommand = null;
599086
599341
  this._lastDeclaredVerifierOutput = null;
599087
599342
  this._lastDeclaredVerifierDiagnostics = [];
@@ -599826,7 +600081,6 @@ ${dynamicProjectContext}`
599826
600081
  let lastShellPivotTurn = -1;
599827
600082
  const recentToolResults = /* @__PURE__ */ new Map();
599828
600083
  const exactFileReadObservations = /* @__PURE__ */ new Map();
599829
- const exactReadEvidenceEpochs = /* @__PURE__ */ new Map();
599830
600084
  let fileMutationEpoch = 0;
599831
600085
  const dedupHitCount = /* @__PURE__ */ new Map();
599832
600086
  const noopedMemoryWriteFingerprints = /* @__PURE__ */ new Set();
@@ -599841,21 +600095,7 @@ ${dynamicProjectContext}`
599841
600095
  find_files: 10,
599842
600096
  grep_search: 12,
599843
600097
  camera_capture: 3
599844
- } : loopTier === "medium" ? {
599845
- web_search: 10,
599846
- web_fetch: 8,
599847
- list_directory: 18,
599848
- find_files: 14,
599849
- grep_search: 18,
599850
- camera_capture: 4
599851
- } : {
599852
- web_search: 20,
599853
- web_fetch: 15,
599854
- list_directory: 30,
599855
- find_files: 20,
599856
- grep_search: 30,
599857
- camera_capture: 5
599858
- };
600098
+ } : {};
599859
600099
  for (const [tool, budget] of Object.entries(toolBudgets)) {
599860
600100
  toolCallBudget.set(tool, budget);
599861
600101
  }
@@ -601365,7 +601605,7 @@ Respond with EXACTLY this structure before your next tool call:
601365
601605
  }
601366
601606
  }
601367
601607
  const turnTier = this.options.modelTier ?? "large";
601368
- if (turn === 0 && !this.options.disableTodoPlanningNudges && this._todoWriteAvailable() && (turnTier === "small" || turnTier === "medium")) {
601608
+ if (turn === 0 && !this.options.disableTodoPlanningNudges && this._todoWriteAvailable() && turnTier === "small") {
601369
601609
  const goal = this._taskState.goal || "";
601370
601610
  const substantiveGoal = goal.replace(/\b(?:then\s+)?call\s+task_complete\b[^.?!;]*/gi, "").replace(/\b(?:observe|report|summarize|finish|complete)\b[^.?!;]*/gi, "");
601371
601611
  const wordCount2 = substantiveGoal.split(/\s+/).filter(Boolean).length;
@@ -601428,7 +601668,7 @@ Now call file_write with YOUR skeleton for this task.`
601428
601668
  });
601429
601669
  }
601430
601670
  }
601431
- if (turn === 0 && (turnTier === "small" || turnTier === "medium")) {
601671
+ if (turn === 0 && turnTier === "small") {
601432
601672
  const taskGoal = this._taskState.goal || "";
601433
601673
  const taskLower = taskGoal.toLowerCase();
601434
601674
  const taskTokens = new Set(taskLower.split(/\s+/).filter((w) => w.length > 2));
@@ -601471,7 +601711,7 @@ Now call file_write with YOUR skeleton for this task.`
601471
601711
  ${top.map((t2) => `- ${t2.name}: ${t2.desc}`).join("\n")}`);
601472
601712
  }
601473
601713
  }
601474
- if (turn === 0 && (turnTier === "small" || turnTier === "medium")) {
601714
+ if (turn === 0 && turnTier === "small") {
601475
601715
  const taskGoal = (this._taskState.goal || "").toLowerCase();
601476
601716
  const isSimpleTask = taskGoal.length < 150 && (taskGoal.match(/\band\b|\bthen\b/gi) || []).length < 3;
601477
601717
  const isSearchTask = /\bfind\b|\bsearch\b|\bwhere\b|\bwhich file\b|\bcontain/i.test(taskGoal);
@@ -601496,7 +601736,7 @@ ${top.map((t2) => `- ${t2.name}: ${t2.desc}`).join("\n")}`);
601496
601736
  ${hints.join("\n")}`);
601497
601737
  }
601498
601738
  }
601499
- if (turn === 0 && (turnTier === "small" || turnTier === "medium")) {
601739
+ if (turn === 0 && turnTier === "small") {
601500
601740
  const taskGoal = this._taskState.goal || "";
601501
601741
  const hasMultiplePremises = (taskGoal.match(/\band\b|\bthen\b|\bif\b|\bbecause\b|\bsince\b|\bgiven\b/gi) || []).length >= 3;
601502
601742
  const hasConditionalLogic = (taskGoal.match(/\bif\b.*\bthen\b|\bwhen\b.*\bshould\b|\bassuming\b/gi) || []).length >= 1;
@@ -601568,7 +601808,7 @@ If you're stuck, try a completely different approach. Do NOT repeat what failed
601568
601808
  compacted = messages2;
601569
601809
  }
601570
601810
  this._retireStaleEvidenceInPlace(messages2, turn);
601571
- if (turn > 0 && this._toolEvents.length > 0) {
601811
+ if (turn > 0 && this._toolEvents.length > 0 && ((this.options.modelTier ?? "large") === "small" || process.env["OMNIUS_ENABLE_LEGACY_CONTEXT_ENGINE_TRIM"] === "1")) {
601572
601812
  try {
601573
601813
  const _limits = this.contextLimits();
601574
601814
  const ceCompactInput = {
@@ -602100,7 +602340,7 @@ ${memoryLines.join("\n")}`
602100
602340
  "shell"
602101
602341
  ]);
602102
602342
  const selfConsistencyK = this.options.selfConsistencyK ?? 0;
602103
- const shouldVote = selfConsistencyK >= 2 && this._selfConsistencyVotes < 2 && (this.options.modelTier === "small" || this.options.modelTier === "medium") && firstToolCall && HIGH_STAKE_TOOLS.has(firstToolCall.name) && turn <= 3;
602343
+ const shouldVote = selfConsistencyK >= 2 && this._selfConsistencyVotes < 2 && this.options.modelTier === "small" && firstToolCall && HIGH_STAKE_TOOLS.has(firstToolCall.name) && turn <= 3;
602104
602344
  if (shouldVote && firstToolCall) {
602105
602345
  try {
602106
602346
  const alternativeA = {
@@ -602157,7 +602397,7 @@ ${memoryLines.join("\n")}`
602157
602397
  const isEmptyResponse = !isThinkOnly && (!msg.content || !msg.content.trim()) && (!msg.toolCalls || msg.toolCalls.length === 0);
602158
602398
  if (isEmptyResponse) {
602159
602399
  consecutiveEmptyResponses++;
602160
- if (consecutiveEmptyResponses >= 2) {
602400
+ if (consecutiveEmptyResponses >= 2 && (this.options.modelTier ?? "large") === "small") {
602161
602401
  this.emit({
602162
602402
  type: "status",
602163
602403
  content: `${consecutiveEmptyResponses} consecutive empty responses — injecting recovery nudge`,
@@ -602178,6 +602418,18 @@ ${memoryLines.join("\n")}`
602178
602418
  continue;
602179
602419
  }
602180
602420
  consecutiveEmptyResponses = 0;
602421
+ const pendingCompileDelegation = this._steeringToolGate(turn) ? null : this._takePendingCompileDelegation(messages2, turn);
602422
+ if (pendingCompileDelegation) {
602423
+ const supersededCalls = msg.toolCalls?.length ?? 0;
602424
+ msg.toolCalls = [pendingCompileDelegation];
602425
+ msg.content = null;
602426
+ this.emit({
602427
+ type: "status",
602428
+ content: `[FAN-OUT] automatic compile-fixer dispatch preempted ${supersededCalls} model-selected call${supersededCalls === 1 ? "" : "s"}; the parent will resume only after the isolated fold-back.`,
602429
+ turn,
602430
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
602431
+ });
602432
+ }
602181
602433
  if (msg.toolCalls && msg.toolCalls.length > 0) {
602182
602434
  consecutiveTextOnly = 0;
602183
602435
  consecutiveThinkOnly = 0;
@@ -602190,15 +602442,10 @@ ${memoryLines.join("\n")}`
602190
602442
  });
602191
602443
  continue;
602192
602444
  }
602193
- const _RESPONSE_CALL_CAPS = {
602194
- small: 2,
602195
- medium: 4,
602196
- large: 6
602197
- };
602198
- const _responseCap = _RESPONSE_CALL_CAPS[this.options.modelTier ?? "large"] ?? 6;
602445
+ const _responseCap = (this.options.modelTier ?? "large") === "small" ? 2 : Number.POSITIVE_INFINITY;
602199
602446
  const _originalCallCount = msg.toolCalls.length;
602200
602447
  let _capDeferredCount = 0;
602201
- if (msg.toolCalls.length > _responseCap) {
602448
+ if (Number.isFinite(_responseCap) && msg.toolCalls.length > _responseCap) {
602202
602449
  _capDeferredCount = msg.toolCalls.length - _responseCap;
602203
602450
  msg.toolCalls = msg.toolCalls.slice(0, _responseCap);
602204
602451
  this.emit({
@@ -602236,7 +602483,7 @@ ${memoryLines.join("\n")}`
602236
602483
  role: "system",
602237
602484
  content: [
602238
602485
  `[BATCH CAPPED]`,
602239
- `You emitted ${_originalCallCount} tool calls in one response. The orchestrator caps responses at ${_responseCap} for the ${this.options.modelTier ?? "large"} model tier.`,
602486
+ `You emitted ${_originalCallCount} tool calls in one response. The small-model safety profile caps responses at ${_responseCap}.`,
602240
602487
  `The first ${_responseCap} executed; the remaining ${_capDeferredCount} were DROPPED.`,
602241
602488
  ``,
602242
602489
  `Best practice for this model tier: emit at most ${_responseCap} tool calls per turn.`,
@@ -602266,17 +602513,6 @@ ${memoryLines.join("\n")}`
602266
602513
  return { tc, output: steeringGate, success: false };
602267
602514
  }
602268
602515
  this._markFirstSteeringAffectedAction(tc.name, this._currentSteeringTurn);
602269
- const resolvedReadBlock = this._rejectRepeatedResolvedRead(tc, messages2);
602270
- if (resolvedReadBlock) {
602271
- this.emit({
602272
- type: "status",
602273
- toolName: tc.name,
602274
- content: "Repeated planned file_read rejected until evidence scope changes.",
602275
- turn,
602276
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
602277
- });
602278
- return { tc, output: resolvedReadBlock, success: true };
602279
- }
602280
602516
  const cohortKey = this.buildArgCohortKey(tc.name, tc.arguments);
602281
602517
  const cohort = this._argCohorts.get(cohortKey);
602282
602518
  if (cohort && cohort.failure >= 3 && cohort.success === 0) {
@@ -602366,7 +602602,8 @@ Corrective action: try a different approach first: read relevant files, adjust a
602366
602602
  timestampMs: Date.now()
602367
602603
  });
602368
602604
  const _toolLogTailIdx = toolCallLog.length - 1;
602369
- if (tc.name !== "task_complete") {
602605
+ const isDeclaredCompileVerifier = tc.name === "shell" && Boolean(this._compileFixLoop?.active) && commandReliablySatisfiesVerifyCommand(String((tc.arguments ?? {})["command"] ?? (tc.arguments ?? {})["cmd"] ?? "").trim(), this._compileFixLoop?.verifierCommand ?? "");
602606
+ if (this._enforcesStrictActionBoundaries() && tc.name !== "task_complete" && !isDeclaredCompileVerifier) {
602370
602607
  const doomHistory = toolCallLog.slice(-5).map((e2) => ({ tool: e2.name, args: e2.argsKey }));
602371
602608
  doomHistory.push({
602372
602609
  tool: tc.name,
@@ -602501,7 +602738,7 @@ Corrective action: try a different approach first: read relevant files, adjust a
602501
602738
  detail: `attempted_tool=${tc.name}`
602502
602739
  });
602503
602740
  }
602504
- if (this._reg61PerpetualGateActive && !focusDirectiveForEditPressure && !REG61_BYPASS_TOOLS.has(tc.name) && process.env["OMNIUS_DISABLE_REG61_COERCE"] !== "1") {
602741
+ if (this._enforcesStrictActionBoundaries() && this._reg61PerpetualGateActive && !focusDirectiveForEditPressure && !REG61_BYPASS_TOOLS.has(tc.name) && process.env["OMNIUS_DISABLE_REG61_COERCE"] !== "1") {
602505
602742
  const _dbgLoop = this._detectDebugLoop([
602506
602743
  ...toolCallLog,
602507
602744
  { name: tc.name, argsKey }
@@ -602596,7 +602833,7 @@ Corrective action: try a different approach first: read relevant files, adjust a
602596
602833
  const toolFingerprint = this._resolveReadCoverageFingerprint(tc.name, tc.arguments ?? {}, exactToolFingerprint);
602597
602834
  const repeatedMemoryWriteNoop = tc.name === "memory_write" && noopedMemoryWriteFingerprints.has(toolFingerprint);
602598
602835
  const repeatedProjectWriteNoop = this._isProjectEditTool(tc.name) && noopedProjectWriteFingerprints.has(toolFingerprint);
602599
- if (repeatedMemoryWriteNoop || repeatedProjectWriteNoop) {
602836
+ if (this._enforcesStrictActionBoundaries() && (repeatedMemoryWriteNoop || repeatedProjectWriteNoop)) {
602600
602837
  this.emit({
602601
602838
  type: "tool_call",
602602
602839
  toolName: tc.name,
@@ -602628,7 +602865,7 @@ Read the current file if needed, make a different concrete edit, or move to veri
602628
602865
  systemGuidance: repeatNoopMsg
602629
602866
  };
602630
602867
  }
602631
- const staleEditBlock = this.staleEditPreflightBlock(tc.name, tc.arguments ?? {});
602868
+ const staleEditBlock = this._enforcesStrictActionBoundaries() ? this.staleEditPreflightBlock(tc.name, tc.arguments ?? {}) : null;
602632
602869
  if (staleEditBlock) {
602633
602870
  const focusDecision2 = this._focusSupervisor?.evaluateProposedCall({
602634
602871
  turn,
@@ -602693,7 +602930,7 @@ Read the current file if needed, make a different concrete edit, or move to veri
602693
602930
  systemGuidance: staleBlockOutput
602694
602931
  };
602695
602932
  }
602696
- const staleRewriteBlock = this.staleEditOverwritePreflightBlock(tc.name, tc.arguments ?? {}, turn);
602933
+ const staleRewriteBlock = this._enforcesStrictActionBoundaries() ? this.staleEditOverwritePreflightBlock(tc.name, tc.arguments ?? {}, turn) : null;
602697
602934
  if (staleRewriteBlock) {
602698
602935
  const focusDecision2 = this._focusSupervisor?.evaluateProposedCall({
602699
602936
  turn,
@@ -602911,47 +603148,6 @@ Read the current file if needed, make a different concrete edit, or move to veri
602911
603148
  adversaryRedundantSignal
602912
603149
  });
602913
603150
  let repeatShortCircuit = null;
602914
- const exactReadArgs = tc.arguments;
602915
- const exactReadPath = String(exactReadArgs?.["path"] ?? exactReadArgs?.["file"] ?? "");
602916
- const exactReadEvidence = exactReadEvidenceEpochs.get(toolFingerprint);
602917
- const exactReadEvidenceFresh = tc.name === "file_read" && exactReadPath.length > 0 && this._evidenceLedger.validateFreshness(this._normalizeEvidencePath(exactReadPath), this._absoluteToolPath(exactReadPath));
602918
- if (tc.name === "file_read" && exactReadEvidenceFresh && exactReadEvidence?.taskEpoch === this._taskEpoch && exactReadEvidence.mutationEpoch === fileMutationEpoch) {
602919
- const path16 = this._normalizeEvidencePath(exactReadPath);
602920
- const evidence = this._evidenceLedger.get(path16);
602921
- const rawCurated = this._branchEvidenceByPath.get(path16) ?? [...this._branchEvidenceByPath.entries()].find(([candidate]) => this._normalizeEvidencePath(candidate) === path16)?.[1];
602922
- const curated = rawCurated?.taskEpoch === this._taskEpoch ? rawCurated : void 0;
602923
- const curatedPayload = curated?.output ?? (evidence?.fidelity === "extract" && evidence.content.includes("[BRANCH-EXTRACT") ? evidence.content : null);
602924
- repeatShortCircuit = {
602925
- success: true,
602926
- output: curatedPayload ? this._rehydrateResolvedReadEvidence({
602927
- fingerprint: toolFingerprint,
602928
- canonicalPath: path16,
602929
- contentHash: curated?.contentHash ?? evidence?.contentHash ?? "unknown",
602930
- payload: curatedPayload,
602931
- turn
602932
- }) : [
602933
- ...evidence?.fidelity === "extract" ? [
602934
- "[REHYDRATED_FILE_EVIDENCE]",
602935
- "source=active_context_frame fidelity=extract"
602936
- ] : [],
602937
- "[READ EVIDENCE REFERENCE]",
602938
- `path=${path16 || "unknown"}`,
602939
- `task_epoch=${this._taskEpoch}`,
602940
- `freshness=${evidence?.stale ? "stale" : "fresh"}`,
602941
- evidence?.contentHash ? `sha256=${evidence.contentHash}` : null,
602942
- "Exact unchanged range was not re-executed. Use the existing evidence handle or request a newly uncovered range after identifying the missing fact."
602943
- ].filter(Boolean).join("\n"),
602944
- runtimeAuthored: true,
602945
- noop: true
602946
- };
602947
- this.emit({
602948
- type: "status",
602949
- toolName: tc.name,
602950
- content: `Exact unchanged file_read blocked before dispatch: ${path16}`,
602951
- turn,
602952
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
602953
- });
602954
- }
602955
603151
  if (criticDecision.decision === "guidance" && !repeatShortCircuit) {
602956
603152
  dedupHitCount.set(toolFingerprint, criticDecision.hitNumber);
602957
603153
  const _existingFp = recentToolResults.get(toolFingerprint);
@@ -602992,68 +603188,12 @@ Read the current file if needed, make a different concrete edit, or move to veri
602992
603188
  });
602993
603189
  }
602994
603190
  const _repeatGateMax = this._resolveRepeatGateMax();
602995
- const isFailedShellRepeat = tc.name === "shell" && typeof _existingFp?.result === "string" && _existingFp.result.includes("status: failure") && (_existingFp.mutationEpoch ?? fileMutationEpoch) === fileMutationEpoch && !this._compileFixLoopRequiresLiveShell(String(tc.arguments?.["command"] ?? tc.arguments?.["cmd"] ?? "")) && !shellLikelyMutatesFilesystem;
602996
- const repeatGateEligible = isReadLike || tc.name === "memory_write" || isFailedShellRepeat;
603191
+ const isFailedShellRepeat = this._enforcesStrictActionBoundaries() && tc.name === "shell" && typeof _existingFp?.result === "string" && _existingFp.result.includes("status: failure") && (_existingFp.mutationEpoch ?? fileMutationEpoch) === fileMutationEpoch && !this._compileFixLoopRequiresLiveShell(String(tc.arguments?.["command"] ?? tc.arguments?.["cmd"] ?? "")) && !shellLikelyMutatesFilesystem;
603192
+ const repeatGateEligible = isReadLike && tc.name !== "file_read" || tc.name === "memory_write" || isFailedShellRepeat;
602997
603193
  const suppressSuccessfulShellCacheGuidance = tc.name === "shell" && !isFailedShellRepeat;
602998
603194
  if (suppressSuccessfulShellCacheGuidance)
602999
603195
  criticGuidance = null;
603000
- let exactReadEvidenceFresh2 = true;
603001
- if (isReadLike && this._evidenceLedger) {
603002
- const readArgs = tc.arguments;
603003
- const readPath2 = String(readArgs?.["path"] ?? readArgs?.["file"] ?? "");
603004
- if (readPath2) {
603005
- const evidencePath = this._normalizeEvidencePath(readPath2);
603006
- const wasFresh = evidencePath && this._evidenceLedger.validateFreshness(evidencePath, this._absoluteToolPath(readPath2));
603007
- exactReadEvidenceFresh2 = Boolean(wasFresh);
603008
- if (!wasFresh) {
603009
- recentToolResults.delete(toolFingerprint);
603010
- dedupHitCount.delete(toolFingerprint);
603011
- this._recentFailures = (this._recentFailures ?? []).filter((f2) => f2.fingerprint !== toolFingerprint);
603012
- repeatShortCircuit = null;
603013
- this.emit({
603014
- type: "status",
603015
- content: `[EXTERNAL MUTATION] ${readPath2} mtime changed since last read — cache invalidated, fresh read allowed`,
603016
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
603017
- });
603018
- }
603019
- }
603020
- }
603021
- const exactReadEvidence2 = exactReadEvidenceEpochs.get(toolFingerprint);
603022
- const exactFileReadReference = tc.name === "file_read" && exactReadEvidenceFresh2 && exactReadEvidence2?.taskEpoch === this._taskEpoch && exactReadEvidence2.mutationEpoch === fileMutationEpoch;
603023
- if (exactFileReadReference) {
603024
- const path16 = this._normalizeEvidencePath(String(tc.arguments?.["path"] ?? tc.arguments?.["file"] ?? ""));
603025
- const evidence = this._evidenceLedger?.get(path16);
603026
- const rawCurated = this._branchEvidenceByPath.get(path16) ?? [...this._branchEvidenceByPath.entries()].find(([candidate]) => this._normalizeEvidencePath(candidate) === path16)?.[1];
603027
- const curated = rawCurated?.taskEpoch === this._taskEpoch ? rawCurated : void 0;
603028
- const curatedPayload = curated?.output ?? (evidence?.fidelity === "extract" && evidence.content.includes("[BRANCH-EXTRACT") ? evidence.content : null);
603029
- repeatShortCircuit = {
603030
- success: true,
603031
- // Curated branch output is the bounded authoritative payload
603032
- // for this source version. Rehydrate it instead of replacing
603033
- // it with a pointer; exact/overlap suppression must not force
603034
- // the model to reread a large source merely to recover facts.
603035
- output: curatedPayload ? this._rehydrateResolvedReadEvidence({
603036
- fingerprint: toolFingerprint,
603037
- canonicalPath: path16,
603038
- contentHash: curated?.contentHash ?? evidence?.contentHash ?? "unknown",
603039
- payload: curatedPayload,
603040
- turn
603041
- }) : [
603042
- ...evidence?.fidelity === "extract" ? [
603043
- "[REHYDRATED_FILE_EVIDENCE]",
603044
- "source=active_context_frame fidelity=extract"
603045
- ] : [],
603046
- "[READ EVIDENCE REFERENCE]",
603047
- `path=${path16 || "unknown"}`,
603048
- `task_epoch=${this._taskEpoch}`,
603049
- `freshness=${evidence?.stale ? "stale" : "fresh"}`,
603050
- evidence?.contentHash ? `sha256=${evidence.contentHash}` : null,
603051
- "Exact unchanged range was not re-executed. Use the existing evidence handle or request a newly uncovered range after identifying the missing fact."
603052
- ].filter(Boolean).join("\n"),
603053
- runtimeAuthored: true,
603054
- noop: true
603055
- };
603056
- } else if (repeatGateEligible && _existingFp !== void 0 && _repeatGateMax > 0) {
603196
+ if (repeatGateEligible && _existingFp !== void 0 && _repeatGateMax > 0) {
603057
603197
  const _rehydrateArgs = tc.arguments;
603058
603198
  const _rehydratePath = String(_rehydrateArgs?.["path"] ?? _rehydrateArgs?.["file"] ?? "");
603059
603199
  const _visibleViaEvidenceFrame = _rehydratePath.length > 0 && (this._evidenceLedger?.renderedFullInLastBlock(this._normalizeEvidencePath(_rehydratePath)) ?? false);
@@ -603119,6 +603259,15 @@ ${cachedResult}`,
603119
603259
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
603120
603260
  });
603121
603261
  }
603262
+ if (!repeatShortCircuit && this.options.subAgent && tc.name === "workboard_complete_card" && String((tc.arguments ?? {})["outcome"] ?? "completed") !== "request_changes") {
603263
+ repeatShortCircuit = {
603264
+ success: false,
603265
+ output: "",
603266
+ error: "[PARENT_COMPLETION_AUTHORITY] A sub-agent may attach action/verifier evidence or request changes, but only its parent/coordinator may complete or verify a workboard card.",
603267
+ runtimeAuthored: true,
603268
+ noop: true
603269
+ };
603270
+ }
603122
603271
  const focusCachedEntry = recentToolResults.get(toolFingerprint);
603123
603272
  const focusDuplicateHits = criticDecision.decision === "guidance" ? dedupHitCount.get(toolFingerprint) ?? criticDecision.hitNumber : dedupHitCount.get(toolFingerprint) ?? 0;
603124
603273
  const usesAuthoritativeTargetEvidence = this._toolCallUsesFreshFileReadEvidence(tc.name, tc.arguments ?? {});
@@ -603138,8 +603287,9 @@ ${cachedResult}`,
603138
603287
  taskEpoch: this._taskEpoch
603139
603288
  });
603140
603289
  if (focusDecision && focusDecision.kind !== "pass") {
603290
+ const advisoryOnlyForLargeModel = focusDecision.kind === "block_tool_call" && !this._enforcesStrictActionBoundaries() && tc.name !== "task_complete";
603141
603291
  this._emitFocusSupervisorEvent({
603142
- decision: focusDecision.kind,
603292
+ decision: advisoryOnlyForLargeModel ? "inject_guidance" : focusDecision.kind,
603143
603293
  state: focusDecision.state,
603144
603294
  directiveId: focusDecision.directive.id,
603145
603295
  reason: focusDecision.directive.reason,
@@ -603147,22 +603297,26 @@ ${cachedResult}`,
603147
603297
  blockedTool: focusDecision.kind === "block_tool_call" ? tc.name : void 0,
603148
603298
  turn
603149
603299
  });
603150
- this._maybeMarkFocusTerminalIncomplete({
603151
- decision: focusDecision,
603152
- blockedTool: focusDecision.kind === "block_tool_call" ? tc.name : void 0,
603153
- turn
603154
- });
603155
- if (focusDecision.kind === "block_tool_call" && this._maybeAutoDelegate(tc, focusDecision.directive, messages2, turn)) {
603156
- } else if (focusDecision.kind === "inject_guidance") {
603157
- void focusDecision.message;
603158
- } else if (!repeatShortCircuit) {
603159
- repeatShortCircuit = {
603160
- success: focusDecision.success,
603161
- output: focusDecision.message,
603162
- error: focusDecision.success ? void 0 : focusDecision.message,
603163
- runtimeAuthored: true,
603164
- noop: true
603165
- };
603300
+ if (advisoryOnlyForLargeModel) {
603301
+ pushSoftInjection("system", `[FOCUS ADVISORY — large-model freedom] ${focusDecision.message}`);
603302
+ } else {
603303
+ this._maybeMarkFocusTerminalIncomplete({
603304
+ decision: focusDecision,
603305
+ blockedTool: focusDecision.kind === "block_tool_call" ? tc.name : void 0,
603306
+ turn
603307
+ });
603308
+ if (focusDecision.kind === "block_tool_call" && this._maybeAutoDelegate(tc, focusDecision.directive, messages2, turn)) {
603309
+ } else if (focusDecision.kind === "inject_guidance") {
603310
+ void focusDecision.message;
603311
+ } else if (!repeatShortCircuit) {
603312
+ repeatShortCircuit = {
603313
+ success: focusDecision.success,
603314
+ output: focusDecision.message,
603315
+ error: focusDecision.success ? void 0 : focusDecision.message,
603316
+ runtimeAuthored: true,
603317
+ noop: true
603318
+ };
603319
+ }
603166
603320
  }
603167
603321
  }
603168
603322
  const compileLoopPreflight = !repeatShortCircuit ? this._compileFixLoopPreflightBlock(tc.name, tc.arguments ?? {}, turn, shellLikelyMutatesFilesystem) : null;
@@ -603228,7 +603382,9 @@ ${cachedResult}`,
603228
603382
  tc.arguments = this._normalizeToolArgsForExecution(resolvedTool?.name ?? tc.name, tc.arguments ?? {});
603229
603383
  tc.arguments = this._autoDeriveDelegationMutationScope(resolvedTool?.name ?? tc.name, tc.arguments ?? {}, turn);
603230
603384
  tc.arguments = await this._enrichDelegationToolArgs(resolvedTool?.name ?? tc.name, tc.arguments ?? {}, messages2, turn);
603231
- validationError = this._validateFileWriteOverwriteContract(resolvedTool?.name ?? tc.name, tc.arguments ?? {});
603385
+ validationError = this._partialBranchExplorationMutationBlock(resolvedTool?.name ?? tc.name, tc.arguments ?? {}, turn);
603386
+ if (!validationError)
603387
+ validationError = this._validateFileWriteOverwriteContract(resolvedTool?.name ?? tc.name, tc.arguments ?? {});
603232
603388
  }
603233
603389
  if (!validationError) {
603234
603390
  validationError = this._validateFreshExpectedHashesForEdit(resolvedTool?.name ?? tc.name, tc.arguments ?? {});
@@ -603367,7 +603523,9 @@ ${cachedResult}`,
603367
603523
  exactFileReadObservations.set(exactReadKey, currentRead);
603368
603524
  const canonicalPayload = this._canonicalReadEvidencePayload(currentRead.canonicalPath, currentRead.contentHash);
603369
603525
  if (canonicalPayload) {
603370
- const rehydrated = this._rehydrateResolvedReadEvidence({
603526
+ const evidence = this._evidenceLedger.get(currentRead.canonicalPath);
603527
+ const fullSource = evidence?.fidelity === "full" && evidence.content === canonicalPayload;
603528
+ const delivered = fullSource ? canonicalPayload : this._rehydrateResolvedReadEvidence({
603371
603529
  fingerprint: exactReadKey,
603372
603530
  canonicalPath: currentRead.canonicalPath,
603373
603531
  contentHash: currentRead.contentHash,
@@ -603376,8 +603534,8 @@ ${cachedResult}`,
603376
603534
  });
603377
603535
  branchEvidenceResult = {
603378
603536
  success: true,
603379
- output: rehydrated,
603380
- llmContent: rehydrated,
603537
+ output: delivered,
603538
+ llmContent: delivered,
603381
603539
  beforeHash: currentRead.contentHash,
603382
603540
  runtimeAuthored: true,
603383
603541
  noop: true,
@@ -603390,44 +603548,19 @@ ${cachedResult}`,
603390
603548
  this.emit({
603391
603549
  type: "status",
603392
603550
  toolName: normalizedDispatchName,
603393
- content: `Exact unchanged file_read rehydrated: ${currentRead.path} sha256=${currentRead.contentHash.slice(0, 12)} fingerprint_state=resolved_from_cache`,
603551
+ content: fullSource ? `Exact unchanged file_read served as canonical full source: ${currentRead.path} sha256=${currentRead.contentHash.slice(0, 12)}` : `Exact unchanged file_read reused complete branch evidence: ${currentRead.path} sha256=${currentRead.contentHash.slice(0, 12)}`,
603394
603552
  turn,
603395
603553
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
603396
603554
  });
603397
603555
  } else {
603398
- if (this._deterministicNarrowReadFallbacks.has(exactReadKey)) {
603399
- const fallbackBlocked = [
603400
- "[REPEATED_NARROW_READ_REJECTED]",
603401
- `path=${currentRead.path}`,
603402
- "No canonical payload was produced by the allowed narrow reread. Change scope with a new range or symbol query; do not repeat identical arguments."
603403
- ].join("\n");
603404
- branchEvidenceResult = {
603405
- success: true,
603406
- output: fallbackBlocked,
603407
- llmContent: fallbackBlocked,
603408
- beforeHash: currentRead.contentHash,
603409
- runtimeAuthored: true,
603410
- noop: true
603411
- };
603412
- } else {
603413
- this._deterministicNarrowReadFallbacks.add(exactReadKey);
603414
- const previousOffset = tc.arguments["offset"];
603415
- const previousLimit = tc.arguments["limit"];
603416
- Object.assign(finalArgs, {
603417
- offset: typeof previousOffset === "number" && Number.isFinite(previousOffset) ? Math.max(1, Math.floor(previousOffset)) : 1,
603418
- limit: typeof previousLimit === "number" && Number.isFinite(previousLimit) ? Math.max(1, Math.min(160, Math.floor(previousLimit))) : 160
603419
- });
603420
- tc.arguments = finalArgs;
603421
- this._deterministicNarrowReadFallbacks.add(this._buildToolFingerprint("file_read", tc.arguments));
603422
- exactFileReadObservations.delete(exactReadKey);
603423
- this.emit({
603424
- type: "status",
603425
- toolName: normalizedDispatchName,
603426
- content: `Exact read cache lacked canonical payload; allowing one deterministic narrow reread: ${currentRead.path} offset=${tc.arguments["offset"]} limit=${tc.arguments["limit"]}`,
603427
- turn,
603428
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
603429
- });
603430
- }
603556
+ exactFileReadObservations.delete(exactReadKey);
603557
+ this.emit({
603558
+ type: "status",
603559
+ toolName: normalizedDispatchName,
603560
+ content: `Exact read cache lacks model-visible source; executing requested read: ${currentRead.path}`,
603561
+ turn,
603562
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
603563
+ });
603431
603564
  }
603432
603565
  } else {
603433
603566
  exactFileReadObservations.delete(exactReadKey);
@@ -603697,7 +603830,7 @@ ${cachedResult}`,
603697
603830
  fileVersion: this._worldFacts.files.get(p2)?.writeCount ?? 0,
603698
603831
  mtimeMs: this._statMtimeMsForToolPath(p2),
603699
603832
  turn,
603700
- fidelity: result.runtimeAuthored === true && result.output.startsWith("[BRANCH-EXTRACT") ? "extract" : void 0
603833
+ fidelity: result.runtimeAuthored === true && result.output.startsWith("[BRANCH-EXTRACT") ? "extract" : this._fileReadMode(tc.arguments) === "full" && this._mustHonorExplicitFullFileRead(Buffer.byteLength(result.output, "utf8"), result.output.split("\n").length, this._branchRoutingContextWindow()) ? "full" : void 0
603701
603834
  });
603702
603835
  if (result.runtimeAuthored !== true && this._fileReadMode(tc.arguments) !== "extract" && typeof result.beforeHash === "string") {
603703
603836
  this._inlineReadArtifacts.set(tc.id, {
@@ -603717,10 +603850,6 @@ ${cachedResult}`,
603717
603850
  this._inlineReadArtifacts.delete(oldest);
603718
603851
  }
603719
603852
  }
603720
- exactReadEvidenceEpochs.set(toolFingerprint, {
603721
- taskEpoch: this._taskEpoch,
603722
- mutationEpoch: fileMutationEpoch
603723
- });
603724
603853
  this._registerReadCoverage("file_read", tc.arguments, toolFingerprint);
603725
603854
  }
603726
603855
  if (this._fileSummaryStore && result.success && result.output && result.output.length > 100) {
@@ -604643,7 +604772,7 @@ ${bookkeepingGuidance}`;
604643
604772
 
604644
604773
  ${bookkeepingGuidance}` : bookkeepingGuidance;
604645
604774
  }
604646
- if (!result.success && (this.options.modelTier === "small" || this.options.modelTier === "medium")) {
604775
+ if (!result.success && this.options.modelTier === "small") {
604647
604776
  const recovery = this.buildRecoveryGuidance(tc.name, result.error ?? "", tc.arguments);
604648
604777
  if (recovery)
604649
604778
  output += "\n\n" + recovery;
@@ -605094,7 +605223,7 @@ ${delegateDir}` : delegateDir;
605094
605223
  sameToolFailStreak = 1;
605095
605224
  }
605096
605225
  const consecutiveSameTool = Math.max(sameToolFailStreak, this._taskState.failedApproaches.slice(-2).filter((f2) => f2.startsWith(`${tc.name}(`)).length);
605097
- if (sameToolFailStreak >= 5 && (this.options.modelTier === "small" || this.options.modelTier === "medium")) {
605226
+ if (sameToolFailStreak >= 5 && this.options.modelTier === "small") {
605098
605227
  this.enqueueRuntimeGuidance(`[BRANCH — evaluate alternatives before acting]
605099
605228
  Tool "${tc.name}" has failed ${sameToolFailStreak} times. STOP and enumerate:
605100
605229
  Option A: refresh the exact evidence or correct the current tool arguments
@@ -605104,7 +605233,7 @@ Pick the BEST option and explain why, then execute it. Do NOT retry ${tc.name} w
605104
605233
  sameToolFailStreak = 0;
605105
605234
  sameToolFailName = null;
605106
605235
  }
605107
- if (consecutiveSameTool >= 2 && (this.options.modelTier === "small" || this.options.modelTier === "medium")) {
605236
+ if (consecutiveSameTool >= 2 && this.options.modelTier === "small") {
605108
605237
  this.enqueueRuntimeGuidance(`[PIVOT REQUIRED] You have failed ${consecutiveSameTool + 1} times in a row with ${tc.name}. Your current approach is not working. You MUST try something fundamentally different:
605109
605238
  - If file_edit/file_patch keeps failing: re-read the implicated current range, then correct the exact text/range/hash or inspect git diff
605110
605239
  - If shell keeps failing: try a different command or check prerequisites
@@ -605151,7 +605280,7 @@ Do NOT retry ${tc.name} with similar arguments and do NOT use file_write to esca
605151
605280
  } catch {
605152
605281
  }
605153
605282
  }
605154
- if (isModify && (turnTier === "small" || turnTier === "medium")) {
605283
+ if (isModify && turnTier === "small") {
605155
605284
  const modCount = this._taskState.modifiedFiles.size;
605156
605285
  if (modCount >= 2 && modCount % 2 === 0) {
605157
605286
  this.enqueueRuntimeGuidance(`[Test reminder] You've modified ${modCount} files. Run relevant tests NOW to verify: shell(command="npm test") or the project's test command. Fix any failures before continuing.`);
@@ -607452,6 +607581,17 @@ ${marker}` : marker);
607452
607581
  if (toolName === "file_read") {
607453
607582
  const path17 = this.extractPrimaryToolPath(args);
607454
607583
  const evidencePath = path17 ? this._normalizeEvidencePath(path17) : "";
607584
+ const explicitBoundedFullRead = this._fileReadMode(args ?? {}) === "full" && this._mustHonorExplicitFullFileRead(Buffer.byteLength(displayOutput, "utf8"), this.countTextLines(displayOutput), this._branchRoutingContextWindow());
607585
+ if (explicitBoundedFullRead) {
607586
+ return [
607587
+ "[ADMITTED_FILE_READ v1]",
607588
+ `path=${path17 || "unknown"}`,
607589
+ "delivery=explicit_full_source",
607590
+ "The requested bounded full source is present below. It may be reread after a filesystem change or when a new range is needed.",
607591
+ "",
607592
+ output
607593
+ ].join("\n");
607594
+ }
607455
607595
  const admitted = [...this._inlineReadArtifacts.values()].find((artifact) => artifact.path === evidencePath && output.includes(`sha256=${artifact.contentHash}`));
607456
607596
  if (admitted) {
607457
607597
  return [
@@ -607459,7 +607599,7 @@ ${marker}` : marker);
607459
607599
  `path=${admitted.path}`,
607460
607600
  `sha256=${admitted.contentHash}`,
607461
607601
  "delivery=full_body_once",
607462
- 'The full selected source body below is canonical for this turn. To replace it with compact verified anchors, call file_read again with mode="extract" and purpose="the exact fact needed". Do not use shell/cat as a read workaround.',
607602
+ 'The full selected source body below is canonical for this turn. To replace it with compact verified anchors, call file_read again with mode="extract" and purpose="the exact fact needed".',
607463
607603
  "",
607464
607604
  output
607465
607605
  ].join("\n");
@@ -607491,7 +607631,7 @@ ${marker}` : marker);
607491
607631
  ].filter(Boolean).join("\n"));
607492
607632
  }
607493
607633
  shouldBypassDiscoveryCompaction(output) {
607494
- return output.includes("[IMAGE_BASE64:") || output.includes("[ADMITTED_FILE_READ") || /^\[BRANCH-EXTRACT(?:\s+v\d+)?\]/m.test(output) || output.includes("[REPEAT GATE - cached evidence not re-sent]") || output.includes("[REPEATED_READ_REJECTED]") || output.includes("[REPEATED_NARROW_READ_REJECTED]") || output.includes("[CACHED READ — content unchanged") || output.includes("[REHYDRATED FROM CACHE") || output.includes("[Tool output truncated") || output.includes(TRIAGE_ENVELOPE_MARKER);
607634
+ return output.includes("[IMAGE_BASE64:") || output.includes("[ADMITTED_FILE_READ") || /^\[BRANCH-EXTRACT(?:\s+v\d+)?\]/m.test(output) || output.includes("[REPEAT GATE - cached evidence not re-sent]") || output.includes("[CACHED READ — content unchanged") || output.includes("[REHYDRATED FROM CACHE") || output.includes("[Tool output truncated") || output.includes(TRIAGE_ENVELOPE_MARKER);
607495
607635
  }
607496
607636
  countTextLines(text2) {
607497
607637
  if (!text2)
@@ -607927,6 +608067,8 @@ ${marker}` : marker);
607927
608067
  _validateFileWriteOverwriteContract(toolName, args) {
607928
608068
  if (toolName !== "file_write")
607929
608069
  return null;
608070
+ if (!this._enforcesStrictActionBoundaries())
608071
+ return null;
607930
608072
  if (process.env["OMNIUS_ALLOW_UNVERIFIED_FILE_WRITE_OVERWRITE"] === "1") {
607931
608073
  return null;
607932
608074
  }
@@ -607943,7 +608085,7 @@ ${marker}` : marker);
607943
608085
  });
607944
608086
  if (active) {
607945
608087
  const tier = this.options.modelTier ?? "large";
607946
- if (tier !== "small" && tier !== "medium")
608088
+ if (tier !== "small")
607947
608089
  return null;
607948
608090
  return [
607949
608091
  `[EDIT REPAIR LOCK] A recent narrow edit to ${active.path} failed because the model-visible target diverged from disk (${active.errorKind}; latest_file_hash=${active.latestFileHash || "unknown"}).`,
@@ -607989,7 +608131,40 @@ ${marker}` : marker);
607989
608131
  }
607990
608132
  return null;
607991
608133
  }
608134
+ /**
608135
+ * Partial branch coverage is useful evidence, never mutation authority and
608136
+ * never a tool admission gate. The parent model may decide that its current
608137
+ * evidence is sufficient, request more branch work, or perform a narrow edit
608138
+ * validated by the normal file hash contract. Blocking here caused file_edit
608139
+ * calls to be mislabeled as stale hashes and stranded real exploration.
608140
+ */
608141
+ _partialBranchExplorationMutationBlock(toolName, args, turn) {
608142
+ const delegatedMutation = (toolName === "sub_agent" || toolName === "agent") && (args["mutation_role"] === "mutation_worker" || args["subagent_type"] === "fixer");
608143
+ if (!this._isProjectEditTool(toolName) && !delegatedMutation)
608144
+ return null;
608145
+ const targetPaths = this._isProjectEditTool(toolName) ? this._extractToolTargetPaths(toolName, args) : [
608146
+ ...Array.isArray(args["owned_files"]) ? args["owned_files"] : [],
608147
+ ...Array.isArray(args["relevant_files"]) ? args["relevant_files"] : []
608148
+ ].filter((value2) => typeof value2 === "string");
608149
+ for (const target of targetPaths) {
608150
+ const normalizedTarget = this._normalizeEvidencePath(target);
608151
+ const partial = [...this._branchEvidenceByPath.entries()].find(([path17, node2]) => node2.taskEpoch === this._taskEpoch && !node2.contractComplete && this._pathsOverlapForVerifier(normalizedTarget, path17));
608152
+ if (!partial)
608153
+ continue;
608154
+ const [path16, node] = partial;
608155
+ this.emit({
608156
+ type: "status",
608157
+ content: `branch_discovery_partial_advisory: ${toolName} is proceeding with ${path16}; unresolved=${node.unresolvedRequirementIds.join(",") || "unknown"}; coverage is visible evidence, not an admission block`,
608158
+ turn,
608159
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
608160
+ });
608161
+ return null;
608162
+ }
608163
+ return null;
608164
+ }
607992
608165
  _validateFreshExpectedHashesForEdit(toolName, args) {
608166
+ if (!this._enforcesStrictActionBoundaries())
608167
+ return null;
607993
608168
  if (process.env["OMNIUS_ALLOW_UNVERIFIED_OLD_STRING_EDIT"] === "1") {
607994
608169
  return null;
607995
608170
  }
@@ -608150,6 +608325,8 @@ ${marker}` : marker);
608150
608325
  ].join("\n");
608151
608326
  }
608152
608327
  editReversalPreflightBlock(toolName, args, turn) {
608328
+ if (!this._enforcesStrictActionBoundaries())
608329
+ return null;
608153
608330
  if (process.env["OMNIUS_ALLOW_BLIND_EDIT_REVERSAL"] === "1")
608154
608331
  return null;
608155
608332
  const replacements = this.extractReplacementEdits(toolName, args);
@@ -608345,6 +608522,10 @@ ${marker}` : marker);
608345
608522
  return this.wrapToolOutputForModel(toolName, `Error: ${result.error || "unknown error"}
608346
608523
  ${errOutput}`);
608347
608524
  }
608525
+ const explicitBoundedFullRead = toolName === "file_read" && this._fileReadMode(args) === "full" && this._mustHonorExplicitFullFileRead(Buffer.byteLength(modelContent, "utf8"), modelContent.split("\n").length, this._branchRoutingContextWindow());
608526
+ if (explicitBoundedFullRead) {
608527
+ return this.wrapToolOutputForModel(toolName, modelContent);
608528
+ }
608348
608529
  if (modelContent.length <= maxLen) {
608349
608530
  return this.wrapToolOutputForModel(toolName, modelContent);
608350
608531
  }
@@ -608806,7 +608987,50 @@ Actions: (1) list_directory on the parent directory to see what's there, (2) Che
608806
608987
  *
608807
608988
  * Returns true if it rewrote `tc` (the caller must let it EXECUTE, not noop it).
608808
608989
  */
608990
+ _takePendingCompileDelegation(messages2, turn) {
608991
+ const cardId = this._pendingCompileDelegationCardId;
608992
+ if (!cardId || !this._enforcesStrictActionBoundaries() || this.options.subAgent || !this.tools.has("sub_agent")) {
608993
+ return null;
608994
+ }
608995
+ const state = this._compileFixLoop;
608996
+ const card = state?.cards.find((candidate) => candidate.id === cardId && (candidate.status === "open" || candidate.status === "assigned" || candidate.status === "needs_changes"));
608997
+ if (!card) {
608998
+ this._pendingCompileDelegationCardId = null;
608999
+ return null;
609000
+ }
609001
+ this._pendingCompileDelegationCardId = null;
609002
+ card.status = "assigned";
609003
+ card.assignedTurn = turn;
609004
+ this._mirrorCompileFixCardAssigned(card, turn);
609005
+ const contract = buildMutationWorkerContractForCard(card);
609006
+ const prompt = buildCuratedFixerPrompt({
609007
+ card,
609008
+ sourceExcerpt: this._compileFixSourceExcerpt(card.diagnostic.file, card.diagnostic.line),
609009
+ declarationExcerpt: card.declarationFiles.length > 0 ? this._compileFixSourceExcerpt(card.declarationFiles[0], void 0) : void 0
609010
+ });
609011
+ const parentTok = estimateMessagesTokens2(messages2);
609012
+ this.emit({
609013
+ type: "status",
609014
+ content: `[FAN-OUT] compile verifier produced ${card.id}; orchestrator is launching one isolated fixer (main ~${parentTok.toLocaleString()} tok -> curated worker frame: ${card.ownedFiles.join(", ") || "diagnostic target"}).`,
609015
+ turn,
609016
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
609017
+ });
609018
+ return {
609019
+ id: `auto-compile-${card.id}-${turn}`,
609020
+ name: "sub_agent",
609021
+ arguments: {
609022
+ subagent_type: "fixer",
609023
+ description: `fix ${card.id}`,
609024
+ prompt,
609025
+ relevant_files: card.ownedFiles,
609026
+ exit_criterion: "diagnostic fingerprint disappeared after verifier rerun",
609027
+ ...contract
609028
+ }
609029
+ };
609030
+ }
608809
609031
  _maybeAutoDelegate(tc, directive, messages2, turn) {
609032
+ if (!this._enforcesStrictActionBoundaries())
609033
+ return false;
608810
609034
  if (directive.requiredNextAction !== "delegate_isolated_fix")
608811
609035
  return false;
608812
609036
  if (tc.name === "sub_agent" || tc.name === "agent")
@@ -608904,11 +609128,20 @@ Actions: (1) list_directory on the parent directory to see what's there, (2) Che
608904
609128
  _retireStaleEvidenceInPlace(messages2, currentTurn) {
608905
609129
  if (process.env["OMNIUS_DISABLE_EVIDENCE_RETIREMENT"] === "1")
608906
609130
  return;
609131
+ const tier = this.options.modelTier ?? "large";
609132
+ const forceRetirement = process.env["OMNIUS_FORCE_EVIDENCE_RETIREMENT"] === "1";
609133
+ const residentTokens = estimateMessagesTokens2(messages2);
609134
+ const pressureThreshold = Math.floor(this.contextLimits().compactionThreshold * 0.9);
609135
+ if (tier !== "small" && !forceRetirement && residentTokens < pressureThreshold) {
609136
+ return;
609137
+ }
608907
609138
  const keepRecent = Math.max(0, Number(process.env["OMNIUS_EVIDENCE_KEEP_TURNS"] ?? 2));
608908
609139
  const minChars = Math.max(512, Number(process.env["OMNIUS_EVIDENCE_MIN_CHARS"] ?? 2e3));
608909
609140
  const staleBefore = currentTurn - keepRecent;
608910
609141
  if (staleBefore <= 0)
608911
609142
  return;
609143
+ const liveToolCallIds = new Set(this._recentToolOutcomes.slice(-4).map((outcome) => outcome.toolCallId).filter((id2) => Boolean(id2)));
609144
+ const unresolvedBranchPaths = [...this._branchEvidenceByPath.entries()].filter(([, node]) => node.taskEpoch === this._taskEpoch && !node.contractComplete).map(([path16]) => this._normalizeEvidencePath(path16)).filter(Boolean);
608912
609145
  let turnCount = 0;
608913
609146
  let retired = 0;
608914
609147
  let reclaimed = 0;
@@ -608922,9 +609155,20 @@ Actions: (1) list_directory on the parent directory to see what's there, (2) Che
608922
609155
  const content = typeof msg.content === "string" ? msg.content : "";
608923
609156
  if (!content)
608924
609157
  continue;
609158
+ if (msg.role === "tool" && liveToolCallIds.has(msg.tool_call_id ?? "")) {
609159
+ continue;
609160
+ }
608925
609161
  if (content.startsWith("[RETIRED EVIDENCE") || content.startsWith("[Todo context archived") || content.startsWith("[Tool result cleared")) {
608926
609162
  continue;
608927
609163
  }
609164
+ if (isRecoveryCriticalRuntimeOutcome(content))
609165
+ continue;
609166
+ if (unresolvedBranchPaths.some((path16) => content.includes(path16)))
609167
+ continue;
609168
+ const fileContextPath = /\[FILE CONTEXT\s*\|\s*([^|\n]+)/.exec(content)?.[1]?.trim();
609169
+ if (fileContextPath && !this._evidenceLedger.hasFresh(this._normalizeEvidencePath(fileContextPath))) {
609170
+ continue;
609171
+ }
608928
609172
  const rm4 = { role: msg.role, content };
608929
609173
  if (!isRetirableEvidence(rm4, minChars))
608930
609174
  continue;
@@ -609463,6 +609707,23 @@ Describe what you see and integrate this into your current approach.` : "[User s
609463
609707
  if (!force && estimatedTokens < limits.compactionThreshold) {
609464
609708
  return messages2;
609465
609709
  }
609710
+ if (!force) {
609711
+ const partialBranchActive = [...this._branchEvidenceByPath.values()].some((node) => node.taskEpoch === this._taskEpoch && !node.contractComplete);
609712
+ const decision2 = decideCompaction({
609713
+ pressureRatio: estimatedTokens / Math.max(1, limits.compactionThreshold),
609714
+ lastSubtaskResolved: this._recentToolOutcomes.at(-1)?.succeeded === true,
609715
+ midDerivation: partialBranchActive,
609716
+ convergenceStalled: this._compileFixLoop?.verifierStasisBlocked === true
609717
+ });
609718
+ if (!decision2.compact) {
609719
+ this.emit({
609720
+ type: "status",
609721
+ content: `[semantic-compaction] held: ${decision2.reason}`,
609722
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
609723
+ });
609724
+ return messages2;
609725
+ }
609726
+ }
609466
609727
  if (force && messages2.length < 5)
609467
609728
  return messages2;
609468
609729
  let keepRecent = limits.keepRecent;
@@ -609637,13 +609898,42 @@ Describe what you see and integrate this into your current approach.` : "[User s
609637
609898
  const postChars = combinedSummary.length + recent.reduce((s2, m2) => s2 + _estimateMsgChars(m2), 0) + head.reduce((s2, m2) => s2 + _estimateMsgChars(m2), 0);
609638
609899
  const postTokens = Math.ceil(postChars / 4);
609639
609900
  const savedTokens = preTokens - postTokens;
609901
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString();
609902
+ const removedMessages = messages2.slice(headEndIdx, recentStart).map((message2, offset) => {
609903
+ const content = typeof message2.content === "string" ? message2.content : JSON.stringify(message2.content);
609904
+ const isLegacy = this._isLegacyControlMessage(message2);
609905
+ const isPriorSummary = message2.role === "system" && typeof message2.content === "string" && message2.content.startsWith("[Context compacted");
609906
+ return {
609907
+ index: headEndIdx + offset,
609908
+ role: message2.role,
609909
+ content,
609910
+ chars: content.length,
609911
+ reason: isLegacy ? "legacy_control_retired" : isPriorSummary ? "prior_summary_folded" : "history_summarized",
609912
+ ...message2.tool_call_id ? { toolCallId: message2.tool_call_id } : {}
609913
+ };
609914
+ });
609915
+ const compactionAudit = {
609916
+ id: `cmp-${this.currentArtifactRunId()}-${Date.now().toString(36)}`,
609917
+ runId: this.currentArtifactRunId(),
609918
+ sessionId: this._sessionId,
609919
+ timestamp,
609920
+ strategy,
609921
+ manual: force,
609922
+ beforeTokens: preTokens,
609923
+ afterTokens: postTokens,
609924
+ savedTokens,
609925
+ retainedMessages: head.length + recent.length + 1,
609926
+ removedMessages,
609927
+ summary: combinedSummary
609928
+ };
609640
609929
  this.emit({
609641
609930
  type: "compaction",
609642
- content: `Compacted ${middle.length} messages${strategyLabel}${forceLabel}${previousSummary ? " (progressive)" : ""} | ~${preTokens.toLocaleString()} → ~${postTokens.toLocaleString()} tokens (saved ~${savedTokens.toLocaleString()})`,
609643
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
609931
+ content: `Compacted ${removedMessages.length} messages${strategyLabel}${forceLabel}${previousSummary ? " (progressive)" : ""} | ~${preTokens.toLocaleString()} → ~${postTokens.toLocaleString()} tokens (saved ~${savedTokens.toLocaleString()})`,
609932
+ timestamp,
609933
+ compaction: compactionAudit
609644
609934
  });
609645
609935
  const tier = this.options.modelTier ?? "large";
609646
- if (tier === "small" || tier === "medium") {
609936
+ if (tier === "small") {
609647
609937
  this._taskState.nextAction = this.inferNextAction(recent);
609648
609938
  }
609649
609939
  const manifestText = (() => {
@@ -609745,14 +610035,14 @@ ${postCompactRestore.join("\n")}`);
609745
610035
  const goalReminder = this._taskState.goal ? `
609746
610036
 
609747
610037
  **YOUR ACTIVE TASK:** ${this._taskState.goal}` : "";
609748
- const nextActionDirective = (tier === "small" || tier === "medium") && this._taskState.nextAction ? `
610038
+ const nextActionDirective = tier === "small" && this._taskState.nextAction ? `
609749
610039
 
609750
610040
  **DO THIS NEXT:** ${this._taskState.nextAction}` : "";
609751
610041
  const toolCallingReminder = tier === "small" ? `
609752
610042
 
609753
610043
  **IMPORTANT:** You MUST invoke tools through the function calling interface. Do NOT write tool names as text, markdown, or code blocks — that does nothing. Call tools using the structured tool/function API.` : "";
609754
610044
  const readFilesList = Array.from(this._fileRegistry.entries()).filter(([, e2]) => e2.accessCount > 0).map(([p2]) => p2).slice(0, 10);
609755
- const fileFreshnessReminder = (tier === "small" || tier === "medium") && readFilesList.length > 0 ? `
610045
+ const fileFreshnessReminder = tier === "small" && readFilesList.length > 0 ? `
609756
610046
 
609757
610047
  **PREVIOUSLY OBSERVED FILES:** ${readFilesList.join(", ")}. Treat restored or summarized text as orientation, not guaranteed current bytes. Before editing, make a narrow live read when the body is elided/truncated, the file may have changed, a hash or edit anchor is stale, or exact current text is otherwise required. Avoid only redundant reads when the latest complete authoritative content is still visible and unchanged.` : "";
609758
610048
  const ephemeralSkillPackReminder = this._ephemeralSkillPackContext ? `
@@ -609820,6 +610110,21 @@ ${telegramPersonaHead}` : stripped
609820
610110
  const fileRecoveryBudget = Math.floor((this._branchRoutingContextWindow() || 32768) * 0.15);
609821
610111
  const maxRecoverFiles = tier === "small" ? 3 : tier === "medium" ? 4 : 5;
609822
610112
  const recoveredFiles = [];
610113
+ const alreadyVisiblePaths = /* @__PURE__ */ new Set();
610114
+ for (const message2 of result) {
610115
+ if (typeof message2.content !== "string")
610116
+ continue;
610117
+ const content = message2.content;
610118
+ const matches = [
610119
+ ...content.matchAll(/(?:^|\n)path=([^\n]+)/g),
610120
+ ...content.matchAll(/<recovered-(?:branch-evidence|file-reference|file) path="([^"]+)"/g)
610121
+ ];
610122
+ for (const match of matches) {
610123
+ const path16 = String(match[1] ?? "").trim();
610124
+ if (path16)
610125
+ alreadyVisiblePaths.add(this._normalizeEvidencePath(path16));
610126
+ }
610127
+ }
609823
610128
  if (this._fileRegistry.size > 0) {
609824
610129
  const entries = Array.from(this._fileRegistry.entries()).sort((a2, b) => {
609825
610130
  if (a2[1].modified && !b[1].modified)
@@ -609830,18 +610135,36 @@ ${telegramPersonaHead}` : stripped
609830
610135
  }).slice(0, maxRecoverFiles);
609831
610136
  let recoveredTokens = 0;
609832
610137
  for (const [filePath, entry] of entries) {
610138
+ const canonicalPath = this._normalizeEvidencePath(filePath);
610139
+ if (alreadyVisiblePaths.has(canonicalPath))
610140
+ continue;
609833
610141
  try {
609834
610142
  const { readFileSync: readFileSync144 } = await import("node:fs");
609835
610143
  const absolutePath = this._absoluteToolPath(filePath);
609836
610144
  const content = readFileSync144(absolutePath, "utf8");
609837
610145
  const tokenEst = Math.ceil(content.length / 4);
609838
- const canonicalPath = this._normalizeEvidencePath(filePath);
609839
610146
  const branchNode = this._branchEvidenceByPath.get(canonicalPath);
609840
610147
  const currentMtime = this._statMtimeMsForToolPath(filePath) ?? 0;
610148
+ const smallCompleteSource = this._mustHonorExplicitFullFileRead(Buffer.byteLength(content, "utf8"), content.split("\n").length, this._branchRoutingContextWindow());
610149
+ if (smallCompleteSource) {
610150
+ const sourceTokens = Math.ceil(content.length / 4);
610151
+ if (recoveredTokens + sourceTokens > fileRecoveryBudget)
610152
+ continue;
610153
+ result.push({
610154
+ role: "system",
610155
+ content: `<recovered-file path="${filePath}" status="${entry.modified ? "modified" : "read"}" sha256="${_createHash("sha256").update(content).digest("hex")}" truncated="false">
610156
+ ${content}
610157
+ </recovered-file>`
610158
+ });
610159
+ alreadyVisiblePaths.add(canonicalPath);
610160
+ recoveredFiles.push(filePath);
610161
+ recoveredTokens += sourceTokens;
610162
+ continue;
610163
+ }
609841
610164
  if (branchNode && // Pre-epoch in-memory nodes are same-run compatibility records;
609842
610165
  // retain their verified curated evidence during compaction rather
609843
610166
  // than falling back to a raw-file recovery reference.
609844
- (branchNode.taskEpoch === void 0 || branchNode.taskEpoch === this._taskEpoch) && branchNode.mtimeMs === currentMtime) {
610167
+ (branchNode.taskEpoch === void 0 || branchNode.taskEpoch === this._taskEpoch) && branchNode.mtimeMs === currentMtime && branchNode.contractComplete) {
609845
610168
  const nodeTokens = Math.ceil(branchNode.output.length / 4);
609846
610169
  if (recoveredTokens + nodeTokens > fileRecoveryBudget)
609847
610170
  continue;
@@ -609853,6 +610176,18 @@ ${branchNode.output}
609853
610176
  });
609854
610177
  recoveredFiles.push(filePath);
609855
610178
  recoveredTokens += nodeTokens;
610179
+ alreadyVisiblePaths.add(canonicalPath);
610180
+ continue;
610181
+ }
610182
+ if (branchNode && !branchNode.contractComplete) {
610183
+ const partialReference = `<recovered-file-reference path="${filePath}" status="partial-extract" sha256="${branchNode.contentHash}">A prior isolated extraction was partial; it is advisory only. Request full source or a new targeted range if this file is now needed.</recovered-file-reference>`;
610184
+ const referenceTokens = Math.ceil(partialReference.length / 4);
610185
+ if (recoveredTokens + referenceTokens > fileRecoveryBudget)
610186
+ continue;
610187
+ result.push({ role: "system", content: partialReference });
610188
+ alreadyVisiblePaths.add(canonicalPath);
610189
+ recoveredFiles.push(filePath);
610190
+ recoveredTokens += referenceTokens;
609856
610191
  continue;
609857
610192
  }
609858
610193
  const recoveryDecision = assessBranchRead({
@@ -609869,6 +610204,7 @@ ${branchNode.output}
609869
610204
  const referenceTokens = Math.ceil(reference.length / 4);
609870
610205
  if (recoveredTokens + referenceTokens <= fileRecoveryBudget) {
609871
610206
  result.push({ role: "system", content: reference });
610207
+ alreadyVisiblePaths.add(canonicalPath);
609872
610208
  recoveredFiles.push(filePath);
609873
610209
  recoveredTokens += referenceTokens;
609874
610210
  }
@@ -609990,6 +610326,23 @@ ${content.slice(0, 8e3)}${truncated ? "\n[truncated recovery; use a narrow live
609990
610326
  });
609991
610327
  }
609992
610328
  }
610329
+ const pinnedSymbols = [
610330
+ ...[...this._branchEvidenceByPath.entries()].filter(([, node]) => node.taskEpoch === this._taskEpoch && !node.contractComplete).map(([path16]) => this._normalizeEvidencePath(path16)).filter(Boolean),
610331
+ ...this._recentToolOutcomes.slice(-2).map((outcome) => outcome.path).filter((path16) => Boolean(path16))
610332
+ ];
610333
+ const activeSteering = this._renderActiveSteeringSlot();
610334
+ const validation = validateCompaction(result.map((message2) => typeof message2.content === "string" ? message2.content : JSON.stringify(message2.content)).join("\n"), {
610335
+ symbols: pinnedSymbols,
610336
+ ...activeSteering ? { openBugs: ["[ACTIVE USER STEERING]"] } : {}
610337
+ });
610338
+ if (!validation.valid) {
610339
+ this.emit({
610340
+ type: "status",
610341
+ content: `[semantic-compaction] rollback: ${validation.reason}`,
610342
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
610343
+ });
610344
+ return messages2;
610345
+ }
609993
610346
  if (result.length < 2)
609994
610347
  return messages2;
609995
610348
  return result;
@@ -610222,7 +610575,7 @@ ${trimmedNew}`;
610222
610575
  ];
610223
610576
  const tier = this.options.modelTier ?? "large";
610224
610577
  const directive = this._focusSupervisor?.snapshot().directive;
610225
- if (directive && tier !== "large") {
610578
+ if (directive && tier === "small") {
610226
610579
  const expiresTurn = Math.max(turn + 1, directive.createdTurn + 6);
610227
610580
  lines.push(`active_directive=next_action:${directive.requiredNextAction}; evidence:${directive.reason.replace(/\s+/g, " ").slice(0, 260)}; expires_turn:${expiresTurn}; exit_when:action_evidence_or_verified_mutation_or_user_redirect`);
610228
610581
  }
@@ -610234,7 +610587,7 @@ ${trimmedNew}`;
610234
610587
  const resultState = outcome ? outcome.succeeded ? "tool_result=success" : "tool_result=failure" : "tool_result=not_recorded";
610235
610588
  const hash = evidence?.contentHash ?? "unknown";
610236
610589
  const bytes = fact && typeof fact.size === "number" ? String(fact.size) : "unknown";
610237
- const nextAction = verifierRequired ? "run_declared_verifier" : outcome?.succeeded ? "verify_or_complete_distinct_leaf" : "inspect_external_blocker_or_change_scope";
610590
+ const nextAction = tier === "small" ? verifierRequired ? "run_declared_verifier" : outcome?.succeeded ? "verify_or_complete_distinct_leaf" : "inspect_external_blocker_or_change_scope" : "model_select_from_current_evidence";
610238
610591
  const doNot = action === "created" ? "do_not_create_again" : action === "modified" ? "do_not_full_rewrite_without_fresh_read" : "do_not_recreate_without_authoritative_target";
610239
610592
  lines.push(`${action} path=${entry.path} hash=${hash} bytes=${bytes} ${resultState} stateVersion=${outcome?.stateVersion ?? this._adversaryStateVersion} turn=${outcome?.turn ?? turn} next_valid_action=${nextAction} ${doNot}`);
610240
610593
  }
@@ -612241,8 +612594,8 @@ ${description}`
612241
612594
  });
612242
612595
  }
612243
612596
  }
612244
- const delay4 = isGpuSlotUnavailable ? baseDelayMs : Math.min(baseDelayMs * Math.pow(2, attempt - 1), maxDelayMs);
612245
- const effectiveDelay = delay4;
612597
+ const delay5 = isGpuSlotUnavailable ? baseDelayMs : Math.min(baseDelayMs * Math.pow(2, attempt - 1), maxDelayMs);
612598
+ const effectiveDelay = delay5;
612246
612599
  const attemptLabel = maxRetries === Infinity ? `${attempt}` : `${attempt}/${maxRetries}`;
612247
612600
  if (isGpuSlotUnavailable) {
612248
612601
  this.emit({
@@ -624294,8 +624647,8 @@ function normalizeLiveCameraRotation(value2) {
624294
624647
  if (n2 === 0 || n2 === 90 || n2 === 180 || n2 === 270) return n2;
624295
624648
  }
624296
624649
  const raw = String(value2).trim().toLowerCase();
624297
- const numeric = Number(raw.replace(/deg(?:rees)?$/i, ""));
624298
- if (Number.isFinite(numeric)) return normalizeLiveCameraRotation(numeric);
624650
+ const numeric2 = Number(raw.replace(/deg(?:rees)?$/i, ""));
624651
+ if (Number.isFinite(numeric2)) return normalizeLiveCameraRotation(numeric2);
624299
624652
  if (["none", "off", "upright", "normal", "0"].includes(raw)) return 0;
624300
624653
  if (["cw", "clockwise", "right", "rotate-cw", "rotate_cw", "90"].includes(raw)) return 90;
624301
624654
  if (["180", "upside-down", "upside_down", "flip", "inverted"].includes(raw)) return 180;
@@ -627783,8 +628136,8 @@ function finiteRecord(value2) {
627783
628136
  return result;
627784
628137
  }
627785
628138
  function sampleTime(value2) {
627786
- const numeric = finiteNumber(value2);
627787
- if (numeric !== null) return numeric < 1e11 ? numeric * 1e3 : numeric;
628139
+ const numeric2 = finiteNumber(value2);
628140
+ if (numeric2 !== null) return numeric2 < 1e11 ? numeric2 * 1e3 : numeric2;
627788
628141
  if (typeof value2 !== "string") return null;
627789
628142
  const parsed = Date.parse(value2);
627790
628143
  return Number.isFinite(parsed) ? parsed : null;
@@ -643845,10 +644198,139 @@ var init_profiles = __esm({
643845
644198
  }
643846
644199
  });
643847
644200
 
644201
+ // packages/cli/src/tui/ollama-gpu-policy.ts
644202
+ import { execFile as execFile9 } from "node:child_process";
644203
+ import { promisify as promisify6 } from "node:util";
644204
+ function numeric(value2) {
644205
+ const parsed = Number.parseFloat((value2 ?? "").trim());
644206
+ return Number.isFinite(parsed) ? parsed : null;
644207
+ }
644208
+ function parseNvidiaGpuCsv(stdout) {
644209
+ const result = [];
644210
+ for (const rawLine of stdout.split(/\r?\n/)) {
644211
+ const line = rawLine.trim();
644212
+ if (!line) continue;
644213
+ const [rawIndex, rawUuid, rawName, rawMemory, rawCapability] = line.split(",").map((value2) => value2.trim());
644214
+ const index = numeric(rawIndex);
644215
+ const memoryTotalMiB = numeric(rawMemory);
644216
+ const computeCapability = numeric(rawCapability);
644217
+ const uuid = rawUuid ?? "";
644218
+ if (index === null || memoryTotalMiB === null || computeCapability === null || !uuid || !CUDA_IDENTIFIER.test(uuid)) {
644219
+ continue;
644220
+ }
644221
+ result.push({
644222
+ index,
644223
+ uuid,
644224
+ name: rawName ?? "NVIDIA GPU",
644225
+ memoryTotalMiB,
644226
+ computeCapability
644227
+ });
644228
+ }
644229
+ return result;
644230
+ }
644231
+ function satisfiesOllamaGpuMinimum(gpu) {
644232
+ return gpu.memoryTotalMiB >= MIN_OLLAMA_GPU_VRAM_MIB && gpu.computeCapability >= MIN_OLLAMA_GPU_COMPUTE_CAPABILITY;
644233
+ }
644234
+ function isA100ClassAccelerator(name10) {
644235
+ return /\b(?:A100|H100|H200|B100|B200|GB200)\b/i.test(name10);
644236
+ }
644237
+ function describeGpu(gpu) {
644238
+ return `${gpu.name} (${gpu.uuid}; ${Math.round(gpu.memoryTotalMiB / 1024)} GiB; compute ${gpu.computeCapability})`;
644239
+ }
644240
+ function selectApprovedOllamaGpu(gpus, configuredUuid = process.env[OMNIUS_OLLAMA_GPU_UUID_ENV]) {
644241
+ const requestedUuid = configuredUuid?.trim();
644242
+ if (requestedUuid) {
644243
+ const requested = gpus.find((gpu) => gpu.uuid === requestedUuid);
644244
+ if (!requested) {
644245
+ return {
644246
+ ok: false,
644247
+ reason: `${OMNIUS_OLLAMA_GPU_UUID_ENV}=${requestedUuid} was not found in the current NVIDIA inventory. Refusing to launch Ollama on an inferred device.`
644248
+ };
644249
+ }
644250
+ if (!satisfiesOllamaGpuMinimum(requested)) {
644251
+ return {
644252
+ ok: false,
644253
+ reason: `Configured GPU ${describeGpu(requested)} does not meet the required ${MIN_OLLAMA_GPU_VRAM_MIB / 1024} GiB VRAM and compute capability ${MIN_OLLAMA_GPU_COMPUTE_CAPABILITY}. Refusing to launch Ollama.`
644254
+ };
644255
+ }
644256
+ return {
644257
+ ok: true,
644258
+ approval: {
644259
+ gpu: requested,
644260
+ source: "configured_uuid",
644261
+ cudaVisibleDevices: requested.uuid
644262
+ }
644263
+ };
644264
+ }
644265
+ const automatic = gpus.filter(
644266
+ (gpu) => satisfiesOllamaGpuMinimum(gpu) && isA100ClassAccelerator(gpu.name)
644267
+ ).sort(
644268
+ (left, right) => right.memoryTotalMiB - left.memoryTotalMiB || right.computeCapability - left.computeCapability || left.index - right.index
644269
+ )[0];
644270
+ if (automatic) {
644271
+ return {
644272
+ ok: true,
644273
+ approval: {
644274
+ gpu: automatic,
644275
+ source: "a100_class_auto",
644276
+ cudaVisibleDevices: automatic.uuid
644277
+ }
644278
+ };
644279
+ }
644280
+ const discovered = gpus.length ? gpus.map(describeGpu).join("; ") : "no queryable NVIDIA GPUs";
644281
+ return {
644282
+ ok: false,
644283
+ reason: `No approved GPU is available (${discovered}). Set ${OMNIUS_OLLAMA_GPU_UUID_ENV} to the UUID of a designated GPU meeting ${MIN_OLLAMA_GPU_VRAM_MIB / 1024} GiB VRAM and compute capability ${MIN_OLLAMA_GPU_COMPUTE_CAPABILITY}, or make an A100-class accelerator visible.`
644284
+ };
644285
+ }
644286
+ async function defaultNvidiaSmiRunner(command, args) {
644287
+ const { stdout } = await execFileAsync5(command, args, {
644288
+ timeout: 5e3,
644289
+ windowsHide: true
644290
+ });
644291
+ return { stdout };
644292
+ }
644293
+ async function resolveApprovedOllamaGpu(options2 = {}) {
644294
+ try {
644295
+ const runner = options2.runner ?? defaultNvidiaSmiRunner;
644296
+ const { stdout } = await runner("nvidia-smi", [
644297
+ "--query-gpu=index,uuid,name,memory.total,compute_cap",
644298
+ "--format=csv,noheader,nounits"
644299
+ ]);
644300
+ return selectApprovedOllamaGpu(
644301
+ parseNvidiaGpuCsv(stdout),
644302
+ options2.configuredUuid
644303
+ );
644304
+ } catch (error) {
644305
+ const detail = error instanceof Error ? error.message : String(error);
644306
+ return {
644307
+ ok: false,
644308
+ reason: `Could not verify NVIDIA GPU placement with nvidia-smi (${detail}). Refusing to launch Ollama.`
644309
+ };
644310
+ }
644311
+ }
644312
+ function withApprovedOllamaGpu(env2, approval) {
644313
+ return {
644314
+ ...env2,
644315
+ CUDA_VISIBLE_DEVICES: approval.cudaVisibleDevices
644316
+ };
644317
+ }
644318
+ var execFileAsync5, OMNIUS_OLLAMA_GPU_UUID_ENV, MIN_OLLAMA_GPU_VRAM_MIB, MIN_OLLAMA_GPU_COMPUTE_CAPABILITY, CUDA_IDENTIFIER;
644319
+ var init_ollama_gpu_policy = __esm({
644320
+ "packages/cli/src/tui/ollama-gpu-policy.ts"() {
644321
+ execFileAsync5 = promisify6(execFile9);
644322
+ OMNIUS_OLLAMA_GPU_UUID_ENV = "OMNIUS_OLLAMA_GPU_UUID";
644323
+ MIN_OLLAMA_GPU_VRAM_MIB = 16 * 1024;
644324
+ MIN_OLLAMA_GPU_COMPUTE_CAPABILITY = 7;
644325
+ CUDA_IDENTIFIER = /^[A-Za-z0-9._:-]+$/;
644326
+ }
644327
+ });
644328
+
643848
644329
  // packages/cli/src/tui/omnius-directory.ts
643849
644330
  var omnius_directory_exports = {};
643850
644331
  __export(omnius_directory_exports, {
643851
644332
  OMNIUS_DIR: () => OMNIUS_DIR,
644333
+ appendCompactionAudit: () => appendCompactionAudit,
643852
644334
  buildContextRestorePrompt: () => buildContextRestorePrompt,
643853
644335
  buildContextRestoreSnapshot: () => buildContextRestoreSnapshot,
643854
644336
  buildHandoffPrompt: () => buildHandoffPrompt,
@@ -644009,7 +644491,7 @@ function watchForOmniusGitignore(repoRoot) {
644009
644491
  function scheduleOmniusGitignoreRescans(repoRoot) {
644010
644492
  const key = resolve62(repoRoot);
644011
644493
  if (gitignoreRetryTimers.has(key)) return;
644012
- const timers = [25, 100, 250, 500, 1e3].map((delay4) => {
644494
+ const timers = [25, 100, 250, 500, 1e3].map((delay5) => {
644013
644495
  const timer = setTimeout(() => {
644014
644496
  try {
644015
644497
  ensureOmniusIgnored(repoRoot);
@@ -644021,7 +644503,7 @@ function scheduleOmniusGitignoreRescans(repoRoot) {
644021
644503
  if (idx >= 0) list.splice(idx, 1);
644022
644504
  if (list.length === 0) gitignoreRetryTimers.delete(key);
644023
644505
  }
644024
- }, delay4);
644506
+ }, delay5);
644025
644507
  timer.unref?.();
644026
644508
  return timer;
644027
644509
  });
@@ -644553,6 +645035,32 @@ function pruneContextLedger(ledgerPath) {
644553
645035
  } catch {
644554
645036
  }
644555
645037
  }
645038
+ function appendCompactionAudit(repoRoot, record) {
645039
+ try {
645040
+ const contextDir = join136(repoRoot, OMNIUS_DIR, "context");
645041
+ mkdirSync76(contextDir, { recursive: true });
645042
+ const ledgerPath = join136(contextDir, COMPACTION_AUDIT_FILE);
645043
+ appendFileSync14(ledgerPath, JSON.stringify(record) + "\n", "utf-8");
645044
+ const st = statSync51(ledgerPath);
645045
+ if (st.size > 64 * 1024 * 1024) {
645046
+ const lines = readFileSync102(ledgerPath, "utf-8").split(/\r?\n/).filter((line) => line.trim());
645047
+ if (lines.length > 100) {
645048
+ const archiveDir = join136(contextDir, "archive");
645049
+ mkdirSync76(archiveDir, { recursive: true });
645050
+ const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
645051
+ writeFileSync64(
645052
+ join136(archiveDir, `compactions.${stamp}.jsonl`),
645053
+ lines.slice(0, -100).join("\n") + "\n",
645054
+ "utf-8"
645055
+ );
645056
+ writeFileSync64(ledgerPath, lines.slice(-100).join("\n") + "\n", "utf-8");
645057
+ }
645058
+ }
645059
+ return ledgerPath;
645060
+ } catch {
645061
+ return null;
645062
+ }
645063
+ }
644556
645064
  function saveSessionContext(repoRoot, entry) {
644557
645065
  const contextDir = join136(repoRoot, OMNIUS_DIR, "context");
644558
645066
  mkdirSync76(contextDir, { recursive: true });
@@ -645509,7 +646017,7 @@ function deleteUsageRecord(kind, value2, repoRoot) {
645509
646017
  remove(join136(repoRoot, OMNIUS_DIR, USAGE_HISTORY_FILE));
645510
646018
  }
645511
646019
  }
645512
- var OMNIUS_DIR, LEGACY_DIRS, SUBDIRS, gitignoreWatchers, gitignoreRetryTimers, CONTEXT_FILES, PENDING_TASK_FILE, HANDOFF_FILE, CONTEXT_SAVE_FILE, CONTEXT_LEDGER_FILE, MAX_CONTEXT_ENTRIES, MAX_SESSION_DIARY_ENTRIES, MAX_SESSION_DIARY_DETAILED_ENTRIES, MAX_CONTEXT_LEDGER_LINES, MAX_CONTEXT_LEDGER_BYTES, SAME_TASK_REPLACE_WINDOW_MS, LOCK_TIMEOUT_MS, LOCK_RETRY_MS, LOCK_RETRY_MAX, MODEL_CONTEXT_NOISE_LINE_RE, DEFAULT_RESTORED_SESSION_HISTORY_MAX_LINES, DEICTIC_CONTINUATION_TERMS, SESSIONS_DIR, SESSIONS_INDEX, TUI_STATE_SUFFIX, AUTHORED_SESSION_LINE, VISUAL_CHROME_LINE, SKIP_DIRS3, HOME_SKIP_DIRS, USAGE_HISTORY_FILE, MAX_HISTORY_RECORDS;
646020
+ var OMNIUS_DIR, LEGACY_DIRS, SUBDIRS, gitignoreWatchers, gitignoreRetryTimers, CONTEXT_FILES, PENDING_TASK_FILE, HANDOFF_FILE, CONTEXT_SAVE_FILE, CONTEXT_LEDGER_FILE, COMPACTION_AUDIT_FILE, MAX_CONTEXT_ENTRIES, MAX_SESSION_DIARY_ENTRIES, MAX_SESSION_DIARY_DETAILED_ENTRIES, MAX_CONTEXT_LEDGER_LINES, MAX_CONTEXT_LEDGER_BYTES, SAME_TASK_REPLACE_WINDOW_MS, LOCK_TIMEOUT_MS, LOCK_RETRY_MS, LOCK_RETRY_MAX, MODEL_CONTEXT_NOISE_LINE_RE, DEFAULT_RESTORED_SESSION_HISTORY_MAX_LINES, DEICTIC_CONTINUATION_TERMS, SESSIONS_DIR, SESSIONS_INDEX, TUI_STATE_SUFFIX, AUTHORED_SESSION_LINE, VISUAL_CHROME_LINE, SKIP_DIRS3, HOME_SKIP_DIRS, USAGE_HISTORY_FILE, MAX_HISTORY_RECORDS;
645513
646021
  var init_omnius_directory = __esm({
645514
646022
  "packages/cli/src/tui/omnius-directory.ts"() {
645515
646023
  init_dist5();
@@ -645533,6 +646041,7 @@ var init_omnius_directory = __esm({
645533
646041
  HANDOFF_FILE = "task-handoff.json";
645534
646042
  CONTEXT_SAVE_FILE = "session-context.json";
645535
646043
  CONTEXT_LEDGER_FILE = "session-context.events.jsonl";
646044
+ COMPACTION_AUDIT_FILE = "compactions.jsonl";
645536
646045
  MAX_CONTEXT_ENTRIES = 200;
645537
646046
  MAX_SESSION_DIARY_ENTRIES = 80;
645538
646047
  MAX_SESSION_DIARY_DETAILED_ENTRIES = 50;
@@ -648871,8 +649380,8 @@ var init_project_context = __esm({
648871
649380
  });
648872
649381
 
648873
649382
  // packages/cli/src/tui/disk-monitor.ts
648874
- import { execFile as execFile9 } from "node:child_process";
648875
- import { promisify as promisify6 } from "node:util";
649383
+ import { execFile as execFile10 } from "node:child_process";
649384
+ import { promisify as promisify7 } from "node:util";
648876
649385
  function unavailableDiskMetrics(path16 = process.cwd()) {
648877
649386
  return {
648878
649387
  path: path16,
@@ -648886,7 +649395,7 @@ function unavailableDiskMetrics(path16 = process.cwd()) {
648886
649395
  async function collectDiskMetrics(path16 = process.cwd()) {
648887
649396
  if (process.platform === "win32") return unavailableDiskMetrics(path16);
648888
649397
  try {
648889
- const { stdout } = await execFileAsync5("df", ["-Pk", path16], {
649398
+ const { stdout } = await execFileAsync6("df", ["-Pk", path16], {
648890
649399
  encoding: "utf8",
648891
649400
  timeout: 3e3,
648892
649401
  maxBuffer: 128 * 1024
@@ -648916,10 +649425,10 @@ async function collectDiskMetrics(path16 = process.cwd()) {
648916
649425
  return unavailableDiskMetrics(path16);
648917
649426
  }
648918
649427
  }
648919
- var execFileAsync5;
649428
+ var execFileAsync6;
648920
649429
  var init_disk_monitor = __esm({
648921
649430
  "packages/cli/src/tui/disk-monitor.ts"() {
648922
- execFileAsync5 = promisify6(execFile9);
649431
+ execFileAsync6 = promisify7(execFile10);
648923
649432
  }
648924
649433
  });
648925
649434
 
@@ -652628,7 +653137,7 @@ var init_status_bar = __esm({
652628
653137
  const prefix = i2 === 0 ? this.promptText : " ".repeat(this.promptWidth);
652629
653138
  const lineContent = `${prefix}${inputWrap.lines[i2]}`;
652630
653139
  buf += `\x1B[${row2};1H${PANEL_BG_SEQ}\x1B[2K`;
652631
- buf += `${this.borderVSeq(1)}${BOX_V3}${RESET4}${PANEL_BG_SEQ}${lineContent}`;
653140
+ buf += `${this.inputLeftRailSeq()}${BOX_V3}${RESET4}${PANEL_BG_SEQ}${lineContent}`;
652632
653141
  buf += `${PANEL_BG_SEQ}\x1B[K\x1B[${row2};${w}H${this.borderVSeq(w)}${BOX_V3}${RESET4}${PANEL_BG_SEQ}`;
652633
653142
  }
652634
653143
  buf += this.buildEnhanceSegment(
@@ -653893,6 +654402,10 @@ ${CONTENT_BG_SEQ}`);
653893
654402
  );
653894
654403
  return `\x1B[38;2;${r2};${g};${b}m`;
653895
654404
  }
654405
+ /** Keep the rail before the `+` prompt static while stream frames animate. */
654406
+ inputLeftRailSeq() {
654407
+ return BOX_FG;
654408
+ }
653896
654409
  /** Box top border with an optional ┬ carving out the enhance segment. */
653897
654410
  buildInputBoxTop(w) {
653898
654411
  if (!this.enhanceSegEnabled(w)) {
@@ -654406,7 +654919,7 @@ ${CONTENT_BG_SEQ}`);
654406
654919
  const prefix = i2 === 0 ? this.promptText : " ".repeat(this.promptWidth);
654407
654920
  const lineContent = `${prefix}${inputWrap.lines[i2]}`;
654408
654921
  buf += `\x1B[${row2};1H${PANEL_BG_SEQ}\x1B[2K`;
654409
- buf += `${this.borderVSeq(1)}${BOX_V3}${RESET4}${PANEL_BG_SEQ}${lineContent}`;
654922
+ buf += `${this.inputLeftRailSeq()}${BOX_V3}${RESET4}${PANEL_BG_SEQ}${lineContent}`;
654410
654923
  buf += `${PANEL_BG_SEQ}\x1B[K`;
654411
654924
  buf += `\x1B[${row2};${w}H${this.borderVSeq(w)}${BOX_V3}${RESET4}${PANEL_BG_SEQ}`;
654412
654925
  }
@@ -654425,7 +654938,7 @@ ${CONTENT_BG_SEQ}`);
654425
654938
  const fg2 = isHighlighted ? `\x1B[1;38;5;${TEXT_PRIMARY}m` : `\x1B[38;5;${TEXT_PRIMARY}m`;
654426
654939
  const slash = isHighlighted ? `\x1B[38;5;245m` : `\x1B[38;5;${TEXT_DIM}m`;
654427
654940
  const marker = isHighlighted ? `\x1B[38;5;${TEXT_PRIMARY}m› ` : " ";
654428
- buf += `\x1B[${row2};1H${PANEL_BG_SEQ}\x1B[2K${this.borderVSeq(1)}${BOX_V3}${RESET4}${PANEL_BG_SEQ}`;
654941
+ buf += `\x1B[${row2};1H${PANEL_BG_SEQ}\x1B[2K${this.inputLeftRailSeq()}${BOX_V3}${RESET4}${PANEL_BG_SEQ}`;
654429
654942
  buf += `${bg} ${marker}${slash}/${fg2}${cmd}`;
654430
654943
  buf += `${PANEL_BG_SEQ}\x1B[K`;
654431
654944
  buf += `\x1B[${row2};${w}H${this.borderVSeq(w)}${BOX_V3}${RESET4}${PANEL_BG_SEQ}`;
@@ -654480,7 +654993,7 @@ ${CONTENT_BG_SEQ}`);
654480
654993
  const prefix = i2 === 0 ? this.promptText : " ".repeat(this.promptWidth);
654481
654994
  const lineContent = `${prefix}${inputWrap.lines[i2]}`;
654482
654995
  buf += `\x1B[${row2};1H${PANEL_BG_SEQ}\x1B[2K`;
654483
- buf += `${this.borderVSeq(1)}${BOX_V3}${RESET4}${PANEL_BG_SEQ}${lineContent}`;
654996
+ buf += `${this.inputLeftRailSeq()}${BOX_V3}${RESET4}${PANEL_BG_SEQ}${lineContent}`;
654484
654997
  buf += `${PANEL_BG_SEQ}\x1B[K`;
654485
654998
  buf += `\x1B[${row2};${w}H${this.borderVSeq(w)}${BOX_V3}${RESET4}${PANEL_BG_SEQ}`;
654486
654999
  }
@@ -654503,7 +655016,7 @@ ${CONTENT_BG_SEQ}`);
654503
655016
  const isHl = si === this._suggestIndex;
654504
655017
  const fg2 = isHl ? `\x1B[1;38;5;${TEXT_PRIMARY}m` : `\x1B[38;5;${TEXT_PRIMARY}m`;
654505
655018
  const marker = isHl ? `\x1B[38;5;${TEXT_PRIMARY}m› ` : " ";
654506
- buf += `\x1B[${row2};1H${PANEL_BG_SEQ}\x1B[2K${this.borderVSeq(1)}${BOX_V3}${RESET4}${PANEL_BG_SEQ} ${marker}\x1B[38;5;${TEXT_DIM}m/${fg2}${cmd}`;
655019
+ buf += `\x1B[${row2};1H${PANEL_BG_SEQ}\x1B[2K${this.inputLeftRailSeq()}${BOX_V3}${RESET4}${PANEL_BG_SEQ} ${marker}\x1B[38;5;${TEXT_DIM}m/${fg2}${cmd}`;
654507
655020
  buf += `${PANEL_BG_SEQ}\x1B[K\x1B[${row2};${w}H${this.borderVSeq(w)}${BOX_V3}${RESET4}`;
654508
655021
  }
654509
655022
  buf += `\x1B[${pos.bufferRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildInputBoxBottom(w)}`;
@@ -654570,7 +655083,7 @@ ${CONTENT_BG_SEQ}`);
654570
655083
  const row2 = pos.inputStartRow + 1 + i2;
654571
655084
  const prefix = i2 === 0 ? this.promptText : " ".repeat(this.promptWidth);
654572
655085
  const lineContent = `${prefix}${inputWrap.lines[i2]}`;
654573
- buf += `\x1B[${row2};1H${PANEL_BG_SEQ}\x1B[2K${this.borderVSeq(1)}${BOX_V3}${RESET4}${PANEL_BG_SEQ}${lineContent}${PANEL_BG_SEQ}\x1B[K\x1B[${row2};${w}H${this.borderVSeq(w)}${BOX_V3}${RESET4}`;
655086
+ buf += `\x1B[${row2};1H${PANEL_BG_SEQ}\x1B[2K${this.inputLeftRailSeq()}${BOX_V3}${RESET4}${PANEL_BG_SEQ}${lineContent}${PANEL_BG_SEQ}\x1B[K\x1B[${row2};${w}H${this.borderVSeq(w)}${BOX_V3}${RESET4}`;
654574
655087
  }
654575
655088
  buf += this.buildEnhanceSegment(
654576
655089
  w,
@@ -654585,7 +655098,7 @@ ${CONTENT_BG_SEQ}`);
654585
655098
  const bg = isHl ? `\x1B[48;5;235m` : PANEL_BG_SEQ;
654586
655099
  const fg2 = isHl ? `\x1B[1;38;5;${TEXT_PRIMARY}m` : `\x1B[38;5;${TEXT_PRIMARY}m`;
654587
655100
  const marker = isHl ? `\x1B[38;5;${TEXT_PRIMARY}m› ` : " ";
654588
- buf += `\x1B[${row2};1H${PANEL_BG_SEQ}\x1B[2K${this.borderVSeq(1)}${BOX_V3}${RESET4}${PANEL_BG_SEQ}`;
655101
+ buf += `\x1B[${row2};1H${PANEL_BG_SEQ}\x1B[2K${this.inputLeftRailSeq()}${BOX_V3}${RESET4}${PANEL_BG_SEQ}`;
654589
655102
  buf += `${bg} ${marker}\x1B[38;5;${TEXT_DIM}m/${fg2}${cmd}`;
654590
655103
  buf += `${PANEL_BG_SEQ}\x1B[K\x1B[${row2};${w}H${this.borderVSeq(w)}${BOX_V3}${RESET4}`;
654591
655104
  }
@@ -654613,7 +655126,7 @@ ${CONTENT_BG_SEQ}`);
654613
655126
  const prefix = i2 === 0 ? this.promptText : " ".repeat(this.promptWidth);
654614
655127
  const lineContent = `${prefix}${inputWrap.lines[i2]}`;
654615
655128
  buf += `\x1B[${row2};1H${PANEL_BG_SEQ}\x1B[2K`;
654616
- buf += `${this.borderVSeq(1)}${BOX_V3}${RESET4}${PANEL_BG_SEQ}${lineContent}`;
655129
+ buf += `${this.inputLeftRailSeq()}${BOX_V3}${RESET4}${PANEL_BG_SEQ}${lineContent}`;
654617
655130
  buf += `${PANEL_BG_SEQ}\x1B[K`;
654618
655131
  buf += `\x1B[${row2};${w}H${this.borderVSeq(w)}${BOX_V3}${RESET4}${PANEL_BG_SEQ}`;
654619
655132
  }
@@ -654630,7 +655143,7 @@ ${CONTENT_BG_SEQ}`);
654630
655143
  const bg = isHl ? `\x1B[48;5;235m` : PANEL_BG_SEQ;
654631
655144
  const fg2 = isHl ? `\x1B[1;38;5;${TEXT_PRIMARY}m` : `\x1B[38;5;${TEXT_PRIMARY}m`;
654632
655145
  const marker = isHl ? `\x1B[38;5;${TEXT_PRIMARY}m› ` : " ";
654633
- buf += `\x1B[${row2};1H${PANEL_BG_SEQ}\x1B[2K${this.borderVSeq(1)}${BOX_V3}${RESET4}${PANEL_BG_SEQ}`;
655146
+ buf += `\x1B[${row2};1H${PANEL_BG_SEQ}\x1B[2K${this.inputLeftRailSeq()}${BOX_V3}${RESET4}${PANEL_BG_SEQ}`;
654634
655147
  buf += `${bg} ${marker}\x1B[38;5;${TEXT_DIM}m/${fg2}${cmd}`;
654635
655148
  buf += `${PANEL_BG_SEQ}\x1B[K\x1B[${row2};${w}H${this.borderVSeq(w)}${BOX_V3}${RESET4}${PANEL_BG_SEQ}`;
654636
655149
  }
@@ -656814,7 +657327,7 @@ __export(setup_exports, {
656814
657327
  });
656815
657328
  import * as readline from "node:readline";
656816
657329
  import { spawn as spawn34, exec as exec5 } from "node:child_process";
656817
- import { promisify as promisify7 } from "node:util";
657330
+ import { promisify as promisify8 } from "node:util";
656818
657331
  import { existsSync as existsSync132, writeFileSync as writeFileSync68, readFileSync as readFileSync109, appendFileSync as appendFileSync15, mkdirSync as mkdirSync80, chmodSync as chmodSync3 } from "node:fs";
656819
657332
  import { delimiter as pathDelimiter, join as join143 } from "node:path";
656820
657333
  import { freemem as freemem8, homedir as homedir48, platform as platform6, totalmem as totalmem9 } from "node:os";
@@ -657646,6 +658159,30 @@ async function installOllamaWindows() {
657646
658159
  return false;
657647
658160
  }
657648
658161
  }
658162
+ async function startApprovedOllamaServe() {
658163
+ const admission = await resolveApprovedOllamaGpu();
658164
+ if (!admission.ok) {
658165
+ process.stdout.write(
658166
+ ` ${c3.red("✖")} Ollama launch blocked by GPU safety policy: ${admission.reason}
658167
+ `
658168
+ );
658169
+ return false;
658170
+ }
658171
+ try {
658172
+ const child = spawn34("ollama", ["serve"], {
658173
+ stdio: "ignore",
658174
+ detached: true,
658175
+ env: withApprovedOllamaGpu(process.env, admission.approval)
658176
+ });
658177
+ child.unref();
658178
+ return true;
658179
+ } catch (error) {
658180
+ const detail = error instanceof Error ? error.message : String(error);
658181
+ process.stdout.write(` ${c3.cyan("⚠")} Could not start ollama serve: ${detail}
658182
+ `);
658183
+ return false;
658184
+ }
658185
+ }
657649
658186
  async function ensureOllamaRunning(backendUrl2, rl) {
657650
658187
  const ollamaInstalled = hasCmd("ollama");
657651
658188
  if (!ollamaInstalled) {
@@ -657674,13 +658211,8 @@ async function ensureOllamaRunning(backendUrl2, rl) {
657674
658211
  }
657675
658212
  process.stdout.write(` ${c3.cyan("●")} Starting ollama serve...
657676
658213
  `);
657677
- try {
657678
- const child = spawn34("ollama", ["serve"], { stdio: "ignore", detached: true });
657679
- child.unref();
657680
- } catch {
657681
- process.stdout.write(` ${c3.cyan("⚠")} Could not start ollama serve.
657682
-
657683
- `);
658214
+ if (!await startApprovedOllamaServe()) {
658215
+ process.stdout.write("\n");
657684
658216
  return false;
657685
658217
  }
657686
658218
  for (let i2 = 0; i2 < 5; i2++) {
@@ -657698,7 +658230,7 @@ async function ensureOllamaRunning(backendUrl2, rl) {
657698
658230
  } catch {
657699
658231
  }
657700
658232
  }
657701
- process.stdout.write(` ${c3.cyan("⚠")} Ollama started but not responding. Try ${c3.bold("ollama serve")} manually.
658233
+ process.stdout.write(` ${c3.cyan("⚠")} Ollama started on the approved GPU but is not responding yet.
657702
658234
 
657703
658235
  `);
657704
658236
  return false;
@@ -658367,9 +658899,7 @@ ${c3.cyan(OMNIUS_FIRST_RUN_BANNER)}
658367
658899
  process.stdout.write(`
658368
658900
  ${c3.cyan("●")} Ollama is installed but not running. Starting automatically...
658369
658901
  `);
658370
- try {
658371
- const child = spawn34("ollama", ["serve"], { stdio: "ignore", detached: true });
658372
- child.unref();
658902
+ if (await startApprovedOllamaServe()) {
658373
658903
  await new Promise((resolve82) => setTimeout(resolve82, 3e3));
658374
658904
  try {
658375
658905
  models = await fetchOllamaModels(config.backendUrl);
@@ -658381,8 +658911,8 @@ ${c3.cyan(OMNIUS_FIRST_RUN_BANNER)}
658381
658911
 
658382
658912
  `);
658383
658913
  }
658384
- } catch {
658385
- process.stdout.write(` ${c3.cyan("⚠")} Could not start Ollama. Try running ${c3.bold("ollama serve")} manually.
658914
+ } else {
658915
+ process.stdout.write(` ${c3.cyan("⚠")} Ollama was not started. Configure an approved GPU or a custom endpoint.
658386
658916
 
658387
658917
  `);
658388
658918
  }
@@ -658395,9 +658925,7 @@ ${c3.cyan(OMNIUS_FIRST_RUN_BANNER)}
658395
658925
  process.stdout.write(`
658396
658926
  ${c3.cyan("●")} Starting ollama serve...
658397
658927
  `);
658398
- try {
658399
- const child = spawn34("ollama", ["serve"], { stdio: "ignore", detached: true });
658400
- child.unref();
658928
+ if (await startApprovedOllamaServe()) {
658401
658929
  await new Promise((resolve82) => setTimeout(resolve82, 3e3));
658402
658930
  try {
658403
658931
  models = await fetchOllamaModels(config.backendUrl);
@@ -658405,12 +658933,12 @@ ${c3.cyan(OMNIUS_FIRST_RUN_BANNER)}
658405
658933
 
658406
658934
  `);
658407
658935
  } catch {
658408
- process.stdout.write(` ${c3.cyan("⚠")} Ollama installed but not responding yet. Try ${c3.bold("ollama serve")} manually.
658936
+ process.stdout.write(` ${c3.cyan("⚠")} Ollama installed but not responding yet.
658409
658937
 
658410
658938
  `);
658411
658939
  }
658412
- } catch {
658413
- process.stdout.write(` ${c3.cyan("⚠")} Ollama installed. Start it with: ${c3.bold("ollama serve")}
658940
+ } else {
658941
+ process.stdout.write(` ${c3.cyan("⚠")} Ollama installed but was not started without an approved GPU.
658414
658942
 
658415
658943
  `);
658416
658944
  }
@@ -659685,7 +660213,8 @@ var init_setup = __esm({
659685
660213
  init_dist6();
659686
660214
  init_tui_select();
659687
660215
  init_listen();
659688
- execAsync2 = promisify7(exec5);
660216
+ init_ollama_gpu_policy();
660217
+ execAsync2 = promisify8(exec5);
659689
660218
  OMNIUS_FIRST_RUN_BANNER = [
659690
660219
  " ░▒▓██████▓▒░░▒▓██████████████▓▒░░▒▓███████▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░░▒▓███████▓▒░ ",
659691
660220
  "░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░ ",
@@ -664354,10 +664883,12 @@ __export(daemon_exports, {
664354
664883
  ensureDaemonVersion: () => ensureDaemonVersion,
664355
664884
  forceKillDaemon: () => forceKillDaemon,
664356
664885
  getDaemonPid: () => getDaemonPid,
664886
+ getDaemonReportedIdentity: () => getDaemonReportedIdentity,
664357
664887
  getDaemonReportedVersion: () => getDaemonReportedVersion,
664358
664888
  getDaemonStatus: () => getDaemonStatus,
664359
664889
  getLocalCliVersion: () => getLocalCliVersion,
664360
664890
  isDaemonRunning: () => isDaemonRunning,
664891
+ recoverDaemonVersionBoundedly: () => recoverDaemonVersionBoundedly,
664361
664892
  releaseDaemonEndpointClaim: () => releaseDaemonEndpointClaim,
664362
664893
  releaseDaemonEndpointForCurrentProcess: () => releaseDaemonEndpointForCurrentProcess,
664363
664894
  restartDaemon: () => restartDaemon,
@@ -664365,7 +664896,7 @@ __export(daemon_exports, {
664365
664896
  stopDaemon: () => stopDaemon
664366
664897
  });
664367
664898
  import { spawn as spawn35 } from "node:child_process";
664368
- import { existsSync as existsSync140, readFileSync as readFileSync114, writeFileSync as writeFileSync70, mkdirSync as mkdirSync82, unlinkSync as unlinkSync27, openSync as openSync5, closeSync as closeSync5, writeSync as writeSync2, statSync as statSync57 } from "node:fs";
664899
+ import { existsSync as existsSync140, readFileSync as readFileSync114, writeFileSync as writeFileSync70, mkdirSync as mkdirSync82, unlinkSync as unlinkSync27, openSync as openSync5, closeSync as closeSync5, writeSync as writeSync2, statSync as statSync57, renameSync as renameSync13 } from "node:fs";
664369
664900
  import { join as join149 } from "node:path";
664370
664901
  import { homedir as homedir51 } from "node:os";
664371
664902
  import { fileURLToPath as fileURLToPath20 } from "node:url";
@@ -664504,17 +665035,26 @@ function getLocalCliVersion() {
664504
665035
  }
664505
665036
  return "0.0.0";
664506
665037
  }
664507
- async function getDaemonReportedVersion(port) {
665038
+ async function getDaemonReportedIdentity(port) {
664508
665039
  const p2 = port ?? getDaemonPort();
664509
665040
  try {
664510
665041
  const resp = await fetch(`http://127.0.0.1:${p2}/health`, { signal: AbortSignal.timeout(2e3) });
664511
665042
  if (!resp.ok) return null;
664512
665043
  const data = await resp.json();
664513
- return data.version ?? null;
665044
+ const version5 = data.boot_version ?? data.version;
665045
+ if (!version5) return null;
665046
+ return {
665047
+ version: version5,
665048
+ bootVersion: data.boot_version ?? version5,
665049
+ bootPackageHash: data.boot_package_hash ?? null
665050
+ };
664514
665051
  } catch {
664515
665052
  return null;
664516
665053
  }
664517
665054
  }
665055
+ async function getDaemonReportedVersion(port) {
665056
+ return (await getDaemonReportedIdentity(port))?.bootVersion ?? null;
665057
+ }
664518
665058
  async function waitForDaemonReady(port, expectedVersion, attempts = 24) {
664519
665059
  let observedVersion = null;
664520
665060
  for (let attempt = 0; attempt < attempts; attempt++) {
@@ -664527,22 +665067,165 @@ async function waitForDaemonReady(port, expectedVersion, attempts = 24) {
664527
665067
  }
664528
665068
  return { ok: false, observedVersion };
664529
665069
  }
664530
- async function restartDaemon(port, expectedVersion) {
664531
- const p2 = port ?? getDaemonPort();
665070
+ function delay4(ms) {
665071
+ return new Promise((resolve82) => setTimeout(resolve82, ms));
665072
+ }
665073
+ async function runUserSystemctl(args, timeout2 = 2e4) {
664532
665074
  try {
664533
665075
  const { spawnSync: spawnSync9 } = await import("node:child_process");
664534
- const enabled2 = spawnSync9("systemctl", ["--user", "is-enabled", "omnius-daemon.service"], {
665076
+ const result = spawnSync9("systemctl", ["--user", ...args], {
664535
665077
  stdio: "ignore",
664536
- timeout: 5e3
665078
+ timeout: timeout2
665079
+ });
665080
+ return { available: !result.error, ok: result.status === 0 };
665081
+ } catch {
665082
+ return { available: false, ok: false };
665083
+ }
665084
+ }
665085
+ async function hasManagedDaemonService() {
665086
+ const enabled2 = await runUserSystemctl(["is-enabled", "omnius-daemon.service"], 5e3);
665087
+ if (enabled2.ok) return true;
665088
+ const active = await runUserSystemctl(["is-active", "omnius-daemon.service"], 5e3);
665089
+ return active.ok;
665090
+ }
665091
+ function systemdQuote(value2) {
665092
+ return /[\s"\\]/.test(value2) ? `"${value2.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"` : value2;
665093
+ }
665094
+ async function repairManagedDaemonUnit(port) {
665095
+ if (process.platform !== "linux") return false;
665096
+ const command = await resolveDaemonCommand(process.execPath);
665097
+ if (!command) return false;
665098
+ try {
665099
+ const configHome2 = process.env["XDG_CONFIG_HOME"] || join149(homedir51(), ".config");
665100
+ const unitDir = join149(configHome2, "systemd", "user");
665101
+ const unitPath = join149(unitDir, "omnius-daemon.service");
665102
+ const logDir = join149(OMNIUS_DIR2);
665103
+ mkdirSync82(unitDir, { recursive: true });
665104
+ mkdirSync82(logDir, { recursive: true });
665105
+ const execStart = [command.command, ...command.args].map(systemdQuote).join(" ");
665106
+ const unit = [
665107
+ "[Unit]",
665108
+ `Description=Omnius API Daemon (port ${port})`,
665109
+ "After=network-online.target",
665110
+ "Wants=network-online.target",
665111
+ "StartLimitIntervalSec=30",
665112
+ "StartLimitBurst=10",
665113
+ "",
665114
+ "[Service]",
665115
+ "Type=simple",
665116
+ "Environment=OMNIUS_DAEMON=1",
665117
+ `Environment=OMNIUS_PORT=${port}`,
665118
+ "Environment=NODE_ENV=production",
665119
+ `ExecStart=${execStart}`,
665120
+ "Restart=always",
665121
+ "RestartSec=3",
665122
+ `StandardOutput=append:${join149(logDir, "daemon.log")}`,
665123
+ `StandardError=append:${join149(logDir, "daemon.err.log")}`,
665124
+ "",
665125
+ "[Install]",
665126
+ "WantedBy=default.target",
665127
+ ""
665128
+ ].join("\n");
665129
+ const tmp = `${unitPath}.tmp.${process.pid}.${Date.now()}`;
665130
+ writeFileSync70(tmp, unit, { encoding: "utf8", mode: 384 });
665131
+ renameSync13(tmp, unitPath);
665132
+ return (await runUserSystemctl(["daemon-reload"], 1e4)).ok;
665133
+ } catch {
665134
+ return false;
665135
+ }
665136
+ }
665137
+ async function portHolderPids(port) {
665138
+ try {
665139
+ const { spawnSync: spawnSync9 } = await import("node:child_process");
665140
+ const lsof = spawnSync9("lsof", ["-ti", `:${port}`], {
665141
+ encoding: "utf8",
665142
+ stdio: ["ignore", "pipe", "ignore"],
665143
+ timeout: 3e3
664537
665144
  });
664538
- if (enabled2.status === 0) {
664539
- spawnSync9("systemctl", ["--user", "restart", "omnius-daemon.service"], { stdio: "ignore", timeout: 2e4 });
664540
- return (await waitForDaemonReady(p2, expectedVersion)).ok;
665145
+ let output = lsof.stdout ?? "";
665146
+ if (!output.trim()) {
665147
+ const fuser = spawnSync9("fuser", [`${port}/tcp`], {
665148
+ encoding: "utf8",
665149
+ stdio: ["ignore", "pipe", "ignore"],
665150
+ timeout: 3e3
665151
+ });
665152
+ output = `${fuser.stdout ?? ""}
665153
+ ${fuser.stderr ?? ""}`;
665154
+ if (lsof.error && fuser.error) return null;
664541
665155
  }
665156
+ return output.split(/[\s\n]+/).map((value2) => parseInt(value2, 10)).filter((pid) => Number.isInteger(pid) && pid > 0 && pid !== process.pid);
665157
+ } catch {
665158
+ return null;
665159
+ }
665160
+ }
665161
+ function processCommandLine(pid) {
665162
+ try {
665163
+ return readFileSync114(`/proc/${pid}/cmdline`, "utf8").replace(/\0/g, " ");
664542
665164
  } catch {
665165
+ return "";
664543
665166
  }
664544
- await forceKillDaemon(p2);
664545
- const pid = await startDaemon();
665167
+ }
665168
+ function isOwnedOmniusDaemon(pid, daemonPid) {
665169
+ if (pid === daemonPid) return true;
665170
+ if (listProcessLeases({ includeInactive: false }).some((lease) => lease.pid === pid && lease.ownerKind === "daemon")) {
665171
+ return true;
665172
+ }
665173
+ const command = processCommandLine(pid);
665174
+ return /(?:^|[\\/\s])omnius(?:[\\/\s]|$)|omnius-daemon|[\\/]dist[\\/]index\.js\b|launcher\.cjs\b/i.test(command);
665175
+ }
665176
+ async function ownedDaemonPids(port) {
665177
+ const daemonPid = getDaemonPid();
665178
+ const candidates = /* @__PURE__ */ new Set();
665179
+ if (daemonPid) candidates.add(daemonPid);
665180
+ const holders = await portHolderPids(port);
665181
+ for (const pid of holders ?? []) candidates.add(pid);
665182
+ return [...candidates].filter((pid) => processIsAlive(pid) && isOwnedOmniusDaemon(pid, daemonPid));
665183
+ }
665184
+ async function waitForDaemonStopped(port, attempts = DAEMON_GRACEFUL_STOP_ATTEMPTS) {
665185
+ for (let attempt = 0; attempt < attempts; attempt++) {
665186
+ const healthy = await isDaemonRunning(port);
665187
+ const holders = await portHolderPids(port);
665188
+ if (!healthy && (holders === null || holders.length === 0)) return true;
665189
+ await delay4(500);
665190
+ }
665191
+ return false;
665192
+ }
665193
+ async function gracefullyStopOwnedDaemon(port) {
665194
+ const pids = await ownedDaemonPids(port);
665195
+ for (const pid of pids) {
665196
+ try {
665197
+ process.kill(pid, "SIGTERM");
665198
+ } catch {
665199
+ }
665200
+ }
665201
+ if (await waitForDaemonStopped(port)) return true;
665202
+ const survivors = await ownedDaemonPids(port);
665203
+ for (const pid of survivors) {
665204
+ try {
665205
+ process.kill(pid, "SIGKILL");
665206
+ } catch {
665207
+ }
665208
+ }
665209
+ return waitForDaemonStopped(port, 10);
665210
+ }
665211
+ async function restartDaemon(port, expectedVersion) {
665212
+ const p2 = port ?? getDaemonPort();
665213
+ const managed = await hasManagedDaemonService();
665214
+ if (managed) {
665215
+ const restarted = await runUserSystemctl(["restart", "omnius-daemon.service"]);
665216
+ if (restarted.ok && (await waitForDaemonReady(p2, expectedVersion)).ok) return true;
665217
+ const repaired = await repairManagedDaemonUnit(p2);
665218
+ if (repaired) {
665219
+ await runUserSystemctl(["stop", "omnius-daemon.service"]);
665220
+ await waitForDaemonStopped(p2);
665221
+ const started = await runUserSystemctl(["start", "omnius-daemon.service"]);
665222
+ if (started.ok && (await waitForDaemonReady(p2, expectedVersion)).ok) return true;
665223
+ }
665224
+ await runUserSystemctl(["stop", "omnius-daemon.service"]);
665225
+ if (!await waitForDaemonStopped(p2)) return false;
665226
+ }
665227
+ if (await isDaemonRunning(p2) && !await gracefullyStopOwnedDaemon(p2)) return false;
665228
+ const pid = await startDaemon(p2);
664546
665229
  if (!pid) return false;
664547
665230
  return (await waitForDaemonReady(p2, expectedVersion)).ok;
664548
665231
  }
@@ -664579,6 +665262,8 @@ function commandForEntrypoint(path16, nodeExe) {
664579
665262
  }
664580
665263
  async function resolveDaemonCommand(nodeExe) {
664581
665264
  const candidates = [];
665265
+ const thisDir = dirname47(fileURLToPath20(import.meta.url));
665266
+ candidates.push(join149(thisDir, "index.js"));
664582
665267
  if (process.argv[1]) candidates.push(process.argv[1]);
664583
665268
  try {
664584
665269
  const { spawnSync: spawnSync9 } = await import("node:child_process");
@@ -664590,8 +665275,6 @@ async function resolveDaemonCommand(nodeExe) {
664590
665275
  if (first2) candidates.push(first2);
664591
665276
  } catch {
664592
665277
  }
664593
- const thisDir = dirname47(fileURLToPath20(import.meta.url));
664594
- candidates.push(join149(thisDir, "index.js"));
664595
665278
  const seen = /* @__PURE__ */ new Set();
664596
665279
  for (const candidate of candidates) {
664597
665280
  if (!candidate || seen.has(candidate)) continue;
@@ -664601,9 +665284,9 @@ async function resolveDaemonCommand(nodeExe) {
664601
665284
  }
664602
665285
  return null;
664603
665286
  }
664604
- async function startDaemon() {
665287
+ async function startDaemon(port = getDaemonPort()) {
664605
665288
  mkdirSync82(OMNIUS_DIR2, { recursive: true });
664606
- const daemonPort = getDaemonPort();
665289
+ const daemonPort = port;
664607
665290
  const endpointClaim = claimDaemonEndpoint(daemonPort);
664608
665291
  if (!endpointClaim) return null;
664609
665292
  const nodeExe = process.execPath;
@@ -664627,6 +665310,7 @@ async function startDaemon() {
664627
665310
  ...processLeaseEnv(leaseId, ownerId, process.cwd()),
664628
665311
  OMNIUS_DAEMON: "1",
664629
665312
  // signal to serve.ts that it's running as daemon
665313
+ OMNIUS_PORT: String(daemonPort),
664630
665314
  OMNIUS_DAEMON_LOCK_TOKEN: endpointClaim.token,
664631
665315
  OMNIUS_DAEMON_LOCK_PORT: String(daemonPort),
664632
665316
  OMNIUS_PROCESS_OWNER_KIND: "daemon",
@@ -664746,15 +665430,47 @@ async function forceKillDaemon(port) {
664746
665430
  }
664747
665431
  return killed;
664748
665432
  }
665433
+ async function recoverDaemonVersionBoundedly(expectedVersion, observe, recover, maxAttempts = DAEMON_VERSION_RECOVERY_ATTEMPTS) {
665434
+ let observedVersion = await observe();
665435
+ if (expectedVersion === "0.0.0" || observedVersion === expectedVersion) {
665436
+ return { ok: true, observedVersion, attempts: 0 };
665437
+ }
665438
+ const boundedAttempts = Math.max(1, Math.min(3, Math.floor(maxAttempts)));
665439
+ for (let attempt = 1; attempt <= boundedAttempts; attempt++) {
665440
+ await recover();
665441
+ observedVersion = await observe();
665442
+ if (observedVersion === expectedVersion) {
665443
+ return { ok: true, observedVersion, attempts: attempt };
665444
+ }
665445
+ }
665446
+ return { ok: false, observedVersion, attempts: boundedAttempts };
665447
+ }
664749
665448
  async function ensureDaemonVersion(expectedVersion = getLocalCliVersion(), port = getDaemonPort()) {
664750
- const finish = (ok3, action, observedVersion) => ({ ok: ok3, action, expectedVersion, observedVersion, port });
665449
+ const finish = (ok3, action, observedVersion, recoveryAttempts = 0, requiresPrivilegedMigration = false) => ({
665450
+ ok: ok3,
665451
+ action,
665452
+ expectedVersion,
665453
+ observedVersion,
665454
+ port,
665455
+ recoveryAttempts,
665456
+ requiresPrivilegedMigration
665457
+ });
664751
665458
  if (await isDaemonRunning(port)) {
664752
665459
  if (process.env["OMNIUS_NO_VERSION_GUARD"] !== "1") {
664753
665460
  const running = await getDaemonReportedVersion(port);
664754
665461
  if (expectedVersion !== "0.0.0" && running !== expectedVersion) {
664755
- const ok3 = await restartDaemon(port, expectedVersion);
664756
- const observedVersion = await getDaemonReportedVersion(port);
664757
- return finish(ok3 && observedVersion === expectedVersion, ok3 ? "restarted" : "failed", observedVersion);
665462
+ const recovery = await recoverDaemonVersionBoundedly(
665463
+ expectedVersion,
665464
+ () => getDaemonReportedVersion(port),
665465
+ () => restartDaemon(port, expectedVersion)
665466
+ );
665467
+ return finish(
665468
+ recovery.ok,
665469
+ recovery.ok ? "restarted" : "failed",
665470
+ recovery.observedVersion,
665471
+ recovery.attempts,
665472
+ !recovery.ok && process.platform === "linux"
665473
+ );
664758
665474
  }
664759
665475
  }
664760
665476
  return finish(true, "unchanged", await getDaemonReportedVersion(port));
@@ -664770,7 +665486,7 @@ async function ensureDaemonVersion(expectedVersion = getLocalCliVersion(), port
664770
665486
  } catch {
664771
665487
  }
664772
665488
  }
664773
- const pid = await startDaemon();
665489
+ const pid = await startDaemon(port);
664774
665490
  if (!pid) {
664775
665491
  for (let i2 = 0; i2 < 20; i2++) {
664776
665492
  await new Promise((r2) => setTimeout(r2, 500));
@@ -664817,7 +665533,7 @@ async function getDaemonStatus() {
664817
665533
  }
664818
665534
  return { running, pid, port, uptime: uptime2, pidFile: PID_FILE2 };
664819
665535
  }
664820
- var OMNIUS_DIR2, PID_FILE2, DEFAULT_PORT2, LOCK_INITIALIZATION_GRACE_MS;
665536
+ var OMNIUS_DIR2, PID_FILE2, DEFAULT_PORT2, LOCK_INITIALIZATION_GRACE_MS, DAEMON_VERSION_RECOVERY_ATTEMPTS, DAEMON_GRACEFUL_STOP_ATTEMPTS;
664821
665537
  var init_daemon = __esm({
664822
665538
  "packages/cli/src/daemon.ts"() {
664823
665539
  init_dist5();
@@ -664825,6 +665541,8 @@ var init_daemon = __esm({
664825
665541
  PID_FILE2 = join149(OMNIUS_DIR2, "daemon.pid");
664826
665542
  DEFAULT_PORT2 = 11435;
664827
665543
  LOCK_INITIALIZATION_GRACE_MS = 5e3;
665544
+ DAEMON_VERSION_RECOVERY_ATTEMPTS = 2;
665545
+ DAEMON_GRACEFUL_STOP_ATTEMPTS = 20;
664828
665546
  }
664829
665547
  });
664830
665548
 
@@ -672665,52 +673383,83 @@ async function acquireSudoCredentials(ctx3, reason) {
672665
673383
  });
672666
673384
  });
672667
673385
  }
673386
+ async function runSudoScriptChecked(ctx3, script) {
673387
+ const { spawn: spawn40 } = await import("node:child_process");
673388
+ const full = `set -e; ${script}`;
673389
+ await withTransientTerminalPrivilegePrompt(
673390
+ ctx3,
673391
+ "Running elevated system changes.",
673392
+ () => new Promise((resolve82, reject) => {
673393
+ const isRoot = typeof process.getuid === "function" && process.getuid() === 0;
673394
+ const hasInteractiveTty = Boolean(
673395
+ process.stdin.isTTY && process.stdout.isTTY
673396
+ );
673397
+ const cmd = isRoot ? "bash" : "sudo";
673398
+ const args = isRoot ? ["-lc", full] : hasInteractiveTty ? ["bash", "-lc", full] : ["-n", "bash", "-lc", full];
673399
+ const child = spawn40(cmd, args, {
673400
+ stdio: hasInteractiveTty ? "inherit" : ["ignore", "pipe", "pipe"],
673401
+ env: { ...process.env, DEBIAN_FRONTEND: "noninteractive" }
673402
+ });
673403
+ let stdout = "";
673404
+ let stderr = "";
673405
+ child.stdout?.on("data", (data) => {
673406
+ stdout += data.toString();
673407
+ });
673408
+ child.stderr?.on("data", (data) => {
673409
+ stderr += data.toString();
673410
+ });
673411
+ onChildExit(child, (code8) => {
673412
+ if (code8 === 0) {
673413
+ resolve82();
673414
+ return;
673415
+ }
673416
+ reject(
673417
+ new Error(
673418
+ (stderr || stdout || `elevated command exited with ${code8}`).trim().slice(0, 500)
673419
+ )
673420
+ );
673421
+ });
673422
+ onChildError(child, (err) => reject(err));
673423
+ })
673424
+ );
673425
+ }
672668
673426
  async function runSudoScript(ctx3, script) {
672669
673427
  try {
672670
- const { spawn: spawn40 } = await import("node:child_process");
672671
- const full = `set -e; ${script}`;
672672
- await withTransientTerminalPrivilegePrompt(
672673
- ctx3,
672674
- "Running elevated system changes.",
672675
- () => new Promise((resolve82, reject) => {
672676
- const isRoot = typeof process.getuid === "function" && process.getuid() === 0;
672677
- const hasInteractiveTty = Boolean(
672678
- process.stdin.isTTY && process.stdout.isTTY
672679
- );
672680
- const cmd = isRoot ? "bash" : "sudo";
672681
- const args = isRoot ? ["-lc", full] : hasInteractiveTty ? ["bash", "-lc", full] : ["-n", "bash", "-lc", full];
672682
- const child = spawn40(cmd, args, {
672683
- stdio: hasInteractiveTty ? "inherit" : ["ignore", "pipe", "pipe"],
672684
- env: { ...process.env, DEBIAN_FRONTEND: "noninteractive" }
672685
- });
672686
- let stdout = "";
672687
- let stderr = "";
672688
- child.stdout?.on("data", (data) => {
672689
- stdout += data.toString();
672690
- });
672691
- child.stderr?.on("data", (data) => {
672692
- stderr += data.toString();
672693
- });
672694
- onChildExit(child, (code8) => {
672695
- if (code8 === 0) {
672696
- resolve82();
672697
- return;
672698
- }
672699
- reject(
672700
- new Error(
672701
- (stderr || stdout || `elevated command exited with ${code8}`).trim().slice(0, 500)
672702
- )
672703
- );
672704
- });
672705
- onChildError(child, (err) => reject(err));
672706
- })
672707
- );
673428
+ await runSudoScriptChecked(ctx3, script);
672708
673429
  } catch (err) {
672709
673430
  renderWarning(
672710
673431
  `Elevated command failed: ${err instanceof Error ? err.message : String(err)}`
672711
673432
  );
672712
673433
  }
672713
673434
  }
673435
+ async function migrateAttestedPrivilegedDaemonOwner(ctx3, port) {
673436
+ if (process.platform !== "linux" || !Number.isInteger(port) || port <= 0) {
673437
+ return false;
673438
+ }
673439
+ const script = [
673440
+ "set -euo pipefail",
673441
+ `port=${port}`,
673442
+ "found=0",
673443
+ "for pid in $( { lsof -nP -t -iTCP:${port} -sTCP:LISTEN 2>/dev/null || true; fuser ${port}/tcp 2>/dev/null || true; } | tr ' ' '\\n' | sort -un); do",
673444
+ " [ -r /proc/$pid/cmdline ] || continue",
673445
+ " cmd=$(tr '\\000' ' ' </proc/$pid/cmdline)",
673446
+ ' case "$cmd" in *omnius*serve*--daemon*) ;; *) continue ;; esac',
673447
+ " unit=$(sed -nE 's#.*(/[^:]*\\.service).*#\\1#p' /proc/$pid/cgroup | head -n1 | sed 's#.*/##')",
673448
+ ' [ "$unit" = power-monitor.service ] || continue',
673449
+ ' echo "Migrating attested Omnius daemon owner: $unit (pid $pid)"',
673450
+ ' systemctl restart "$unit"',
673451
+ " found=1",
673452
+ " break",
673453
+ "done",
673454
+ '[ "$found" = 1 ]'
673455
+ ].join("\n");
673456
+ try {
673457
+ await runSudoScriptChecked(ctx3, script);
673458
+ return true;
673459
+ } catch {
673460
+ return false;
673461
+ }
673462
+ }
672714
673463
  async function ensureVoiceDeps(ctx3) {
672715
673464
  try {
672716
673465
  const mod3 = await Promise.resolve().then(() => (init_py_embed(), py_embed_exports));
@@ -686539,6 +687288,15 @@ async function handleParallel(arg, ctx3) {
686539
687288
  );
686540
687289
  return;
686541
687290
  }
687291
+ const gpuAdmission = await resolveApprovedOllamaGpu();
687292
+ if (!gpuAdmission.ok) {
687293
+ renderError(`Ollama restart blocked by GPU safety policy: ${gpuAdmission.reason}`);
687294
+ return;
687295
+ }
687296
+ const approvedGpuEnv = withApprovedOllamaGpu(
687297
+ process.env,
687298
+ gpuAdmission.approval
687299
+ );
686542
687300
  let isSystemd = false;
686543
687301
  try {
686544
687302
  const out = (await execFileText5(
@@ -686557,6 +687315,7 @@ async function handleParallel(arg, ctx3) {
686557
687315
  const overrideFile = `${overrideDir}/parallel.conf`;
686558
687316
  const overrideContent = `[Service]
686559
687317
  Environment="OLLAMA_NUM_PARALLEL=${n2}"
687318
+ Environment="CUDA_VISIBLE_DEVICES=${gpuAdmission.approval.cudaVisibleDevices}"
686560
687319
  `;
686561
687320
  const { runElevatedCommand: runElev } = await Promise.resolve().then(() => (init_setup(), setup_exports));
686562
687321
  await runElev(`mkdir -p ${overrideDir}`, { timeoutMs: 3e4 });
@@ -686592,7 +687351,7 @@ ${escapedContent}EOF'`, {
686592
687351
  renderInfo(
686593
687352
  `Manual steps:
686594
687353
  sudo mkdir -p /etc/systemd/system/ollama.service.d
686595
- echo '[Service]\\nEnvironment="OLLAMA_NUM_PARALLEL=${n2}"' | sudo tee /etc/systemd/system/ollama.service.d/parallel.conf
687354
+ printf '[Service]\\nEnvironment="OLLAMA_NUM_PARALLEL=${n2}"\\nEnvironment="CUDA_VISIBLE_DEVICES=${gpuAdmission.approval.cudaVisibleDevices}"\\n' | sudo tee /etc/systemd/system/ollama.service.d/parallel.conf
686596
687355
  sudo systemctl daemon-reload && sudo systemctl restart ollama`
686597
687356
  );
686598
687357
  }
@@ -686615,13 +687374,14 @@ ${escapedContent}EOF'`, {
686615
687374
  }
686616
687375
  await new Promise((r2) => setTimeout(r2, 1e3));
686617
687376
  process.env.OLLAMA_NUM_PARALLEL = String(n2);
687377
+ process.env.CUDA_VISIBLE_DEVICES = gpuAdmission.approval.cudaVisibleDevices;
686618
687378
  const { spawn: spawn40 } = await import("node:child_process");
686619
687379
  const leaseId = newProcessLeaseId("model-service");
686620
687380
  const child = spawn40("ollama", ["serve"], {
686621
687381
  stdio: "ignore",
686622
687382
  detached: true,
686623
687383
  env: {
686624
- ...process.env,
687384
+ ...approvedGpuEnv,
686625
687385
  ...processLeaseEnv(leaseId, "ollama", process.cwd()),
686626
687386
  OMNIUS_PROCESS_OWNER_KIND: "model_service",
686627
687387
  OMNIUS_PROCESS_LIFECYCLE: "model",
@@ -688416,20 +689176,35 @@ async function handleUpdate(subcommand, ctx3) {
688416
689176
  installOverlay.setStatus("Gracefully upgrading shared daemon...");
688417
689177
  const { ensureDaemonVersion: ensureDaemonVersion2, getLocalCliVersion: getLocalCliVersion2 } = await Promise.resolve().then(() => (init_daemon(), daemon_exports));
688418
689178
  const expectedDaemonVersion = getLocalCliVersion2();
688419
- const daemonUpgrade = await ensureDaemonVersion2(expectedDaemonVersion);
689179
+ let daemonUpgrade = await ensureDaemonVersion2(expectedDaemonVersion);
689180
+ if (!daemonUpgrade.ok && daemonUpgrade.requiresPrivilegedMigration) {
689181
+ installOverlay.stop("Migrating the verified privileged daemon owner...");
689182
+ await new Promise((r2) => setTimeout(r2, 300));
689183
+ installOverlay.dismiss();
689184
+ const migrated = await migrateAttestedPrivilegedDaemonOwner(
689185
+ ctx3,
689186
+ daemonUpgrade.port
689187
+ );
689188
+ if (migrated) {
689189
+ const migrationOverlay = startInstallOverlay(targetVersion);
689190
+ Object.assign(installOverlay, migrationOverlay);
689191
+ installOverlay.setPhase("Daemon");
689192
+ installOverlay.setStatus("Verifying the migrated daemon...");
689193
+ daemonUpgrade = await ensureDaemonVersion2(expectedDaemonVersion);
689194
+ }
689195
+ }
688420
689196
  if (!daemonUpgrade.ok) {
688421
689197
  installOverlay.stop("Update installed, but daemon upgrade was not verified");
688422
689198
  await new Promise((r2) => setTimeout(r2, 1200));
688423
689199
  installOverlay.dismiss();
688424
689200
  renderError(
688425
- `Updated CLI to ${expectedDaemonVersion}, but the shared daemon still reports ${daemonUpgrade.observedVersion ?? "unavailable"}. The TUI will remain open; retry /update after resolving the daemon service.`
689201
+ `Updated CLI to ${expectedDaemonVersion}, but the shared daemon still reports ${daemonUpgrade.observedVersion ?? "unavailable"} after ${daemonUpgrade.recoveryAttempts} verified recovery round(s). A privileged owner was ${daemonUpgrade.requiresPrivilegedMigration ? "not safely migratable" : "not detected"}; no arbitrary port holder was terminated.`
688426
689202
  );
688427
689203
  return;
688428
689204
  }
688429
689205
  installOverlay.setStatus(
688430
689206
  daemonUpgrade.action === "restarted" ? `Daemon upgraded to ${expectedDaemonVersion}` : `Daemon verified at ${expectedDaemonVersion}`
688431
689207
  );
688432
- registry2.killAll();
688433
689208
  ctx3.contextSave?.();
688434
689209
  const hadActiveTask = ctx3.savePendingTaskState?.() ?? false;
688435
689210
  const resumeFlag = hadActiveTask ? "1" : "update-only";
@@ -688439,7 +689214,7 @@ async function handleUpdate(subcommand, ctx3) {
688439
689214
  await new Promise((r2) => setTimeout(r2, 200));
688440
689215
  ctx3.contextSave?.();
688441
689216
  if (ctx3.hasActiveTask?.()) ctx3.abortActiveTask?.();
688442
- ctx3.killEphemeral?.();
689217
+ ctx3.killEphemeral?.({ preserveInfrastructure: true });
688443
689218
  process.exit(120);
688444
689219
  }
688445
689220
  async function switchModel(query, ctx3, local = false) {
@@ -688929,6 +689704,7 @@ var OMNIUS_PINNED_DEPENDENCY_SPECS, NEXUS_DIRECTORY_ORIGIN, NEXUS_SPONSORS_URL,
688929
689704
  var init_commands = __esm({
688930
689705
  "packages/cli/src/tui/commands.ts"() {
688931
689706
  init_model_picker();
689707
+ init_ollama_gpu_policy();
688932
689708
  init_render();
688933
689709
  init_session_summary();
688934
689710
  init_generative_progress();
@@ -689487,7 +690263,7 @@ import {
689487
690263
  readFileSync as readFileSync121,
689488
690264
  readdirSync as readdirSync50,
689489
690265
  writeFileSync as writeFileSync76,
689490
- renameSync as renameSync14,
690266
+ renameSync as renameSync15,
689491
690267
  mkdirSync as mkdirSync88,
689492
690268
  unlinkSync as unlinkSync31,
689493
690269
  appendFileSync as appendFileSync17
@@ -689511,7 +690287,7 @@ function persistSession(s2) {
689511
690287
  const final2 = sessionPath(s2.id);
689512
690288
  const tmp = `${final2}.tmp.${process.pid}.${Date.now()}`;
689513
690289
  writeFileSync76(tmp, JSON.stringify(s2, null, 2), "utf-8");
689514
- renameSync14(tmp, final2);
690290
+ renameSync15(tmp, final2);
689515
690291
  } catch {
689516
690292
  }
689517
690293
  }
@@ -689521,7 +690297,7 @@ function persistInFlight(j) {
689521
690297
  const final2 = inFlightPath(j.sessionId);
689522
690298
  const tmp = `${final2}.tmp.${process.pid}.${Date.now()}`;
689523
690299
  writeFileSync76(tmp, JSON.stringify(j, null, 2), "utf-8");
689524
- renameSync14(tmp, final2);
690300
+ renameSync15(tmp, final2);
689525
690301
  } catch {
689526
690302
  }
689527
690303
  }
@@ -696046,7 +696822,7 @@ import {
696046
696822
  } from "node:fs";
696047
696823
  import { join as join165, basename as basename39 } from "node:path";
696048
696824
  import { exec as exec6 } from "node:child_process";
696049
- import { promisify as promisify8 } from "node:util";
696825
+ import { promisify as promisify9 } from "node:util";
696050
696826
  function buildDMNGatherPrompt(recentTaskSummaries, dueReminders, attentionItems, memoryTopics, capabilities, competence, reflectionBuffer, projectOpportunities = []) {
696051
696827
  const competenceReport = competence.length > 0 ? competence.map((c9) => {
696052
696828
  const rate = c9.attempts > 0 ? Math.round(c9.successes / c9.attempts * 100) : 0;
@@ -696170,7 +696946,7 @@ var init_dmn_engine = __esm({
696170
696946
  init_render();
696171
696947
  init_promptLoader3();
696172
696948
  init_tool_adapter();
696173
- execAsync3 = promisify8(exec6);
696949
+ execAsync3 = promisify9(exec6);
696174
696950
  DMNEngine = class {
696175
696951
  constructor(config, repoRoot) {
696176
696952
  this.config = config;
@@ -709937,8 +710713,8 @@ ${mediaContext}` : ""
709937
710713
  }
709938
710714
  }
709939
710715
  telegramChatIdFromArtifact(artifact) {
709940
- const numeric = Number(artifact.chatId);
709941
- return Number.isFinite(numeric) && String(Math.trunc(numeric)) === artifact.chatId ? Math.trunc(numeric) : artifact.chatId;
710716
+ const numeric2 = Number(artifact.chatId);
710717
+ return Number.isFinite(numeric2) && String(Math.trunc(numeric2)) === artifact.chatId ? Math.trunc(numeric2) : artifact.chatId;
709942
710718
  }
709943
710719
  async maybeSendTelegramReflectionFollowup(sessionKey, artifact, reason = "reflection") {
709944
710720
  if (!this.agentConfig)
@@ -723591,7 +724367,7 @@ __export(projects_exports, {
723591
724367
  setCurrentProject: () => setCurrentProject,
723592
724368
  unregisterProject: () => unregisterProject
723593
724369
  });
723594
- import { readFileSync as readFileSync132, writeFileSync as writeFileSync86, mkdirSync as mkdirSync99, existsSync as existsSync161, statSync as statSync63, renameSync as renameSync15 } from "node:fs";
724370
+ import { readFileSync as readFileSync132, writeFileSync as writeFileSync86, mkdirSync as mkdirSync99, existsSync as existsSync161, statSync as statSync63, renameSync as renameSync16 } from "node:fs";
723595
724371
  import { homedir as homedir58 } from "node:os";
723596
724372
  import { basename as basename43, join as join171, resolve as resolve74 } from "node:path";
723597
724373
  import { randomUUID as randomUUID19 } from "node:crypto";
@@ -723610,7 +724386,7 @@ function writeAll(file) {
723610
724386
  mkdirSync99(OMNIUS_DIR3, { recursive: true });
723611
724387
  const tmp = `${PROJECTS_FILE}.${randomUUID19().slice(0, 8)}.tmp`;
723612
724388
  writeFileSync86(tmp, JSON.stringify(file, null, 2), "utf8");
723613
- renameSync15(tmp, PROJECTS_FILE);
724389
+ renameSync16(tmp, PROJECTS_FILE);
723614
724390
  }
723615
724391
  function listProjects() {
723616
724392
  const { projects } = readAll2();
@@ -724585,7 +725361,7 @@ var init_access_policy = __esm({
724585
725361
 
724586
725362
  // packages/cli/src/api/project-preferences.ts
724587
725363
  import { createHash as createHash50 } from "node:crypto";
724588
- import { existsSync as existsSync162, mkdirSync as mkdirSync100, readFileSync as readFileSync133, renameSync as renameSync16, writeFileSync as writeFileSync87, unlinkSync as unlinkSync37 } from "node:fs";
725364
+ import { existsSync as existsSync162, mkdirSync as mkdirSync100, readFileSync as readFileSync133, renameSync as renameSync17, writeFileSync as writeFileSync87, unlinkSync as unlinkSync37 } from "node:fs";
724589
725365
  import { homedir as homedir59 } from "node:os";
724590
725366
  import { join as join172, resolve as resolve75 } from "node:path";
724591
725367
  import { randomUUID as randomUUID20 } from "node:crypto";
@@ -724639,7 +725415,7 @@ function writeProjectPreferences(root, partial) {
724639
725415
  const tmp = `${file}.${randomUUID20().slice(0, 8)}.tmp`;
724640
725416
  writeFileSync87(tmp, JSON.stringify(merged, null, 2), "utf8");
724641
725417
  try {
724642
- renameSync16(tmp, file);
725418
+ renameSync17(tmp, file);
724643
725419
  } catch (err) {
724644
725420
  try {
724645
725421
  writeFileSync87(file, JSON.stringify(merged, null, 2), "utf8");
@@ -725689,7 +726465,7 @@ var init_direct_tool_registry = __esm({
725689
726465
  });
725690
726466
 
725691
726467
  // packages/cli/src/api/external-tool-registry.ts
725692
- import { existsSync as existsSync166, mkdirSync as mkdirSync104, readFileSync as readFileSync135, writeFileSync as writeFileSync88, renameSync as renameSync17 } from "node:fs";
726468
+ import { existsSync as existsSync166, mkdirSync as mkdirSync104, readFileSync as readFileSync135, writeFileSync as writeFileSync88, renameSync as renameSync18 } from "node:fs";
725693
726469
  import { join as join175 } from "node:path";
725694
726470
  function externalToolStorePath(workingDir) {
725695
726471
  return join175(workingDir, ".omnius", "external-tools.json");
@@ -725713,7 +726489,7 @@ function persist3(workingDir, tools) {
725713
726489
  const file = { version: STORE_VERSION, tools };
725714
726490
  const tmp = `${path16}.tmp`;
725715
726491
  writeFileSync88(tmp, JSON.stringify(file, null, 2), { mode: 384 });
725716
- renameSync17(tmp, path16);
726492
+ renameSync18(tmp, path16);
725717
726493
  }
725718
726494
  function validateManifest2(input, existing) {
725719
726495
  if (!input || typeof input !== "object") {
@@ -744331,6 +745107,7 @@ var init_embedding_workers = __esm({
744331
745107
  var serve_exports = {};
744332
745108
  __export(serve_exports, {
744333
745109
  apiServeCommand: () => apiServeCommand,
745110
+ readServerPackageIdentity: () => readServerPackageIdentity,
744334
745111
  startApiServer: () => startApiServer
744335
745112
  });
744336
745113
  import * as http5 from "node:http";
@@ -744348,15 +745125,14 @@ import {
744348
745125
  readdirSync as readdirSync59,
744349
745126
  existsSync as existsSync173,
744350
745127
  watch as fsWatch5,
744351
- renameSync as renameSync18,
745128
+ renameSync as renameSync19,
744352
745129
  unlinkSync as unlinkSync38,
744353
745130
  statSync as statSync68,
744354
745131
  openSync as openSync8,
744355
745132
  readSync as readSync4,
744356
745133
  closeSync as closeSync8
744357
745134
  } from "node:fs";
744358
- import { randomBytes as randomBytes29, randomUUID as randomUUID21, timingSafeEqual as timingSafeEqual2 } from "node:crypto";
744359
- import { createHash as createHash52 } from "node:crypto";
745135
+ import { createHash as createHash52, randomBytes as randomBytes29, randomUUID as randomUUID21, timingSafeEqual as timingSafeEqual2 } from "node:crypto";
744360
745136
  function memoryDbPaths3(baseDir = process.cwd()) {
744361
745137
  const dir = join183(baseDir, ".omnius");
744362
745138
  return {
@@ -744365,7 +745141,7 @@ function memoryDbPaths3(baseDir = process.cwd()) {
744365
745141
  knowledge: join183(dir, "knowledge.db")
744366
745142
  };
744367
745143
  }
744368
- function getVersion3() {
745144
+ function readServerPackageIdentity() {
744369
745145
  try {
744370
745146
  const thisDir = dirname56(fileURLToPath23(import.meta.url));
744371
745147
  const candidates = [
@@ -744376,9 +745152,14 @@ function getVersion3() {
744376
745152
  for (const pkgPath of candidates) {
744377
745153
  try {
744378
745154
  if (!existsSync173(pkgPath)) continue;
744379
- const pkg = JSON.parse(readFileSync140(pkgPath, "utf8"));
745155
+ const raw = readFileSync140(pkgPath, "utf8");
745156
+ const pkg = JSON.parse(raw);
744380
745157
  if (pkg.name === "omnius" || pkg.name === "@omnius/cli" || pkg.name === "@omnius/monorepo") {
744381
- return pkg.version ?? "0.0.0";
745158
+ return {
745159
+ version: pkg.version ?? "0.0.0",
745160
+ packagePath: pkgPath,
745161
+ packageHash: createHash52("sha256").update(raw).digest("hex")
745162
+ };
744382
745163
  }
744383
745164
  } catch {
744384
745165
  continue;
@@ -744386,7 +745167,10 @@ function getVersion3() {
744386
745167
  }
744387
745168
  } catch {
744388
745169
  }
744389
- return "0.0.0";
745170
+ return { version: "0.0.0", packagePath: null, packageHash: null };
745171
+ }
745172
+ function getVersion3() {
745173
+ return SERVER_BOOT_IDENTITY.version;
744390
745174
  }
744391
745175
  function normalizeLocalhostForDaemon(url) {
744392
745176
  if (process.env["OMNIUS_KEEP_LOCALHOST"] === "1") return url;
@@ -745967,7 +746751,7 @@ function atomicJobWrite(dir, id2, job) {
745967
746751
  const tmpPath = `${finalPath}.tmp.${process.pid}.${Date.now()}`;
745968
746752
  try {
745969
746753
  writeFileSync92(tmpPath, JSON.stringify(job, null, 2), "utf-8");
745970
- renameSync18(tmpPath, finalPath);
746754
+ renameSync19(tmpPath, finalPath);
745971
746755
  } catch {
745972
746756
  try {
745973
746757
  writeFileSync92(finalPath, JSON.stringify(job, null, 2), "utf-8");
@@ -746192,7 +746976,12 @@ function handleHealth(res) {
746192
746976
  jsonResponse(res, 200, {
746193
746977
  status: "ok",
746194
746978
  uptime_s: Math.floor((Date.now() - startedAt) / 1e3),
746195
- version: version5
746979
+ version: version5,
746980
+ // `version` is retained for old clients. These explicit boot fields let
746981
+ // an updater prove that the process, rather than only its install path,
746982
+ // changed after an npm swap.
746983
+ boot_version: SERVER_BOOT_IDENTITY.version,
746984
+ boot_package_hash: SERVER_BOOT_IDENTITY.packageHash
746196
746985
  });
746197
746986
  }
746198
746987
  async function handleHealthReady(res, ollamaUrl) {
@@ -746225,6 +747014,8 @@ function handleVersion(res) {
746225
747014
  const version5 = getVersion3();
746226
747015
  jsonResponse(res, 200, {
746227
747016
  version: version5,
747017
+ boot_version: SERVER_BOOT_IDENTITY.version,
747018
+ boot_package_hash: SERVER_BOOT_IDENTITY.packageHash,
746228
747019
  node: process.version,
746229
747020
  platform: process.platform
746230
747021
  });
@@ -747768,7 +748559,7 @@ function writeUpdateState(state) {
747768
748559
  const finalPath = updateStateFile();
747769
748560
  const tmpPath = `${finalPath}.tmp.${process.pid}`;
747770
748561
  writeFileSync92(tmpPath, JSON.stringify(state, null, 2), "utf-8");
747771
- renameSync18(tmpPath, finalPath);
748562
+ renameSync19(tmpPath, finalPath);
747772
748563
  } catch {
747773
748564
  }
747774
748565
  }
@@ -753754,27 +754545,11 @@ function startApiServer(options2 = {}) {
753754
754545
  omnius API server v${version5}
753755
754546
  `);
753756
754547
  if (process.env["OMNIUS_DAEMON"] === "1" && process.env["OMNIUS_NO_VERSION_GUARD"] !== "1") {
753757
- const readDiskVersion = () => {
753758
- try {
753759
- const here = dirname56(fileURLToPath23(import.meta.url));
753760
- for (const rel of ["../package.json", "../../package.json", "../../../package.json", "../../../../package.json"]) {
753761
- const p2 = join183(here, rel);
753762
- if (existsSync173(p2)) {
753763
- const pkg = JSON.parse(readFileSync140(p2, "utf8"));
753764
- if (pkg.name === "omnius" || pkg.name === "@omnius/cli" || pkg.name === "@omnius/monorepo") {
753765
- return pkg.version ?? null;
753766
- }
753767
- }
753768
- }
753769
- } catch {
753770
- }
753771
- return null;
753772
- };
753773
- const bootVersion = readDiskVersion() ?? version5;
754548
+ const bootIdentity = SERVER_BOOT_IDENTITY;
753774
754549
  const versionWatch = setInterval(() => {
753775
- const disk = readDiskVersion();
753776
- if (disk && disk !== bootVersion) {
753777
- log22(` [daemon] version changed on disk ${bootVersion} -> ${disk}; restarting for the new version…
754550
+ const disk = readServerPackageIdentity();
754551
+ if (disk.version !== bootIdentity.version || disk.packageHash && disk.packageHash !== bootIdentity.packageHash) {
754552
+ log22(` [daemon] package identity changed on disk ${bootIdentity.version} -> ${disk.version}; restarting for the new version…
753778
754553
  `);
753779
754554
  try {
753780
754555
  server2.close(() => process.exit(0));
@@ -754656,7 +755431,7 @@ function setTimerEnabled(name10, enabled2) {
754656
755431
  return false;
754657
755432
  }
754658
755433
  }
754659
- var require4, NEXUS_DIRECTORY_ORIGIN2, NEXUS_SPONSORS_URL2, endpointRegistry, modelRouteMap, endpointUsage, _lastEndpointDiagnostics, BACKEND_TIMEOUT_DEFAULT_MS, BACKEND_TIMEOUT_MAX_MS, MODEL_LIST_TIMEOUT_DEFAULT_MS, metrics, startedAt, FILE_MIME_BY_EXT, realtimeOllamaFallbackCache, runningProcesses, LOCAL_UI_SESSION_COOKIE, LOCAL_UI_SESSION_TOKEN, perKeyUsage, CRON_MARKER2;
755434
+ var require4, NEXUS_DIRECTORY_ORIGIN2, NEXUS_SPONSORS_URL2, SERVER_BOOT_IDENTITY, endpointRegistry, modelRouteMap, endpointUsage, _lastEndpointDiagnostics, BACKEND_TIMEOUT_DEFAULT_MS, BACKEND_TIMEOUT_MAX_MS, MODEL_LIST_TIMEOUT_DEFAULT_MS, metrics, startedAt, FILE_MIME_BY_EXT, realtimeOllamaFallbackCache, runningProcesses, LOCAL_UI_SESSION_COOKIE, LOCAL_UI_SESSION_TOKEN, perKeyUsage, CRON_MARKER2;
754660
755435
  var init_serve = __esm({
754661
755436
  "packages/cli/src/api/serve.ts"() {
754662
755437
  init_config();
@@ -754693,6 +755468,7 @@ var init_serve = __esm({
754693
755468
  require4 = createRequire8(import.meta.url);
754694
755469
  NEXUS_DIRECTORY_ORIGIN2 = (process.env["OMNIUS_NEXUS_DIRECTORY_ORIGIN"] || process.env["OMNIUS_NEXUS_SIGNALING_SERVER"] || "https://openagents.nexus").replace(/\/+$/, "");
754695
755470
  NEXUS_SPONSORS_URL2 = `${NEXUS_DIRECTORY_ORIGIN2}/api/v1/sponsors`;
755471
+ SERVER_BOOT_IDENTITY = readServerPackageIdentity();
754696
755472
  endpointRegistry = [];
754697
755473
  modelRouteMap = /* @__PURE__ */ new Map();
754698
755474
  endpointUsage = /* @__PURE__ */ new Map();
@@ -755120,9 +755896,9 @@ ${incompleteList}${more}
755120
755896
  const checkScript = scripts["typecheck"] ? "typecheck" : scripts["build"] ? "build" : null;
755121
755897
  if (checkScript) {
755122
755898
  const { exec: exec7 } = await import("node:child_process");
755123
- const { promisify: promisify9 } = await import("node:util");
755899
+ const { promisify: promisify10 } = await import("node:util");
755124
755900
  try {
755125
- await promisify9(exec7)(`npm run ${checkScript} --silent 2>&1`, {
755901
+ await promisify10(exec7)(`npm run ${checkScript} --silent 2>&1`, {
755126
755902
  cwd: cwd4,
755127
755903
  timeout: 12e4,
755128
755904
  encoding: "utf-8",
@@ -755853,6 +756629,57 @@ function appendSubAgentNoteBox(statusBar, agentId, event, title, metrics2, conte
755853
756629
  spec
755854
756630
  );
755855
756631
  }
756632
+ function prepareCompactionAudit(event) {
756633
+ const record = event.compaction;
756634
+ if (!record) {
756635
+ return {
756636
+ display: event.content ?? "Context compacted (legacy event without an audit payload).",
756637
+ ledger: {
756638
+ schemaVersion: 1,
756639
+ timestamp: event.timestamp,
756640
+ legacy: true,
756641
+ summary: event.content ?? "",
756642
+ removedMessages: []
756643
+ }
756644
+ };
756645
+ }
756646
+ const redactor = getSecretRedactor();
756647
+ const removedMessages = record.removedMessages.map((message2) => ({
756648
+ ...message2,
756649
+ content: redactor.redactText(message2.content)
756650
+ }));
756651
+ const summary = redactor.redactText(record.summary);
756652
+ const lines = [
756653
+ "[COMPACTION AUDIT]",
756654
+ `id=${record.id}`,
756655
+ `reason=context budget; strategy=${record.strategy}${record.manual ? "; manual" : ""}`,
756656
+ `tokens=~${record.beforeTokens.toLocaleString()} → ~${record.afterTokens.toLocaleString()} (saved ~${record.savedTokens.toLocaleString()})`,
756657
+ `removed=${removedMessages.length}; retained=${record.retainedMessages}`,
756658
+ "ledger=.omnius/context/compactions.jsonl",
756659
+ "",
756660
+ "Summary retained for the model:",
756661
+ summary || "(none)",
756662
+ "",
756663
+ `Exact removed model-visible messages (${removedMessages.length}):`
756664
+ ];
756665
+ for (const message2 of removedMessages) {
756666
+ lines.push(
756667
+ `--- removed[${message2.index}] role=${message2.role} chars=${message2.chars} reason=${message2.reason}${message2.toolCallId ? ` tool_call_id=${message2.toolCallId}` : ""} ---`,
756668
+ message2.content || "(empty)"
756669
+ );
756670
+ }
756671
+ return {
756672
+ display: lines.join("\n"),
756673
+ ledger: {
756674
+ schemaVersion: 1,
756675
+ ...record,
756676
+ summary,
756677
+ removedMessages,
756678
+ recordedAt: (/* @__PURE__ */ new Date()).toISOString(),
756679
+ source: "interactive-tui"
756680
+ }
756681
+ };
756682
+ }
755856
756683
  function writeSubAgentEventForView(statusBar, agentId, event, verbose = false) {
755857
756684
  const previewLine = formatSubAgentEventForView(event);
755858
756685
  statusBar.updateAgentViewEvent(agentId, event, previewLine ?? event.type);
@@ -758605,11 +759432,18 @@ ${entry.fullContent}`
758605
759432
  statusBar?.updateTrajectoryCheckpoint(event.trajectory ?? null);
758606
759433
  break;
758607
759434
  case "compaction":
759435
+ const compactionAudit = prepareCompactionAudit(event);
759436
+ appendCompactionAudit(process.cwd(), compactionAudit.ledger);
758608
759437
  if (isNeovimActive()) {
758609
- writeToNeovimOutput("\x1B[33m⚠ Context compacted\x1B[0m\r\n");
759438
+ writeToNeovimOutput("\x1B[33m⚠ Context compacted — audit: .omnius/context/compactions.jsonl\x1B[0m\r\n");
758610
759439
  } else {
758611
759440
  contentWrite(
758612
- () => renderWarning(`Context compacted: ${event.content}`)
759441
+ () => renderToolResult(
759442
+ "context_compaction",
759443
+ true,
759444
+ compactionAudit.display,
759445
+ { verbose: config.verbose }
759446
+ )
758613
759447
  );
758614
759448
  }
758615
759449
  if (onCompaction) onCompaction();
@@ -762073,11 +762907,11 @@ The user pasted a clipboard image saved at ${relPath}. Use the OCR, vision analy
762073
762907
  };
762074
762908
  }
762075
762909
  },
762076
- killEphemeral() {
762910
+ killEphemeral(options2) {
762077
762911
  if (_shellToolRef) _shellToolRef.killAll();
762078
762912
  killAllFullSubAgents();
762079
762913
  taskManager.stopAll();
762080
- registry2.killAll();
762914
+ if (!options2?.preserveInfrastructure) registry2.killAll();
762081
762915
  if (_replToolRef) {
762082
762916
  try {
762083
762917
  _replToolRef.dispose();