omnius 1.0.546 → 1.0.547

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
@@ -6559,11 +6559,29 @@ import { resolve as resolve4 } from "node:path";
6559
6559
  function computeMaxUngatedLines(contextWindow) {
6560
6560
  if (contextWindow <= 0)
6561
6561
  return 200;
6562
- const budget = Math.floor(contextWindow * 0.15);
6562
+ const budget = Math.floor(contextWindow * 0.2);
6563
6563
  const maxLines = Math.floor(budget / 10);
6564
6564
  return Math.max(80, Math.min(500, maxLines));
6565
6565
  }
6566
- function buildStructuralPreview(lines, filePath, maxLines) {
6566
+ function exceedsInlineCharacterBudget(lines, contextWindow) {
6567
+ const sourceBytes = Buffer.byteLength(lines.join("\n"), "utf8");
6568
+ const projectedTokens = Math.ceil((sourceBytes + lines.length * 10 + 512) / 4);
6569
+ const tokenBudget = contextWindow > 0 ? Math.floor(contextWindow * 0.2) : 2e3;
6570
+ return projectedTokens > tokenBudget;
6571
+ }
6572
+ function boundedBranchPreview(prefix, preview, contextWindow) {
6573
+ const tokenBudget = contextWindow > 0 ? Math.floor(contextWindow * 0.2) : 2e3;
6574
+ const maxChars = Math.max(192, Math.max(0, tokenBudget - 128) * 4);
6575
+ const combined = `${prefix}
6576
+ ${preview}`;
6577
+ if (combined.length <= maxChars)
6578
+ return combined;
6579
+ const suffix = "\n[preview truncated to the 20% context budget; use AgenticRunner branch extraction]";
6580
+ if (suffix.length >= maxChars)
6581
+ return suffix.slice(0, maxChars);
6582
+ return `${combined.slice(0, maxChars - suffix.length).trimEnd()}${suffix}`;
6583
+ }
6584
+ function buildStructuralPreview(lines, filePath, maxLines, lineOffset = 0) {
6567
6585
  const total = lines.length;
6568
6586
  const HEAD = Math.min(30, Math.floor(maxLines * 0.35));
6569
6587
  const TAIL = Math.min(15, Math.floor(maxLines * 0.15));
@@ -6572,13 +6590,14 @@ function buildStructuralPreview(lines, filePath, maxLines) {
6572
6590
  `);
6573
6591
  parts.push(`## Lines 1-${HEAD}:`);
6574
6592
  for (let i2 = 0; i2 < HEAD; i2++) {
6575
- parts.push(`${String(i2 + 1).padStart(6)} | ${lines[i2]}`);
6593
+ const line = lines[i2] ?? "";
6594
+ parts.push(`${String(lineOffset + i2 + 1).padStart(6)} | ${line.slice(0, 400)}${line.length > 400 ? "…" : ""}`);
6576
6595
  }
6577
6596
  const sigs = [];
6578
6597
  for (let i2 = HEAD; i2 < total - TAIL; i2++) {
6579
6598
  const line = lines[i2];
6580
6599
  if (SIG_PATTERNS.some((p2) => p2.test(line))) {
6581
- sigs.push(`${String(i2 + 1).padStart(6)} | ${line}`);
6600
+ sigs.push(`${String(lineOffset + i2 + 1).padStart(6)} | ${line.slice(0, 400)}${line.length > 400 ? "…" : ""}`);
6582
6601
  }
6583
6602
  }
6584
6603
  if (sigs.length > 0) {
@@ -6600,7 +6619,8 @@ function buildStructuralPreview(lines, filePath, maxLines) {
6600
6619
  parts.push(`
6601
6620
  ## Lines ${tailStart + 1}-${total}:`);
6602
6621
  for (let i2 = tailStart; i2 < total; i2++) {
6603
- parts.push(`${String(i2 + 1).padStart(6)} | ${lines[i2]}`);
6622
+ const line = lines[i2] ?? "";
6623
+ parts.push(`${String(lineOffset + i2 + 1).padStart(6)} | ${line.slice(0, 400)}${line.length > 400 ? "…" : ""}`);
6604
6624
  }
6605
6625
  }
6606
6626
  parts.push(``);
@@ -6656,7 +6676,7 @@ var init_file_read = __esm({
6656
6676
  FileReadTool = class {
6657
6677
  name = "file_read";
6658
6678
  aliases = ["read_file", "read", "cat"];
6659
- description = "Read the contents of a file. For large files (200+ lines), returns a structural preview with signatures — use offset/limit to read specific sections.";
6679
+ description = "Read file contents. Payloads projected above 20% of context are branch-extracted by the agent runner; direct use returns a bounded structural preview. offset/limit does not bypass the budget.";
6660
6680
  parameters = {
6661
6681
  type: "object",
6662
6682
  properties: {
@@ -6701,7 +6721,21 @@ var init_file_read = __esm({
6701
6721
  const totalLines = lines.length;
6702
6722
  if (offset !== void 0 || limit !== void 0) {
6703
6723
  const startIdx = Math.max(0, (offset ?? 1) - 1);
6704
- lines = lines.slice(startIdx, limit ? startIdx + limit : void 0);
6724
+ lines = lines.slice(startIdx, limit !== void 0 ? startIdx + Math.max(0, limit) : void 0);
6725
+ if (exceedsInlineCharacterBudget(lines, this._contextWindowSize)) {
6726
+ const maxLines2 = computeMaxUngatedLines(this._contextWindowSize);
6727
+ return {
6728
+ success: true,
6729
+ output: boundedBranchPreview([
6730
+ fileContextHeader(filePath, content, { offset, limit }),
6731
+ `[BRANCH_REQUIRED] The selected range exceeds 20% of the context window and was not inlined. An AgenticRunner must route this request through branch extraction; direct callers receive only this bounded structural preview.`
6732
+ ].join("\n"), buildStructuralPreview(lines, filePath, maxLines2, startIdx), this._contextWindowSize),
6733
+ durationMs: performance.now() - start2,
6734
+ mutated: false,
6735
+ mutatedFiles: [],
6736
+ beforeHash: contentHash(content)
6737
+ };
6738
+ }
6705
6739
  const numbered2 = lines.map((line, i2) => `${String(startIdx + i2 + 1).padStart(6)} | ${line}`).join("\n");
6706
6740
  const hash = contentHash(content);
6707
6741
  return {
@@ -6716,12 +6750,14 @@ ${numbered2}`,
6716
6750
  }
6717
6751
  touchFile(this.workingDir, filePath);
6718
6752
  const maxLines = computeMaxUngatedLines(this._contextWindowSize);
6719
- if (totalLines > maxLines) {
6753
+ if (exceedsInlineCharacterBudget(lines, this._contextWindowSize)) {
6720
6754
  const notes = getFileNotes(this.workingDir, filePath);
6721
6755
  return {
6722
6756
  success: true,
6723
- output: `${fileContextHeader(filePath, content)}
6724
- ${buildStructuralPreview(lines, filePath, maxLines)}${notes ? "\n\n" + notes : ""}`,
6757
+ output: boundedBranchPreview([
6758
+ fileContextHeader(filePath, content),
6759
+ `[BRANCH_REQUIRED] This file exceeds 20% of the context window and was not inlined. An AgenticRunner must route it through branch extraction.`
6760
+ ].join("\n"), `${buildStructuralPreview(lines, filePath, maxLines)}${notes ? "\n\n" + notes : ""}`, this._contextWindowSize),
6725
6761
  durationMs: performance.now() - start2,
6726
6762
  mutated: false,
6727
6763
  mutatedFiles: [],
@@ -119450,7 +119486,7 @@ var require_auto = __commonJS({
119450
119486
  // ../node_modules/acme-client/src/client.js
119451
119487
  var require_client = __commonJS({
119452
119488
  "../node_modules/acme-client/src/client.js"(exports, module) {
119453
- var { createHash: createHash53 } = __require("crypto");
119489
+ var { createHash: createHash54 } = __require("crypto");
119454
119490
  var { getPemBodyAsB64u } = require_crypto();
119455
119491
  var { log: log22 } = require_logger();
119456
119492
  var HttpClient = require_http();
@@ -119761,14 +119797,14 @@ var require_client = __commonJS({
119761
119797
  */
119762
119798
  async getChallengeKeyAuthorization(challenge) {
119763
119799
  const jwk = this.http.getJwk();
119764
- const keysum = createHash53("sha256").update(JSON.stringify(jwk));
119800
+ const keysum = createHash54("sha256").update(JSON.stringify(jwk));
119765
119801
  const thumbprint = keysum.digest("base64url");
119766
119802
  const result = `${challenge.token}.${thumbprint}`;
119767
119803
  if (challenge.type === "http-01") {
119768
119804
  return result;
119769
119805
  }
119770
119806
  if (challenge.type === "dns-01") {
119771
- return createHash53("sha256").update(result).digest("base64url");
119807
+ return createHash54("sha256").update(result).digest("base64url");
119772
119808
  }
119773
119809
  if (challenge.type === "tls-alpn-01") {
119774
119810
  return result;
@@ -124395,9 +124431,9 @@ var require_sha256 = __commonJS({
124395
124431
  var forge = require_forge();
124396
124432
  require_md();
124397
124433
  require_util2();
124398
- var sha2565 = module.exports = forge.sha256 = forge.sha256 || {};
124399
- forge.md.sha256 = forge.md.algorithms.sha256 = sha2565;
124400
- sha2565.create = function() {
124434
+ var sha2566 = module.exports = forge.sha256 = forge.sha256 || {};
124435
+ forge.md.sha256 = forge.md.algorithms.sha256 = sha2566;
124436
+ sha2566.create = function() {
124401
124437
  if (!_initialized) {
124402
124438
  _init();
124403
124439
  }
@@ -262448,7 +262484,7 @@ var require_websocket2 = __commonJS({
262448
262484
  var http6 = __require("http");
262449
262485
  var net5 = __require("net");
262450
262486
  var tls2 = __require("tls");
262451
- var { randomBytes: randomBytes31, createHash: createHash53 } = __require("crypto");
262487
+ var { randomBytes: randomBytes31, createHash: createHash54 } = __require("crypto");
262452
262488
  var { Duplex: Duplex3, Readable } = __require("stream");
262453
262489
  var { URL: URL3 } = __require("url");
262454
262490
  var PerMessageDeflate3 = require_permessage_deflate2();
@@ -263108,7 +263144,7 @@ var require_websocket2 = __commonJS({
263108
263144
  abortHandshake(websocket, socket, "Invalid Upgrade header");
263109
263145
  return;
263110
263146
  }
263111
- const digest3 = createHash53("sha1").update(key + GUID).digest("base64");
263147
+ const digest3 = createHash54("sha1").update(key + GUID).digest("base64");
263112
263148
  if (res.headers["sec-websocket-accept"] !== digest3) {
263113
263149
  abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
263114
263150
  return;
@@ -263475,7 +263511,7 @@ var require_websocket_server = __commonJS({
263475
263511
  var EventEmitter15 = __require("events");
263476
263512
  var http6 = __require("http");
263477
263513
  var { Duplex: Duplex3 } = __require("stream");
263478
- var { createHash: createHash53 } = __require("crypto");
263514
+ var { createHash: createHash54 } = __require("crypto");
263479
263515
  var extension3 = require_extension2();
263480
263516
  var PerMessageDeflate3 = require_permessage_deflate2();
263481
263517
  var subprotocol3 = require_subprotocol();
@@ -263776,7 +263812,7 @@ var require_websocket_server = __commonJS({
263776
263812
  );
263777
263813
  }
263778
263814
  if (this._state > RUNNING) return abortHandshake(socket, 503);
263779
- const digest3 = createHash53("sha1").update(key + GUID).digest("base64");
263815
+ const digest3 = createHash54("sha1").update(key + GUID).digest("base64");
263780
263816
  const headers = [
263781
263817
  "HTTP/1.1 101 Switching Protocols",
263782
263818
  "Upgrade: websocket",
@@ -276583,13 +276619,13 @@ Justification: ${justification || "(none provided)"}`,
276583
276619
  }
276584
276620
  const snapshot = JSON.stringify(this.selfState, null, 2);
276585
276621
  try {
276586
- const { createHash: createHash53 } = await import("node:crypto");
276622
+ const { createHash: createHash54 } = await import("node:crypto");
276587
276623
  const snapshotDir = join44(this.cwd, ".omnius", "identity", "snapshots");
276588
276624
  await mkdir7(snapshotDir, { recursive: true });
276589
276625
  const version5 = this.selfState.version;
276590
276626
  const snapshotPath = join44(snapshotDir, `v${version5}.json`);
276591
276627
  await writeFile12(snapshotPath, snapshot, "utf8");
276592
- const hash = createHash53("sha256").update(snapshot).digest("hex");
276628
+ const hash = createHash54("sha256").update(snapshot).digest("hex");
276593
276629
  await writeFile12(join44(this.cwd, ".omnius", "identity", "latest-hash.txt"), hash, "utf8");
276594
276630
  let ipfsCid = "";
276595
276631
  try {
@@ -276722,8 +276758,8 @@ New: ${newNarrative.slice(0, 200)}...`,
276722
276758
  }
276723
276759
  // ── Helpers ──────────────────────────────────────────────────────────────
276724
276760
  createDefaultState() {
276725
- const { createHash: createHash53 } = __require("node:crypto");
276726
- const machineId = createHash53("sha256").update(this.cwd).digest("hex").slice(0, 12);
276761
+ const { createHash: createHash54 } = __require("node:crypto");
276762
+ const machineId = createHash54("sha256").update(this.cwd).digest("hex").slice(0, 12);
276727
276763
  return {
276728
276764
  self_id: `omnius-${machineId}`,
276729
276765
  version: 1,
@@ -276805,9 +276841,9 @@ New: ${newNarrative.slice(0, 200)}...`,
276805
276841
  let cid;
276806
276842
  if (this.selfState.version > prevVersion) {
276807
276843
  try {
276808
- const { createHash: createHash53 } = await import("node:crypto");
276844
+ const { createHash: createHash54 } = await import("node:crypto");
276809
276845
  const stateJson = JSON.stringify(this.selfState);
276810
- const hash = createHash53("sha256").update(stateJson).digest("hex").slice(0, 32);
276846
+ const hash = createHash54("sha256").update(stateJson).digest("hex").slice(0, 32);
276811
276847
  const cidsPath = join44(this.cwd, ".omnius", "identity", "cids.json");
276812
276848
  const cidsData = { latest: "", hash, version: this.selfState.version };
276813
276849
  try {
@@ -577071,6 +577107,7 @@ var init_streaming_executor = __esm({
577071
577107
  reset() {
577072
577108
  this.tools.clear();
577073
577109
  this.insertionOrder = [];
577110
+ this.executeFn = null;
577074
577111
  }
577075
577112
  // ─────────────────────────────────────────────────────────
577076
577113
  // Internal — Hannover-aligned concurrency control
@@ -578943,9 +578980,11 @@ var init_evidenceLedger = __esm({
578943
578980
  if (!path16 || !content)
578944
578981
  return;
578945
578982
  const built = buildExtract(content);
578983
+ if (input.fidelity)
578984
+ built.fidelity = input.fidelity;
578946
578985
  const existing = this.entries.get(path16);
578947
578986
  if (existing && existing.readVersion === fileVersion && !existing.stale) {
578948
- const keepNew = built.text.length >= existing.content.length;
578987
+ const keepNew = input.fidelity === "extract" || built.text.length >= existing.content.length;
578949
578988
  this.entries.set(path16, {
578950
578989
  ...existing,
578951
578990
  content: keepNew ? built.text : existing.content,
@@ -584082,6 +584121,7 @@ var init_completion_resolution_verifier = __esm({
584082
584121
  });
584083
584122
 
584084
584123
  // packages/orchestrator/dist/evidenceBranch.js
584124
+ import { createHash as createHash33 } from "node:crypto";
584085
584125
  function buildBranchExtractionBrief(input) {
584086
584126
  const path16 = cleanBriefText(input.path, 320) || "the requested file";
584087
584127
  const intent = firstBriefText([
@@ -584091,37 +584131,75 @@ function buildBranchExtractionBrief(input) {
584091
584131
  ]);
584092
584132
  const openQuestion = cleanBriefText(input.trajectoryOpenQuestion, 280);
584093
584133
  const focus = openQuestion || intent;
584134
+ const goalAnchor = cleanBriefText(input.goalAnchor || input.currentStep || input.trajectoryAssessment || intent, 320);
584094
584135
  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.`;
584136
+ const rangeLabel2 = input.requestedRange ? `requested range offset=${input.requestedRange.offset ?? 1}, limit=${input.requestedRange.limit ?? "EOF"}` : "whole-file read";
584137
+ const budgetLabel = input.projectedReadTokens && input.contextWindowTokens ? ` The projected payload is ~${Math.max(0, input.projectedReadTokens)} tokens of a ${Math.max(0, input.contextWindowTokens)}-token context.` : "";
584095
584138
  const triggerEvidence = uniqueBriefLines([
584096
- `The active action is a whole-file read of ${path16}; disk inspection found ${Math.max(0, input.lineCount)} lines / ${Math.max(0, input.byteCount)} bytes, so the parent context would otherwise receive only a preview.`,
584139
+ `The active action is a ${rangeLabel2} of ${path16}; disk inspection found ${Math.max(0, input.lineCount)} lines selected / ${Math.max(0, input.byteCount)} bytes selected.${budgetLabel}`,
584140
+ input.routingReason ? `Branch routing reason: ${cleanBriefText(input.routingReason, 300)}` : "",
584097
584141
  input.trajectoryAssessment ? `Current trajectory assessment: ${cleanBriefText(input.trajectoryAssessment, 360)}` : "No current file-level evidence has been returned to the parent yet.",
584098
584142
  input.currentStep ? `Current task step: ${cleanBriefText(input.currentStep, 260)}` : "",
584099
584143
  input.recentFailure ? `Recent unresolved evidence: ${cleanBriefText(input.recentFailure, 320)}` : ""
584100
584144
  ]);
584101
584145
  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.";
584102
- const retrievalQuery = uniqueBriefLines([
584103
- path16,
584104
- focus,
584146
+ const requirementQuestions = uniqueBriefLines([
584105
584147
  openQuestion,
584106
- "relevant declarations behavior configuration line spans"
584148
+ intent,
584149
+ input.currentStep && input.currentStep !== intent ? input.currentStep : "",
584150
+ input.recentFailure ? `Which file-local declaration, value, or behavior explains this unresolved failure: ${cleanBriefText(input.recentFailure, 260)}` : ""
584151
+ ]).slice(0, 3);
584152
+ if (requirementQuestions.length === 0) {
584153
+ requirementQuestions.push(`Which declarations, values, and behavior in this file are required for the next narrow action?`);
584154
+ }
584155
+ const requirements = requirementQuestions.map((question, index) => ({
584156
+ id: `R${index + 1}`,
584157
+ question,
584158
+ required: index === 0 || requirementQuestions.length === 1,
584159
+ expectedEvidence: "Exact source declarations, literal values, control/configuration behavior, and their line anchors.",
584160
+ searchTerms: queryTerms(question).slice(0, 16)
584161
+ }));
584162
+ const retrievalQuery = uniqueBriefLines([
584163
+ ...requirements.map((requirement) => requirement.question),
584164
+ input.recentFailure
584107
584165
  ]).join(" ");
584166
+ const discoveryContract = {
584167
+ version: 1,
584168
+ path: path16,
584169
+ goalAnchor: goalAnchor || "Choose the next narrow evidence-backed action.",
584170
+ query: cleanBriefText(retrievalQuery, 700),
584171
+ requirements,
584172
+ completionCriteria: [
584173
+ "Every required requirement is either supported by an exact anchored segment or explicitly marked unresolved.",
584174
+ "Every returned factual claim names its source line span; discontiguous evidence remains separate.",
584175
+ "Stop when the contract is satisfied, no new query/range is available, or the bounded search budget is exhausted."
584176
+ ],
584177
+ budget: {
584178
+ maxRounds: 3,
584179
+ maxWindowsPerRound: 3,
584180
+ maxTotalWindows: MAX_WINDOWS,
584181
+ maxPresentedLines: MAX_SNIPPET_LINES,
584182
+ maxInjectedChars: 2400
584183
+ }
584184
+ };
584108
584185
  return {
584109
584186
  request: cleanBriefText(request, 520),
584110
- triggerEvidence: triggerEvidence.slice(0, 4),
584187
+ triggerEvidence: triggerEvidence.slice(0, 5),
584111
584188
  returnContract: cleanBriefText(returnContract, 520),
584112
- retrievalQuery: cleanBriefText(retrievalQuery, 700)
584189
+ retrievalQuery: cleanBriefText(retrievalQuery, 700),
584190
+ discoveryContract
584113
584191
  };
584114
584192
  }
584115
- function buildStructuralPreview2(lines, path16, query) {
584193
+ function buildStructuralPreview2(lines, path16, query, sourceLineOffset = 0) {
584116
584194
  const n2 = lines.length;
584117
584195
  const clip3 = (l2) => l2.length > 180 ? l2.slice(0, 180) + "…" : l2;
584118
- const head = lines.slice(0, HEAD_LINES2).map((l2, i2) => `${i2 + 1}: ${clip3(l2)}`);
584196
+ const head = lines.slice(0, HEAD_LINES2).map((l2, i2) => `${sourceLineOffset + i2 + 1}: ${clip3(l2)}`);
584119
584197
  const isStructural = (l2) => /^\s*(<[A-Za-z!]|#{1,6}\s|def |class |function |export |interface |type |async |public |private |\[[^\]]+\]|[A-Za-z_][\w.]*\s*=)/.test(l2) && l2.trim().length > 0 && l2.trim().length <= 180;
584120
584198
  const markers = [];
584121
584199
  for (let i2 = HEAD_LINES2; i2 < n2; i2++) {
584122
584200
  const l2 = lines[i2];
584123
584201
  if (isStructural(l2))
584124
- markers.push(`${i2 + 1}: ${clip3(l2.trim())}`);
584202
+ markers.push(`${sourceLineOffset + i2 + 1}: ${clip3(l2.trim())}`);
584125
584203
  }
584126
584204
  const MAX_MARKERS = 30;
584127
584205
  const sampled = markers.length > MAX_MARKERS ? Array.from({ length: MAX_MARKERS }, (_, k) => markers[Math.floor(k * markers.length / MAX_MARKERS)]) : markers;
@@ -584207,7 +584285,9 @@ function selectWindows(lines, terms2) {
584207
584285
  return chosen.sort((a2, b) => a2.start - b.start).map((m2) => ({
584208
584286
  start: m2.start + 1,
584209
584287
  end: m2.end + 1,
584210
- text: lines.slice(m2.start, m2.end + 1).join("\n"),
584288
+ // A one-line minified artifact can be hundreds of KB. The branch prompt
584289
+ // is bounded independently of line count; exact source remains local.
584290
+ text: lines.slice(m2.start, m2.end + 1).map((line) => line.length > 400 ? `${line.slice(0, 400)}…` : line).join("\n"),
584211
584291
  score: m2.score
584212
584292
  }));
584213
584293
  }
@@ -584222,6 +584302,8 @@ ${w.text}`).join("\n\n");
584222
584302
  ...brief.triggerEvidence.map((evidence) => `- ${evidence}`),
584223
584303
  `Return contract: ${brief.returnContract}`,
584224
584304
  `Retrieval focus: ${brief.retrievalQuery}`,
584305
+ brief.discoveryContract ? `Discovery contract: ${JSON.stringify(brief.discoveryContract)}` : "",
584306
+ `Search-loop contract: resolve required facts from the supplied windows; if unresolved, return NEW narrow search terms. Never request or summarize the whole file.`,
584225
584307
  ``,
584226
584308
  `File excerpts:`,
584227
584309
  blocks,
@@ -584231,8 +584313,10 @@ ${w.text}`).join("\n\n");
584231
584313
  ` "source_start":<1-based line where the answer is, or null>,`,
584232
584314
  ` "source_end":<1-based end line, or null>,`,
584233
584315
  ` "confidence":0.0-1.0, // how sure the excerpts actually contain the answer`,
584316
+ ` "satisfied_requirement_ids":["R1"],`,
584317
+ ` "refined_search_terms":["new exact symbol or phrase"],`,
584234
584318
  ` "found":true|false}`
584235
- ].join("\n");
584319
+ ].filter(Boolean).join("\n");
584236
584320
  }
584237
584321
  function parseExtraction(raw) {
584238
584322
  if (!raw)
@@ -584256,127 +584340,442 @@ function parseExtraction(raw) {
584256
584340
  sourceStart: num3(o2["source_start"]),
584257
584341
  sourceEnd: num3(o2["source_end"]),
584258
584342
  confidence: Math.min(1, Math.max(0, conf)),
584259
- found: o2["found"] !== false
584343
+ found: o2["found"] !== false,
584344
+ satisfiedRequirementIds: Array.isArray(o2["satisfied_requirement_ids"]) ? o2["satisfied_requirement_ids"].map((value2) => cleanBriefText(value2, 40)).filter(Boolean).slice(0, 8) : [],
584345
+ refinedSearchTerms: Array.isArray(o2["refined_search_terms"]) ? o2["refined_search_terms"].map((value2) => cleanBriefText(value2, 80)).filter(Boolean).slice(0, 8) : []
584346
+ };
584347
+ }
584348
+ function sha2564(text2) {
584349
+ return createHash33("sha256").update(text2).digest("hex");
584350
+ }
584351
+ function lineNumberedExcerpt(lines, startIndex, endIndex, sourceLineOffset, maxLineChars = 240) {
584352
+ return lines.slice(startIndex, endIndex + 1).map((line, index) => {
584353
+ const clipped = line.length > maxLineChars ? `${line.slice(0, maxLineChars)}…` : line;
584354
+ return `${sourceLineOffset + startIndex + index + 1}: ${clipped}`;
584355
+ }).join("\n");
584356
+ }
584357
+ function rangesOverlap(a2, b) {
584358
+ return a2.startLine <= b.endLine + 1 && b.startLine <= a2.endLine + 1;
584359
+ }
584360
+ function makeSegment(input) {
584361
+ const segmentHash = sha2564(input.excerpt);
584362
+ return {
584363
+ id: `E${input.index + 1}-${segmentHash.slice(0, 10)}`,
584364
+ requirementIds: [...new Set(input.requirementIds)],
584365
+ summary: cleanBriefText(input.summary, 280),
584366
+ excerpt: input.excerpt,
584367
+ confidence: Math.min(1, Math.max(0, input.confidence)),
584368
+ anchor: {
584369
+ path: input.path,
584370
+ startLine: input.startLine,
584371
+ endLine: input.endLine,
584372
+ contentHash: input.contentHash,
584373
+ segmentHash
584374
+ }
584375
+ };
584376
+ }
584377
+ function renderSegments(segments, maxChars) {
584378
+ const blocks = [];
584379
+ let used = 0;
584380
+ for (const segment of segments) {
584381
+ const block = [
584382
+ `[${segment.id} ${segment.anchor.path}:L${segment.anchor.startLine}-L${segment.anchor.endLine} requirements=${segment.requirementIds.join(",") || "supporting"}]`,
584383
+ segment.excerpt
584384
+ ].join("\n");
584385
+ if (used + block.length > maxChars && blocks.length > 0)
584386
+ break;
584387
+ const clipped = block.slice(0, Math.max(0, maxChars - used));
584388
+ blocks.push(clipped);
584389
+ used += clipped.length + 1;
584390
+ }
584391
+ return blocks.join("\n");
584392
+ }
584393
+ function legacyContiguousSpan(segments) {
584394
+ if (segments.length === 0)
584395
+ return { start: null, end: null };
584396
+ const sorted = [...segments].sort((a2, b) => a2.anchor.startLine - b.anchor.startLine);
584397
+ for (let index = 1; index < sorted.length; index++) {
584398
+ if (sorted[index].anchor.startLine > sorted[index - 1].anchor.endLine + 1) {
584399
+ return { start: null, end: null };
584400
+ }
584401
+ }
584402
+ return {
584403
+ start: sorted[0].anchor.startLine,
584404
+ end: sorted.at(-1).anchor.endLine
584260
584405
  };
584261
584406
  }
584407
+ function requirementSearchPasses(brief) {
584408
+ const requirements = brief.discoveryContract?.requirements ?? [];
584409
+ const passes = requirements.map((requirement) => ({
584410
+ id: requirement.id,
584411
+ query: requirement.question,
584412
+ strategy: "literal"
584413
+ }));
584414
+ if (passes.length === 0 && brief.retrievalQuery) {
584415
+ passes.push({ id: "R1", query: brief.retrievalQuery, strategy: "literal" });
584416
+ }
584417
+ return passes.slice(0, brief.discoveryContract?.budget.maxRounds ?? 3);
584418
+ }
584419
+ function deterministicSegments(input) {
584420
+ const { lines, path: path16, contentHash: contentHash2, sourceLineOffset, brief } = input;
584421
+ const segments = [];
584422
+ const satisfied = /* @__PURE__ */ new Set();
584423
+ const rounds = [];
584424
+ const lowers = lines.map((line) => line.toLowerCase());
584425
+ const lineCount = Math.max(1, lines.length);
584426
+ const passes = requirementSearchPasses(brief);
584427
+ let totalMatches = 0;
584428
+ for (const pass of passes) {
584429
+ const terms2 = queryTerms(pass.query);
584430
+ const weights = /* @__PURE__ */ new Map();
584431
+ for (const term of terms2) {
584432
+ let documentFrequency = 0;
584433
+ for (const line of lowers)
584434
+ if (line.includes(term))
584435
+ documentFrequency++;
584436
+ weights.set(term, documentFrequency === 0 ? 0 : Math.log(lineCount / documentFrequency) + 0.1);
584437
+ }
584438
+ const hits = [];
584439
+ for (let index = 0; index < lines.length; index++) {
584440
+ const matched = terms2.filter((term) => lowers[index].includes(term));
584441
+ const score = matched.reduce((sum2, term) => sum2 + (weights.get(term) ?? 0), 0);
584442
+ if (score > 0)
584443
+ hits.push({ index, score, matched });
584444
+ }
584445
+ totalMatches += hits.length;
584446
+ const ranked = hits.sort((a2, b) => b.score - a2.score).slice(0, 4);
584447
+ for (const hit of ranked) {
584448
+ if (segments.length >= input.maxSegments)
584449
+ break;
584450
+ const startIndex = Math.max(0, hit.index - 2);
584451
+ const endIndex = Math.min(lines.length - 1, hit.index + 2);
584452
+ const absolute = {
584453
+ startLine: sourceLineOffset + startIndex + 1,
584454
+ endLine: sourceLineOffset + endIndex + 1
584455
+ };
584456
+ if (segments.some((segment) => rangesOverlap(segment.anchor, absolute))) {
584457
+ continue;
584458
+ }
584459
+ const discriminatingTerms = terms2.filter((term) => (weights.get(term) ?? 0) > 0);
584460
+ const coverage = discriminatingTerms.length > 0 ? hit.matched.length / discriminatingTerms.length : 0;
584461
+ const confidence2 = Math.min(1, Math.max(0.2, coverage));
584462
+ if (confidence2 < EXTRACT_CONFIDENCE_FLOOR)
584463
+ continue;
584464
+ const excerpt = lineNumberedExcerpt(lines, startIndex, endIndex, sourceLineOffset);
584465
+ segments.push(makeSegment({
584466
+ path: path16,
584467
+ contentHash: contentHash2,
584468
+ requirementIds: [pass.id],
584469
+ summary: `Literal/identifier evidence for ${pass.query}`,
584470
+ excerpt,
584471
+ startLine: absolute.startLine,
584472
+ endLine: absolute.endLine,
584473
+ confidence: confidence2,
584474
+ index: segments.length
584475
+ }));
584476
+ satisfied.add(pass.id);
584477
+ }
584478
+ }
584479
+ rounds.push({
584480
+ round: 1,
584481
+ strategy: "literal",
584482
+ query: cleanBriefText(passes.map((pass) => pass.query).join(" | "), 180),
584483
+ matches: totalMatches
584484
+ });
584485
+ return { segments, satisfied: [...satisfied], rounds };
584486
+ }
584262
584487
  async function extractEvidence(opts) {
584263
584488
  const { path: path16, content, fileVersion, backend } = opts;
584489
+ const sourceLineOffset = Math.max(0, Math.floor(opts.sourceLineOffset ?? 0));
584264
584490
  const brief = opts.brief ?? buildBranchExtractionBrief({
584265
584491
  path: path16,
584266
584492
  lineCount: content.split("\n").length,
584267
- byteCount: content.length,
584493
+ byteCount: Buffer.byteLength(content, "utf8"),
584268
584494
  assistantIntent: opts.query
584269
584495
  });
584270
584496
  const query = brief.retrievalQuery || opts.query;
584271
584497
  const lines = content.split("\n");
584272
- const terms2 = queryTerms(query);
584273
- if (terms2.length > 0) {
584274
- const lowers = lines.map((l2) => l2.toLowerCase());
584275
- const N = Math.max(1, lines.length);
584276
- const weight = /* @__PURE__ */ new Map();
584277
- for (const t2 of terms2) {
584278
- let df = 0;
584279
- for (const l2 of lowers)
584280
- if (l2.includes(t2))
584281
- df++;
584282
- weight.set(t2, df === 0 ? 0 : Math.log(N / df) + 0.1);
584498
+ const contentHash2 = opts.contentHash || sha2564(content);
584499
+ const byteCount = Buffer.byteLength(content, "utf8");
584500
+ const requirements = brief.discoveryContract?.requirements ?? [
584501
+ {
584502
+ id: "R1",
584503
+ question: query,
584504
+ required: true,
584505
+ expectedEvidence: "Anchored source evidence",
584506
+ searchTerms: queryTerms(query)
584283
584507
  }
584284
- const hits = [];
584285
- for (let i2 = 0; i2 < lines.length; i2++) {
584286
- const lower = lowers[i2];
584287
- let score = 0;
584288
- for (const t2 of terms2)
584289
- if (lower.includes(t2))
584290
- score += weight.get(t2) ?? 0;
584291
- if (score > 0)
584292
- hits.push({ idx: i2, score });
584293
- }
584294
- if (hits.length > 0) {
584295
- const CHAR_BUDGET = 900;
584296
- const ranked = [...hits].sort((a2, b) => b.score - a2.score).slice(0, 8);
584297
- const MAX_LINE = 200;
584298
- const snippets = ranked.map((h) => {
584299
- const lo = Math.max(0, h.idx - 2);
584300
- const hi = Math.min(lines.length - 1, h.idx + 2);
584301
- const text2 = lines.slice(lo, hi + 1).map((l2, k) => {
584302
- const v = l2.length > MAX_LINE ? l2.slice(0, MAX_LINE) + "…" : l2;
584303
- return `${lo + k + 1}: ${v}`;
584304
- }).join("\n");
584305
- return { score: h.score, start: lo + 1, end: hi + 1, text: text2 };
584306
- });
584307
- const kept = [];
584308
- let used = 0;
584309
- for (const s2 of snippets) {
584310
- if (used + s2.text.length + 1 > CHAR_BUDGET && kept.length > 0)
584508
+ ];
584509
+ const maxSegments = Math.max(1, Math.min(brief.discoveryContract?.budget.maxTotalWindows ?? MAX_WINDOWS, MAX_WINDOWS));
584510
+ const maxInjectedChars = Math.max(600, Math.min(brief.discoveryContract?.budget.maxInjectedChars ?? 2400, 4e3));
584511
+ const deterministic = deterministicSegments({
584512
+ lines,
584513
+ path: path16,
584514
+ contentHash: contentHash2,
584515
+ sourceLineOffset,
584516
+ brief,
584517
+ maxSegments
584518
+ });
584519
+ const requiredIds = requirements.filter((requirement) => requirement.required).map((requirement) => requirement.id);
584520
+ const deterministicSatisfied = new Set(deterministic.satisfied);
584521
+ if (deterministic.segments.length > 0 && requiredIds.every((id2) => deterministicSatisfied.has(id2))) {
584522
+ const claim = renderSegments(deterministic.segments, maxInjectedChars);
584523
+ const legacySpan = legacyContiguousSpan(deterministic.segments);
584524
+ return {
584525
+ path: path16,
584526
+ query,
584527
+ claim,
584528
+ sourceStart: legacySpan.start,
584529
+ sourceEnd: legacySpan.end,
584530
+ fileVersion,
584531
+ confidence: Math.max(...deterministic.segments.map((segment) => segment.confidence)),
584532
+ exploredLines: lines.length,
584533
+ injectedChars: claim.length,
584534
+ segments: deterministic.segments,
584535
+ satisfiedRequirementIds: [...deterministicSatisfied],
584536
+ unresolvedRequirementIds: requirements.map((requirement) => requirement.id).filter((id2) => !deterministicSatisfied.has(id2)),
584537
+ provenance: {
584538
+ contentHash: contentHash2,
584539
+ byteCount,
584540
+ lineCount: lines.length,
584541
+ fileVersion,
584542
+ exploredRanges: deterministic.segments.map((segment) => ({
584543
+ startLine: segment.anchor.startLine,
584544
+ endLine: segment.anchor.endLine
584545
+ })),
584546
+ searchRounds: deterministic.rounds,
584547
+ truncated: deterministic.segments.length >= maxSegments
584548
+ }
584549
+ };
584550
+ }
584551
+ const seenQueries = /* @__PURE__ */ new Set();
584552
+ let activeQuery = query;
584553
+ let parsed = null;
584554
+ let parsedWindows = [];
584555
+ const searchRounds = [...deterministic.rounds];
584556
+ let remainingWindows = Math.min(MAX_WINDOWS, brief.discoveryContract?.budget.maxTotalWindows ?? MAX_WINDOWS);
584557
+ let remainingPresentedLines = Math.min(MAX_SNIPPET_LINES, brief.discoveryContract?.budget.maxPresentedLines ?? MAX_SNIPPET_LINES);
584558
+ if (backend) {
584559
+ const maxSemanticRounds = Math.max(0, (brief.discoveryContract?.budget.maxRounds ?? 3) - searchRounds.length);
584560
+ for (let attempt = 0; attempt < Math.min(2, maxSemanticRounds); attempt++) {
584561
+ const queryKey = cleanBriefText(activeQuery, 700).toLowerCase();
584562
+ if (!queryKey || seenQueries.has(queryKey))
584563
+ break;
584564
+ seenQueries.add(queryKey);
584565
+ const activeTerms = queryTerms(activeQuery);
584566
+ const perRound = Math.min(remainingWindows, brief.discoveryContract?.budget.maxWindowsPerRound ?? 3);
584567
+ const selectedWindows = [];
584568
+ for (const window2 of selectWindows(lines, activeTerms)) {
584569
+ if (selectedWindows.length >= perRound)
584570
+ break;
584571
+ const windowLines = window2.end - window2.start + 1;
584572
+ if (windowLines > remainingPresentedLines)
584311
584573
  continue;
584312
- kept.push(s2);
584313
- used += s2.text.length + 1;
584314
- }
584315
- kept.sort((a2, b) => a2.start - b.start);
584316
- const claim2 = kept.map((s2) => s2.text).join("\n …\n");
584317
- const starts = kept.map((s2) => s2.start);
584318
- const ends = kept.map((s2) => s2.end);
584319
- const snippetLower = claim2.toLowerCase();
584320
- const covered = terms2.filter((t2) => snippetLower.includes(t2)).length;
584321
- const grepConfidence = Math.min(1, covered / Math.max(1, terms2.length));
584322
- if (grepConfidence >= EXTRACT_CONFIDENCE_FLOOR) {
584323
- return {
584324
- path: path16,
584325
- query,
584326
- claim: claim2,
584327
- sourceStart: starts.length ? Math.min(...starts) : null,
584328
- sourceEnd: ends.length ? Math.max(...ends) : null,
584329
- fileVersion,
584330
- confidence: grepConfidence,
584331
- exploredLines: lines.length,
584332
- injectedChars: claim2.length
584333
- };
584574
+ selectedWindows.push(window2);
584575
+ remainingPresentedLines -= windowLines;
584576
+ }
584577
+ remainingWindows -= selectedWindows.length;
584578
+ const relativeWindows = selectedWindows.map((window2) => ({
584579
+ start: window2.start + sourceLineOffset,
584580
+ end: window2.end + sourceLineOffset,
584581
+ text: window2.text
584582
+ }));
584583
+ if (relativeWindows.length === 0)
584584
+ break;
584585
+ parsedWindows = relativeWindows;
584586
+ searchRounds.push({
584587
+ round: searchRounds.length + 1,
584588
+ strategy: attempt === 0 ? "semantic" : "refined",
584589
+ query: cleanBriefText(activeQuery, 180),
584590
+ matches: relativeWindows.length
584591
+ });
584592
+ try {
584593
+ const resp = await backend.chatCompletion({
584594
+ messages: [
584595
+ {
584596
+ role: "system",
584597
+ content: "You extract precise facts from bounded file excerpts. Output ONLY a JSON object and never invent source text or line spans."
584598
+ },
584599
+ { role: "user", content: extractionPrompt(brief, path16, relativeWindows) }
584600
+ ],
584601
+ tools: [],
584602
+ temperature: 0,
584603
+ maxTokens: 900,
584604
+ timeoutMs: opts.timeoutMs ?? 3e4
584605
+ });
584606
+ parsed = parseExtraction(resp.choices?.[0]?.message?.content ?? "");
584607
+ } catch {
584608
+ parsed = null;
584334
584609
  }
584610
+ if (parsed?.found)
584611
+ break;
584612
+ const refined = uniqueBriefLines(parsed?.refinedSearchTerms ?? []).join(" ");
584613
+ if (!refined || seenQueries.has(refined.toLowerCase()))
584614
+ break;
584615
+ activeQuery = refined;
584335
584616
  }
584336
584617
  }
584337
- const windows = lines.length <= WINDOW_LINES * 2 ? [{ start: 1, end: lines.length, text: content, score: 1 }] : selectWindows(lines, terms2);
584338
- const exploredLines = windows.reduce((n2, w) => n2 + (w.end - w.start + 1), 0);
584339
- let parsed = null;
584340
- for (let attempt = 0; attempt < 2 && !parsed; attempt++) {
584341
- try {
584342
- const resp = await backend.chatCompletion({
584343
- messages: [
584344
- { role: "system", content: "You extract precise facts from file excerpts. Output ONLY a JSON object." },
584345
- { role: "user", content: extractionPrompt(brief, path16, windows) }
584346
- ],
584347
- tools: [],
584348
- temperature: 0,
584349
- maxTokens: 900,
584350
- timeoutMs: opts.timeoutMs ?? 3e4
584618
+ let semanticSegment = null;
584619
+ if (parsed?.found && parsed.claim && Number.isInteger(parsed.sourceStart) && Number.isInteger(parsed.sourceEnd) && parsed.sourceStart <= parsed.sourceEnd && parsedWindows.some((window2) => parsed.sourceStart >= window2.start && parsed.sourceEnd <= window2.end)) {
584620
+ const startIndex = parsed.sourceStart - sourceLineOffset - 1;
584621
+ const endIndex = parsed.sourceEnd - sourceLineOffset - 1;
584622
+ if (startIndex >= 0 && endIndex < lines.length) {
584623
+ semanticSegment = makeSegment({
584624
+ path: path16,
584625
+ contentHash: contentHash2,
584626
+ requirementIds: parsed.satisfiedRequirementIds.length > 0 ? parsed.satisfiedRequirementIds : [requirements[0].id],
584627
+ summary: parsed.claim,
584628
+ excerpt: lineNumberedExcerpt(lines, startIndex, endIndex, sourceLineOffset),
584629
+ startLine: parsed.sourceStart,
584630
+ endLine: parsed.sourceEnd,
584631
+ confidence: parsed.confidence,
584632
+ index: deterministic.segments.length
584351
584633
  });
584352
- parsed = parseExtraction(resp.choices?.[0]?.message?.content ?? "");
584353
- } catch {
584354
- parsed = null;
584355
584634
  }
584356
584635
  }
584357
- const claim = parsed && parsed.found && parsed.claim ? parsed.claim : buildStructuralPreview2(lines, path16, query);
584636
+ const segments = [...deterministic.segments];
584637
+ if (semanticSegment && !segments.some((segment) => rangesOverlap(segment.anchor, semanticSegment.anchor))) {
584638
+ segments.push(semanticSegment);
584639
+ }
584640
+ const satisfied = new Set(deterministic.satisfied);
584641
+ for (const segment of segments) {
584642
+ for (const id2 of segment.requirementIds)
584643
+ satisfied.add(id2);
584644
+ }
584645
+ if (segments.length > 0) {
584646
+ const claim = renderSegments(segments, maxInjectedChars);
584647
+ const legacySpan = legacyContiguousSpan(segments);
584648
+ return {
584649
+ path: path16,
584650
+ query,
584651
+ claim,
584652
+ sourceStart: legacySpan.start,
584653
+ sourceEnd: legacySpan.end,
584654
+ fileVersion,
584655
+ confidence: Math.max(...segments.map((segment) => segment.confidence)),
584656
+ exploredLines: Math.min(lines.length, parsedWindows.reduce((sum2, window2) => sum2 + (window2.end - window2.start + 1), 0) || lines.length),
584657
+ injectedChars: claim.length,
584658
+ segments,
584659
+ satisfiedRequirementIds: [...satisfied],
584660
+ unresolvedRequirementIds: requirements.map((requirement) => requirement.id).filter((id2) => !satisfied.has(id2)),
584661
+ provenance: {
584662
+ contentHash: contentHash2,
584663
+ byteCount,
584664
+ lineCount: lines.length,
584665
+ fileVersion,
584666
+ exploredRanges: segments.map((segment) => ({
584667
+ startLine: segment.anchor.startLine,
584668
+ endLine: segment.anchor.endLine
584669
+ })),
584670
+ searchRounds,
584671
+ truncated: segments.length >= maxSegments
584672
+ }
584673
+ };
584674
+ }
584675
+ const structuralClaim = buildStructuralPreview2(lines, path16, query, sourceLineOffset);
584676
+ const headEndIndex = Math.max(0, Math.min(lines.length - 1, HEAD_LINES2 - 1));
584677
+ const structuralSegment = makeSegment({
584678
+ path: path16,
584679
+ contentHash: contentHash2,
584680
+ requirementIds: [],
584681
+ summary: "Structural navigation anchor; required facts remain unresolved.",
584682
+ excerpt: lineNumberedExcerpt(lines, 0, headEndIndex, sourceLineOffset),
584683
+ startLine: sourceLineOffset + 1,
584684
+ endLine: sourceLineOffset + headEndIndex + 1,
584685
+ confidence: 0.2,
584686
+ index: 0
584687
+ });
584688
+ const maxRounds = brief.discoveryContract?.budget.maxRounds ?? 3;
584689
+ if (searchRounds.length < maxRounds) {
584690
+ searchRounds.push({
584691
+ round: searchRounds.length + 1,
584692
+ strategy: "structural",
584693
+ query: cleanBriefText(query, 180),
584694
+ matches: 1
584695
+ });
584696
+ }
584358
584697
  return {
584359
584698
  path: path16,
584360
584699
  query,
584361
- claim,
584362
- sourceStart: parsed?.sourceStart ?? null,
584363
- sourceEnd: parsed?.sourceEnd ?? null,
584700
+ claim: structuralClaim.slice(0, maxInjectedChars),
584701
+ sourceStart: structuralSegment.anchor.startLine,
584702
+ sourceEnd: structuralSegment.anchor.endLine,
584364
584703
  fileVersion,
584365
- confidence: parsed?.found ? parsed.confidence : 0.2,
584366
- exploredLines,
584367
- injectedChars: claim.length
584704
+ confidence: 0.2,
584705
+ exploredLines: Math.min(lines.length, HEAD_LINES2),
584706
+ injectedChars: Math.min(structuralClaim.length, maxInjectedChars),
584707
+ segments: [structuralSegment],
584708
+ satisfiedRequirementIds: [],
584709
+ unresolvedRequirementIds: requirements.map((requirement) => requirement.id),
584710
+ provenance: {
584711
+ contentHash: contentHash2,
584712
+ byteCount,
584713
+ lineCount: lines.length,
584714
+ fileVersion,
584715
+ exploredRanges: [
584716
+ {
584717
+ startLine: structuralSegment.anchor.startLine,
584718
+ endLine: structuralSegment.anchor.endLine
584719
+ }
584720
+ ],
584721
+ searchRounds,
584722
+ truncated: true
584723
+ }
584368
584724
  };
584369
584725
  }
584370
- function shouldBranchRead(contentLength, lineCount, hasExplicitSmallRange, thresholdChars = 8e3) {
584371
- if (hasExplicitSmallRange)
584372
- return false;
584726
+ function shouldBranchRead(contentLength, lineCount, _hasExplicitSmallRange, thresholdChars = 8e3) {
584373
584727
  return contentLength > thresholdChars || lineCount > 200;
584374
584728
  }
584375
- var WINDOW_LINES, SNIPPET_CONTEXT, HEAD_LINES2, MAX_SNIPPET_LINES, EXTRACT_CONFIDENCE_FLOOR, STOPWORDS2;
584729
+ function estimateFileReadInjectionTokens(sourceBytes, sourceLines) {
584730
+ const bytes = Math.max(0, Math.floor(sourceBytes));
584731
+ const lines = Math.max(0, Math.floor(sourceLines));
584732
+ return Math.ceil((bytes + lines * 10 + 512) / 4);
584733
+ }
584734
+ function assessBranchRead(input) {
584735
+ const projectedReadTokens = Math.max(0, Math.ceil(input.projectedReadTokens ?? estimateFileReadInjectionTokens(input.sourceBytes, input.sourceLines)));
584736
+ const contextWindowTokens = Math.max(0, Math.floor(input.contextWindowTokens));
584737
+ if (contextWindowTokens <= 0) {
584738
+ const legacy = shouldBranchRead(input.sourceBytes, input.sourceLines, false);
584739
+ return {
584740
+ branch: legacy,
584741
+ reasons: legacy ? ["legacy_size"] : [],
584742
+ projectedReadTokens,
584743
+ fractionLimitTokens: 0,
584744
+ availableHeadroomTokens: Number.POSITIVE_INFINITY,
584745
+ projectedFraction: 0,
584746
+ ...input.requestedRange ? { requestedRange: input.requestedRange } : {}
584747
+ };
584748
+ }
584749
+ const fraction = Math.min(0.9, Math.max(0.01, input.maxInlineFraction ?? DEFAULT_BRANCH_READ_CONTEXT_FRACTION));
584750
+ const fractionLimitTokens = Math.floor(contextWindowTokens * fraction);
584751
+ const resident = Math.max(0, Math.ceil(input.residentContextTokens ?? 0));
584752
+ const reserved = Math.max(0, Math.ceil(input.reservedTokens ?? 0));
584753
+ const pending2 = Math.max(0, Math.ceil(input.pendingInlineReadTokens ?? 0));
584754
+ const safeCeiling = Math.max(0, Math.min(contextWindowTokens, Math.floor(input.safeContextTokens ?? contextWindowTokens)));
584755
+ const availableHeadroomTokens = Math.max(0, safeCeiling - resident - reserved - pending2);
584756
+ const reasons = [];
584757
+ if (projectedReadTokens > fractionLimitTokens)
584758
+ reasons.push("read_fraction");
584759
+ if (projectedReadTokens > availableHeadroomTokens)
584760
+ reasons.push("headroom");
584761
+ if (pending2 > 0 && pending2 + projectedReadTokens > fractionLimitTokens) {
584762
+ reasons.push("batch_budget");
584763
+ }
584764
+ return {
584765
+ branch: reasons.length > 0,
584766
+ reasons: [...new Set(reasons)],
584767
+ projectedReadTokens,
584768
+ fractionLimitTokens,
584769
+ availableHeadroomTokens,
584770
+ projectedFraction: projectedReadTokens / contextWindowTokens,
584771
+ ...input.requestedRange ? { requestedRange: input.requestedRange } : {}
584772
+ };
584773
+ }
584774
+ var MAX_WINDOWS, SNIPPET_CONTEXT, HEAD_LINES2, MAX_SNIPPET_LINES, EXTRACT_CONFIDENCE_FLOOR, STOPWORDS2, DEFAULT_BRANCH_READ_CONTEXT_FRACTION;
584376
584775
  var init_evidenceBranch = __esm({
584377
584776
  "packages/orchestrator/dist/evidenceBranch.js"() {
584378
584777
  "use strict";
584379
- WINDOW_LINES = 40;
584778
+ MAX_WINDOWS = 6;
584380
584779
  SNIPPET_CONTEXT = 4;
584381
584780
  HEAD_LINES2 = 10;
584382
584781
  MAX_SNIPPET_LINES = 220;
@@ -584414,6 +584813,7 @@ var init_evidenceBranch = __esm({
584414
584813
  "report",
584415
584814
  "tell"
584416
584815
  ]);
584816
+ DEFAULT_BRANCH_READ_CONTEXT_FRACTION = 0.2;
584417
584817
  }
584418
584818
  });
584419
584819
 
@@ -584836,7 +585236,7 @@ var init_prompt_cache = __esm({
584836
585236
 
584837
585237
  // packages/orchestrator/dist/git-progress.js
584838
585238
  import { existsSync as existsSync104, readFileSync as readFileSync80, statSync as statSync41 } from "node:fs";
584839
- import { createHash as createHash33 } from "node:crypto";
585239
+ import { createHash as createHash34 } from "node:crypto";
584840
585240
  import { relative as relative13, resolve as resolve56, sep as sep4 } from "node:path";
584841
585241
  function isRunnerOwnedGitPath(path16) {
584842
585242
  const normalized = normalizeGitPath(path16);
@@ -584863,7 +585263,7 @@ function pathHash(repoRoot, relPath) {
584863
585263
  const st = statSync41(absolute);
584864
585264
  if (!st.isFile())
584865
585265
  return `non-file:${st.size}:${Math.floor(st.mtimeMs)}`;
584866
- return createHash33("sha256").update(readFileSync80(absolute)).digest("hex");
585266
+ return createHash34("sha256").update(readFileSync80(absolute)).digest("hex");
584867
585267
  } catch {
584868
585268
  return void 0;
584869
585269
  }
@@ -585763,7 +586163,7 @@ __export(preflightSnapshot_exports, {
585763
586163
  import { existsSync as existsSync105, readFileSync as readFileSync81, statSync as statSync42, statfsSync as statfsSync6 } from "node:fs";
585764
586164
  import { homedir as homedir36, platform as platform4, arch as arch2, totalmem as totalmem4, freemem as freemem3, hostname as hostname3 } from "node:os";
585765
586165
  import { join as join113 } from "node:path";
585766
- import { createHash as createHash34 } from "node:crypto";
586166
+ import { createHash as createHash35 } from "node:crypto";
585767
586167
  function capturePreflightSnapshot(workingDir) {
585768
586168
  const warnings = [];
585769
586169
  const configFingerprints = {};
@@ -585777,7 +586177,7 @@ function capturePreflightSnapshot(workingDir) {
585777
586177
  } catch {
585778
586178
  continue;
585779
586179
  }
585780
- configFingerprints[det.path] = sha2564(raw);
586180
+ configFingerprints[det.path] = sha2565(raw);
585781
586181
  for (const w of det.check(raw)) {
585782
586182
  warnings.push({ ...w, source: expanded });
585783
586183
  }
@@ -585795,7 +586195,7 @@ function capturePreflightSnapshot(workingDir) {
585795
586195
  } catch {
585796
586196
  continue;
585797
586197
  }
585798
- configFingerprints[`<cwd>/${localName}`] = sha2564(raw);
586198
+ configFingerprints[`<cwd>/${localName}`] = sha2565(raw);
585799
586199
  for (const w of det.check(raw)) {
585800
586200
  warnings.push({ ...w, source: projectPath });
585801
586201
  }
@@ -585931,8 +586331,8 @@ function expandPath(p2) {
585931
586331
  return join113(homedir36(), p2.slice(2));
585932
586332
  return p2;
585933
586333
  }
585934
- function sha2564(s2) {
585935
- return createHash34("sha256").update(s2).digest("hex").slice(0, 16);
586334
+ function sha2565(s2) {
586335
+ return createHash35("sha256").update(s2).digest("hex").slice(0, 16);
585936
586336
  }
585937
586337
  function freeDiskBytes(path16 = "/tmp") {
585938
586338
  try {
@@ -588246,6 +588646,13 @@ var init_agenticRunner = __esm({
588246
588646
  // sees the evidence it already has instead of re-deriving it. See
588247
588647
  // evidenceLedger.ts.
588248
588648
  _evidenceLedger = new EvidenceLedger();
588649
+ /**
588650
+ * Curated branch nodes keyed by source hash + discovery contract. Raw source
588651
+ * is deliberately absent so retries/compaction cannot rehydrate it.
588652
+ */
588653
+ _branchEvidenceCache = /* @__PURE__ */ new Map();
588654
+ /** Latest curated node per canonical path for safe post-compaction recovery. */
588655
+ _branchEvidenceByPath = /* @__PURE__ */ new Map();
588249
588656
  // OBS-1: durable "current observed state" for non-file_read tool outputs
588250
588657
  // (shell/web_fetch/list_directory/…). EvidenceLedger's counterpart for the
588251
588658
  // observation channels that were previously invisible after compaction —
@@ -596099,7 +596506,31 @@ Rewrite it now for ${ctx3.model}.`;
596099
596506
  };
596100
596507
  }
596101
596508
  try {
596102
- const result = await tool.execute(args);
596509
+ const callId = `runTool:${resolved.name}:${Date.now()}:${Math.random()}`;
596510
+ const batchBudget = {
596511
+ inlineTokens: 0,
596512
+ reservations: /* @__PURE__ */ new Map()
596513
+ };
596514
+ const preempted = await this._preemptFileReadWithBranch({
596515
+ callId,
596516
+ toolName: resolved.name,
596517
+ args,
596518
+ messages: [],
596519
+ turn: this._taskState.toolCallCount,
596520
+ batchBudget
596521
+ });
596522
+ if (preempted)
596523
+ return preempted;
596524
+ let result = await tool.execute(args);
596525
+ result = await this._guardMaterializedFileReadResult({
596526
+ callId,
596527
+ toolName: resolved.name,
596528
+ args,
596529
+ result,
596530
+ messages: [],
596531
+ turn: this._taskState.toolCallCount,
596532
+ batchBudget
596533
+ });
596103
596534
  return this.applyRegisteredToolResultTriage(result, resolved.name, tool);
596104
596535
  } catch (e2) {
596105
596536
  return { success: false, output: "", error: e2?.message || String(e2) };
@@ -596324,8 +596755,309 @@ ${notice}`;
596324
596755
  trajectoryNextAction: trajectory?.nextAction || this._taskState.nextAction,
596325
596756
  trajectoryOpenQuestion: trajectory?.openQuestions[0],
596326
596757
  currentStep: this._taskState.currentStep,
596327
- recentFailure
596758
+ recentFailure,
596759
+ goalAnchor: trajectory?.currentStep || this._taskState.currentStep || this._taskState.nextAction,
596760
+ requestedRange: input.requestedRange,
596761
+ projectedReadTokens: input.routingDecision?.projectedReadTokens,
596762
+ contextWindowTokens: this._branchRoutingContextWindow(),
596763
+ routingReason: input.routingDecision?.reasons.join(", ")
596764
+ });
596765
+ }
596766
+ /** The usable total window for mandatory read routing. */
596767
+ _branchRoutingContextWindow() {
596768
+ const declared = Math.max(0, this.options.contextWindowSize ?? 0);
596769
+ const effective = Math.max(0, this.effectiveContextWindow());
596770
+ if (declared > 0 && effective > 0)
596771
+ return Math.min(declared, effective);
596772
+ return declared || effective;
596773
+ }
596774
+ _branchReadReservedTokens(contextWindow) {
596775
+ if (contextWindow <= 0)
596776
+ return 0;
596777
+ const generation = Math.min(this.contextLimits().maxOutputTokens, Math.max(1024, Math.floor(contextWindow * 0.15)));
596778
+ return generation + Math.max(512, Math.floor(contextWindow * 0.05));
596779
+ }
596780
+ _branchReadPath(args) {
596781
+ for (const key of ["path", "file", "file_path", "filename", "filepath"]) {
596782
+ const value2 = args[key];
596783
+ if (typeof value2 === "string" && value2.trim())
596784
+ return value2.trim();
596785
+ }
596786
+ return "";
596787
+ }
596788
+ /** Content identity used to prove an exact local read is still unchanged. */
596789
+ _fileReadDiskIdentity(args) {
596790
+ const path16 = this._branchReadPath(args);
596791
+ if (!path16)
596792
+ return null;
596793
+ try {
596794
+ const absolutePath = this._absoluteToolPath(path16);
596795
+ const stat9 = _fsStatSync(absolutePath);
596796
+ if (!stat9.isFile())
596797
+ return null;
596798
+ const content = _fsReadFileSync(absolutePath, "utf8");
596799
+ return {
596800
+ path: path16,
596801
+ canonicalPath: this._normalizeEvidencePath(path16),
596802
+ contentHash: _createHash("sha256").update(content).digest("hex"),
596803
+ byteCount: stat9.size,
596804
+ mtimeMs: stat9.mtimeMs
596805
+ };
596806
+ } catch {
596807
+ return null;
596808
+ }
596809
+ }
596810
+ /**
596811
+ * Mandatory pre-dispatch router for local file reads. It resolves exactly
596812
+ * once against the authoritative run directory, computes the actual selected
596813
+ * range, and intercepts unsafe reads before registered tool code or any
596814
+ * transcript/evidence consumer can observe raw content.
596815
+ */
596816
+ async _preemptFileReadWithBranch(input) {
596817
+ if (this.lookupRegisteredTool(input.toolName)?.name !== "file_read") {
596818
+ return null;
596819
+ }
596820
+ const rawPath = this._branchReadPath(input.args);
596821
+ if (!rawPath)
596822
+ return null;
596823
+ let fullContent;
596824
+ let stat9;
596825
+ let absolutePath;
596826
+ try {
596827
+ absolutePath = this._absoluteToolPath(rawPath);
596828
+ stat9 = _fsStatSync(absolutePath);
596829
+ if (!stat9.isFile())
596830
+ return null;
596831
+ fullContent = _fsReadFileSync(absolutePath, "utf8");
596832
+ } catch {
596833
+ return null;
596834
+ }
596835
+ const allLines = fullContent.split("\n");
596836
+ const rawOffset = input.args["offset"];
596837
+ const rawLimit = input.args["limit"];
596838
+ const hasRange = typeof rawOffset === "number" || typeof rawLimit === "number";
596839
+ const offset = typeof rawOffset === "number" && Number.isFinite(rawOffset) ? Math.max(1, Math.floor(rawOffset)) : void 0;
596840
+ const limit = typeof rawLimit === "number" && Number.isFinite(rawLimit) ? Math.max(0, Math.floor(rawLimit)) : void 0;
596841
+ const startIndex = hasRange ? Math.max(0, (offset ?? 1) - 1) : 0;
596842
+ const selectedLines = hasRange ? allLines.slice(startIndex, limit === void 0 ? void 0 : startIndex + limit) : allLines;
596843
+ const selectedContent = selectedLines.join("\n");
596844
+ const selectedBytes = Buffer.byteLength(selectedContent, "utf8");
596845
+ const contextWindow = this._branchRoutingContextWindow();
596846
+ const residentTokens = estimateMessagesTokens2(input.messages);
596847
+ const reservedTokens = this._branchReadReservedTokens(contextWindow);
596848
+ const decision2 = assessBranchRead({
596849
+ sourceBytes: selectedBytes,
596850
+ sourceLines: selectedLines.length,
596851
+ contextWindowTokens: contextWindow,
596852
+ residentContextTokens: residentTokens,
596853
+ reservedTokens,
596854
+ pendingInlineReadTokens: input.batchBudget.inlineTokens,
596855
+ safeContextTokens: this.contextLimits().compactionThreshold,
596856
+ ...hasRange ? { requestedRange: { offset, limit } } : {}
596857
+ });
596858
+ if (!decision2.branch) {
596859
+ input.batchBudget.inlineTokens += decision2.projectedReadTokens;
596860
+ input.batchBudget.reservations.set(input.callId, decision2.projectedReadTokens);
596861
+ return null;
596862
+ }
596863
+ const fullHash = _createHash("sha256").update(fullContent).digest("hex");
596864
+ const branchBrief = this._buildBranchExtractionBrief({
596865
+ path: rawPath,
596866
+ lineCount: selectedLines.length,
596867
+ byteCount: selectedBytes,
596868
+ messages: input.messages,
596869
+ ...hasRange ? { requestedRange: { offset, limit } } : {},
596870
+ routingDecision: decision2
596871
+ });
596872
+ const contractFingerprint = _createHash("sha256").update(JSON.stringify(branchBrief.discoveryContract ?? branchBrief)).digest("hex").slice(0, 20);
596873
+ const canonicalPath = this._normalizeEvidencePath(rawPath);
596874
+ const cacheKey = `${canonicalPath}|${fullHash}|${offset ?? 0}:${limit ?? "EOF"}|${contractFingerprint}`;
596875
+ const cached = this._branchEvidenceCache.get(cacheKey);
596876
+ if (cached) {
596877
+ const duplicateBlocked = [
596878
+ `[BRANCH-DUPLICATE-BLOCKED] path=${rawPath} sha256=${fullHash} contract=${contractFingerprint}`,
596879
+ `The unchanged source was already branch-extracted into the current evidence ledger; the registered file_read was not executed and raw content was not re-injected.`,
596880
+ `Use the existing curated anchors. If a required discovery is unresolved, issue one narrower grep_search or a range whose projected payload stays below the 20% limit; otherwise take the next task action.`
596881
+ ].join("\n");
596882
+ this.emit({
596883
+ type: "status",
596884
+ toolName: input.toolName,
596885
+ content: `Branch-extract cache hit: ${rawPath} sha256=${fullHash.slice(0, 12)} contract=${contractFingerprint}`,
596886
+ turn: input.turn,
596887
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
596888
+ });
596889
+ return {
596890
+ success: true,
596891
+ output: duplicateBlocked,
596892
+ llmContent: duplicateBlocked,
596893
+ beforeHash: fullHash,
596894
+ runtimeAuthored: true,
596895
+ noop: true,
596896
+ completionEvidenceMetrics: {
596897
+ branchSourceBytes: cached.sourceBytes,
596898
+ branchCacheHit: true
596899
+ }
596900
+ };
596901
+ }
596902
+ const extractionBackend = process.env["OMNIUS_DISABLE_BRANCH_EXTRACT"] === "1" ? void 0 : this._auxInferenceBackend();
596903
+ const ev = await extractEvidence({
596904
+ path: rawPath,
596905
+ query: branchBrief.retrievalQuery,
596906
+ brief: branchBrief,
596907
+ content: selectedContent,
596908
+ contentHash: fullHash,
596909
+ sourceLineOffset: startIndex,
596910
+ fileVersion: this._worldFacts.files.get(rawPath)?.writeCount ?? 0,
596911
+ backend: extractionBackend,
596912
+ timeoutMs: 3e4
596328
596913
  });
596914
+ const verboseOutput = [
596915
+ `[BRANCH-EXTRACT v2] path=${rawPath}`,
596916
+ `routing=mandatory reasons=${decision2.reasons.join(",")} projected_read_tokens=${decision2.projectedReadTokens} fraction_limit_tokens=${decision2.fractionLimitTokens} available_headroom_tokens=${decision2.availableHeadroomTokens}`,
596917
+ `source=sha256:${fullHash} selected_lines=${selectedLines.length} selected_bytes=${selectedBytes}${hasRange ? ` range=${offset ?? 1}:${limit ?? "EOF"}` : " range=whole"}`,
596918
+ `[DISCOVERY CONTRACT]`,
596919
+ `Goal anchor: ${branchBrief.discoveryContract?.goalAnchor ?? this._taskState.currentStep}`,
596920
+ `Request: ${branchBrief.request}`,
596921
+ `Required discoveries:`,
596922
+ ...(branchBrief.discoveryContract?.requirements ?? []).map((requirement) => `- ${requirement.id}${requirement.required ? " [required]" : ""}: ${requirement.question}`),
596923
+ `Stop conditions: ${(branchBrief.discoveryContract?.completionCriteria ?? []).join(" | ")}`,
596924
+ `[CURATED SEGMENTS]`,
596925
+ ev.claim,
596926
+ `satisfied=${ev.satisfiedRequirementIds.join(",") || "none"}`,
596927
+ `unresolved=${ev.unresolvedRequirementIds.join(",") || "none"}`,
596928
+ `provenance=content:${ev.provenance.contentHash} searches:${ev.provenance.searchRounds.length} ranges:${ev.provenance.exploredRanges.map((range) => `L${range.startLine}-L${range.endLine}`).join(",")}`,
596929
+ `Contract: use these anchors as evidence. If a required item remains unresolved, issue one narrow grep_search or bounded file_read for that item; never re-read the whole file or expand a range past the 20% budget.`
596930
+ ].join("\n");
596931
+ const outputBudgetChars = Math.max(800, decision2.fractionLimitTokens * 4);
596932
+ let output = verboseOutput;
596933
+ if (verboseOutput.length > outputBudgetChars) {
596934
+ const required = (branchBrief.discoveryContract?.requirements ?? []).filter((requirement) => requirement.required).map((requirement) => `${requirement.id}:${requirement.question.slice(0, 180)}`).join(" | ");
596935
+ const prefix = [
596936
+ `[BRANCH-EXTRACT v2] path=${rawPath} sha256=${fullHash}`,
596937
+ `routing=${decision2.reasons.join(",")} projected=${decision2.projectedReadTokens}/${contextWindow}t limit=${decision2.fractionLimitTokens}t`,
596938
+ `[DISCOVERY CONTRACT] required=${required || "next narrow file-local fact"}`,
596939
+ `[CURATED SEGMENTS]`
596940
+ ].join("\n");
596941
+ const suffix = [
596942
+ `unresolved=${ev.unresolvedRequirementIds.join(",") || "none"}`,
596943
+ `anchors=${ev.provenance.exploredRanges.map((range) => `L${range.startLine}-L${range.endLine}`).join(",")}`,
596944
+ `Do not whole-read again; act on these anchors or issue one narrower search.`
596945
+ ].join("\n");
596946
+ const claimBudget = Math.max(120, outputBudgetChars - prefix.length - suffix.length - 2);
596947
+ output = `${prefix}
596948
+ ${ev.claim.slice(0, claimBudget)}
596949
+ ${suffix}`.slice(0, outputBudgetChars);
596950
+ }
596951
+ this._branchEvidenceCache.set(cacheKey, {
596952
+ output,
596953
+ path: canonicalPath,
596954
+ contentHash: fullHash,
596955
+ sourceBytes: stat9.size,
596956
+ createdAt: Date.now()
596957
+ });
596958
+ this._branchEvidenceByPath.set(canonicalPath, {
596959
+ output,
596960
+ contentHash: fullHash,
596961
+ mtimeMs: stat9.mtimeMs
596962
+ });
596963
+ this.emit({
596964
+ type: "status",
596965
+ toolName: input.toolName,
596966
+ content: `Branch-extract preempted ${rawPath}: ${decision2.projectedReadTokens}/${contextWindow} projected tokens (${(decision2.projectedFraction * 100).toFixed(1)}%); resident=${residentTokens}t reserve=${reservedTokens}t pending_reads=${input.batchBudget.inlineTokens}t; ${selectedBytes}B → ${output.length} curated chars; reasons=${decision2.reasons.join(",")}`,
596967
+ turn: input.turn,
596968
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
596969
+ });
596970
+ return {
596971
+ success: true,
596972
+ output,
596973
+ llmContent: output,
596974
+ beforeHash: fullHash,
596975
+ runtimeAuthored: true,
596976
+ mutated: false,
596977
+ mutatedFiles: [],
596978
+ completionEvidenceMetrics: {
596979
+ branchSourceBytes: stat9.size,
596980
+ branchSelectedBytes: selectedBytes,
596981
+ branchProjectedTokens: decision2.projectedReadTokens
596982
+ }
596983
+ };
596984
+ }
596985
+ /** Fail-safe for virtual/custom file_read tools that cannot be statted locally. */
596986
+ async _guardMaterializedFileReadResult(input) {
596987
+ if (this.lookupRegisteredTool(input.toolName)?.name !== "file_read") {
596988
+ return input.result;
596989
+ }
596990
+ const reservedForThisCall = input.batchBudget.reservations.get(input.callId) ?? 0;
596991
+ if (!input.result.success) {
596992
+ if (reservedForThisCall > 0) {
596993
+ input.batchBudget.inlineTokens = Math.max(0, input.batchBudget.inlineTokens - reservedForThisCall);
596994
+ input.batchBudget.reservations.delete(input.callId);
596995
+ }
596996
+ return input.result;
596997
+ }
596998
+ if (!input.result.output)
596999
+ return input.result;
597000
+ const lines = input.result.output.split("\n");
597001
+ const contextWindow = this._branchRoutingContextWindow();
597002
+ const decision2 = assessBranchRead({
597003
+ sourceBytes: Buffer.byteLength(input.result.output, "utf8"),
597004
+ sourceLines: lines.length,
597005
+ contextWindowTokens: contextWindow,
597006
+ residentContextTokens: estimateMessagesTokens2(input.messages),
597007
+ reservedTokens: this._branchReadReservedTokens(contextWindow),
597008
+ pendingInlineReadTokens: Math.max(0, input.batchBudget.inlineTokens - reservedForThisCall),
597009
+ safeContextTokens: this.contextLimits().compactionThreshold
597010
+ });
597011
+ if (!decision2.branch) {
597012
+ if (reservedForThisCall === 0) {
597013
+ input.batchBudget.inlineTokens += decision2.projectedReadTokens;
597014
+ input.batchBudget.reservations.set(input.callId, decision2.projectedReadTokens);
597015
+ }
597016
+ return input.result;
597017
+ }
597018
+ if (reservedForThisCall > 0) {
597019
+ input.batchBudget.inlineTokens = Math.max(0, input.batchBudget.inlineTokens - reservedForThisCall);
597020
+ input.batchBudget.reservations.delete(input.callId);
597021
+ }
597022
+ const path16 = this._branchReadPath(input.args) || "virtual:file_read";
597023
+ const brief = this._buildBranchExtractionBrief({
597024
+ path: path16,
597025
+ lineCount: lines.length,
597026
+ byteCount: Buffer.byteLength(input.result.output, "utf8"),
597027
+ messages: input.messages,
597028
+ routingDecision: decision2
597029
+ });
597030
+ const ev = await extractEvidence({
597031
+ path: path16,
597032
+ query: brief.retrievalQuery,
597033
+ brief,
597034
+ content: input.result.output,
597035
+ fileVersion: 0,
597036
+ backend: process.env["OMNIUS_DISABLE_BRANCH_EXTRACT"] === "1" ? void 0 : this._auxInferenceBackend(),
597037
+ timeoutMs: 3e4
597038
+ });
597039
+ const output = [
597040
+ `[BRANCH-EXTRACT v2] path=${path16}`,
597041
+ `routing=post-execution-failsafe reasons=${decision2.reasons.join(",")} projected_read_tokens=${decision2.projectedReadTokens}`,
597042
+ `[DISCOVERY CONTRACT] ${brief.request}`,
597043
+ `[CURATED SEGMENTS]`,
597044
+ ev.claim,
597045
+ `unresolved=${ev.unresolvedRequirementIds.join(",") || "none"}`,
597046
+ `provenance=content:${ev.provenance.contentHash} ranges:${ev.provenance.exploredRanges.map((range) => `L${range.startLine}-L${range.endLine}`).join(",")}`
597047
+ ].join("\n").slice(0, Math.max(800, decision2.fractionLimitTokens * 4));
597048
+ return {
597049
+ ...input.result,
597050
+ output,
597051
+ llmContent: output,
597052
+ beforeHash: input.result.beforeHash ?? ev.provenance.contentHash,
597053
+ runtimeAuthored: true,
597054
+ completionEvidenceMetrics: {
597055
+ ...input.result.completionEvidenceMetrics,
597056
+ branchSourceBytes: Buffer.byteLength(input.result.output, "utf8"),
597057
+ branchSelectedBytes: Buffer.byteLength(input.result.output, "utf8"),
597058
+ branchProjectedTokens: decision2.projectedReadTokens
597059
+ }
597060
+ };
596329
597061
  }
596330
597062
  /**
596331
597063
  * Build a child-task request from the live parent state. This is the common
@@ -597610,6 +598342,8 @@ TASK: ${scrubbedTask}` : scrubbedTask;
597610
598342
  let completionTokens = 0;
597611
598343
  let estimatedTokens = 0;
597612
598344
  let toolCallCount = 0;
598345
+ let substantiveProgressCount = 0;
598346
+ const substantiveProgressFingerprints = /* @__PURE__ */ new Set();
597613
598347
  let completed = false;
597614
598348
  let summary = "";
597615
598349
  let bruteForceCycle = 0;
@@ -597678,6 +598412,7 @@ TASK: ${scrubbedTask}` : scrubbedTask;
597678
598412
  let lastCommitGateTurn = -1;
597679
598413
  let lastShellPivotTurn = -1;
597680
598414
  const recentToolResults = /* @__PURE__ */ new Map();
598415
+ const exactFileReadObservations = /* @__PURE__ */ new Map();
597681
598416
  let fileMutationEpoch = 0;
597682
598417
  const dedupHitCount = /* @__PURE__ */ new Map();
597683
598418
  const noopedMemoryWriteFingerprints = /* @__PURE__ */ new Set();
@@ -599523,8 +600258,8 @@ If you're stuck, try a completely different approach. Do NOT repeat what failed
599523
600258
  if (process.env["OMNIUS_DISABLE_ADAPTIVE_RETRIEVAL"] !== "1") {
599524
600259
  const goalForSig = (this._taskState.goal || "").slice(0, 200);
599525
600260
  const recentTools = this._toolSequence.slice(-5).join("|");
599526
- const { createHash: createHash53 } = await import("node:crypto");
599527
- const sig = createHash53("sha256").update(`${goalForSig}::${recentTools}`).digest("hex").slice(0, 16);
600261
+ const { createHash: createHash54 } = await import("node:crypto");
600262
+ const sig = createHash54("sha256").update(`${goalForSig}::${recentTools}`).digest("hex").slice(0, 16);
599528
600263
  if (this._lastPprSig === sig && this._lastPprMemoryLines.length > 0) {
599529
600264
  compacted.push({
599530
600265
  role: "system",
@@ -599863,9 +600598,7 @@ ${memoryLines.join("\n")}`
599863
600598
  const parsed = JSON.parse(jsonMatch[1]);
599864
600599
  const resolvedParsedTool = parsed.tool ? this.lookupRegisteredTool(parsed.tool) : null;
599865
600600
  if (parsed.tool && resolvedParsedTool) {
599866
- const tool = resolvedParsedTool.tool;
599867
- const rawResult = await tool.execute(parsed.args ?? {});
599868
- const result = this.applyRegisteredToolResultTriage(rawResult, resolvedParsedTool.name, tool);
600601
+ const result = await this.runToolByName(resolvedParsedTool.name, parsed.args ?? {});
599869
600602
  messages2.push({ role: "assistant", content });
599870
600603
  messages2.push({
599871
600604
  role: "system",
@@ -600140,6 +600873,10 @@ ${memoryLines.join("\n")}`
600140
600873
  });
600141
600874
  }
600142
600875
  let editFeedbackRequiredBeforeMoreEdits = null;
600876
+ const branchReadBatchBudget = {
600877
+ inlineTokens: 0,
600878
+ reservations: /* @__PURE__ */ new Map()
600879
+ };
600143
600880
  executeSingle = async (tc) => {
600144
600881
  if (this.aborted)
600145
600882
  return null;
@@ -600998,6 +601735,7 @@ ${cachedResult}`,
600998
601735
  const resolvedTool = this.lookupRegisteredTool(tc.name);
600999
601736
  const tool = resolvedTool?.tool;
601000
601737
  let result;
601738
+ let fileReadSafetyChecked = false;
601001
601739
  let runtimeSystemGuidance = null;
601002
601740
  if (repeatShortCircuit) {
601003
601741
  result = repeatShortCircuit;
@@ -601147,22 +601885,86 @@ ${cachedResult}`,
601147
601885
  }
601148
601886
  }
601149
601887
  try {
601150
- if (typeof tool.executeStream === "function") {
601151
- const gen = tool.executeStream(finalArgs);
601152
- let iterResult = await gen.next();
601153
- while (!iterResult.done) {
601154
- const progress = String(iterResult.value);
601155
- this.emit({
601156
- type: "status",
601157
- toolName: tc.name,
601158
- content: progress,
601159
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
601160
- });
601161
- iterResult = await gen.next();
601888
+ tc.arguments = finalArgs;
601889
+ const normalizedDispatchName = resolvedTool?.name ?? tc.name;
601890
+ let branchPreempted = null;
601891
+ if (normalizedDispatchName === "file_read") {
601892
+ const exactReadKey = this._buildToolFingerprint("file_read", tc.arguments);
601893
+ const priorRead = exactFileReadObservations.get(exactReadKey);
601894
+ if (priorRead) {
601895
+ const currentRead = this._fileReadDiskIdentity(tc.arguments);
601896
+ if (currentRead && currentRead.contentHash === priorRead.contentHash) {
601897
+ exactFileReadObservations.set(exactReadKey, currentRead);
601898
+ const duplicateOutput = [
601899
+ `[DUPLICATE_READ_BLOCKED] path=${currentRead.path} sha256=${currentRead.contentHash}`,
601900
+ `The exact file_read arguments already produced evidence from this unchanged source during the current run. The tool was not re-executed and the raw body was not re-injected.`,
601901
+ `Use the existing evidence/anchors now. To discover something different, issue one narrower offset/limit or grep_search with a new symbol; otherwise take the next mutation, verification, or completion action.`
601902
+ ].join("\n");
601903
+ branchPreempted = {
601904
+ success: true,
601905
+ output: duplicateOutput,
601906
+ llmContent: duplicateOutput,
601907
+ beforeHash: currentRead.contentHash,
601908
+ runtimeAuthored: true,
601909
+ noop: true,
601910
+ completionEvidenceMetrics: {
601911
+ duplicateReadBlocked: true,
601912
+ duplicateReadSourceBytes: currentRead.byteCount
601913
+ }
601914
+ };
601915
+ this.emit({
601916
+ type: "status",
601917
+ toolName: normalizedDispatchName,
601918
+ content: `Exact unchanged file_read blocked before dispatch: ${currentRead.path} sha256=${currentRead.contentHash.slice(0, 12)}`,
601919
+ turn,
601920
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
601921
+ });
601922
+ } else {
601923
+ exactFileReadObservations.delete(exactReadKey);
601924
+ }
601162
601925
  }
601163
- result = iterResult.value;
601926
+ }
601927
+ if (!branchPreempted) {
601928
+ branchPreempted = await this._preemptFileReadWithBranch({
601929
+ callId: tc.id,
601930
+ toolName: normalizedDispatchName,
601931
+ args: tc.arguments,
601932
+ messages: messages2,
601933
+ turn,
601934
+ batchBudget: branchReadBatchBudget
601935
+ });
601936
+ }
601937
+ if (branchPreempted) {
601938
+ result = branchPreempted;
601939
+ fileReadSafetyChecked = true;
601164
601940
  } else {
601165
- result = await tool.execute(finalArgs);
601941
+ if (typeof tool.executeStream === "function") {
601942
+ const gen = tool.executeStream(finalArgs);
601943
+ let iterResult = await gen.next();
601944
+ while (!iterResult.done) {
601945
+ const progress = String(iterResult.value);
601946
+ this.emit({
601947
+ type: "status",
601948
+ toolName: tc.name,
601949
+ content: progress,
601950
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
601951
+ });
601952
+ iterResult = await gen.next();
601953
+ }
601954
+ result = iterResult.value;
601955
+ } else {
601956
+ result = await tool.execute(finalArgs);
601957
+ }
601958
+ result = await this._guardMaterializedFileReadResult({
601959
+ callId: tc.id,
601960
+ toolName: resolvedTool?.name ?? tc.name,
601961
+ args: tc.arguments,
601962
+ result,
601963
+ messages: messages2,
601964
+ turn,
601965
+ batchBudget: branchReadBatchBudget
601966
+ });
601967
+ fileReadSafetyChecked = true;
601166
601968
  }
601167
601969
  result = this.applyRegisteredToolResultTriage(result, resolvedTool?.name ?? tc.name, tool);
601168
601970
  if (tc.name === "shell" && result.success === true) {
@@ -601262,6 +602064,23 @@ Respond with EXACTLY this structure before your next tool call:
601262
602064
  }
601263
602065
  }
601264
602066
  }
602067
+ if (!fileReadSafetyChecked) {
602068
+ result = await this._guardMaterializedFileReadResult({
602069
+ callId: tc.id,
602070
+ toolName: resolvedTool?.name ?? tc.name,
602071
+ args: tc.arguments,
602072
+ result,
602073
+ messages: messages2,
602074
+ turn,
602075
+ batchBudget: branchReadBatchBudget
602076
+ });
602077
+ }
602078
+ if ((resolvedTool?.name ?? tc.name) === "file_read" && result.success === true && result.noop !== true) {
602079
+ const observedIdentity = this._fileReadDiskIdentity(tc.arguments);
602080
+ if (observedIdentity && (!result.beforeHash || result.beforeHash === observedIdentity.contentHash)) {
602081
+ exactFileReadObservations.set(this._buildToolFingerprint("file_read", tc.arguments), observedIdentity);
602082
+ }
602083
+ }
601265
602084
  const shellFilesystemMutation = tc.name === "shell" && result.success === true && this._shellCommandLikelyMutatesFilesystem(String(tc.arguments?.["command"] ?? tc.arguments?.["cmd"] ?? ""));
601266
602085
  this._releaseMutationWorkerLeaseForArgs(resolvedTool?.name ?? tc.name, tc.arguments, result, turn);
601267
602086
  const shellMutationPaths = shellFilesystemMutation ? extractShellMutationPaths(String(tc.arguments?.["command"] ?? tc.arguments?.["cmd"] ?? ""), { workingDir: this.authoritativeWorkingDirectory() }).paths : [];
@@ -601312,6 +602131,13 @@ Respond with EXACTLY this structure before your next tool call:
601312
602131
  writeCount: nextWriteCount
601313
602132
  });
601314
602133
  this._evidenceLedger.markMutated(this._normalizeEvidencePath(p2), nextWriteCount, turn);
602134
+ const branchPath = this._normalizeEvidencePath(p2);
602135
+ this._branchEvidenceByPath.delete(branchPath);
602136
+ for (const [cacheKey, cached] of this._branchEvidenceCache) {
602137
+ if (cached.path === branchPath) {
602138
+ this._branchEvidenceCache.delete(cacheKey);
602139
+ }
602140
+ }
601315
602141
  {
601316
602142
  const _normMut = this._normalizeEvidencePath(p2);
601317
602143
  for (const _covKey of this._readCoverage.keys()) {
@@ -601351,7 +602177,7 @@ Respond with EXACTLY this structure before your next tool call:
601351
602177
  const prev = this._worldFacts.files.get(p2);
601352
602178
  this._worldFacts.files.set(p2, {
601353
602179
  exists: result.success,
601354
- size: (result.output || "").length,
602180
+ size: typeof result.completionEvidenceMetrics?.["branchSourceBytes"] === "number" ? result.completionEvidenceMetrics["branchSourceBytes"] : (result.output || "").length,
601355
602181
  hashSample: (result.output || "").slice(0, 32),
601356
602182
  lastSeenTurn: turn,
601357
602183
  lastWriteTurn: prev?.lastWriteTurn,
@@ -601370,7 +602196,8 @@ Respond with EXACTLY this structure before your next tool call:
601370
602196
  range: { start: start3, end },
601371
602197
  fileVersion: this._worldFacts.files.get(p2)?.writeCount ?? 0,
601372
602198
  mtimeMs: this._statMtimeMsForToolPath(p2),
601373
- turn
602199
+ turn,
602200
+ fidelity: result.runtimeAuthored === true && result.output.startsWith("[BRANCH-EXTRACT") ? "extract" : void 0
601374
602201
  });
601375
602202
  }
601376
602203
  if (this._fileSummaryStore && result.success && result.output && result.output.length > 100) {
@@ -602275,74 +603102,6 @@ Respond with EXACTLY this structure before your next tool call:
602275
603102
  result = await this.offloadEmbeddedImageResult(result, tc.name, turn);
602276
603103
  }
602277
603104
  let output = this.normalizeToolOutput(result, tc.name, tc.arguments, turn);
602278
- if (process.env["OMNIUS_DISABLE_BRANCH_EXTRACT"] !== "1" && this.lookupRegisteredTool(tc.name)?.name === "file_read" && result.success && this.backend && typeof this.backend.chatCompletion === "function") {
602279
- const a2 = tc.arguments ?? {};
602280
- const hasExplicitRange = typeof a2["offset"] === "number" || typeof a2["limit"] === "number";
602281
- const pRaw = String(a2["path"] ?? a2["file"] ?? a2["file_path"] ?? "");
602282
- if (!hasExplicitRange && pRaw) {
602283
- let fullContent = null;
602284
- let trueLines = 0;
602285
- let trueBytes = 0;
602286
- for (const cand of [
602287
- pRaw,
602288
- _pathResolve(this._workingDirectory || process.cwd(), pRaw)
602289
- ]) {
602290
- try {
602291
- const st = _fsStatSync(cand);
602292
- if (st.isFile()) {
602293
- trueBytes = st.size;
602294
- if (trueBytes > 8e3) {
602295
- fullContent = _fsReadFileSync(cand, "utf-8");
602296
- trueLines = fullContent.split("\n").length;
602297
- }
602298
- break;
602299
- }
602300
- } catch {
602301
- }
602302
- }
602303
- if (fullContent && shouldBranchRead(trueBytes, trueLines, false)) {
602304
- const branchBrief = this._buildBranchExtractionBrief({
602305
- path: pRaw,
602306
- lineCount: trueLines,
602307
- byteCount: trueBytes,
602308
- messages: messages2
602309
- });
602310
- try {
602311
- const ev = await extractEvidence({
602312
- path: pRaw,
602313
- query: branchBrief.retrievalQuery,
602314
- brief: branchBrief,
602315
- content: fullContent,
602316
- // the REAL body, not the preview
602317
- fileVersion: this._worldFacts.files.get(pRaw)?.writeCount ?? 0,
602318
- // Native /api/chat so the extractor LLM fallback isn't
602319
- // silently empty on qwen3-family models.
602320
- backend: this._auxInferenceBackend(),
602321
- timeoutMs: 3e4
602322
- });
602323
- output = [
602324
- `[BRANCH-EXTRACT] ${pRaw} is large (${trueLines} lines, ${trueBytes} bytes); a whole-file read only returns a preview, so it was read in an isolated branch and distilled.`,
602325
- `[AGENTIC EXTRACTION REQUEST] ${branchBrief.request}`,
602326
- `Evidence driving this request:`,
602327
- ...branchBrief.triggerEvidence.map((evidence) => `- ${evidence}`),
602328
- `Looking for: ${branchBrief.returnContract}`,
602329
- `Retrieval focus: "${branchBrief.retrievalQuery.slice(0, 240)}"`,
602330
- `Relevant evidence (lines ${ev.sourceStart ?? "?"}-${ev.sourceEnd ?? "?"}, confidence ${ev.confidence.toFixed(2)}):`,
602331
- ev.claim,
602332
- `If you need a different region, call file_read with a specific offset+limit. Do NOT re-read the whole file — you already have the relevant content above.`
602333
- ].join("\n");
602334
- this.emit({
602335
- type: "status",
602336
- toolName: tc.name,
602337
- content: `Branch-extract: ${pRaw} (${trueLines} lines / ${trueBytes}B) → ${ev.injectedChars} chars to context (${(trueBytes / Math.max(1, ev.injectedChars)).toFixed(0)}× smaller)`,
602338
- turn,
602339
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
602340
- });
602341
- } catch {
602342
- }
602343
- }
602344
- }
602345
- }
602346
603105
  if (criticGuidance && !repeatShortCircuit) {
602347
603106
  output += `
602348
603107
 
@@ -602426,6 +603185,22 @@ Evidence: ${evidencePreview}`.slice(0, 500);
602426
603185
  turn,
602427
603186
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
602428
603187
  });
603188
+ const branchCacheHit = result.completionEvidenceMetrics?.["branchCacheHit"] === true;
603189
+ const nonSubstantiveResult = result.noop === true || branchCacheHit || repeatShortCircuit !== null && result.runtimeAuthored === true;
603190
+ if (!nonSubstantiveResult) {
603191
+ const observationFingerprint = [
603192
+ this._buildToolFingerprint(tc.name, tc.arguments ?? {}),
603193
+ result.success ? "ok" : "error",
603194
+ result.beforeHash ?? "",
603195
+ result.afterHash ?? "",
603196
+ realMutationPaths.join(","),
603197
+ this.quickHash(String(result.output ?? result.error ?? result.llmContent ?? ""))
603198
+ ].join("|");
603199
+ if (!substantiveProgressFingerprints.has(observationFingerprint)) {
603200
+ substantiveProgressFingerprints.add(observationFingerprint);
603201
+ substantiveProgressCount++;
603202
+ }
603203
+ }
602429
603204
  this._taskState.toolCallCount++;
602430
603205
  if (realFileMutation) {
602431
603206
  this._lastFileWriteTurn = turn;
@@ -603716,24 +604491,24 @@ Your most recent tool calls SUCCEEDED. If the task is complete, call task_comple
603716
604491
  } catch {
603717
604492
  }
603718
604493
  }
603719
- let prevCycleToolCalls = toolCallCount;
604494
+ let prevCycleSubstantiveProgress = substantiveProgressCount;
603720
604495
  while (!completed && !this.aborted && !this._completionIncompleteVerification && this.options.bruteForce && bruteForceCycle < this.options.bruteForceMaxCycles) {
603721
604496
  bruteForceCycle++;
603722
604497
  const totalTurns = messages2.filter((m2) => m2.role === "assistant").length;
603723
- if (bruteForceCycle > 1 && toolCallCount === prevCycleToolCalls) {
604498
+ if (bruteForceCycle > 1 && substantiveProgressCount === prevCycleSubstantiveProgress) {
603724
604499
  this.emit({
603725
604500
  type: "status",
603726
- content: `Stopping re-engagement — no tool call progress in cycle ${bruteForceCycle - 1}. Model may not support tool calling for this task.`,
604501
+ content: `Stopping re-engagement — cycle ${bruteForceCycle - 1} produced no new executed fingerprint, mutation, todo transition, or verifier evidence (${toolCallCount} attempted tool calls; ${substantiveProgressCount} substantive observations).`,
603727
604502
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
603728
604503
  });
603729
604504
  break;
603730
604505
  }
603731
- prevCycleToolCalls = toolCallCount;
604506
+ prevCycleSubstantiveProgress = substantiveProgressCount;
603732
604507
  consecutiveTextOnly = 0;
603733
604508
  consecutiveThinkOnly = 0;
603734
604509
  this.emit({
603735
604510
  type: "status",
603736
- content: `Re-engaging — cycle ${bruteForceCycle} (${totalTurns} turns, ${toolCallCount} tool calls so far)`,
604511
+ content: `Re-engaging — cycle ${bruteForceCycle} (${totalTurns} turns, ${toolCallCount} attempted calls / ${substantiveProgressCount} substantive observations)`,
603737
604512
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
603738
604513
  });
603739
604514
  this._reg61CooldownUntilTurn = -1;
@@ -607553,7 +608328,7 @@ ${telegramPersonaHead}` : stripped
607553
608328
  ...stickyToKeep,
607554
608329
  ...filteredRecent
607555
608330
  ];
607556
- const fileRecoveryBudget = Math.floor((this.options.contextWindowSize || 32768) * 0.15);
608331
+ const fileRecoveryBudget = Math.floor((this._branchRoutingContextWindow() || 32768) * 0.15);
607557
608332
  const maxRecoverFiles = tier === "small" ? 3 : tier === "medium" ? 4 : 5;
607558
608333
  const recoveredFiles = [];
607559
608334
  if (this._fileRegistry.size > 0) {
@@ -607568,8 +608343,45 @@ ${telegramPersonaHead}` : stripped
607568
608343
  for (const [filePath, entry] of entries) {
607569
608344
  try {
607570
608345
  const { readFileSync: readFileSync144 } = await import("node:fs");
607571
- const content = readFileSync144(filePath, "utf8");
608346
+ const absolutePath = this._absoluteToolPath(filePath);
608347
+ const content = readFileSync144(absolutePath, "utf8");
607572
608348
  const tokenEst = Math.ceil(content.length / 4);
608349
+ const canonicalPath = this._normalizeEvidencePath(filePath);
608350
+ const branchNode = this._branchEvidenceByPath.get(canonicalPath);
608351
+ const currentMtime = this._statMtimeMsForToolPath(filePath) ?? 0;
608352
+ if (branchNode && branchNode.mtimeMs === currentMtime) {
608353
+ const nodeTokens = Math.ceil(branchNode.output.length / 4);
608354
+ if (recoveredTokens + nodeTokens > fileRecoveryBudget)
608355
+ continue;
608356
+ result.push({
608357
+ role: "system",
608358
+ content: `<recovered-branch-evidence path="${filePath}" sha256="${branchNode.contentHash}">
608359
+ ${branchNode.output}
608360
+ </recovered-branch-evidence>`
608361
+ });
608362
+ recoveredFiles.push(filePath);
608363
+ recoveredTokens += nodeTokens;
608364
+ continue;
608365
+ }
608366
+ const recoveryDecision = assessBranchRead({
608367
+ sourceBytes: Buffer.byteLength(content, "utf8"),
608368
+ sourceLines: content.split("\n").length,
608369
+ contextWindowTokens: this._branchRoutingContextWindow(),
608370
+ residentContextTokens: estimateMessagesTokens2(result),
608371
+ reservedTokens: this._branchReadReservedTokens(this._branchRoutingContextWindow()),
608372
+ pendingInlineReadTokens: recoveredTokens,
608373
+ safeContextTokens: this.contextLimits().compactionThreshold
608374
+ });
608375
+ if (recoveryDecision.branch) {
608376
+ const reference = `<recovered-file-reference path="${filePath}" status="${entry.modified ? "modified" : "read"}" routing="branch-required" projected_tokens="${recoveryDecision.projectedReadTokens}">Raw recovery suppressed by the 20% context contract; use the existing evidence ledger or issue one goal-scoped file_read.</recovered-file-reference>`;
608377
+ const referenceTokens = Math.ceil(reference.length / 4);
608378
+ if (recoveredTokens + referenceTokens <= fileRecoveryBudget) {
608379
+ result.push({ role: "system", content: reference });
608380
+ recoveredFiles.push(filePath);
608381
+ recoveredTokens += referenceTokens;
608382
+ }
608383
+ continue;
608384
+ }
607573
608385
  if (recoveredTokens + tokenEst > fileRecoveryBudget)
607574
608386
  break;
607575
608387
  const truncated = content.length > 8e3;
@@ -607639,6 +608451,7 @@ ${content.slice(0, 8e3)}${truncated ? "\n[truncated recovery; use a narrow live
607639
608451
  } catch {
607640
608452
  }
607641
608453
  }
608454
+ const protectedRecoveryMessages = result.filter((message2) => message2.role === "system" && typeof message2.content === "string" && /^<recovered-(?:branch-evidence|file-reference|file)\b/.test(message2.content));
607642
608455
  const ctxWindow = this.options.contextWindowSize;
607643
608456
  if (ctxWindow > 0) {
607644
608457
  const _safetyImgPat = /\[IMAGE_BASE64:[^\]]+\]/g;
@@ -607676,6 +608489,7 @@ ${content.slice(0, 8e3)}${truncated ? "\n[truncated recovery; use a narrow live
607676
608489
  ...narrowedHead,
607677
608490
  compactionMsg,
607678
608491
  ...stickyToKeep,
608492
+ ...protectedRecoveryMessages,
607679
608493
  ...trimmedRecent
607680
608494
  ];
607681
608495
  }
@@ -612690,7 +613504,7 @@ var init_composite_scorer = __esm({
612690
613504
  });
612691
613505
 
612692
613506
  // packages/orchestrator/dist/memory/materialization-policy.js
612693
- import { createHash as createHash35 } from "node:crypto";
613507
+ import { createHash as createHash36 } from "node:crypto";
612694
613508
  function materializeMemoryItems(items, options2 = {}) {
612695
613509
  const config = options2.config ?? DEFAULT_WEIGHTING_CONFIG;
612696
613510
  const sorted = [...items].sort((a2, b) => b.weight - a2.weight || a2.id.localeCompare(b.id));
@@ -612928,7 +613742,7 @@ function estimateTokens4(text2) {
612928
613742
  return Math.max(1, Math.ceil(text2.length / 4));
612929
613743
  }
612930
613744
  function hashText2(text2) {
612931
- return createHash35("sha256").update(text2).digest("hex");
613745
+ return createHash36("sha256").update(text2).digest("hex");
612932
613746
  }
612933
613747
  var init_materialization_policy = __esm({
612934
613748
  "packages/orchestrator/dist/memory/materialization-policy.js"() {
@@ -613092,7 +613906,7 @@ var init_config_loader = __esm({
613092
613906
  });
613093
613907
 
613094
613908
  // packages/orchestrator/dist/memory/stability-tracker.js
613095
- import { createHash as createHash36 } from "node:crypto";
613909
+ import { createHash as createHash37 } from "node:crypto";
613096
613910
  import { existsSync as existsSync109, mkdirSync as mkdirSync60, readFileSync as readFileSync84, writeFileSync as writeFileSync51 } from "node:fs";
613097
613911
  import { dirname as dirname36, join as join117 } from "node:path";
613098
613912
  function stabilityFilePath(repoRoot) {
@@ -613156,7 +613970,7 @@ function computeStabilityHash(item) {
613156
613970
  item.scope.name,
613157
613971
  item.topicKey
613158
613972
  ].join("|");
613159
- return createHash36("sha256").update(normalized).digest("hex");
613973
+ return createHash37("sha256").update(normalized).digest("hex");
613160
613974
  }
613161
613975
  function normalizeContent2(content) {
613162
613976
  return content.replace(/\s+/g, " ").trim();
@@ -617176,10 +617990,10 @@ var init_project_arc = __esm({
617176
617990
  });
617177
617991
 
617178
617992
  // packages/orchestrator/dist/dedup-gate.js
617179
- import { createHash as createHash37 } from "node:crypto";
617993
+ import { createHash as createHash38 } from "node:crypto";
617180
617994
  function fingerprintCall(name10, args) {
617181
617995
  const canon = canonicalize(args);
617182
- return createHash37("sha1").update(`${name10}\0${canon}`).digest("hex").slice(0, 16);
617996
+ return createHash38("sha1").update(`${name10}\0${canon}`).digest("hex").slice(0, 16);
617183
617997
  }
617184
617998
  function canonicalize(value2) {
617185
617999
  if (value2 === null || typeof value2 !== "object")
@@ -628111,7 +628925,7 @@ var require_websocket3 = __commonJS({
628111
628925
  var http6 = __require("http");
628112
628926
  var net5 = __require("net");
628113
628927
  var tls2 = __require("tls");
628114
- var { randomBytes: randomBytes31, createHash: createHash53 } = __require("crypto");
628928
+ var { randomBytes: randomBytes31, createHash: createHash54 } = __require("crypto");
628115
628929
  var { Duplex: Duplex3, Readable } = __require("stream");
628116
628930
  var { URL: URL3 } = __require("url");
628117
628931
  var PerMessageDeflate3 = require_permessage_deflate3();
@@ -628771,7 +629585,7 @@ var require_websocket3 = __commonJS({
628771
629585
  abortHandshake(websocket, socket, "Invalid Upgrade header");
628772
629586
  return;
628773
629587
  }
628774
- const digest3 = createHash53("sha1").update(key + GUID).digest("base64");
629588
+ const digest3 = createHash54("sha1").update(key + GUID).digest("base64");
628775
629589
  if (res.headers["sec-websocket-accept"] !== digest3) {
628776
629590
  abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
628777
629591
  return;
@@ -629138,7 +629952,7 @@ var require_websocket_server2 = __commonJS({
629138
629952
  var EventEmitter15 = __require("events");
629139
629953
  var http6 = __require("http");
629140
629954
  var { Duplex: Duplex3 } = __require("stream");
629141
- var { createHash: createHash53 } = __require("crypto");
629955
+ var { createHash: createHash54 } = __require("crypto");
629142
629956
  var extension3 = require_extension3();
629143
629957
  var PerMessageDeflate3 = require_permessage_deflate3();
629144
629958
  var subprotocol3 = require_subprotocol2();
@@ -629439,7 +630253,7 @@ var require_websocket_server2 = __commonJS({
629439
630253
  );
629440
630254
  }
629441
630255
  if (this._state > RUNNING) return abortHandshake(socket, 503);
629442
- const digest3 = createHash53("sha1").update(key + GUID).digest("base64");
630256
+ const digest3 = createHash54("sha1").update(key + GUID).digest("base64");
629443
630257
  const headers = [
629444
630258
  "HTTP/1.1 101 Switching Protocols",
629445
630259
  "Upgrade: websocket",
@@ -636220,14 +637034,14 @@ var init_voice_session = __esm({
636220
637034
  });
636221
637035
 
636222
637036
  // packages/cli/src/tui/scoped-personality.ts
636223
- import { createHash as createHash38 } from "node:crypto";
637037
+ import { createHash as createHash39 } from "node:crypto";
636224
637038
  import { appendFileSync as appendFileSync13, existsSync as existsSync120, mkdirSync as mkdirSync72, readFileSync as readFileSync97, writeFileSync as writeFileSync60 } from "node:fs";
636225
637039
  import { join as join131, resolve as resolve60 } from "node:path";
636226
637040
  function safeName(input) {
636227
637041
  return input.replace(/[^A-Za-z0-9_.-]/g, "-").slice(0, 80) || "default";
636228
637042
  }
636229
637043
  function scopeHash(scope) {
636230
- return createHash38("sha1").update(`${scope.kind}:${scope.id}`).digest("hex").slice(0, 16);
637044
+ return createHash39("sha1").update(`${scope.kind}:${scope.id}`).digest("hex").slice(0, 16);
636231
637045
  }
636232
637046
  function scopedPersonalityDir(repoRoot, kind) {
636233
637047
  return resolve60(repoRoot, ".omnius", "scoped-personality", kind);
@@ -636598,7 +637412,7 @@ var init_scoped_personality = __esm({
636598
637412
  });
636599
637413
 
636600
637414
  // packages/cli/src/tui/voice-soul.ts
636601
- import { createHash as createHash39 } from "node:crypto";
637415
+ import { createHash as createHash40 } from "node:crypto";
636602
637416
  import { existsSync as existsSync121, readdirSync as readdirSync38, readFileSync as readFileSync98 } from "node:fs";
636603
637417
  import { basename as basename26, join as join132, resolve as resolve61 } from "node:path";
636604
637418
  function compactText(text2, limit) {
@@ -636613,7 +637427,7 @@ function blockText(text2, limit) {
636613
637427
  ... [truncated]`;
636614
637428
  }
636615
637429
  function scopeStateKey(scope, surface) {
636616
- return createHash39("sha1").update(`${surface}:${scope.kind}:${scope.id}`).digest("hex").slice(0, 16);
637430
+ return createHash40("sha1").update(`${surface}:${scope.kind}:${scope.id}`).digest("hex").slice(0, 16);
636617
637431
  }
636618
637432
  function safeName2(input) {
636619
637433
  return input.replace(/[^A-Za-z0-9_.-]/g, "-").slice(0, 80) || "default";
@@ -639253,7 +640067,7 @@ var init_types3 = __esm({
639253
640067
  });
639254
640068
 
639255
640069
  // packages/cli/src/tui/p2p/secret-vault.ts
639256
- import { createCipheriv as createCipheriv3, createDecipheriv as createDecipheriv3, randomBytes as randomBytes23, scryptSync as scryptSync2, createHash as createHash40 } from "node:crypto";
640070
+ import { createCipheriv as createCipheriv3, createDecipheriv as createDecipheriv3, randomBytes as randomBytes23, scryptSync as scryptSync2, createHash as createHash41 } from "node:crypto";
639257
640071
  import { readFileSync as readFileSync100, writeFileSync as writeFileSync62, existsSync as existsSync123, mkdirSync as mkdirSync74 } from "node:fs";
639258
640072
  import { dirname as dirname39 } from "node:path";
639259
640073
  var PLACEHOLDER_PREFIX, PLACEHOLDER_SUFFIX, CIPHER_ALGO, SALT_LEN, IV_LEN, KEY_LEN, SecretVault;
@@ -639497,7 +640311,7 @@ var init_secret_vault = __esm({
639497
640311
  /** Generate a deterministic fingerprint of vault contents (for sync verification) */
639498
640312
  fingerprint() {
639499
640313
  const names = Array.from(this.secrets.keys()).sort();
639500
- const hash = createHash40("sha256");
640314
+ const hash = createHash41("sha256");
639501
640315
  for (const name10 of names) {
639502
640316
  hash.update(name10 + ":");
639503
640317
  hash.update(this.secrets.get(name10).value);
@@ -639512,7 +640326,7 @@ var init_secret_vault = __esm({
639512
640326
  // packages/cli/src/tui/p2p/peer-mesh.ts
639513
640327
  import { EventEmitter as EventEmitter9 } from "node:events";
639514
640328
  import { createServer as createServer6 } from "node:http";
639515
- import { randomBytes as randomBytes24, createHash as createHash41, generateKeyPairSync } from "node:crypto";
640329
+ import { randomBytes as randomBytes24, createHash as createHash42, generateKeyPairSync } from "node:crypto";
639516
640330
  var PING_INTERVAL_MS, PEER_TIMEOUT_MS, GOSSIP_INTERVAL_MS, MAX_PEERS, PeerMesh;
639517
640331
  var init_peer_mesh = __esm({
639518
640332
  "packages/cli/src/tui/p2p/peer-mesh.ts"() {
@@ -639528,7 +640342,7 @@ var init_peer_mesh = __esm({
639528
640342
  const { publicKey: publicKey2, privateKey } = generateKeyPairSync("ed25519");
639529
640343
  this.publicKey = publicKey2.export({ type: "spki", format: "der" });
639530
640344
  this.privateKey = privateKey.export({ type: "pkcs8", format: "der" });
639531
- this.peerId = createHash41("sha256").update(this.publicKey).digest("base64url").slice(0, 22);
640345
+ this.peerId = createHash42("sha256").update(this.publicKey).digest("base64url").slice(0, 22);
639532
640346
  this.capabilities = options2.capabilities;
639533
640347
  this.displayName = options2.displayName;
639534
640348
  this._authKey = options2.authKey ?? randomBytes24(24).toString("base64url");
@@ -640894,7 +641708,7 @@ __export(omnius_directory_exports, {
640894
641708
  import { appendFileSync as appendFileSync14, cpSync as cpSync2, existsSync as existsSync125, mkdirSync as mkdirSync76, readFileSync as readFileSync102, writeFileSync as writeFileSync64, readdirSync as readdirSync41, statSync as statSync51, unlinkSync as unlinkSync23, openSync as openSync2, closeSync as closeSync2, renameSync as renameSync11, watch as fsWatch2 } from "node:fs";
640895
641709
  import { join as join136, relative as relative17, basename as basename27, dirname as dirname40, resolve as resolve62 } from "node:path";
640896
641710
  import { homedir as homedir42 } from "node:os";
640897
- import { createHash as createHash43 } from "node:crypto";
641711
+ import { createHash as createHash44 } from "node:crypto";
640898
641712
  function isGitRoot(dir) {
640899
641713
  const gitPath = join136(dir, ".git");
640900
641714
  if (!existsSync125(gitPath)) return false;
@@ -641392,7 +642206,7 @@ function buildHandoffPrompt(repoRoot) {
641392
642206
  return lines.join("\n");
641393
642207
  }
641394
642208
  function computeDedupeHash(task, savedAt) {
641395
- return createHash43("sha256").update(`${task}|${savedAt}`).digest("hex").slice(0, 16);
642209
+ return createHash44("sha256").update(`${task}|${savedAt}`).digest("hex").slice(0, 16);
641396
642210
  }
641397
642211
  function generateSessionId() {
641398
642212
  const timestamp = Date.now().toString(36);
@@ -668986,7 +669800,7 @@ __export(commands_exports, {
668986
669800
  });
668987
669801
  import * as nodeOs from "node:os";
668988
669802
  import { spawn as nodeSpawn2 } from "node:child_process";
668989
- import { createHash as createHash44 } from "node:crypto";
669803
+ import { createHash as createHash45 } from "node:crypto";
668990
669804
  import {
668991
669805
  existsSync as existsSync147,
668992
669806
  readFileSync as readFileSync119,
@@ -682346,7 +683160,7 @@ async function collectSponsorMediaStream(args) {
682346
683160
  };
682347
683161
  }
682348
683162
  if (artifact.sha256) {
682349
- const sha = createHash44("sha256").update(bytes).digest("hex");
683163
+ const sha = createHash45("sha256").update(bytes).digest("hex");
682350
683164
  if (sha !== artifact.sha256)
682351
683165
  return { ok: false, error: `Artifact hash mismatch for ${artifactId}` };
682352
683166
  }
@@ -688972,6 +689786,18 @@ var init_stream_renderer = __esm({
688972
689786
  * runs. Tracked in VISIBLE chars (ANSI escapes stripped).
688973
689787
  */
688974
689788
  _cursorCol = 0;
689789
+ /**
689790
+ * RESIZE-REWRAP: raw (un-highlighted) text of the CURRENT in-progress
689791
+ * logical content line — everything streamed since the last "\n",
689792
+ * including already-flushed partials. Streaming hard-breaks rows at the
689793
+ * width current at flush time, so without this raw copy a SIGWINCH left
689794
+ * the in-progress line "locked" at the old width (the reported artifact).
689795
+ * onResize() erases the line's visual rows and re-emits from this buffer
689796
+ * wrapped at the new width.
689797
+ */
689798
+ _currentLineRaw = "";
689799
+ /** Visual rows (newlines) already emitted for the current logical line. */
689800
+ _wrapRowsEmitted = 0;
688975
689801
  /** Called when a new model response starts streaming */
688976
689802
  onStreamStart() {
688977
689803
  this.lineBuffer = "";
@@ -688983,6 +689809,8 @@ var init_stream_renderer = __esm({
688983
689809
  this.jsonBlobSize = 0;
688984
689810
  this.jsonBlobSuppressed = false;
688985
689811
  this._cursorCol = 0;
689812
+ this._currentLineRaw = "";
689813
+ this._wrapRowsEmitted = 0;
688986
689814
  this.enabled = true;
688987
689815
  this.tokenCount = 0;
688988
689816
  this.startTime = Date.now();
@@ -689071,6 +689899,34 @@ var init_stream_renderer = __esm({
689071
689899
  process.stdout.write("\n");
689072
689900
  this.lineStarted = false;
689073
689901
  }
689902
+ this._currentLineRaw = "";
689903
+ this._wrapRowsEmitted = 0;
689904
+ this._cursorCol = 0;
689905
+ }
689906
+ /**
689907
+ * RESIZE-REWRAP: re-render the in-progress logical content line at the new
689908
+ * terminal width. Streaming hard-breaks rows at flush-time width, so after
689909
+ * a SIGWINCH the current line was left "locked" at the old width — wrapped
689910
+ * rows missing the pipe gutter or overflowing. Erases the rows this line
689911
+ * occupies (tracked in _wrapRowsEmitted) and re-emits from the raw buffer.
689912
+ * Completed lines live in terminal scrollback and are not repainted.
689913
+ * Call AFTER setTermSize() so termCols() reflects the new width.
689914
+ */
689915
+ onResize() {
689916
+ if (!this.enabled) return;
689917
+ const raw = this._currentLineRaw;
689918
+ if (!raw) return;
689919
+ if (isTTY8) {
689920
+ const rowsUp = Math.min(this._wrapRowsEmitted, 40);
689921
+ let seq = "\r\x1B[2K";
689922
+ for (let i2 = 0; i2 < rowsUp; i2++) seq += "\x1B[A\x1B[2K";
689923
+ process.stdout.write(`\x1B[?25l\x1B[?7l${seq}\x1B[?7h`);
689924
+ }
689925
+ this._cursorCol = 0;
689926
+ this.lineStarted = false;
689927
+ this._currentLineRaw = "";
689928
+ this._wrapRowsEmitted = 0;
689929
+ this.writeHighlighted(raw, "content");
689074
689930
  }
689075
689931
  /** Called when streaming ends for this response */
689076
689932
  onStreamEnd() {
@@ -689111,6 +689967,9 @@ var init_stream_renderer = __esm({
689111
689967
  if (this.lineStarted) {
689112
689968
  process.stdout.write("\n");
689113
689969
  this.lineStarted = false;
689970
+ this._currentLineRaw = "";
689971
+ this._wrapRowsEmitted = 0;
689972
+ this._cursorCol = 0;
689114
689973
  }
689115
689974
  return;
689116
689975
  }
@@ -689180,6 +690039,14 @@ var init_stream_renderer = __esm({
689180
690039
  this.jsonBlobSuppressed = false;
689181
690040
  }
689182
690041
  }
690042
+ const trackedContent = kind === "content" && !this.inCodeBlock && !this.looksLikeJson(raw);
690043
+ if (trackedContent) this._currentLineRaw += raw;
690044
+ const endTrackedLine = () => {
690045
+ if (trackedContent && hasNewline) {
690046
+ this._currentLineRaw = "";
690047
+ this._wrapRowsEmitted = 0;
690048
+ }
690049
+ };
689183
690050
  const prefix = this.lineStarted ? "" : " │ ";
689184
690051
  const maxW = Math.max(10, termCols() - 6);
689185
690052
  let rendered;
@@ -689190,6 +690057,7 @@ var init_stream_renderer = __esm({
689190
690057
  const firstChunkLen = Math.min(text3.length, Math.max(1, remaining));
689191
690058
  if (remaining < 8 && text3.length > remaining) {
689192
690059
  this.writeRaw("\n");
690060
+ if (trackedContent) this._wrapRowsEmitted++;
689193
690061
  this.lineStarted = false;
689194
690062
  } else if (text3.length > remaining) {
689195
690063
  const window2 = text3.slice(0, firstChunkLen);
@@ -689198,12 +690066,13 @@ var init_stream_renderer = __esm({
689198
690066
  const head = text3.slice(0, wb).replace(/\s+$/, "");
689199
690067
  const tail = text3.slice(wb).replace(/^\s+/, "");
689200
690068
  this.writeRaw(highlight(head) + "\n");
690069
+ if (trackedContent) this._wrapRowsEmitted++;
689201
690070
  this.lineStarted = false;
689202
690071
  text3 = tail;
689203
690072
  if (!text3) return;
689204
690073
  }
689205
690074
  }
689206
- const usePrefix = this.lineStarted && this._cursorCol > 0 ? "" : prefix;
690075
+ const usePrefix = this.lineStarted && this._cursorCol > 0 ? "" : " │ ";
689207
690076
  const usableW = this.lineStarted ? maxW : Math.max(1, maxW - usePrefix.length);
689208
690077
  const lines = text3.length > usableW ? this.wordWrap(text3, usableW) : [text3];
689209
690078
  const isBlockquote = kind === "content" && /^>\s/.test(text3);
@@ -689216,12 +690085,14 @@ var init_stream_renderer = __esm({
689216
690085
  this.writeRaw(
689217
690086
  dimText(lp) + highlight(chunk) + (needsNewline ? "\n" : "")
689218
690087
  );
690088
+ if (trackedContent && needsNewline) this._wrapRowsEmitted++;
689219
690089
  }
689220
690090
  this.lineStarted = !trailingNewline;
689221
690091
  };
689222
690092
  switch (kind) {
689223
690093
  case "thinking":
689224
690094
  emitWrapped(raw, dimItalic, hasNewline);
690095
+ endTrackedLine();
689225
690096
  return;
689226
690097
  case "tool_args":
689227
690098
  rendered = this.highlightJson(raw, true);
@@ -689245,6 +690116,7 @@ var init_stream_renderer = __esm({
689245
690116
  } else {
689246
690117
  if (visibleLength(raw) > maxW || this.lineStarted && this._cursorCol + visibleLength(raw) > maxW) {
689247
690118
  emitWrapped(raw, (s2) => this.highlightMarkdown(s2), hasNewline);
690119
+ endTrackedLine();
689248
690120
  return;
689249
690121
  }
689250
690122
  rendered = this.highlightMarkdown(raw);
@@ -689254,10 +690126,12 @@ var init_stream_renderer = __esm({
689254
690126
  }
689255
690127
  if (kind === "content" && this.lineStarted && this._cursorCol + visibleLength(raw) > maxW) {
689256
690128
  emitWrapped(raw, (s2) => this.highlightMarkdown(s2), hasNewline);
690129
+ endTrackedLine();
689257
690130
  return;
689258
690131
  }
689259
690132
  this.writeRaw(dimText(prefix) + rendered + (hasNewline ? "\n" : ""));
689260
690133
  this.lineStarted = !hasNewline;
690134
+ endTrackedLine();
689261
690135
  }
689262
690136
  /** In-place update of the compact thinking box content row (cursor-up + rewrite) */
689263
690137
  updateThinkingBox(text2, width) {
@@ -696814,7 +697688,7 @@ import {
696814
697688
  unlinkSync as unlinkSync34
696815
697689
  } from "node:fs";
696816
697690
  import { join as join168 } from "node:path";
696817
- import { createHash as createHash45 } from "node:crypto";
697691
+ import { createHash as createHash46 } from "node:crypto";
696818
697692
  function safeFilePart(value2) {
696819
697693
  return value2.replace(/[^A-Za-z0-9_.-]+/g, "_").slice(0, 80) || "telegram";
696820
697694
  }
@@ -696822,7 +697696,7 @@ function daydreamRoot(repoRoot) {
696822
697696
  return join168(repoRoot, ".omnius", "telegram-daydreams");
696823
697697
  }
696824
697698
  function sessionDir(repoRoot, sessionKey) {
696825
- const hash = createHash45("sha1").update(sessionKey).digest("hex").slice(0, 20);
697699
+ const hash = createHash46("sha1").update(sessionKey).digest("hex").slice(0, 20);
696826
697700
  return join168(daydreamRoot(repoRoot), safeFilePart(hash));
696827
697701
  }
696828
697702
  function compactLine2(value2, max = 220) {
@@ -696933,7 +697807,7 @@ function buildReplyOpportunities(input, openQuestions) {
696933
697807
  return opportunities;
696934
697808
  }
696935
697809
  function daydreamOpportunityId(input, trigger) {
696936
- return createHash45("sha1").update(`${input.sessionKey}:${input.generatedAtMs}:${trigger}`).digest("hex").slice(0, 16);
697810
+ return createHash46("sha1").update(`${input.sessionKey}:${input.generatedAtMs}:${trigger}`).digest("hex").slice(0, 16);
696937
697811
  }
696938
697812
  function clamp0115(value2) {
696939
697813
  if (!Number.isFinite(value2)) return 0;
@@ -697338,7 +698212,7 @@ function buildTelegramChannelDaydream(input, corpus, extraction, extractionCommi
697338
698212
  const seed = `${input.sessionKey}:${input.generatedAtMs}:${input.history.length}`;
697339
698213
  return {
697340
698214
  version: 3,
697341
- id: createHash45("sha1").update(seed).digest("hex").slice(0, 16),
698215
+ id: createHash46("sha1").update(seed).digest("hex").slice(0, 16),
697342
698216
  sessionKey: input.sessionKey,
697343
698217
  chatId: input.chatId,
697344
698218
  chatTitle: input.chatTitle,
@@ -697650,12 +698524,12 @@ var init_telegram_channel_dmn = __esm({
697650
698524
  });
697651
698525
 
697652
698526
  // packages/cli/src/tui/telegram-reflection-corpus.ts
697653
- import { createHash as createHash46 } from "node:crypto";
698527
+ import { createHash as createHash47 } from "node:crypto";
697654
698528
  function telegramReflectionMemoryDbPaths(repoRoot) {
697655
698529
  return omniusMemoryDbPaths(repoRoot);
697656
698530
  }
697657
698531
  function stableHash2(value2, length4 = 16) {
697658
- return createHash46("sha1").update(value2).digest("hex").slice(0, length4);
698532
+ return createHash47("sha1").update(value2).digest("hex").slice(0, length4);
697659
698533
  }
697660
698534
  function clean3(value2) {
697661
698535
  return String(value2 ?? "").replace(/\s+/g, " ").trim();
@@ -698468,7 +699342,7 @@ var init_telegram_reflection_extraction = __esm({
698468
699342
  });
698469
699343
 
698470
699344
  // packages/cli/src/tui/telegram-social-state-types.ts
698471
- import { createHash as createHash47 } from "node:crypto";
699345
+ import { createHash as createHash48 } from "node:crypto";
698472
699346
  function telegramSocialActorKey(actor) {
698473
699347
  if (!actor) return "unknown";
698474
699348
  if (typeof actor.userId === "number") return `user:${actor.userId}`;
@@ -698501,7 +699375,7 @@ function appendUnique(items, value2, max) {
698501
699375
  return next.slice(-max);
698502
699376
  }
698503
699377
  function hashTelegramSocialId(parts) {
698504
- return createHash47("sha1").update(parts.map((part) => String(part ?? "")).join(":")).digest("hex").slice(0, 16);
699378
+ return createHash48("sha1").update(parts.map((part) => String(part ?? "")).join(":")).digest("hex").slice(0, 16);
698505
699379
  }
698506
699380
  function cleanUsername(value2) {
698507
699381
  if (typeof value2 !== "string") return void 0;
@@ -699561,7 +700435,7 @@ import {
699561
700435
  } from "node:path";
699562
700436
  import { homedir as homedir56 } from "node:os";
699563
700437
  import { writeFile as writeFileAsync } from "node:fs/promises";
699564
- import { createHash as createHash48, randomBytes as randomBytes28, randomInt } from "node:crypto";
700438
+ import { createHash as createHash49, randomBytes as randomBytes28, randomInt } from "node:crypto";
699565
700439
  function formatModelBytes(bytes) {
699566
700440
  if (!Number.isFinite(bytes) || bytes <= 0) return "0 B";
699567
700441
  const units = ["B", "KB", "MB", "GB", "TB"];
@@ -700806,7 +701680,7 @@ function buildTelegramRuntimeContext(now2 = /* @__PURE__ */ new Date(), repoRoot
700806
701680
  return buildConversationRuntimeContext(now2, repoRoot);
700807
701681
  }
700808
701682
  function telegramSessionIdFromKey(sessionKey) {
700809
- return `telegram-${createHash48("sha1").update(sessionKey).digest("hex").slice(0, 16)}`;
701683
+ return `telegram-${createHash49("sha1").update(sessionKey).digest("hex").slice(0, 16)}`;
700810
701684
  }
700811
701685
  function normalizeTelegramSubAgentLimit(value2) {
700812
701686
  const parsed = typeof value2 === "number" ? value2 : typeof value2 === "string" && value2.trim() ? Number(value2.trim()) : TELEGRAM_SUB_AGENT_DEFAULT_LIMIT;
@@ -702970,7 +703844,7 @@ Telegram link integrity contract:
702970
703844
  return !!this.adminAuthChallenge && this.adminAuthChallenge.expiresAtMs > Date.now();
702971
703845
  }
702972
703846
  hashAdminAuthCode(code8) {
702973
- return createHash48("sha256").update(`omnius-telegram-admin:${code8.trim()}`).digest("hex");
703847
+ return createHash49("sha256").update(`omnius-telegram-admin:${code8.trim()}`).digest("hex");
702974
703848
  }
702975
703849
  viewIdForMessage(msg) {
702976
703850
  return `telegram-${this.sessionKeyForMessage(msg).replace(/[^A-Za-z0-9_-]/g, "-")}`;
@@ -705042,11 +705916,11 @@ ${mediaContext}` : ""
705042
705916
  return payload;
705043
705917
  }
705044
705918
  telegramConversationPath(sessionKey) {
705045
- const safe = createHash48("sha1").update(sessionKey).digest("hex").slice(0, 20);
705919
+ const safe = createHash49("sha1").update(sessionKey).digest("hex").slice(0, 20);
705046
705920
  return join170(this.telegramConversationDir, `${safe}.json`);
705047
705921
  }
705048
705922
  telegramConversationLedgerPath(sessionKey) {
705049
- const safe = createHash48("sha1").update(sessionKey).digest("hex").slice(0, 20);
705923
+ const safe = createHash49("sha1").update(sessionKey).digest("hex").slice(0, 20);
705050
705924
  return join170(this.telegramConversationDir, `${safe}.events.jsonl`);
705051
705925
  }
705052
705926
  telegramDb() {
@@ -705279,7 +706153,7 @@ ${mediaContext}` : ""
705279
706153
  relationships: Array.isArray(raw.relationships) ? raw.relationships.slice(0, TELEGRAM_ASSOCIATIVE_RELATION_LIMIT).map((fact) => this.normalizeTelegramAssociativeFact(fact)) : [],
705280
706154
  actions: Array.isArray(raw.actions) ? raw.actions.slice(-TELEGRAM_ASSOCIATIVE_ACTION_LIMIT).map((action) => ({
705281
706155
  id: String(
705282
- action.id || createHash48("sha1").update(JSON.stringify(action)).digest("hex").slice(0, 12)
706156
+ action.id || createHash49("sha1").update(JSON.stringify(action)).digest("hex").slice(0, 12)
705283
706157
  ),
705284
706158
  ts: typeof action.ts === "number" ? action.ts : Date.now(),
705285
706159
  role: action.role === "assistant" ? "assistant" : "user",
@@ -705298,7 +706172,7 @@ ${mediaContext}` : ""
705298
706172
  const now2 = Date.now();
705299
706173
  return {
705300
706174
  id: String(
705301
- raw.id || createHash48("sha1").update(text2 || String(now2)).digest("hex").slice(0, 12)
706175
+ raw.id || createHash49("sha1").update(text2 || String(now2)).digest("hex").slice(0, 12)
705302
706176
  ),
705303
706177
  text: text2,
705304
706178
  tags: Array.isArray(raw.tags) ? raw.tags.map(String).slice(0, 16) : [],
@@ -705755,7 +706629,7 @@ ${mediaContext}` : ""
705755
706629
  telegramHistoryBackfillMessageId(sessionKey, entry, index) {
705756
706630
  if (typeof entry.messageId === "number" && Number.isFinite(entry.messageId))
705757
706631
  return entry.messageId;
705758
- const digest3 = createHash48("sha1").update(
706632
+ const digest3 = createHash49("sha1").update(
705759
706633
  `${sessionKey}:${index}:${entry.role}:${entry.ts ?? ""}:${entry.text}`
705760
706634
  ).digest("hex").slice(0, 8);
705761
706635
  return -Number.parseInt(digest3, 16);
@@ -706945,7 +707819,7 @@ ${mediaContext}` : ""
706945
707819
  const now2 = entry.ts ?? Date.now();
706946
707820
  memory.updatedAt = now2;
706947
707821
  const speaker = telegramHistorySpeaker(entry);
706948
- const actionId = createHash48("sha1").update(
707822
+ const actionId = createHash49("sha1").update(
706949
707823
  `${sessionKey}:${entry.role}:${entry.messageId ?? ""}:${now2}:${entry.text}`
706950
707824
  ).digest("hex").slice(0, 16);
706951
707825
  if (!memory.actions.some((action) => action.id === actionId)) {
@@ -707108,7 +707982,7 @@ ${mediaContext}` : ""
707108
707982
  let fact = facts.find((item) => item.text.toLowerCase() === key);
707109
707983
  if (!fact) {
707110
707984
  fact = {
707111
- id: createHash48("sha1").update(`${entry.chatId ?? ""}:${key}`).digest("hex").slice(0, 12),
707985
+ id: createHash49("sha1").update(`${entry.chatId ?? ""}:${key}`).digest("hex").slice(0, 12),
707112
707986
  text: clean5,
707113
707987
  tags: telegramMemoryTags(clean5, entry.mediaSummary),
707114
707988
  speakers: [],
@@ -707193,7 +708067,7 @@ ${mediaContext}` : ""
707193
708067
  const titleTags = tags.slice(0, 4);
707194
708068
  const title = titleTags.length > 0 ? `${speaker} / ${titleTags.join(" ")}` : `${speaker} / conversation`;
707195
708069
  const card = {
707196
- id: createHash48("sha1").update(`${sessionKey}:${now2}:${speaker}:${text2}`).digest("hex").slice(0, 12),
708070
+ id: createHash49("sha1").update(`${sessionKey}:${now2}:${speaker}:${text2}`).digest("hex").slice(0, 12),
707197
708071
  title,
707198
708072
  notes: [],
707199
708073
  tags: [],
@@ -709957,7 +710831,7 @@ ${list}` : "No shared group target is currently known for this sender. Ask in th
709957
710831
  }
709958
710832
  telegramRunnerStateDir(sessionKey) {
709959
710833
  if (!this.repoRoot) return void 0;
709960
- const safe = createHash48("sha1").update(sessionKey).digest("hex").slice(0, 20);
710834
+ const safe = createHash49("sha1").update(sessionKey).digest("hex").slice(0, 20);
709961
710835
  return join170(this.repoRoot, ".omnius", "telegram-runner-state", safe);
709962
710836
  }
709963
710837
  buildTelegramAdminOverviewContext(currentSessionKey) {
@@ -720652,14 +721526,14 @@ var init_access_policy = __esm({
720652
721526
  });
720653
721527
 
720654
721528
  // packages/cli/src/api/project-preferences.ts
720655
- import { createHash as createHash49 } from "node:crypto";
721529
+ import { createHash as createHash50 } from "node:crypto";
720656
721530
  import { existsSync as existsSync162, mkdirSync as mkdirSync100, readFileSync as readFileSync133, renameSync as renameSync16, writeFileSync as writeFileSync87, unlinkSync as unlinkSync37 } from "node:fs";
720657
721531
  import { homedir as homedir58 } from "node:os";
720658
721532
  import { join as join172, resolve as resolve75 } from "node:path";
720659
721533
  import { randomUUID as randomUUID20 } from "node:crypto";
720660
721534
  function projectKey(root) {
720661
721535
  const canonical = resolve75(root);
720662
- return createHash49("sha256").update(canonical).digest("hex").slice(0, 16);
721536
+ return createHash50("sha256").update(canonical).digest("hex").slice(0, 16);
720663
721537
  }
720664
721538
  function projectDir(root) {
720665
721539
  return join172(PROJECTS_DIR, projectKey(root));
@@ -720950,7 +721824,7 @@ var init_disk_task_output = __esm({
720950
721824
  });
720951
721825
 
720952
721826
  // packages/cli/src/api/http.ts
720953
- import { createHash as createHash50 } from "node:crypto";
721827
+ import { createHash as createHash51 } from "node:crypto";
720954
721828
  function problemDetails(opts) {
720955
721829
  const p2 = {
720956
721830
  type: opts.type ?? "about:blank",
@@ -721013,7 +721887,7 @@ function paginated(items, page2, total) {
721013
721887
  }
721014
721888
  function computeEtag(payload) {
721015
721889
  const json = typeof payload === "string" ? payload : JSON.stringify(payload);
721016
- const hash = createHash50("sha1").update(json).digest("hex").slice(0, 16);
721890
+ const hash = createHash51("sha1").update(json).digest("hex").slice(0, 16);
721017
721891
  return `W/"${hash}"`;
721018
721892
  }
721019
721893
  function checkNotModified(req3, res, etag) {
@@ -740424,7 +741298,7 @@ import {
740424
741298
  closeSync as closeSync6
740425
741299
  } from "node:fs";
740426
741300
  import { randomBytes as randomBytes29, randomUUID as randomUUID21, timingSafeEqual as timingSafeEqual2 } from "node:crypto";
740427
- import { createHash as createHash51 } from "node:crypto";
741301
+ import { createHash as createHash52 } from "node:crypto";
740428
741302
  function memoryDbPaths3(baseDir = process.cwd()) {
740429
741303
  const dir = join183(baseDir, ".omnius");
740430
741304
  return {
@@ -748593,7 +749467,7 @@ function listScheduledTasks() {
748593
749467
  );
748594
749468
  const enabled2 = typeof t2?.enabled === "boolean" ? t2.enabled : true;
748595
749469
  const realId = typeof t2?.id === "string" && t2.id ? t2.id : null;
748596
- const fallbackId = createHash51("sha1").update(`${file}#${i2}`).digest("hex").slice(0, 16);
749470
+ const fallbackId = createHash52("sha1").update(`${file}#${i2}`).digest("hex").slice(0, 16);
748597
749471
  const uid = realId || fallbackId;
748598
749472
  const key = `${uid}`;
748599
749473
  if (seen.has(key)) return;
@@ -748731,8 +749605,8 @@ function deleteScheduledById(id2) {
748731
749605
  if (typeof entry?.id === "string" && entry.id && !candidates.includes(entry.id))
748732
749606
  candidates.push(entry.id);
748733
749607
  try {
748734
- const { createHash: createHash53 } = require4("node:crypto");
748735
- const fallback = createHash53("sha1").update(`${target.file}#${target.index}`).digest("hex").slice(0, 16);
749608
+ const { createHash: createHash54 } = require4("node:crypto");
749609
+ const fallback = createHash54("sha1").update(`${target.file}#${target.index}`).digest("hex").slice(0, 16);
748736
749610
  if (!candidates.includes(fallback)) candidates.push(fallback);
748737
749611
  } catch {
748738
749612
  }
@@ -750969,7 +751843,7 @@ import { cwd } from "node:process";
750969
751843
  import { resolve as resolve78, join as join185, dirname as dirname56, extname as extname22, relative as relative22, sep as sep7 } from "node:path";
750970
751844
  import { createRequire as createRequire9 } from "node:module";
750971
751845
  import { fileURLToPath as fileURLToPath24 } from "node:url";
750972
- import { createHash as createHash52 } from "node:crypto";
751846
+ import { createHash as createHash53 } from "node:crypto";
750973
751847
  import {
750974
751848
  readFileSync as readFileSync142,
750975
751849
  writeFileSync as writeFileSync94,
@@ -751903,7 +752777,7 @@ function truncateSubAgentViewText(s2, n2) {
751903
752777
  return s2.length > n2 ? `${s2.slice(0, n2)}…` : s2;
751904
752778
  }
751905
752779
  function childAgentTaskHash(task) {
751906
- return createHash52("sha256").update(task).digest("hex").slice(0, 12);
752780
+ return createHash53("sha256").update(task).digest("hex").slice(0, 12);
751907
752781
  }
751908
752782
  function stripAnsiForParentContext(value2) {
751909
752783
  return value2.replace(/\x1b\[[0-9;?]*[ -/]*[@-~]/g, "");
@@ -757008,6 +757882,12 @@ This is an independent background session started from /background.`
757008
757882
  process.stdout.on("resize", () => {
757009
757883
  statusBar.handleResize();
757010
757884
  setTermSize(process.stdout.rows ?? 24, process.stdout.columns ?? 80);
757885
+ if (!isNeovimActive()) {
757886
+ try {
757887
+ streamRenderer.onResize();
757888
+ } catch {
757889
+ }
757890
+ }
757011
757891
  if (isNeovimActive()) {
757012
757892
  const contentRows = statusBar.isActive ? statusBar.availableContentRows : Math.max(5, termRows() - 6);
757013
757893
  resizeNeovim(termCols(), contentRows);
@@ -761224,13 +762104,13 @@ ${taskInput}`;
761224
762104
  writeContent(() => renderError(errMsg));
761225
762105
  if (failureStore) {
761226
762106
  try {
761227
- const { createHash: createHash53 } = await import("node:crypto");
762107
+ const { createHash: createHash54 } = await import("node:crypto");
761228
762108
  failureStore.insert({
761229
762109
  taskId: "",
761230
762110
  sessionId: `${Date.now()}`,
761231
762111
  repoRoot,
761232
762112
  failureType: "runtime-error",
761233
- fingerprint: createHash53("sha256").update(errMsg.slice(0, 200)).digest("hex").slice(0, 16),
762113
+ fingerprint: createHash54("sha256").update(errMsg.slice(0, 200)).digest("hex").slice(0, 16),
761234
762114
  filePath: null,
761235
762115
  errorMessage: errMsg.slice(0, 500),
761236
762116
  context: null,