omnius 1.0.477 → 1.0.479

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
@@ -26393,6 +26393,116 @@ var init_compaction_policy = __esm({
26393
26393
  }
26394
26394
  });
26395
26395
 
26396
+ // packages/memory/dist/evidence-retirement.js
26397
+ function extractDiagnosticSymbols(text2) {
26398
+ const symbols = /* @__PURE__ */ new Set();
26399
+ let count = 0;
26400
+ for (const line of text2.split("\n")) {
26401
+ if (!DIAG_LINE.test(line))
26402
+ continue;
26403
+ count += 1;
26404
+ let m2;
26405
+ QUOTED_SYMBOL.lastIndex = 0;
26406
+ while ((m2 = QUOTED_SYMBOL.exec(line)) !== null) {
26407
+ if (/^[A-Za-z_]/.test(m2[1]) && !m2[1].includes("/"))
26408
+ symbols.add(m2[1]);
26409
+ if (symbols.size >= 12)
26410
+ break;
26411
+ }
26412
+ }
26413
+ return { count, symbols: [...symbols] };
26414
+ }
26415
+ function isRetirableEvidence(message2, minChars) {
26416
+ if (message2.pinned)
26417
+ return false;
26418
+ if (typeof message2.content !== "string")
26419
+ return false;
26420
+ if (message2.content.length < minChars)
26421
+ return false;
26422
+ if (message2.role === "tool")
26423
+ return true;
26424
+ if (message2.role !== "system")
26425
+ return false;
26426
+ return EVIDENCE_MARKERS.some((m2) => message2.content.includes(m2));
26427
+ }
26428
+ function foldEvidenceOutcome(message2) {
26429
+ const text2 = message2.content;
26430
+ const diag = extractDiagnosticSymbols(text2);
26431
+ if (diag.count > 0) {
26432
+ const syms = diag.symbols.slice(0, 6);
26433
+ const exit = /exit_code:\s*(\d+)|Exit code (\d+)/.exec(text2);
26434
+ const code8 = exit ? exit[1] ?? exit[2] : void 0;
26435
+ return `${diag.count} diagnostic(s)${code8 ? ` (exit ${code8})` : ""}${syms.length ? `: ${syms.join(", ")}` : ""}`;
26436
+ }
26437
+ const fileHdr = /\[FILE CONTEXT[^\]]*\]/.exec(text2);
26438
+ if (fileHdr)
26439
+ return fileHdr[0].replace(/^\[|\]$/g, "").trim();
26440
+ if (text2.includes("[SHELL TRANSCRIPT]")) {
26441
+ const cmd = /command:\s*([^\n]+)/.exec(text2);
26442
+ const exit = /exit_code:\s*(\d+)|Exit code (\d+)/.exec(text2);
26443
+ const err = /(^|\n)\s*([^\n]*\berror\b[^\n]*)/i.exec(text2);
26444
+ const parts = [
26445
+ cmd ? `cmd: ${cmd[1].trim().slice(0, 80)}` : "",
26446
+ exit ? `exit ${exit[1] ?? exit[2]}` : "",
26447
+ err ? err[2].trim().slice(0, 100) : ""
26448
+ ].filter(Boolean);
26449
+ if (parts.length)
26450
+ return parts.join("; ");
26451
+ }
26452
+ const firstLine = text2.split("\n").map((l2) => l2.trim()).find((l2) => l2.length > 0 && !EVIDENCE_MARKERS.some((m2) => l2.startsWith(m2)));
26453
+ return (firstLine ?? "evidence").slice(0, 120);
26454
+ }
26455
+ function retirementStub(message2, outcome, originalChars) {
26456
+ const ref = message2.diskRef ? ` ref=${message2.diskRef}` : "";
26457
+ const tool = message2.toolName ? ` tool=${message2.toolName}` : "";
26458
+ const turn = typeof message2.turn === "number" ? ` turn=${message2.turn}` : "";
26459
+ return `[RETIRED EVIDENCE${tool}${turn} bytes=${originalChars}${ref}] outcome: ${outcome}
26460
+ (full evidence retired to disk — re-read the file or re-run the command to re-materialise if you need the detail)`;
26461
+ }
26462
+ function retireStaleEvidence(messages2, options2) {
26463
+ const keepRecentTurns = Math.max(0, options2.keepRecentTurns ?? 2);
26464
+ const minChars = Math.max(256, options2.minChars ?? 2e3);
26465
+ const summarize2 = options2.summarize ?? foldEvidenceOutcome;
26466
+ const staleBefore = options2.currentTurn - keepRecentTurns;
26467
+ let retiredCount = 0;
26468
+ let reclaimedChars = 0;
26469
+ const out = messages2.map((message2) => {
26470
+ if (typeof message2.turn !== "number" || message2.turn > staleBefore) {
26471
+ return message2;
26472
+ }
26473
+ if (!isRetirableEvidence(message2, minChars))
26474
+ return message2;
26475
+ const originalChars = message2.content.length;
26476
+ let outcome;
26477
+ try {
26478
+ outcome = summarize2(message2);
26479
+ } catch {
26480
+ outcome = "evidence";
26481
+ }
26482
+ const stub = retirementStub(message2, outcome, originalChars);
26483
+ if (stub.length >= originalChars)
26484
+ return message2;
26485
+ retiredCount += 1;
26486
+ reclaimedChars += originalChars - stub.length;
26487
+ return { ...message2, content: stub };
26488
+ });
26489
+ return { messages: out, retiredCount, reclaimedChars };
26490
+ }
26491
+ var DIAG_LINE, QUOTED_SYMBOL, EVIDENCE_MARKERS;
26492
+ var init_evidence_retirement = __esm({
26493
+ "packages/memory/dist/evidence-retirement.js"() {
26494
+ "use strict";
26495
+ DIAG_LINE = /\berror\b\s*:/i;
26496
+ QUOTED_SYMBOL = /['"`]([A-Za-z_][A-Za-z0-9_:.<>]{1,80})['"`]/g;
26497
+ EVIDENCE_MARKERS = [
26498
+ "[SHELL TRANSCRIPT]",
26499
+ "[FILE CONTEXT",
26500
+ "[RUN EVIDENCE]",
26501
+ "[TOOL RESULT]"
26502
+ ];
26503
+ }
26504
+ });
26505
+
26396
26506
  // packages/memory/dist/index.js
26397
26507
  var dist_exports = {};
26398
26508
  __export(dist_exports, {
@@ -26494,6 +26604,7 @@ __export(dist_exports, {
26494
26604
  extractTrace: () => extractTrace,
26495
26605
  findNeighbors: () => findNeighbors,
26496
26606
  fingerprintSignature: () => fingerprintSignature,
26607
+ foldEvidenceOutcome: () => foldEvidenceOutcome,
26497
26608
  freshNodeId: () => freshNodeId,
26498
26609
  generateEmbedding: () => generateEmbedding,
26499
26610
  generateEmbeddingBatch: () => generateEmbeddingBatch,
@@ -26503,6 +26614,7 @@ __export(dist_exports, {
26503
26614
  inferDomainFromEpisode: () => inferDomainFromEpisode,
26504
26615
  ingestContextFeedbackMarkdown: () => ingestContextFeedbackMarkdown,
26505
26616
  initDb: () => initDb,
26617
+ isRetirableEvidence: () => isRetirableEvidence,
26506
26618
  isSessionGist: () => isSessionGist,
26507
26619
  lightSleep: () => lightSleep,
26508
26620
  linkEpisode: () => linkEpisode,
@@ -26525,6 +26637,7 @@ __export(dist_exports, {
26525
26637
  reinforceGraphNodes: () => reinforceGraphNodes,
26526
26638
  remDream: () => remDream,
26527
26639
  resetCRLConfigStore: () => resetCRLConfigStore,
26640
+ retireStaleEvidence: () => retireStaleEvidence,
26528
26641
  retrieveByPPR: () => retrieveByPPR,
26529
26642
  runConsolidationCycle: () => runConsolidationCycle,
26530
26643
  runMemoryMaintenance: () => runMemoryMaintenance,
@@ -26609,6 +26722,7 @@ var init_dist = __esm({
26609
26722
  init_attention_select();
26610
26723
  init_context_folding();
26611
26724
  init_compaction_policy();
26725
+ init_evidence_retirement();
26612
26726
  }
26613
26727
  });
26614
26728
 
@@ -552472,7 +552586,7 @@ var init_agent_tool = __esm({
552472
552586
  },
552473
552587
  subagent_type: {
552474
552588
  type: "string",
552475
- enum: ["general", "explore", "plan", "coordinator"],
552589
+ enum: ["general", "explore", "plan", "coordinator", "fixer"],
552476
552590
  description: "Agent type determining tool access and behavior (default: general)"
552477
552591
  },
552478
552592
  deployment_pattern: {
@@ -576129,6 +576243,13 @@ function failureProgressSignal(text2) {
576129
576243
  }
576130
576244
  return lines > 0 ? lines : void 0;
576131
576245
  }
576246
+ function isVerificationCommand(toolName, output) {
576247
+ if (isEditTool(toolName))
576248
+ return false;
576249
+ if (toolName !== "shell" && toolName !== "background_run")
576250
+ return false;
576251
+ return failureProgressSignal(output) != null;
576252
+ }
576132
576253
  function actionFamily(toolName, args, cwd4) {
576133
576254
  if (isEditTool(toolName)) {
576134
576255
  const path13 = primaryPath(args);
@@ -576590,10 +576711,24 @@ var init_focusSupervisor = __esm({
576590
576711
  // Root fix: progress = the action's error count dropped, not that an
576591
576712
  // edit happened. Extract the signal from the action's own output so a
576592
576713
  // futile edit loop (rebuilding with the same error count) escalates.
576593
- failureSignal: failureProgressSignal(input.output || input.error)
576714
+ failureSignal: failureProgressSignal(input.output || input.error),
576715
+ // Build-as-feedback: a build/test command is the verification oracle,
576716
+ // never a failing action to abandon. When set, the breaker caps this
576717
+ // family below terminal abandon and escalates to decompose-and-delegate.
576718
+ isVerificationFeedback: isVerificationCommand(input.toolName, input.output || input.error)
576594
576719
  });
576595
576720
  this.sawMutationSinceFailure = false;
576596
- if (verdict.tier === "abandon") {
576721
+ if (verdict.recommendedAction === "decompose_and_delegate") {
576722
+ this.setDirective({
576723
+ turn: input.turn,
576724
+ state: "forced_replan",
576725
+ reason: verdict.reason,
576726
+ requiredNextAction: this.resolveRequiredNextAction("delegate_isolated_fix"),
576727
+ forbiddenActionFamilies: [
576728
+ actionFamily(input.toolName, input.args, this.familyCwd)
576729
+ ]
576730
+ });
576731
+ } else if (verdict.tier === "abandon") {
576597
576732
  this.markTerminalIncomplete(verdict.reason, input.turn);
576598
576733
  } else if (verdict.tier === "stalled") {
576599
576734
  this.setDirective({
@@ -576788,7 +576923,10 @@ var init_convergence_breaker = __esm({
576788
576923
  }
576789
576924
  const sessionCount = Math.max(1, obs.sessionCount);
576790
576925
  const totalRounds = Math.max(1, base3 + sessionCount - dec);
576791
- const tier = this.tierFor(totalRounds);
576926
+ let tier = this.tierFor(totalRounds);
576927
+ if (obs.isVerificationFeedback && tier === "abandon") {
576928
+ tier = "stalled";
576929
+ }
576792
576930
  this.live.set(obs.family, { totalRounds, tier });
576793
576931
  const carry = this.store.load(obs.family);
576794
576932
  this.store.save({
@@ -576797,7 +576935,7 @@ var init_convergence_breaker = __esm({
576797
576935
  lastSample: obs.sample ?? carry?.lastSample,
576798
576936
  updatedAtMs: Date.now()
576799
576937
  });
576800
- return this.verdict(obs.family, totalRounds, tier, obs.sample);
576938
+ return this.verdict(obs.family, totalRounds, tier, obs.sample, obs.isVerificationFeedback ?? false);
576801
576939
  }
576802
576940
  /** Clear a family's carry when its underlying work is verified/complete. */
576803
576941
  resolve(family) {
@@ -576825,8 +576963,18 @@ var init_convergence_breaker = __esm({
576825
576963
  return "converging_warn";
576826
576964
  return "healthy";
576827
576965
  }
576828
- verdict(family, totalRounds, tier, sample) {
576966
+ verdict(family, totalRounds, tier, sample, verificationFeedback = false) {
576829
576967
  const suffix = sample ? `: ${sample}` : "";
576968
+ if (verificationFeedback && (tier === "stalled" || tier === "abandon")) {
576969
+ return {
576970
+ tier: "stalled",
576971
+ tripped: true,
576972
+ totalRounds,
576973
+ family,
576974
+ reason: `verification command "${family}" has reported the same diagnostic set for ${totalRounds} rounds without shrinking. The build is FEEDBACK, not a failing action — do NOT abandon and do NOT re-run it blindly. Decompose its diagnostics: pick the single top implicated file/symbol, delegate an isolated investigate→fix sub-task for it (sub_agent), then re-run the build to test. Repeat until the diagnostic count drops${suffix}`,
576975
+ recommendedAction: "decompose_and_delegate"
576976
+ };
576977
+ }
576830
576978
  switch (tier) {
576831
576979
  case "abandon":
576832
576980
  return {
@@ -577058,6 +577206,93 @@ var init_spec_gate = __esm({
577058
577206
  }
577059
577207
  });
577060
577208
 
577209
+ // packages/orchestrator/dist/decomposition-orchestrator.js
577210
+ function decomposeToUnits(modules, contract, symbolSources = /* @__PURE__ */ new Map(), options2 = {}) {
577211
+ const maxUnits = Math.max(1, options2.maxUnits ?? 200);
577212
+ const units = [];
577213
+ const symbolsByPath = /* @__PURE__ */ new Map();
577214
+ for (const spec of contract.symbols) {
577215
+ const src2 = symbolSources.get(spec.name);
577216
+ if (!src2)
577217
+ continue;
577218
+ const arr = symbolsByPath.get(src2) ?? [];
577219
+ arr.push(spec);
577220
+ symbolsByPath.set(src2, arr);
577221
+ }
577222
+ let i2 = 0;
577223
+ for (const m2 of modules) {
577224
+ if (units.length >= maxUnits)
577225
+ break;
577226
+ const fileId = `unit-file-${++i2}`;
577227
+ const symbols = symbolsByPath.get(m2.path) ?? [];
577228
+ units.push({
577229
+ id: fileId,
577230
+ path: m2.path,
577231
+ content: `Implement ${m2.path} (delegate via sub_agent for isolated context)`,
577232
+ status: "pending",
577233
+ exitCriterion: symbols.length > 0 ? `${m2.path} compiles AND declares ${symbols.map((s2) => s2.name).join(", ")} matching the locked contract` : `${m2.path} compiles cleanly`
577234
+ });
577235
+ let j = 0;
577236
+ for (const s2 of symbols) {
577237
+ if (units.length >= maxUnits)
577238
+ break;
577239
+ units.push({
577240
+ id: `${fileId}-sym-${++j}`,
577241
+ parentId: fileId,
577242
+ path: m2.path,
577243
+ symbol: s2.name,
577244
+ content: `Declare ${s2.kind} ${s2.name} in ${m2.path} to match the locked contract`,
577245
+ status: "pending",
577246
+ exitCriterion: `${s2.name} declared exactly once with the contract shape; ${m2.path} compiles`
577247
+ });
577248
+ }
577249
+ }
577250
+ return units;
577251
+ }
577252
+ function evaluateUnitResult(input) {
577253
+ const expectedSymbols = input.unit.symbol ? [input.unit.symbol] : input.contract.symbols.filter((s2) => true).map((s2) => s2.name).filter((name10) => input.emittedSource.includes(name10));
577254
+ const spec = evaluateSpecGate({ path: input.unit.path, source: input.emittedSource }, input.contract, { expectedSymbols });
577255
+ const diagnostics = parseCompilerDiagnostics(String(input.buildOutput || ""));
577256
+ const structural = diagnostics.filter((d2) => d2.kind === "signature_mismatch" || d2.kind === "duplicate_definition" || d2.kind === "unknown_member" || d2.kind === "unknown_symbol" || d2.kind === "type_error");
577257
+ if (spec.pass && structural.length === 0) {
577258
+ const label = input.unit.symbol ?? input.unit.path;
577259
+ return {
577260
+ decision: "accept",
577261
+ foldSummary: `${label}: verified (declares ${expectedSymbols.join(", ") || "unit"}, compiles clean)`,
577262
+ violations: [],
577263
+ diagnosticsCount: 0
577264
+ };
577265
+ }
577266
+ const reasons = [];
577267
+ if (!spec.pass)
577268
+ reasons.push(spec.summary);
577269
+ if (structural.length > 0) {
577270
+ const syms = [...new Set(structural.map((d2) => d2.symbol).filter(Boolean))];
577271
+ reasons.push(`${structural.length} compiler diagnostic(s)${syms.length ? ` on ${syms.slice(0, 4).join(", ")}` : ""}`);
577272
+ }
577273
+ return {
577274
+ decision: "reject_regenerate",
577275
+ rejectReason: `Unit ${input.unit.path}${input.unit.symbol ? ` (${input.unit.symbol})` : ""} does not verify — regenerate against the locked contract: ${reasons.join("; ")}`,
577276
+ violations: spec.violations,
577277
+ diagnosticsCount: structural.length
577278
+ };
577279
+ }
577280
+ function buildUnitTodos(units) {
577281
+ return units.map((u) => ({
577282
+ id: u.id,
577283
+ content: u.content,
577284
+ status: u.status,
577285
+ ...u.parentId ? { parentId: u.parentId } : {}
577286
+ }));
577287
+ }
577288
+ var init_decomposition_orchestrator = __esm({
577289
+ "packages/orchestrator/dist/decomposition-orchestrator.js"() {
577290
+ "use strict";
577291
+ init_spec_gate();
577292
+ init_dist5();
577293
+ }
577294
+ });
577295
+
577061
577296
  // packages/orchestrator/dist/longhaul-integration.js
577062
577297
  import fs6 from "node:fs";
577063
577298
  import path7 from "node:path";
@@ -577110,6 +577345,7 @@ var init_longhaul_integration = __esm({
577110
577345
  init_convergence_breaker();
577111
577346
  init_coherence_gate();
577112
577347
  init_spec_gate();
577348
+ init_decomposition_orchestrator();
577113
577349
  init_dist5();
577114
577350
  init_dist();
577115
577351
  init_dist();
@@ -577166,6 +577402,8 @@ var init_longhaul_integration = __esm({
577166
577402
  * breaker's "regenerate from the locked contract" guidance a real target.
577167
577403
  */
577168
577404
  locked = /* @__PURE__ */ new Map();
577405
+ /** WO-11: provenance — which file each locked symbol was declared in. */
577406
+ lockedSource = /* @__PURE__ */ new Map();
577169
577407
  constructor(options2) {
577170
577408
  this.convergenceBreaker = new ConvergenceBreaker({
577171
577409
  ...options2.convergence,
@@ -577233,8 +577471,10 @@ var init_longhaul_integration = __esm({
577233
577471
  if (verdict.regime === "regenerate")
577234
577472
  return this.locked.size;
577235
577473
  for (const s2 of extractSymbols3(input.content, lang)) {
577236
- if (!this.locked.has(s2.name))
577474
+ if (!this.locked.has(s2.name)) {
577237
577475
  this.locked.set(s2.name, s2);
577476
+ this.lockedSource.set(s2.name, input.path);
577477
+ }
577238
577478
  }
577239
577479
  return this.locked.size;
577240
577480
  } catch {
@@ -577245,6 +577485,39 @@ var init_longhaul_integration = __esm({
577245
577485
  lockedContract() {
577246
577486
  return { symbols: [...this.locked.values()] };
577247
577487
  }
577488
+ /** WO-11: map of locked symbol name → declaring file (for per-symbol units). */
577489
+ symbolSources() {
577490
+ return new Map(this.lockedSource);
577491
+ }
577492
+ /**
577493
+ * WO-11: extreme-granularity unit todo TREE for the TUI expanded-list mirror.
577494
+ * When the locked contract has symbols, each file expands into per-symbol
577495
+ * children; otherwise it degrades to the existing per-file granularity (safe
577496
+ * drop-in). Enriches as the contract fills across the run.
577497
+ */
577498
+ unitTreeTodos(modules) {
577499
+ try {
577500
+ const units = decomposeToUnits(modules, this.lockedContract(), this.symbolSources());
577501
+ return buildUnitTodos(units);
577502
+ } catch {
577503
+ return modules.map((m2, i2) => ({
577504
+ id: `unit-file-${i2 + 1}`,
577505
+ content: `Implement ${m2.path}`,
577506
+ status: "pending"
577507
+ }));
577508
+ }
577509
+ }
577510
+ /** WO-11: whether the contract is rich enough to expand into symbol children. */
577511
+ hasSymbolGranularity() {
577512
+ return this.lockedSource.size > 0;
577513
+ }
577514
+ /**
577515
+ * WO-11: compile-verify-FOLD gate for a delegated unit's result. Accept only
577516
+ * when it matches the contract AND compiles; else return the regenerate reason.
577517
+ */
577518
+ evaluateUnit(input) {
577519
+ return evaluateUnitResult({ ...input, contract: this.lockedContract() });
577520
+ }
577248
577521
  /**
577249
577522
  * WO-6: gate an emitted boundary unit against the locked contract. Returns
577250
577523
  * guidance naming symbols that diverge from (or duplicate) a locked shape, so
@@ -577274,6 +577547,39 @@ var init_longhaul_integration = __esm({
577274
577547
  * Uses the model's own compiler output — no separate compiler run. Generic
577275
577548
  * across gcc/clang/tsc; returns null when there's nothing structural.
577276
577549
  */
577550
+ /**
577551
+ * B (delegation): turn a stuck build's diagnostics into an ACTIONABLE isolated
577552
+ * sub-task. The main loop is the orchestrator — it holds trajectory and
577553
+ * delegates; it must not keep re-running the build in a saturating context.
577554
+ * This picks the single top structural diagnostic (a file+symbol the compiler
577555
+ * named) and returns the exact `sub_agent` call to spawn an isolated,
577556
+ * small-context worker that fixes JUST that unit, then folds a one-line result
577557
+ * back. Generic: symbols/files come from the compiler's own output, no
577558
+ * toolchain literals. Returns null when the output has no nameable structural
577559
+ * unit (nothing concrete to delegate).
577560
+ */
577561
+ buildDelegationDirective(output) {
577562
+ try {
577563
+ const diags = parseCompilerDiagnostics(String(output || ""));
577564
+ const structural = diags.filter((d2) => d2.kind === "signature_mismatch" || d2.kind === "duplicate_definition" || d2.kind === "unknown_member" || d2.kind === "unknown_symbol" || d2.kind === "type_error");
577565
+ const top = structural.find((d2) => d2.file && d2.symbol) ?? structural.find((d2) => d2.file) ?? diags.find((d2) => d2.file) ?? structural[0] ?? diags[0];
577566
+ if (!top)
577567
+ return null;
577568
+ const file = top.file ?? "the top implicated file";
577569
+ const symbol3 = top.symbol ? ` symbol \`${top.symbol}\`` : "";
577570
+ const kind = top.kind.replace(/_/g, " ");
577571
+ const contractHint = top.symbol && this.lockedSource.has(top.symbol) ? ` The locked contract for \`${top.symbol}\` lives in ${this.lockedSource.get(top.symbol)} — match it exactly.` : "";
577572
+ return `[DELEGATE — build is feedback, not the task] The build reported a stable diagnostic set. Do NOT re-run the build and do NOT keep editing in this context. Delegate ONE isolated fix to a seeded sub-agent, then re-run the build to test:
577573
+ sub_agent({
577574
+ subagent_type: "fixer",
577575
+ description: "fix ${top.symbol ?? file}",
577576
+ prompt: "In ${file}, resolve the ${kind}${symbol3}. Read ONLY ${file} (and the file that declares${symbol3 || " the offending symbol"}). Make the minimal edit to satisfy the contract. Do not touch unrelated files. Report a one-line outcome.${contractHint}"
577577
+ })
577578
+ The sub-agent works in its own small context; when it folds back, run the build once to verify the diagnostic count dropped, then delegate the next one. This is fan-out/converge — keep THIS context on trajectory, not on the raw fix.`;
577579
+ } catch {
577580
+ return null;
577581
+ }
577582
+ }
577277
577583
  diagnosticGuidance(output) {
577278
577584
  try {
577279
577585
  const diags = parseCompilerDiagnostics(String(output || ""));
@@ -580759,6 +581065,8 @@ var init_agenticRunner = __esm({
580759
581065
  /** WO-1..WO-8 long-haul integration bundle (convergence, adaptive-edit,
580760
581066
  * coherence, folding). Constructed at run setup alongside the supervisor. */
580761
581067
  _longHaul = null;
581068
+ /** WO-11: decomposition modules (files) stashed for contract-enriched todo trees. */
581069
+ _decompModules = [];
580762
581070
  _focusTerminalLedgerRecorded = false;
580763
581071
  // Generic, cross-session failure→resolution learning: learns the token-level
580764
581072
  // change that turned a failed command into a working one (e.g. python→python3)
@@ -587819,7 +588127,23 @@ TASK: ${scrubbedTask}` : scrubbedTask;
587819
588127
  if (_decomp.modules.length > 0) {
587820
588128
  const _directive = buildDecompositionDirective(_decomp.modules, _decomp.strategy);
587821
588129
  messages2.push({ role: "system", content: _directive });
587822
- const _todos = buildDecompositionTodos(_decomp.modules);
588130
+ this._decompModules = _decomp.modules;
588131
+ if (this._longHaul) {
588132
+ const _wd = this.authoritativeWorkingDirectory();
588133
+ for (const _m of _decomp.modules) {
588134
+ try {
588135
+ const _abs = _pathResolve(_wd, _m.path);
588136
+ if (_fsExistsSync(_abs)) {
588137
+ this._longHaul.maybeLockContract({
588138
+ path: _m.path,
588139
+ content: _fsReadFileSync(_abs, "utf-8")
588140
+ });
588141
+ }
588142
+ } catch {
588143
+ }
588144
+ }
588145
+ }
588146
+ const _todos = this._longHaul && this._longHaul.hasSymbolGranularity() ? this._longHaul.unitTreeTodos(_decomp.modules) : buildDecompositionTodos(_decomp.modules);
587823
588147
  try {
587824
588148
  const sid = this._sessionId || process.env["OMNIUS_SESSION_ID"] || "default";
587825
588149
  const safe = sid.replace(/[^a-zA-Z0-9_.-]/g, "_");
@@ -589681,6 +590005,7 @@ If you're stuck, try a completely different approach. Do NOT repeat what failed
589681
590005
  messages2.push(...compacted);
589682
590006
  compacted = messages2;
589683
590007
  }
590008
+ this._retireStaleEvidenceInPlace(messages2, turn);
589684
590009
  if (turn > 0 && this._toolEvents.length > 0) {
589685
590010
  try {
589686
590011
  const _limits = this.contextLimits();
@@ -592754,6 +593079,16 @@ ${specDir}` : specDir;
592754
593079
 
592755
593080
  ${diag}` : diag;
592756
593081
  }
593082
+ const focusDir = this._focusSupervisor?.snapshot().directive;
593083
+ const wantsDelegation = focusDir?.requiredNextAction === "delegate_isolated_fix" || this._decomp2GateActive;
593084
+ if (wantsDelegation) {
593085
+ const delegateDir = lh.buildDelegationDirective(result.output ?? result.error ?? "");
593086
+ if (delegateDir) {
593087
+ runtimeSystemGuidance = runtimeSystemGuidance ? `${runtimeSystemGuidance}
593088
+
593089
+ ${delegateDir}` : delegateDir;
593090
+ }
593091
+ }
592757
593092
  }
592758
593093
  }
592759
593094
  } catch {
@@ -596496,6 +596831,80 @@ Actions: (1) list_directory on the parent directory to see what's there, (2) Che
596496
596831
  * Replaces both assistant messages AND their associated tool-result
596497
596832
  * messages in the turn range [startTurn, currentTurn].
596498
596833
  */
596834
+ /**
596835
+ * Staleness-based evidence retirement (WO-4 realized; operator's microcompaction
596836
+ * goal). The sibling `_evictCompletedTodoMessages` only fires when a todo
596837
+ * COMPLETES and — critically — SKIPS `system` messages. But the live
596838
+ * `myactuator` frame (turn 11) was dominated by a ~77 KB `system`
596839
+ * `[SHELL TRANSCRIPT]` pinned from turn 3: a stuck debug loop completes no
596840
+ * todos, so nothing retired it, and system-role evidence is exempt from the
596841
+ * todo evictor anyway.
596842
+ *
596843
+ * This pass fills that gap: it retires STALE, LARGE evidence bodies (tool
596844
+ * results and marker-gated `system` evidence blocks — `[SHELL TRANSCRIPT]`,
596845
+ * `[FILE CONTEXT`, `[RUN EVIDENCE]`) to a one-line world-state stub, keeping
596846
+ * the OUTCOME resident and moving the bytes out. It mirrors the evictor's safe
596847
+ * in-place, same-length-array style (no index shifting) and reuses the pure,
596848
+ * unit-tested `isRetirableEvidence` / `foldEvidenceOutcome` from @omnius/memory
596849
+ * for the decision — so directives, plans, the completion contract, ordinary
596850
+ * reasoning, and the base prompt are never touched (they carry no evidence
596851
+ * marker). Marker-gating is what makes touching `system` messages safe here.
596852
+ *
596853
+ * OPT-IN (`OMNIUS_EVIDENCE_RETIREMENT=1`) so it cannot perturb a live run until
596854
+ * the operator flips it on and validates — matching the runtime-harness
596855
+ * discipline we hold for anything that reshapes the model-visible frame. The
596856
+ * canonical message history is unaffected structurally (same length); full
596857
+ * evidence remains on disk (`.omnius/tool-results/`) and re-materialisable.
596858
+ */
596859
+ _retireStaleEvidenceInPlace(messages2, currentTurn) {
596860
+ if (process.env["OMNIUS_EVIDENCE_RETIREMENT"] !== "1")
596861
+ return;
596862
+ const keepRecent = Math.max(0, Number(process.env["OMNIUS_EVIDENCE_KEEP_TURNS"] ?? 2));
596863
+ const minChars = Math.max(512, Number(process.env["OMNIUS_EVIDENCE_MIN_CHARS"] ?? 2e3));
596864
+ const staleBefore = currentTurn - keepRecent;
596865
+ if (staleBefore <= 0)
596866
+ return;
596867
+ let turnCount = 0;
596868
+ let retired = 0;
596869
+ let reclaimed = 0;
596870
+ for (let i2 = 0; i2 < messages2.length; i2++) {
596871
+ const msg = messages2[i2];
596872
+ if (msg.role === "assistant") {
596873
+ turnCount++;
596874
+ if (turnCount > staleBefore)
596875
+ break;
596876
+ }
596877
+ const content = typeof msg.content === "string" ? msg.content : "";
596878
+ if (!content)
596879
+ continue;
596880
+ if (content.startsWith("[RETIRED EVIDENCE") || content.startsWith("[Todo context archived") || content.startsWith("[Tool result cleared")) {
596881
+ continue;
596882
+ }
596883
+ const rm4 = { role: msg.role, content };
596884
+ if (!isRetirableEvidence(rm4, minChars))
596885
+ continue;
596886
+ let outcome;
596887
+ try {
596888
+ outcome = foldEvidenceOutcome(rm4);
596889
+ } catch {
596890
+ outcome = "evidence";
596891
+ }
596892
+ const stub = `[RETIRED EVIDENCE turn<=${staleBefore} bytes=${content.length}] outcome: ${outcome}
596893
+ (full evidence retired to disk — re-read the file or re-run the command to re-materialise if you need the detail)`;
596894
+ if (stub.length >= content.length)
596895
+ continue;
596896
+ messages2[i2].content = stub;
596897
+ retired += 1;
596898
+ reclaimed += content.length - stub.length;
596899
+ }
596900
+ if (retired > 0) {
596901
+ this.emit({
596902
+ type: "status",
596903
+ content: `[evidence-retirement] retired ${retired} stale evidence block(s), reclaimed ~${Math.round(reclaimed / 4)} tokens (world-state outcomes retained; bytes on disk)`,
596904
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
596905
+ });
596906
+ }
596907
+ }
596499
596908
  _evictCompletedTodoMessages(startTurn, currentTurn, todoId, todoContent, messages2) {
596500
596909
  const placeholder = [
596501
596910
  `[Todo context archived: "${todoContent.slice(0, 120)}"`,
@@ -603061,7 +603470,7 @@ function resolveAgentTools(type, availableTools) {
603061
603470
  function buildAgentTypeSummary() {
603062
603471
  return _registry2.buildTypeSummary();
603063
603472
  }
603064
- var CORE_TOOLS2, READ_ONLY_TOOLS, COORDINATOR_TOOLS, AGENT_DISALLOWED_TOOLS, GENERAL_AGENT, EXPLORE_AGENT, PLAN_AGENT, COORDINATOR_AGENT, AgentTypeRegistry, _registry2;
603473
+ var CORE_TOOLS2, READ_ONLY_TOOLS, COORDINATOR_TOOLS, AGENT_DISALLOWED_TOOLS, GENERAL_AGENT, EXPLORE_AGENT, PLAN_AGENT, COORDINATOR_AGENT, FIXER_TOOLS, FIXER_AGENT, AgentTypeRegistry, _registry2;
603065
603474
  var init_agent_types = __esm({
603066
603475
  "packages/orchestrator/dist/agent-types.js"() {
603067
603476
  "use strict";
@@ -603184,6 +603593,34 @@ var init_agent_types = __esm({
603184
603593
  canSpawnAgents: true,
603185
603594
  systemPromptAddition: "You are a coordinator agent. Your role is to break down complex tasks into sub-tasks and delegate them to worker agents. You CANNOT edit files directly — you must spawn agents to do the work. Monitor their progress via task notifications and coordinate their efforts."
603186
603595
  };
603596
+ FIXER_TOOLS = [
603597
+ "file_read",
603598
+ "file_edit",
603599
+ "file_patch",
603600
+ "shell",
603601
+ // run the build/test to verify its own fix
603602
+ "grep",
603603
+ "glob",
603604
+ "task_complete"
603605
+ ];
603606
+ FIXER_AGENT = {
603607
+ type: "fixer",
603608
+ description: "Isolated single-unit fix worker. Minimal tools (read/edit/build/locate). Dispatched to resolve ONE named diagnostic in ONE file against the locked contract, then report a one-line outcome. Use for delegated build-diagnostic fixes in the fan-out/converge loop.",
603609
+ allowedTools: [...FIXER_TOOLS],
603610
+ disallowedTools: [
603611
+ "file_write",
603612
+ // prefer targeted edit/patch over whole-file writes
603613
+ "agent",
603614
+ "send_message",
603615
+ ...AGENT_DISALLOWED_TOOLS
603616
+ ],
603617
+ maxTurns: 0,
603618
+ // unlimited; halt only on task_complete or abort
603619
+ model: "inherit",
603620
+ isolation: "none",
603621
+ canSpawnAgents: false,
603622
+ systemPromptAddition: "You are an isolated FIX worker with a deliberately small context and tool set. You were given ONE specific diagnostic to resolve in ONE file. Read ONLY that file and the file that declares the offending symbol; make the MINIMAL edit to satisfy the locked contract; run the build once to confirm your change reduced the error; then call task_complete with a single-line outcome (what you changed and whether it verified). Do NOT refactor, do NOT touch unrelated files, do NOT expand scope. Fold back fast."
603623
+ };
603187
603624
  AgentTypeRegistry = class {
603188
603625
  types = /* @__PURE__ */ new Map();
603189
603626
  constructor() {
@@ -603191,6 +603628,7 @@ var init_agent_types = __esm({
603191
603628
  this.register(EXPLORE_AGENT);
603192
603629
  this.register(PLAN_AGENT);
603193
603630
  this.register(COORDINATOR_AGENT);
603631
+ this.register(FIXER_AGENT);
603194
603632
  }
603195
603633
  /** Register a new agent type (or override existing) */
603196
603634
  register(def) {
@@ -607130,6 +607568,7 @@ __export(dist_exports3, {
607130
607568
  buildRecentSteeringContext: () => buildRecentSteeringContext,
607131
607569
  buildSkillDescription: () => buildSkillDescription,
607132
607570
  buildSteeringPacket: () => buildSteeringPacket,
607571
+ buildUnitTodos: () => buildUnitTodos,
607133
607572
  checkMilestoneComplete: () => checkMilestoneComplete,
607134
607573
  chooseCheapModelRoute: () => chooseCheapModelRoute,
607135
607574
  claimAssertion: () => claimAssertion,
@@ -607163,6 +607602,7 @@ __export(dist_exports3, {
607163
607602
  criticalPathDepth: () => criticalPathDepth,
607164
607603
  debugArtifactRoot: () => debugArtifactRoot,
607165
607604
  decomposeSpec: () => decomposeSpec,
607605
+ decomposeToUnits: () => decomposeToUnits,
607166
607606
  defaultContextWindowDumpLocations: () => defaultContextWindowDumpLocations,
607167
607607
  deleteAgentTaskSidecar: () => deleteAgentTaskSidecar,
607168
607608
  deriveClaimsFromProposedText: () => deriveClaimsFromProposedText,
@@ -607175,6 +607615,7 @@ __export(dist_exports3, {
607175
607615
  discoverSystemOllamaModelStore: () => discoverSystemOllamaModelStore,
607176
607616
  evaluateExecutorStep: () => evaluateExecutorStep,
607177
607617
  evaluateSpecGate: () => evaluateSpecGate,
607618
+ evaluateUnitResult: () => evaluateUnitResult,
607178
607619
  executeBatch: () => executeBatch,
607179
607620
  executeHook: () => executeHook,
607180
607621
  expandContextReference: () => expandContextReference,
@@ -607406,6 +607847,7 @@ var init_dist8 = __esm({
607406
607847
  init_coherence_gate();
607407
607848
  init_spec_gate();
607408
607849
  init_longhaul_integration();
607850
+ init_decomposition_orchestrator();
607409
607851
  }
607410
607852
  });
607411
607853
 
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "omnius",
3
- "version": "1.0.477",
3
+ "version": "1.0.479",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "omnius",
9
- "version": "1.0.477",
9
+ "version": "1.0.479",
10
10
  "bundleDependencies": [
11
11
  "image-to-ascii"
12
12
  ],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "omnius",
3
- "version": "1.0.477",
3
+ "version": "1.0.479",
4
4
  "description": "AI coding agent powered by open-source models (Ollama/vLLM) — interactive TUI with agentic tool-calling loop",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",