@rulvar/core 1.242.0 → 1.244.0

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.
Files changed (3) hide show
  1. package/dist/index.d.ts +386 -26
  2. package/dist/index.js +672 -43
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1310,6 +1310,146 @@ function sanitizeTerminalText(text) {
1310
1310
  return text.replace(ESC_STRING_SEQUENCE, "").replace(ESC_CSI_SEQUENCE, "").replace(CONTROL_RUN, " ");
1311
1311
  }
1312
1312
  //#endregion
1313
+ //#region src/l0/terminal-envelope.ts
1314
+ /**
1315
+ * The unified terminal envelope (RV1105, the P1-5 arc): ONE shape
1316
+ * carrying every fact of a run's terminal, assembled once at the
1317
+ * engine's settlement chokepoint and mirrored verbatim onto the
1318
+ * resolved outcome (`outcome.envelope`), the `run:end` event
1319
+ * (`event.envelope`), and through them the HTTP outcome response and
1320
+ * the OTel run attributes. An SDK consumer, an event-only consumer,
1321
+ * and an HTTP consumer read the SAME set of facts without assembling
1322
+ * pieces from surface-specific fields; nothing pre-existing was
1323
+ * renamed or removed, the envelope is an assembly over it.
1324
+ *
1325
+ * Doctrine notes:
1326
+ * - `status` is the computation's verdict; `settled` says whether
1327
+ * anything durable records it (RV907). A resolved outcome always
1328
+ * carries `settled: true`, because an unsettled terminal REJECTS
1329
+ * `handle.result` typed instead of resolving; the `settled: false`
1330
+ * envelopes exist only on the event stream, where `settledReason:
1331
+ * 'superseded'` distinguishes the fenced-out segment (RV1009) from
1332
+ * a settlement write fault.
1333
+ * - `usageApprox` is normalized to a boolean here (the run:end field
1334
+ * keeps its absent-means-exact byte contract): `true` means some
1335
+ * priced usage was approximate, so `totalUsd` is a lower bound.
1336
+ * - `costByModel` is a detached copy of the settled fold's per-model
1337
+ * split; mutating it never touches the cost report. Since RV1213
1338
+ * `error` is detached the same way, `data` nesting included, so the
1339
+ * whole envelope is a reading a consumer may annotate freely.
1340
+ *
1341
+ * Docs: https://docs.rulvar.com/guide/observability
1342
+ */
1343
+ const ENVELOPE_STATUSES = /* @__PURE__ */ new Set([
1344
+ "ok",
1345
+ "error",
1346
+ "cancelled",
1347
+ "exhausted",
1348
+ "suspended"
1349
+ ]);
1350
+ const ENVELOPE_COMPLETIONS = /* @__PURE__ */ new Set([
1351
+ "complete",
1352
+ "partial",
1353
+ "rejected"
1354
+ ]);
1355
+ function refuseEnvelope(field, requirement, got) {
1356
+ throw new ConfigError(`terminal envelope ${field} must be ${requirement}; got ${typeof got === "number" ? String(got) : JSON.stringify(got) ?? String(got)}`);
1357
+ }
1358
+ function isPlainObject(value) {
1359
+ return typeof value === "object" && value !== null && !Array.isArray(value);
1360
+ }
1361
+ function requireMoney(value, field) {
1362
+ if (typeof value !== "number" || !Number.isFinite(value) || value < 0) refuseEnvelope(field, "a finite nonnegative number", value);
1363
+ return value;
1364
+ }
1365
+ function requireCount$1(value, field) {
1366
+ if (typeof value !== "number" || !Number.isInteger(value) || value < 0) refuseEnvelope(field, "a nonnegative integer", value);
1367
+ }
1368
+ function requireBoolean(value, field) {
1369
+ if (typeof value !== "boolean") refuseEnvelope(field, "a boolean", value);
1370
+ }
1371
+ function requireNonEmptyString(value, field) {
1372
+ if (typeof value !== "string" || value.length === 0) refuseEnvelope(field, "a non-empty string", value);
1373
+ }
1374
+ /** Every numeric leaf of the usage subtree: finite and nonnegative. */
1375
+ function requireUsageNumbers(node, path) {
1376
+ if (typeof node === "number") {
1377
+ if (!Number.isFinite(node) || node < 0) refuseEnvelope(path, "a finite nonnegative number", node);
1378
+ return;
1379
+ }
1380
+ if (isPlainObject(node)) {
1381
+ for (const [key, item] of Object.entries(node)) requireUsageNumbers(item, `${path}.${key}`);
1382
+ return;
1383
+ }
1384
+ refuseEnvelope(path, "a number or a nested usage object", node);
1385
+ }
1386
+ /**
1387
+ * The runtime gate over the terminal envelope contract (RV3903, the
1388
+ * fourth comparison experiment). `terminalEnvelopeOf` is the ONE
1389
+ * producer, but a producer is a compile-time promise, and the envelope
1390
+ * crosses trust boundaries the type system never sees: a journal read
1391
+ * back after a restart, a plain JS caller, an HTTP body a pipeline
1392
+ * gates on. The experiment probed the built dist and the typed copy
1393
+ * accepted `status: 'green'`, NaN dollars, and negative counts without
1394
+ * a sound; a finance or compliance consumer downstream would have
1395
+ * gated a run on fiction.
1396
+ *
1397
+ * The gate validates the CONTRACT fields and refuses with a typed
1398
+ * {@link ConfigError} naming the field and the defect: enum `status`
1399
+ * and `completion`, finite nonnegative money (with `totalUsd <=
1400
+ * grossUsd`, gross being net plus abandoned by construction), usage
1401
+ * and counters, `settledReason` only beside `settled: false`, the
1402
+ * `costBasis` and `provenance` literals, boolean `usageApprox`, and
1403
+ * the `WireError` shape when an error rides along. Unknown top-level
1404
+ * fields pass through untouched: the contract evolves additively, and
1405
+ * a parser that refused tomorrow's field would turn every additive
1406
+ * release into a wire break. On success the SAME reference comes back,
1407
+ * typed: the gate is a boundary check, never a normalizer.
1408
+ *
1409
+ * Wired where external bytes actually enter: `persistedTerminalEnvelope`
1410
+ * runs every journal-rebuilt envelope through it (and refuses typed as
1411
+ * `malformed-envelope`), which also covers the server's persisted
1412
+ * serving by construction. The live settlement chokepoint stays
1413
+ * unparsed on purpose: it is the one producer inside one process, and
1414
+ * gating it would add a throw site to settlement itself.
1415
+ */
1416
+ function parseTerminalEnvelope(value) {
1417
+ if (!isPlainObject(value)) refuseEnvelope("value", "an object", value);
1418
+ requireNonEmptyString(value.runId, "runId");
1419
+ requireNonEmptyString(value.workflow, "workflow");
1420
+ if (typeof value.status !== "string" || !ENVELOPE_STATUSES.has(value.status)) refuseEnvelope("status", "one of 'ok' | 'error' | 'cancelled' | 'exhausted' | 'suspended'", value.status);
1421
+ requireBoolean(value.settled, "settled");
1422
+ if (value.settledReason !== void 0) {
1423
+ if (value.settledReason !== "superseded") refuseEnvelope("settledReason", "the literal 'superseded' when present", value.settledReason);
1424
+ if (value.settled !== false) refuseEnvelope("settledReason", "present only beside settled: false (a settled terminal has no supersession to explain)", value.settledReason);
1425
+ }
1426
+ const totalUsd = requireMoney(value.totalUsd, "totalUsd");
1427
+ const grossUsd = requireMoney(value.grossUsd, "grossUsd");
1428
+ if (totalUsd > grossUsd) refuseEnvelope("totalUsd", `at most grossUsd (${String(grossUsd)}): gross is the net fold plus abandoned spend`, totalUsd);
1429
+ if (value.costBasis !== "locally-estimated") refuseEnvelope("costBasis", "the literal 'locally-estimated'", value.costBasis);
1430
+ if (!isPlainObject(value.costByModel)) refuseEnvelope("costByModel", "an object of per-model dollars", value.costByModel);
1431
+ for (const [model, usd] of Object.entries(value.costByModel)) requireMoney(usd, `costByModel['${model}']`);
1432
+ if (value.wireRequests !== void 0) requireCount$1(value.wireRequests, "wireRequests");
1433
+ if (!isPlainObject(value.usage)) refuseEnvelope("usage", "a usage object", value.usage);
1434
+ requireUsageNumbers(value.usage, "usage");
1435
+ requireBoolean(value.usageApprox, "usageApprox");
1436
+ requireCount$1(value.agentsSpawned, "agentsSpawned");
1437
+ if (value.completion !== void 0 && (typeof value.completion !== "string" || !ENVELOPE_COMPLETIONS.has(value.completion))) refuseEnvelope("completion", "one of 'complete' | 'partial' | 'rejected' when present", value.completion);
1438
+ if (value.error !== void 0) {
1439
+ if (!isPlainObject(value.error)) refuseEnvelope("error", "a typed wire error object when present", value.error);
1440
+ requireNonEmptyString(value.error.code, "error.code");
1441
+ if (typeof value.error.message !== "string") refuseEnvelope("error.message", "a string", value.error.message);
1442
+ requireBoolean(value.error.retryable, "error.retryable");
1443
+ }
1444
+ if (value.deliverableAccepted !== void 0) requireBoolean(value.deliverableAccepted, "deliverableAccepted");
1445
+ if (value.resultAvailable !== void 0) requireBoolean(value.resultAvailable, "resultAvailable");
1446
+ if (value.acceptedArtifactRef !== void 0) requireCount$1(value.acceptedArtifactRef, "acceptedArtifactRef");
1447
+ if (value.claimConsistencyMeta !== void 0 && !isPlainObject(value.claimConsistencyMeta)) refuseEnvelope("claimConsistencyMeta", "an object when present", value.claimConsistencyMeta);
1448
+ if (value.configFingerprint !== void 0) requireNonEmptyString(value.configFingerprint, "configFingerprint");
1449
+ if (value.provenance !== void 0 && value.provenance !== "journal") refuseEnvelope("provenance", "the literal 'journal' when present", value.provenance);
1450
+ return value;
1451
+ }
1452
+ //#endregion
1313
1453
  //#region src/engine/terminal-envelope.ts
1314
1454
  /**
1315
1455
  * A total copy of one typed error (RV1213). `data` is `Json` by the
@@ -6198,8 +6338,12 @@ var LineageIndex = class {
6198
6338
  * exclusively DEBIT-ONLY API and a limits vector frozen at start in the
6199
6339
  * `termination.init` entry, plus the variant function Phi. No credit
6200
6340
  * operation exists anywhere by construction; no journal entry kind
6201
- * carries credit; B0 is immutable after start and no API, including
6202
- * HITL, can top it up. Every debit is atomic with the append of its
6341
+ * carries credit; B0 is immutable within a segment and no API,
6342
+ * including HITL, tops up a live run (the one explicit door is the
6343
+ * journaled ResumeOptions.run override at resume, RV2208, refused
6344
+ * outright under budgetPolicy 'immutable-lifetime', RV3902; the
6345
+ * frozen vector below keeps the GENESIS ceiling either way). Every
6346
+ * debit is atomic with the append of its
6203
6347
  * carrying decision entry and embeds the balance-after; an underflow
6204
6348
  * writes `termination.denied` strictly BEFORE the typed error surfaces.
6205
6349
  *
@@ -6303,8 +6447,9 @@ function readTerminationInit(entry) {
6303
6447
  /**
6304
6448
  * Config-drift detection at resume: the journaled vector
6305
6449
  * always wins; every differing field is reported for the
6306
- * `termination:config-drift` event. Dynamic budget top-up via restart is
6307
- * excluded by construction.
6450
+ * `termination:config-drift` event. Ambient config can never top up a
6451
+ * budget through a restart; the one explicit, journaled door is
6452
+ * ResumeOptions.run (RV2208), which is a decision entry, not a drift.
6308
6453
  */
6309
6454
  function terminationConfigDrift(frozen, live) {
6310
6455
  const drift = [];
@@ -9878,7 +10023,8 @@ function synthesisCandidatesFromJournal(entries, priceUsd) {
9878
10023
  name: failure.name,
9879
10024
  reasons: Array.isArray(failure.reasons) ? failure.reasons.filter((reason) => typeof reason === "string") : []
9880
10025
  })) : [],
9881
- ...span.label === void 0 ? {} : { spanLabel: span.label }
10026
+ ...span.label === void 0 ? {} : { spanLabel: span.label },
10027
+ spanSeq: span.runningSeq
9882
10028
  };
9883
10029
  if (boundary.at !== void 0 && verdictAtMs !== void 0) candidate.windowMs = Math.max(0, verdictAtMs - boundary.at);
9884
10030
  if (attributable.has(span)) {
@@ -9911,6 +10057,29 @@ function synthesisCandidatesFromJournal(entries, priceUsd) {
9911
10057
  tailWires
9912
10058
  };
9913
10059
  }
10060
+ /**
10061
+ * The observed price of the run's LAST mechanical repair turn
10062
+ * (RV3802): the window of the candidate that FOLLOWED a 'repair'
10063
+ * verdict inside the same settled synthesize span, priced by the same
10064
+ * per-call fold every candidate window uses. This is the fallback the
10065
+ * repair round's mechanical money leg sizes itself from when the host
10066
+ * declared no estimate: by the time the round is admitted the initial
10067
+ * composition has settled, so a mechanical repair it performed is a
10068
+ * priced window in the journal. Fail closed under RV1209: no such
10069
+ * pairing, an unattributed span, or an unpriceable window all return
10070
+ * undefined (never a guessed number), and the caller treats undefined
10071
+ * as an inert zero-size leg.
10072
+ */
10073
+ function lastMechanicalRepairCostUsd(entries, priceUsd) {
10074
+ const { candidates } = synthesisCandidatesFromJournal(entries, priceUsd);
10075
+ let observed;
10076
+ for (let index = 1; index < candidates.length; index += 1) {
10077
+ const previous = candidates[index - 1];
10078
+ const row = candidates[index];
10079
+ if (previous?.verdict === "repair" && row?.spanSeq !== void 0 && row.spanSeq === previous.spanSeq && row.costUsd !== void 0) observed = row.costUsd;
10080
+ }
10081
+ return observed;
10082
+ }
9914
10083
  //#endregion
9915
10084
  //#region src/stores/tool-calibration.ts
9916
10085
  /**
@@ -14183,7 +14352,17 @@ async function runAgent(options) {
14183
14352
  output = outcome.turn.text;
14184
14353
  break;
14185
14354
  }
14186
- if (separateExtract) break;
14355
+ if (separateExtract) {
14356
+ const rideAlong = extractCandidate(outcome.turn, rideTierFor(servedTarget));
14357
+ if (rideAlong !== void 0) {
14358
+ const validation = await validateSchemaSpec(options.schema, rideAlong.raw);
14359
+ if (validation.valid) {
14360
+ output = validation.value;
14361
+ break;
14362
+ }
14363
+ }
14364
+ break;
14365
+ }
14187
14366
  const candidate = extractCandidate(outcome.turn, rideTierFor(servedTarget));
14188
14367
  const issues = [];
14189
14368
  if (candidate !== void 0) {
@@ -14472,7 +14651,7 @@ async function runAgent(options) {
14472
14651
  }
14473
14652
  endPhase(finalizePhase, phaseOutcome(), finalizeServed);
14474
14653
  }
14475
- if (status === "ok" && !finishedViaTool && separateExtract && options.extract !== void 0 && options.schema !== void 0) {
14654
+ if (status === "ok" && !finishedViaTool && separateExtract && output === null && options.extract !== void 0 && options.schema !== void 0) {
14476
14655
  const extractResolved = options.extract.resolved;
14477
14656
  const extractPhase = beginPhase("extract", extractResolved.ref);
14478
14657
  let extractServed;
@@ -14517,6 +14696,7 @@ async function runAgent(options) {
14517
14696
  toolChoice: "none"
14518
14697
  };
14519
14698
  req = applyStructuredOutputTier(req, targetTier, options.canonicalSchema ?? {});
14699
+ req = applyCachePolicy(req, target, options.cache);
14520
14700
  return applyOutputBudget(req, target, options.budget);
14521
14701
  },
14522
14702
  streamOptionsFor: (target) => {
@@ -14699,7 +14879,10 @@ async function runAgent(options) {
14699
14879
  * false). The one thing that can change it is `ResumeOptions.run`, an
14700
14880
  * explicit host decision journaled as its own decision entry, and it
14701
14881
  * takes effect only by opening a NEW segment: a live run can never
14702
- * raise the bound it is already being measured against.
14882
+ * raise the bound it is already being measured against. Under
14883
+ * RunOptions.budgetPolicy 'immutable-lifetime' (RV3902) even that door
14884
+ * refuses typed before ownership, and the recorded ceilings hold for
14885
+ * the run's whole life.
14703
14886
  *
14704
14887
  * The account tree: the run root plus one
14705
14888
  * sub-account per admitted child workflow (and, from M7, the orchestrator
@@ -14797,7 +14980,12 @@ function admissionReserveUsd(options) {
14797
14980
  * spawn-admission decision entries, M6).
14798
14981
  */
14799
14982
  var RunBudget = class {
14800
- /** B0; immutable after start. Undefined means no USD ceiling. */
14983
+ /**
14984
+ * B0; immutable within a segment (RV2511): only the explicit,
14985
+ * journaled ResumeOptions.run override (RV2208) changes it, by
14986
+ * opening a new segment, and budgetPolicy 'immutable-lifetime'
14987
+ * (RV3902) refuses even that. Undefined means no USD ceiling.
14988
+ */
14801
14989
  ceilingUsd;
14802
14990
  /**
14803
14991
  * The opt-in in-flight exposure cap (RV711). Undefined means the
@@ -14898,6 +15086,7 @@ var RunBudget = class {
14898
15086
  finalizeReserveUsd: 0,
14899
15087
  synthesisReserveUsd: 0,
14900
15088
  convergenceReserveUsd: 0,
15089
+ repairReserveUsd: 0,
14901
15090
  controller: new AbortController()
14902
15091
  };
14903
15092
  if (options.ceilingUsd !== void 0) root.ceilingUsd = options.ceilingUsd;
@@ -14949,6 +15138,7 @@ var RunBudget = class {
14949
15138
  finalizeReserveUsd: options.finalizeReserveUsd ?? 0,
14950
15139
  synthesisReserveUsd: 0,
14951
15140
  convergenceReserveUsd: 0,
15141
+ repairReserveUsd: 0,
14952
15142
  parentScope,
14953
15143
  controller: new AbortController()
14954
15144
  };
@@ -15050,7 +15240,8 @@ var RunBudget = class {
15050
15240
  committedReserveUsd: account.committedReserveUsd,
15051
15241
  finalizeReserveUsd: account.finalizeReserveUsd,
15052
15242
  synthesisReserveUsd: account.synthesisReserveUsd,
15053
- convergenceReserveUsd: account.convergenceReserveUsd
15243
+ convergenceReserveUsd: account.convergenceReserveUsd,
15244
+ repairReserveUsd: account.repairReserveUsd
15054
15245
  };
15055
15246
  if (account.ceilingUsd !== void 0) view.ceilingUsd = account.ceilingUsd;
15056
15247
  if (account.parentScope !== void 0) view.parentScope = account.parentScope;
@@ -15064,7 +15255,7 @@ var RunBudget = class {
15064
15255
  remainderOf(scope) {
15065
15256
  const account = this.accounts.get(scope);
15066
15257
  if (account?.ceilingUsd === void 0) return;
15067
- return Math.max(0, account.ceilingUsd - account.spentUsd - account.committedReserveUsd - account.finalizeReserveUsd - account.synthesisReserveUsd - account.convergenceReserveUsd);
15258
+ return Math.max(0, account.ceilingUsd - account.spentUsd - account.committedReserveUsd - account.finalizeReserveUsd - account.synthesisReserveUsd - account.convergenceReserveUsd - account.repairReserveUsd);
15068
15259
  }
15069
15260
  /**
15070
15261
  * The tightest allowance headroom on the chain of `scope`: the minimum
@@ -15144,16 +15335,17 @@ var RunBudget = class {
15144
15335
  }
15145
15336
  for (const account of this.chainOf(accountScope)) {
15146
15337
  if (account.ceilingUsd === void 0) continue;
15147
- const committed = account.spentUsd + account.committedReserveUsd + account.finalizeReserveUsd + account.synthesisReserveUsd + account.convergenceReserveUsd;
15338
+ const committed = account.spentUsd + account.committedReserveUsd + account.finalizeReserveUsd + account.synthesisReserveUsd + account.convergenceReserveUsd + account.repairReserveUsd;
15148
15339
  if (committed >= account.ceilingUsd || committed + reserveUsd > account.ceilingUsd) {
15149
15340
  if (account.scope === "run") this.exhaustedInternal = true;
15150
- throw new BudgetExhaustedError(`budget ceiling reached on account '${account.scope}': spent ${account.spentUsd.toFixed(4)} USD plus committed reserves ${(account.committedReserveUsd + account.finalizeReserveUsd).toFixed(4)} USD ` + (account.synthesisReserveUsd > 0 ? `plus the held synthesis reserve ${account.synthesisReserveUsd.toFixed(4)} USD ` : "") + (account.convergenceReserveUsd > 0 ? `plus the held convergence reserve ${account.convergenceReserveUsd.toFixed(4)} USD ` : "") + `plus the proposed reserve ${reserveUsd.toFixed(4)} USD does not fit the ceiling ${account.ceilingUsd.toFixed(4)} USD`, { data: {
15341
+ throw new BudgetExhaustedError(`budget ceiling reached on account '${account.scope}': spent ${account.spentUsd.toFixed(4)} USD plus committed reserves ${(account.committedReserveUsd + account.finalizeReserveUsd).toFixed(4)} USD ` + (account.synthesisReserveUsd > 0 ? `plus the held synthesis reserve ${account.synthesisReserveUsd.toFixed(4)} USD ` : "") + (account.convergenceReserveUsd > 0 ? `plus the held convergence reserve ${account.convergenceReserveUsd.toFixed(4)} USD ` : "") + (account.repairReserveUsd > 0 ? `plus the held repair reserve ${account.repairReserveUsd.toFixed(4)} USD ` : "") + `plus the proposed reserve ${reserveUsd.toFixed(4)} USD does not fit the ceiling ${account.ceilingUsd.toFixed(4)} USD`, { data: {
15151
15342
  account: account.scope,
15152
15343
  spentUsd: account.spentUsd,
15153
15344
  committedReserveUsd: account.committedReserveUsd,
15154
15345
  finalizeReserveUsd: account.finalizeReserveUsd,
15155
15346
  synthesisReserveUsd: account.synthesisReserveUsd,
15156
15347
  convergenceReserveUsd: account.convergenceReserveUsd,
15348
+ repairReserveUsd: account.repairReserveUsd,
15157
15349
  proposedReserveUsd: reserveUsd,
15158
15350
  ceilingUsd: account.ceilingUsd
15159
15351
  } });
@@ -15280,6 +15472,39 @@ var RunBudget = class {
15280
15472
  account.convergenceReserveUsd = 0;
15281
15473
  this.emitUpdate();
15282
15474
  }
15475
+ /**
15476
+ * Registers the repair round's MECHANICAL leg (RV3802), the money
15477
+ * twin of the RV3602 per-invocation pool: the round's finish
15478
+ * contract can grant one bounded mechanical repair turn, and the
15479
+ * third comparison run's round entered exactly that turn's price
15480
+ * short of certainty (the repair existed by pool and by contract,
15481
+ * but nothing guaranteed the money would still be there when the
15482
+ * candidate materialized). Held beside the verdict leg from the
15483
+ * moment the round is admitted; released EARLY, to the round's own
15484
+ * finish loop, at its first journaled verdict (a 'repair' verdict is
15485
+ * about to spend the freed money on the granted turn, an 'accepted'
15486
+ * one never needed it), where the verdict leg lives until the judge
15487
+ * dispatch. Exactly the convergence reserve mechanics otherwise:
15488
+ * joins the projected admission sum and both remainders, named in
15489
+ * the refusal clause, never joined to the severing check, idempotent
15490
+ * per account with the root adjusted by the delta.
15491
+ */
15492
+ commitRepairReserve(scope, reserveUsd) {
15493
+ const account = this.accounts.get(scope);
15494
+ if (account === void 0) throw new ConfigError(`unknown budget account '${scope}' for the repair reserve`);
15495
+ const previous = account.repairReserveUsd;
15496
+ account.repairReserveUsd = reserveUsd;
15497
+ if (account.scope !== "run") this.root.repairReserveUsd = Math.max(0, this.root.repairReserveUsd + reserveUsd - previous);
15498
+ this.emitUpdate();
15499
+ }
15500
+ /** The round's finish loop consumes its leg; see commitRepairReserve. */
15501
+ releaseRepairReserve(scope) {
15502
+ const account = this.accounts.get(scope);
15503
+ if (account === void 0 || account.repairReserveUsd === 0) return;
15504
+ if (account.scope !== "run") this.root.repairReserveUsd = Math.max(0, this.root.repairReserveUsd - account.repairReserveUsd);
15505
+ account.repairReserveUsd = 0;
15506
+ this.emitUpdate();
15507
+ }
15283
15508
  /** The reserve is replaced by real spend when the spawn settles. */
15284
15509
  releaseReserve(reserveUsd, accountScope = "run") {
15285
15510
  for (const account of this.chainOf(accountScope)) account.committedReserveUsd = Math.max(0, account.committedReserveUsd - reserveUsd);
@@ -15487,7 +15712,7 @@ var RunBudget = class {
15487
15712
  let remaining;
15488
15713
  for (const account of this.chainOf(accountScope)) {
15489
15714
  if (account.ceilingUsd === void 0) continue;
15490
- const headroom = account.ceilingUsd - account.spentUsd - account.synthesisReserveUsd - account.convergenceReserveUsd;
15715
+ const headroom = account.ceilingUsd - account.spentUsd - account.synthesisReserveUsd - account.convergenceReserveUsd - account.repairReserveUsd;
15491
15716
  remaining = remaining === void 0 ? headroom : Math.min(remaining, headroom);
15492
15717
  }
15493
15718
  return remaining === void 0 ? void 0 : Math.max(0, remaining);
@@ -15730,6 +15955,27 @@ function foldBuckets(source) {
15730
15955
  return folded;
15731
15956
  }
15732
15957
  /**
15958
+ * The scope key rule of the byScope rollup (RV3805). The root's OWN
15959
+ * scope is the empty string BY CONSTRUCTION: present data whose string
15960
+ * happens to be empty, not an absence, so it folds under the
15961
+ * addressable name 'root' instead of the RV3604 'unknown' fallback,
15962
+ * which stays reserved for a scope that is truly missing. Children
15963
+ * keep their scope strings verbatim. One rule for both builders, so
15964
+ * the live report and the journal fold cannot disagree on the key.
15965
+ */
15966
+ function scopeBucket(scope) {
15967
+ return scope === void 0 ? "unknown" : scope === "" ? "root" : scope;
15968
+ }
15969
+ /** {@link scopeBucket} over a whole live map, merging folded keys. */
15970
+ function foldScopeBuckets(source) {
15971
+ const folded = {};
15972
+ for (const [key, usd] of source) {
15973
+ const bucket = scopeBucket(key);
15974
+ folded[bucket] = (folded[bucket] ?? 0) + usd;
15975
+ }
15976
+ return folded;
15977
+ }
15978
+ /**
15733
15979
  * Folds the per-run attribution buckets into the normative CostReport.
15734
15980
  * Live attribution buckets never see abandoned subtrees, so a host
15735
15981
  * that tracked abandoned spend itself passes it as `abandoned`;
@@ -15760,6 +16006,7 @@ function buildCostReport(attribution, totalUsd, abandoned = {
15760
16006
  byPhase: foldBuckets(attribution.byPhase),
15761
16007
  byAgentType: foldBuckets(attribution.byAgentType),
15762
16008
  byRole,
16009
+ byScope: foldScopeBuckets(attribution.byScope),
15763
16010
  orchestrator: {
15764
16011
  ...orchestrator,
15765
16012
  share: orchestrator.spentUsd / Math.max(totalUsd, .01)
@@ -15785,6 +16032,7 @@ function costReportFromJournal(entries, priceUsd) {
15785
16032
  const byModel = {};
15786
16033
  const byPhase = {};
15787
16034
  const byAgentType = {};
16035
+ const byScope = {};
15788
16036
  const byRole = emptyByRole();
15789
16037
  const unpriced = [];
15790
16038
  let totalUsd = 0;
@@ -15827,6 +16075,8 @@ function costReportFromJournal(entries, priceUsd) {
15827
16075
  byPhase[phase] = (byPhase[phase] ?? 0) + priced.usd;
15828
16076
  const agentType = attributionBucket(facts?.agentType);
15829
16077
  byAgentType[agentType] = (byAgentType[agentType] ?? 0) + priced.usd;
16078
+ const scope = scopeBucket(entry.scope);
16079
+ byScope[scope] = (byScope[scope] ?? 0) + priced.usd;
15830
16080
  const primaryRole = facts?.role ?? "loop";
15831
16081
  for (const unit of priced.units) byRole[unit.role ?? primaryRole] += unit.usd;
15832
16082
  if (facts?.budgetAccount !== void 0 && isOrchestratorAccount(facts.budgetAccount)) {
@@ -15848,6 +16098,7 @@ function costReportFromJournal(entries, priceUsd) {
15848
16098
  byPhase,
15849
16099
  byAgentType,
15850
16100
  byRole,
16101
+ byScope,
15851
16102
  orchestrator: {
15852
16103
  spentUsd: orchestratorSpentUsd,
15853
16104
  share: orchestratorSpentUsd / Math.max(totalUsd, .01),
@@ -16128,10 +16379,13 @@ function invoiceFromJournal(entries, priceUsd, options) {
16128
16379
  const billing = priceEntryBilling(entry, priceUsd);
16129
16380
  if (!billing.fullyAttributed) everyEntryFullyAttributed = false;
16130
16381
  const abandoned = entry.kind !== "resolution" && entry.kind !== "abandon" && abandonFold.isAbandoned(entry.ref ?? entry.seq);
16382
+ const attribution = entry.costAttribution;
16131
16383
  const base = {
16132
16384
  entrySeq: entry.seq,
16133
16385
  scope: entry.scope,
16134
- key: entry.key
16386
+ key: entry.key,
16387
+ ...attribution?.agentType === void 0 || attribution.agentType === "" ? {} : { agentType: attribution.agentType },
16388
+ ...attribution?.label === void 0 ? {} : { label: attribution.label }
16135
16389
  };
16136
16390
  const mark = abandoned ? { abandoned: true } : {};
16137
16391
  const records = entry.providerCalls ?? [];
@@ -16869,7 +17123,8 @@ function statementRowsFromDelimited(text, options) {
16869
17123
  const REFUSAL_MESSAGES = {
16870
17124
  unsettled: "no run settle is journaled for this run: nothing durable records a terminal",
16871
17125
  "not-terminal": "the journaled run settle records a running segment, not a terminal",
16872
- "unknown-workflow": "no stored metadata names the workflow this run belongs to"
17126
+ "unknown-workflow": "no stored metadata names the workflow this run belongs to",
17127
+ "malformed-envelope": "the rebuilt envelope failed the runtime terminal contract gate: the journal bytes produced values the contract forbids"
16873
17128
  };
16874
17129
  /** Every envelope status; a settle may also record the non-terminal 'running'. */
16875
17130
  const TERMINAL_STATUSES = /* @__PURE__ */ new Set([
@@ -16901,10 +17156,18 @@ function persistedTerminalEnvelope(input) {
16901
17156
  if (tail > 0) return refuse("not-terminal", `the journal continued ${String(tail)} entr${tail === 1 ? "y" : "ies"} past the settle at seq ${String(settle.seq)}: the latest segment is not settled`);
16902
17157
  const workflow = input.meta?.workflowName;
16903
17158
  if (workflow === void 0) return refuse("unknown-workflow");
17159
+ try {
17160
+ return assemble(input, workflow, settle);
17161
+ } catch (error) {
17162
+ const detail = error instanceof Error ? error.message : String(error);
17163
+ return refuse("malformed-envelope", `${REFUSAL_MESSAGES["malformed-envelope"]}: ${detail}`);
17164
+ }
17165
+ }
17166
+ function assemble(input, workflow, settle) {
16904
17167
  const ledger = foldLedger(input.entries, buildAbandonFold(input.entries));
16905
17168
  return {
16906
17169
  available: true,
16907
- envelope: terminalEnvelopeOf({
17170
+ envelope: parseTerminalEnvelope(terminalEnvelopeOf({
16908
17171
  runId: input.runId,
16909
17172
  workflow,
16910
17173
  outcome: {
@@ -16920,7 +17183,7 @@ function persistedTerminalEnvelope(input) {
16920
17183
  agentsSpawned: ledger.agentsSpawned,
16921
17184
  ...input.meta?.configFingerprint === void 0 ? {} : { configFingerprint: input.meta.configFingerprint },
16922
17185
  provenance: "journal"
16923
- })
17186
+ }))
16924
17187
  };
16925
17188
  }
16926
17189
  //#endregion
@@ -18953,6 +19216,7 @@ function createCtx(internals, rootWorkflow) {
18953
19216
  });
18954
19217
  bump(internals.cost.byPhase, state.phase ?? "", costUsd);
18955
19218
  bump(internals.cost.byAgentType, agentType, costUsd);
19219
+ bump(internals.cost.byScope, state.scope, costUsd);
18956
19220
  internals.cost.byRole.set(primaryRole, (internals.cost.byRole.get(primaryRole) ?? 0) + costUsd);
18957
19221
  if (result.status === "escalated" && result.escalation !== void 0) {
18958
19222
  if (internals.replayer.snapshot().find((entry) => entry.kind === "decision" && entry.value?.targetRef === matched.running.seq) === void 0 && opts.result !== "full" && internals.onEscalation !== void 0) {
@@ -19728,6 +19992,7 @@ function createCtx(internals, rootWorkflow) {
19728
19992
  }
19729
19993
  bump(internals.cost.byPhase, state.phase ?? "", usd);
19730
19994
  bump(internals.cost.byAgentType, agentType, usd);
19995
+ bump(internals.cost.byScope, state.scope, usd);
19731
19996
  if (result.error?.kind === "budget" || internals.budget.exhausted && result.status !== "ok") {
19732
19997
  if (!internals.budget.exhausted && result.errorMessage !== void 0 && result.errorMessage.startsWith("in flight exposure cap reached")) throw new BudgetExhaustedError(result.errorMessage, { data: {
19733
19998
  scope: state.scope,
@@ -21166,6 +21431,50 @@ const MAX_LISTED_CITATIONS = 20;
21166
21431
  const MAX_NAMED_OFFENDING_SENTENCES = 5;
21167
21432
  const MAX_OFFENDING_SENTENCE_CHARS = 240;
21168
21433
  /**
21434
+ * The most offending sentences a verdict will hint (RV3801). A
21435
+ * document broken in more places than this needs a model repair
21436
+ * anyway, and an unbounded hint set would carry unbounded sentence
21437
+ * bytes through the live verdict.
21438
+ */
21439
+ const MAX_REPAIR_HINTS = 20;
21440
+ /**
21441
+ * The deterministic edit behind the `insert-run-id` mechanism
21442
+ * (RV3801): the id lands INSIDE the sentence, before its trailing
21443
+ * terminator run (a `.`, `!`, or `?` with any closing quotes,
21444
+ * brackets, or markdown emphasis after it), or at the very end when
21445
+ * the sentence carries no terminator. Inside matters: appended AFTER
21446
+ * the terminator the id would belong to the NEXT sentence under the
21447
+ * shared `sentencesOf` segmentation and the re-validation would fail
21448
+ * the same sentence again. Exported so tests and hosts can reproduce
21449
+ * the loop's exact bytes.
21450
+ */
21451
+ function insertRunIdIntoSentence(sentence, insert) {
21452
+ const at = /[.!?]['")\]*_`]*\s*$/u.exec(sentence)?.index ?? sentence.length;
21453
+ return `${sentence.slice(0, at)} (run ${insert})${sentence.slice(at)}`;
21454
+ }
21455
+ /**
21456
+ * Applies `insert-run-id` repair hints to a judged text (RV3801): each
21457
+ * `[start, end)` window is replaced by
21458
+ * {@link insertRunIdIntoSentence}(window, insert), right to left so
21459
+ * earlier offsets stay valid, every other byte identical. Fail closed:
21460
+ * `undefined` (never a partial patch) when the set is empty, any
21461
+ * window is out of bounds or empty, or two windows overlap; the caller
21462
+ * treats a refused patch exactly like an absent one and proceeds to
21463
+ * the model repair pool.
21464
+ */
21465
+ function applyFinishRepairHints(text, hints) {
21466
+ if (hints.length === 0) return;
21467
+ const ordered = [...hints].sort((a, b) => a.start - b.start);
21468
+ let previousEnd = 0;
21469
+ for (const hint of ordered) {
21470
+ if (!Number.isInteger(hint.start) || !Number.isInteger(hint.end) || hint.start < previousEnd || hint.end <= hint.start || hint.end > text.length) return;
21471
+ previousEnd = hint.end;
21472
+ }
21473
+ let patched = text;
21474
+ for (const hint of [...ordered].reverse()) patched = patched.slice(0, hint.start) + insertRunIdIntoSentence(patched.slice(hint.start, hint.end), hint.insert) + patched.slice(hint.end);
21475
+ return patched;
21476
+ }
21477
+ /**
21169
21478
  * The shortest run id {@link evidenceGradeValidator} will accept as an
21170
21479
  * artifact (RV2501). The floor mirrors the id half of
21171
21480
  * {@link DEFAULT_ARTIFACT_PATTERN}: a two character id would satisfy
@@ -21477,6 +21786,13 @@ const DEFAULT_ARTIFACT_PATTERN = "(?:run[ -]?[0-9A-HJKMNP-TV-Z]{6,26}|[\\w./-]+\
21477
21786
  * the repair instruction is executable rather than aspirational. An id
21478
21787
  * shorter than `MIN_RUN_ID_ARTIFACT_CHARS` (six) is ignored, and
21479
21788
  * without an id the verdict is byte identical to the historical one.
21789
+ *
21790
+ * With the id in hand the failure also carries {@link FinishRepairHint}
21791
+ * rows (RV3801), one per offending sentence, so the finish loop can
21792
+ * perform the verdict's own prescription host side without spending a
21793
+ * provider wire; the reasons stay byte identical either way, and the
21794
+ * hints are bounded (at most `MAX_REPAIR_HINTS` offenders) and fail
21795
+ * closed (an id whose bytes could split a sentence is never hinted).
21480
21796
  * Default name 'evidence-grade'.
21481
21797
  */
21482
21798
  function evidenceGradeValidator(options) {
@@ -21496,18 +21812,32 @@ function evidenceGradeValidator(options) {
21496
21812
  const unsupported = [];
21497
21813
  const offenders = [];
21498
21814
  const runId = typeof input.runId === "string" && input.runId.trim().length >= MIN_RUN_ID_ARTIFACT_CHARS ? input.runId.trim() : void 0;
21815
+ let cursor = 0;
21499
21816
  for (const sentence of sentencesOf(input.text)) {
21817
+ const start = input.text.indexOf(sentence, cursor);
21818
+ cursor = start + sentence.length;
21500
21819
  const haystack = sentence.toLowerCase();
21501
21820
  const found = lowered.filter((phrase) => haystack.includes(phrase));
21502
21821
  if (found.length === 0 || new RegExp(artifactPattern, "").test(sentence) || runId !== void 0 && containsIdentifier(sentence, runId)) continue;
21503
- offenders.push(sentence);
21822
+ offenders.push({
21823
+ sentence,
21824
+ start,
21825
+ end: start + sentence.length
21826
+ });
21504
21827
  for (const phrase of found) if (!unsupported.includes(phrase)) unsupported.push(phrase);
21505
21828
  }
21506
21829
  if (unsupported.length === 0) return ok;
21507
- const named = offenders.slice(0, MAX_NAMED_OFFENDING_SENTENCES).map((sentence) => {
21830
+ const named = offenders.slice(0, MAX_NAMED_OFFENDING_SENTENCES).map(({ sentence }) => {
21508
21831
  const flat = sentence.replace(/\s+/gu, " ").trim();
21509
21832
  return `offending sentence: "${flat.length <= MAX_OFFENDING_SENTENCE_CHARS ? flat : `${flat.slice(0, MAX_OFFENDING_SENTENCE_CHARS)}...`}"`;
21510
21833
  });
21834
+ const hints = runId !== void 0 && offenders.length <= MAX_REPAIR_HINTS && !/[.!?]\s|[\r\n]/u.test(runId) && offenders.every((offender) => offender.start >= 0) ? offenders.map(({ sentence, start, end }) => ({
21835
+ mechanism: "insert-run-id",
21836
+ start,
21837
+ end,
21838
+ sentence,
21839
+ insert: runId
21840
+ })) : void 0;
21511
21841
  const overflow = offenders.length - named.length;
21512
21842
  return {
21513
21843
  ok: false,
@@ -21515,7 +21845,8 @@ function evidenceGradeValidator(options) {
21515
21845
  runId === void 0 ? `evidence-grade claims cite no run or repro artifact in their own sentence: ${listCitations(unsupported)}; give each such claim a file:line citation in its own sentence, or state its run id in a SEPARATE sentence carrying no source citation (a run id written beside a path:line citation is not in the cited window and trades this failure for a cited-value one)` : `evidence-grade claims cite no run or repro artifact in their own sentence: ${listCitations(unsupported)}; write this run's id ${runId} inside each such sentence, or give the claim a file:line citation instead (the id may share a sentence with a source citation: cited-value reads a run id as identity, not as a value asserted about the cited line)`,
21516
21846
  ...named,
21517
21847
  ...overflow > 0 ? [`and ${String(overflow)} more offending sentences`] : []
21518
- ]
21848
+ ],
21849
+ ...hints === void 0 ? {} : { repairHints: hints }
21519
21850
  };
21520
21851
  }
21521
21852
  };
@@ -22763,6 +23094,72 @@ function selfTestFinishValidation(options) {
22763
23094
  /** How many rejected finishes are repaired by default: the plan's repair once. */
22764
23095
  const DEFAULT_FINISH_MAX_REPAIRS = 1;
22765
23096
  /**
23097
+ * The most hinted edits one deterministic repair attempt will apply
23098
+ * (RV3801): a validator caps its own hints well below this, so the
23099
+ * bound only guards against a custom validator flooding the journal
23100
+ * with patch rows; past it the candidate goes to the model pool.
23101
+ */
23102
+ const MAX_DETERMINISTIC_PATCHES = 64;
23103
+ /**
23104
+ * Plans the sectional claim repair round (RV3803): which H2 sections
23105
+ * of the accepted pre-repair document own the judged findings. The
23106
+ * third comparison run's round regenerated the WHOLE 43k character
23107
+ * document to consume findings that lived in a handful of sentences,
23108
+ * and the tail after fan-in was 80.1 percent of the run's wall. Each
23109
+ * finding's `draftExcerpt` (whitespace collapsed by the pairing fold)
23110
+ * is located in the document through a collapse-aware scan, and its
23111
+ * owning section is the nearest H2 line above it. Fail closed to the
23112
+ * FULL regeneration (undefined, the historical round byte for byte)
23113
+ * whenever the plan cannot be exact: no excerpts, a document without
23114
+ * H2 headings, duplicated markers (the splice grammar needs unique
23115
+ * lines), or any excerpt the scan cannot locate.
23116
+ */
23117
+ function sectionalRoundPlan(document, excerpts) {
23118
+ if (excerpts.length === 0) return;
23119
+ const markers = [];
23120
+ let offset = 0;
23121
+ for (const line of document.split("\n")) {
23122
+ if (line.trim().startsWith("## ")) markers.push({
23123
+ marker: line.trim(),
23124
+ start: offset
23125
+ });
23126
+ offset += line.length + 1;
23127
+ }
23128
+ if (markers.length === 0 || new Set(markers.map((m) => m.marker)).size !== markers.length) return;
23129
+ const collapsed = [];
23130
+ const rawAt = [];
23131
+ let pendingSpace = false;
23132
+ for (let index = 0; index < document.length; index += 1) {
23133
+ const char = document[index] ?? "";
23134
+ if (/\s/u.test(char)) {
23135
+ pendingSpace = collapsed.length > 0;
23136
+ continue;
23137
+ }
23138
+ if (pendingSpace) {
23139
+ collapsed.push(" ");
23140
+ rawAt.push(index);
23141
+ pendingSpace = false;
23142
+ }
23143
+ collapsed.push(char);
23144
+ rawAt.push(index);
23145
+ }
23146
+ const haystack = collapsed.join("");
23147
+ const targets = [];
23148
+ for (const excerpt of excerpts) {
23149
+ const at = haystack.indexOf(excerpt.trim());
23150
+ if (at < 0) return;
23151
+ const raw = rawAt[at] ?? -1;
23152
+ const owner = [...markers].reverse().find((m) => m.start <= raw);
23153
+ if (owner === void 0) return;
23154
+ if (!targets.includes(owner.marker)) targets.push(owner.marker);
23155
+ }
23156
+ targets.sort((a, b) => markers.findIndex((m) => m.marker === a) - markers.findIndex((m) => m.marker === b));
23157
+ return {
23158
+ sections: markers.map((m) => m.marker),
23159
+ targets
23160
+ };
23161
+ }
23162
+ /**
22766
23163
  * Character cap of the HOST VALIDATION LESSONS prompt block (RV3603):
22767
23164
  * the bounded repair round's prompt folds the run's journaled finish
22768
23165
  * validation failures so the round does not relearn a lesson the run
@@ -22895,6 +23292,8 @@ function validateOrchestrateOptions(opts) {
22895
23292
  }
22896
23293
  if (fv.maxRepairs !== void 0) requireNonNegativeInteger(fv.maxRepairs, "orchestrate finishValidation.maxRepairs");
22897
23294
  if (fv.repairTurnReserve !== void 0) requireNonNegativeInteger(fv.repairTurnReserve, "orchestrate finishValidation.repairTurnReserve");
23295
+ const estRepair = fv.estRepairCostUsd;
23296
+ if (estRepair !== void 0 && (typeof estRepair !== "number" || !Number.isFinite(estRepair) || estRepair < 0)) throw new ConfigError(`orchestrate finishValidation.estRepairCostUsd must be a nonnegative finite number; got ${JSON.stringify(estRepair)}`);
22898
23297
  const retain = fv.retainRejectedCandidates;
22899
23298
  if (retain !== void 0 && typeof retain !== "boolean") throw new ConfigError("orchestrate finishValidation.retainRejectedCandidates must be a boolean");
22900
23299
  const draftPolicy = fv.draftPolicy;
@@ -23114,6 +23513,7 @@ function validateOrchestrateOptions(opts) {
23114
23513
  if (opts.synthesis.mode === "incremental") throw new ConfigError("orchestrate budget.synthesisReserveUsd is incompatible with synthesis.mode 'incremental': the reserve protects the single post-fan-in invocation");
23115
23514
  }
23116
23515
  if (spec.finalizeTurns !== void 0) requirePositiveInteger$2(spec.finalizeTurns, "orchestrate budget.finalizeTurns");
23516
+ if (spec.acceptanceReserve !== void 0 && spec.acceptanceReserve !== "warn" && spec.acceptanceReserve !== "require") throw new ConfigError(`orchestrate budget.acceptanceReserve must be 'warn' or 'require'; got ${String(spec.acceptanceReserve)}`);
23117
23517
  if (spec.atCap !== void 0 && spec.atCap !== "finish-with-partial" && spec.atCap !== "fail-run") throw new ConfigError(`orchestrate budget.atCap must be 'finish-with-partial' or 'fail-run'; got ${String(spec.atCap)}`);
23118
23518
  }
23119
23519
  function orchestratorPrompt(goal, maxSpawns, extensionLines) {
@@ -23311,6 +23711,42 @@ function makeOrchestratorWorkflow(goal, opts) {
23311
23711
  };
23312
23712
  }
23313
23713
  }
23714
+ if (opts?.budget?.acceptanceReserve === "require") {
23715
+ const synthesisHoldUsd = opts.budget.synthesisReserveUsd ?? 0;
23716
+ const judgeEstUsd = opts?.claimConsistency?.judge?.estCost ?? 0;
23717
+ const bootClaimStage = opts?.claimConsistency?.stage ?? "draft";
23718
+ const roundArmed = (opts?.claimConsistency?.onFound ?? "report") === "repair" && bootClaimStage !== "draft";
23719
+ const judgePasses = 1 + (roundArmed ? 1 : 0);
23720
+ const judgeTailUsd = judgeEstUsd * judgePasses;
23721
+ const mechanicalRepairUsd = opts?.finishValidation?.estRepairCostUsd ?? 0;
23722
+ const roundCompositionUsd = roundArmed ? opts?.synthesis?.estCost ?? 0 : 0;
23723
+ const workingRoomUsd = capState?.turnEstimateUsd ?? internals.flatReserveUsd ?? .5;
23724
+ const requiredUsd = synthesisHoldUsd + judgeTailUsd + mechanicalRepairUsd + roundCompositionUsd + workingRoomUsd;
23725
+ const capUsd = capState?.effectiveCapUsd;
23726
+ if (capUsd === void 0 || capUsd < requiredUsd) {
23727
+ const terms = `synthesisReserveUsd ${synthesisHoldUsd.toFixed(4)} + judge ${judgeEstUsd.toFixed(4)} x ${String(judgePasses)} pass(es) + estRepairCostUsd ${mechanicalRepairUsd.toFixed(4)} + round composition ${roundCompositionUsd.toFixed(4)} + working room ${workingRoomUsd.toFixed(4)} = ${requiredUsd.toFixed(4)} USD`;
23728
+ await internals.replayer.appendSinglePhase({
23729
+ scope: callingState.scope,
23730
+ key: deriverV2.deriveKey({ kind: "acceptance-reserve-refused" }),
23731
+ kind: "decision",
23732
+ status: "ok",
23733
+ spanId: internals.spans.mint(callingState.spanId),
23734
+ site: "orchestrator-budget",
23735
+ value: {
23736
+ decisionType: "acceptance_reserve_refused",
23737
+ requiredUsd,
23738
+ effectiveCapUsd: capUsd ?? null,
23739
+ synthesisReserveUsd: synthesisHoldUsd,
23740
+ judgeEstUsd,
23741
+ judgePasses,
23742
+ estRepairCostUsd: mechanicalRepairUsd,
23743
+ roundCompositionUsd,
23744
+ workingRoomUsd
23745
+ }
23746
+ });
23747
+ throw new OrchestratorCapConfigError(capUsd === void 0 ? `budget.acceptanceReserve 'require' needs a resolved effective cap to hold the declared acceptance tail against (${terms}); declare budget.capUsd or a run ceiling` : `budget.acceptanceReserve 'require': the declared acceptance tail does not fit the effective cap ${capUsd.toFixed(4)} USD (${terms}); raise the cap or lower the declared tail`);
23748
+ }
23749
+ }
23314
23750
  const records = /* @__PURE__ */ new Map();
23315
23751
  const byOrdinal = /* @__PURE__ */ new Map();
23316
23752
  const rejectedByOrdinal = /* @__PURE__ */ new Map();
@@ -23461,6 +23897,7 @@ function makeOrchestratorWorkflow(goal, opts) {
23461
23897
  const childState = {
23462
23898
  scope,
23463
23899
  spanId: internals.spans.mint(callingState.spanId),
23900
+ phase: callingState.phase ?? "fan-out",
23464
23901
  signal: upstream === void 0 ? controller.signal : AbortSignal.any([upstream, controller.signal]),
23465
23902
  budgetScope: placement?.ownAccount === true ? scope : callingState.budgetScope ?? "run"
23466
23903
  };
@@ -24263,6 +24700,31 @@ function makeOrchestratorWorkflow(goal, opts) {
24263
24700
  */
24264
24701
  let validationInvocationStart = 0;
24265
24702
  /**
24703
+ * The staged release of the round's mechanical money leg (RV3802),
24704
+ * armed by the bounded claim repair round right before its
24705
+ * composition dispatches and fired at the round invocation's FIRST
24706
+ * journaled finish verdict: a 'repair' verdict is about to spend
24707
+ * the freed money on the granted turn, an 'accepted' one never
24708
+ * needed it, and a 'rejected' one dies into the round's own
24709
+ * finally, which releases whatever is still armed. Live-only state
24710
+ * on the RV808b doctrine: the hold itself is re-committed by the
24711
+ * re-executed round code on a resume, and full replay never runs
24712
+ * validateFinish at all.
24713
+ */
24714
+ let releaseRepairLeg;
24715
+ /**
24716
+ * The sectional round context (RV3803), armed by the bounded claim
24717
+ * repair round exactly when {@link sectionalRoundPlan} is exact
24718
+ * over the accepted pre-repair document and the judged findings:
24719
+ * the retained base, its full H2 marker roster, and the target
24720
+ * sections owning the findings. Live state cleared in the round's
24721
+ * finally; a resume re-derives it from replayed material (the
24722
+ * judged findings and the accepted document both replay verbatim),
24723
+ * so the round's prompt bytes stay identical without journaling
24724
+ * anything new.
24725
+ */
24726
+ let sectionalRoundContext;
24727
+ /**
24266
24728
  * The contract generation membership test (cycle 73). Without a
24267
24729
  * contract there are no generations and every decision is current
24268
24730
  * (the pre 1.77 behavior, byte identical). With one, a decision
@@ -24295,8 +24757,9 @@ function makeOrchestratorWorkflow(goal, opts) {
24295
24757
  const rows = [];
24296
24758
  const seen = /* @__PURE__ */ new Set();
24297
24759
  for (const decision of validationDecisions()) {
24298
- if (decision.failed.length === 0 || !contractGenerationCurrent(decision)) continue;
24299
- for (const failure of decision.failed) {
24760
+ const taught = [...decision.failed, ...decision.deterministicRepair?.healed ?? []];
24761
+ if (taught.length === 0 || !contractGenerationCurrent(decision)) continue;
24762
+ for (const failure of taught) {
24300
24763
  const key = JSON.stringify([failure.name, failure.reasons]);
24301
24764
  if (seen.has(key)) continue;
24302
24765
  seen.add(key);
@@ -24435,7 +24898,45 @@ function makeOrchestratorWorkflow(goal, opts) {
24435
24898
  if (validationSpec === void 0) return { ok: true };
24436
24899
  let effective = call.result ?? null;
24437
24900
  let spliced = false;
24438
- if (finishSectional !== void 0) {
24901
+ if (sectionalRoundContext !== void 0) {
24902
+ const round = sectionalRoundContext;
24903
+ const args = call.args ?? {};
24904
+ const hasSections = Object.hasOwn(args, "sections");
24905
+ const hasResult = Object.hasOwn(args, "result");
24906
+ const guidance = () => ({
24907
+ declaredSections: round.sections,
24908
+ targetSections: round.targets,
24909
+ instruction: "repair ONLY the target sections: call finish({ sections: { \"<marker>\": \"<new section body>\" } }); unchanged sections are spliced from the retained accepted document byte for byte and the spliced whole is validated and judged. Resubmit the full document as result only when a targeted repair is impossible."
24910
+ });
24911
+ if (hasSections && hasResult) return {
24912
+ ok: false,
24913
+ feedback: {
24914
+ error: "pass either result (the full document) or sections (a sectional repair of the retained accepted document), never both",
24915
+ ...guidance()
24916
+ }
24917
+ };
24918
+ if (hasSections) {
24919
+ const patch = args.sections;
24920
+ const markers = Object.keys(patch);
24921
+ if (markers.length === 0) return {
24922
+ ok: false,
24923
+ feedback: {
24924
+ error: "sections must name at least one declared section marker",
24925
+ ...guidance()
24926
+ }
24927
+ };
24928
+ const unknown = markers.filter((marker) => !round.sections.includes(marker));
24929
+ if (unknown.length > 0) return {
24930
+ ok: false,
24931
+ feedback: {
24932
+ error: `sections names an undeclared section ${unknown.map((marker) => `'${marker}'`).join(", ")}; only the retained document's own markers splice`,
24933
+ ...guidance()
24934
+ }
24935
+ };
24936
+ effective = spliceSections(round.base, round.sections, patch);
24937
+ spliced = true;
24938
+ }
24939
+ } else if (finishSectional !== void 0) {
24439
24940
  const resolution = finishSectional.resolve(call);
24440
24941
  if (resolution.kind === "refused") return {
24441
24942
  ok: false,
@@ -24446,6 +24947,7 @@ function makeOrchestratorWorkflow(goal, opts) {
24446
24947
  }
24447
24948
  const maxRepairs = validationSpec.maxRepairs ?? 1;
24448
24949
  const known = validationDecisions();
24950
+ let patchedResult;
24449
24951
  let decision = known.find((candidate) => candidate.callId === call.id);
24450
24952
  if (decision === void 0) {
24451
24953
  const result = effective;
@@ -24456,6 +24958,7 @@ function makeOrchestratorWorkflow(goal, opts) {
24456
24958
  runId: internals.runId
24457
24959
  };
24458
24960
  const failed = [];
24961
+ const failureHints = [];
24459
24962
  for (const validator of validationSpec.validators) {
24460
24963
  let verdict;
24461
24964
  try {
@@ -24468,13 +24971,66 @@ function makeOrchestratorWorkflow(goal, opts) {
24468
24971
  feedback: { error: `finish validator '${validator.name}' is defective; the run fails` }
24469
24972
  };
24470
24973
  }
24471
- if (!verdict.ok) failed.push({
24472
- name: validator.name,
24473
- reasons: verdict.reasons
24474
- });
24974
+ if (!verdict.ok) {
24975
+ failed.push({
24976
+ name: validator.name,
24977
+ reasons: verdict.reasons
24978
+ });
24979
+ failureHints.push(verdict.repairHints);
24980
+ }
24981
+ }
24982
+ let deterministicRepair;
24983
+ if (failed.length > 0 && typeof result === "string" && failureHints.every((hints) => hints !== void 0 && hints.length > 0)) {
24984
+ const merged = [];
24985
+ const seenHints = /* @__PURE__ */ new Set();
24986
+ for (const hints of failureHints) for (const hint of hints ?? []) {
24987
+ const key = `${String(hint.start)}:${String(hint.end)}:${hint.insert}`;
24988
+ if (!seenHints.has(key)) {
24989
+ seenHints.add(key);
24990
+ merged.push(hint);
24991
+ }
24992
+ }
24993
+ const patched = merged.length <= MAX_DETERMINISTIC_PATCHES && merged.every((hint) => hint.mechanism === "insert-run-id" && result.slice(hint.start, hint.end) === hint.sentence) ? applyFinishRepairHints(result, merged) : void 0;
24994
+ if (patched !== void 0) {
24995
+ const patchedInput = {
24996
+ result: patched,
24997
+ text: patched,
24998
+ children: input.children,
24999
+ runId: internals.runId
25000
+ };
25001
+ const residual = [];
25002
+ for (const validator of validationSpec.validators) {
25003
+ let verdict;
25004
+ try {
25005
+ verdict = validator.validate(patchedInput);
25006
+ } catch (thrown) {
25007
+ validationTermination = new ConfigError(`finish validator '${validator.name}' threw instead of returning a verdict: ` + (thrown instanceof Error ? thrown.message : String(thrown)));
25008
+ validationAbort.abort("rulvar:finish-validation-defect");
25009
+ return {
25010
+ ok: false,
25011
+ feedback: { error: `finish validator '${validator.name}' is defective; the run fails` }
25012
+ };
25013
+ }
25014
+ if (!verdict.ok) residual.push(validator.name);
25015
+ }
25016
+ const patchSurvived = residual.length === 0;
25017
+ deterministicRepair = {
25018
+ mechanism: "insert-run-id",
25019
+ patches: merged.map(({ start, end, insert }) => ({
25020
+ start,
25021
+ end,
25022
+ insert
25023
+ })),
25024
+ beforeHash: createHash("sha256").update(jcsSerialize(result), "utf8").digest("hex"),
25025
+ afterHash: createHash("sha256").update(jcsSerialize(patched), "utf8").digest("hex"),
25026
+ outcome: patchSurvived ? "accepted" : "failed",
25027
+ ...patchSurvived ? { healed: failed } : { residual }
25028
+ };
25029
+ if (patchSurvived) patchedResult = patched;
25030
+ }
24475
25031
  }
24476
25032
  const repairsUsed = known.filter((candidate, index) => index >= validationInvocationStart && candidate.verdict !== "accepted" && contractGenerationCurrent(candidate)).length;
24477
- const rejectedCandidate = failed.length > 0;
25033
+ const rejectedCandidate = failed.length > 0 && deterministicRepair?.outcome !== "accepted";
24478
25034
  let candidateRef;
24479
25035
  if (rejectedCandidate && validationSpec.retainRejectedCandidates === true) {
24480
25036
  const ref = `${internals.runId}/finish-rejected/${call.id}`;
@@ -24496,10 +25052,11 @@ function makeOrchestratorWorkflow(goal, opts) {
24496
25052
  decision = {
24497
25053
  decisionType: "orchestrator_finish_validation",
24498
25054
  callId: call.id,
24499
- verdict: failed.length === 0 ? "accepted" : repairsUsed < maxRepairs ? "repair" : "rejected",
24500
- failed,
25055
+ verdict: failed.length === 0 || deterministicRepair?.outcome === "accepted" ? "accepted" : repairsUsed < maxRepairs ? "repair" : "rejected",
25056
+ failed: deterministicRepair?.outcome === "accepted" ? [] : failed,
24501
25057
  repairsUsed,
24502
25058
  maxRepairs,
25059
+ ...deterministicRepair === void 0 ? {} : { deterministicRepair },
24503
25060
  ...validationSpec.contract === void 0 ? {} : { contractHash: validationSpec.contract.hash },
24504
25061
  ...rejectedCandidate ? {
24505
25062
  candidateHash: createHash("sha256").update(jcsSerialize(result), "utf8").digest("hex"),
@@ -24516,11 +25073,18 @@ function makeOrchestratorWorkflow(goal, opts) {
24516
25073
  site: "orchestrator-finish-validation",
24517
25074
  value: decision
24518
25075
  });
25076
+ releaseRepairLeg?.();
25077
+ }
25078
+ if (decision.verdict === "accepted") {
25079
+ if (patchedResult !== void 0) return {
25080
+ ok: true,
25081
+ resolved: { result: patchedResult }
25082
+ };
25083
+ return spliced ? {
25084
+ ok: true,
25085
+ resolved: { result: effective }
25086
+ } : { ok: true };
24519
25087
  }
24520
- if (decision.verdict === "accepted") return spliced ? {
24521
- ok: true,
24522
- resolved: { result: effective }
24523
- } : { ok: true };
24524
25088
  finishSectional?.retain(effective);
24525
25089
  if (decision.verdict === "rejected") {
24526
25090
  if (contractGenerationCurrent(decision)) {
@@ -24541,7 +25105,11 @@ function makeOrchestratorWorkflow(goal, opts) {
24541
25105
  error: "the finish result failed host validation; repair the result and call finish again",
24542
25106
  failed: decision.failed,
24543
25107
  repairsRemaining: decision.maxRepairs - decision.repairsUsed - 1,
24544
- ...finishSectional === void 0 ? {} : { sectionalRepair: finishSectional.guidance() }
25108
+ ...sectionalRoundContext !== void 0 ? { sectionalRepair: {
25109
+ declaredSections: sectionalRoundContext.sections,
25110
+ targetSections: sectionalRoundContext.targets,
25111
+ instruction: "repair ONLY the target sections: call finish({ sections: { \"<marker>\": \"<new section body>\" } }); unchanged sections are spliced from the retained accepted document byte for byte and the spliced whole is validated and judged. Resubmit the full document as result only when a targeted repair is impossible."
25112
+ } } : finishSectional === void 0 ? {} : { sectionalRepair: finishSectional.guidance() }
24545
25113
  }
24546
25114
  };
24547
25115
  };
@@ -24717,6 +25285,7 @@ function makeOrchestratorWorkflow(goal, opts) {
24717
25285
  };
24718
25286
  const orchestratorState = { ...callingState };
24719
25287
  if (orchestratorAccount !== void 0) orchestratorState.budgetScope = orchestratorAccount;
25288
+ orchestratorState.phase = orchestratorState.phase ?? "coordination";
24720
25289
  const loopBreakSignal = validationSpec === void 0 ? forcedFinishController.signal : AbortSignal.any([forcedFinishController.signal, validationAbort.signal]);
24721
25290
  orchestratorState.signal = callingState.signal === void 0 ? loopBreakSignal : AbortSignal.any([callingState.signal, loopBreakSignal]);
24722
25291
  /**
@@ -24772,6 +25341,7 @@ function makeOrchestratorWorkflow(goal, opts) {
24772
25341
  if (orchestratorAccount !== void 0) internals.budget.releaseFinalizeReserve(orchestratorAccount);
24773
25342
  const finalState = { ...callingState };
24774
25343
  if (orchestratorAccount !== void 0) finalState.budgetScope = orchestratorAccount;
25344
+ finalState.phase = finalState.phase ?? "coordination";
24775
25345
  const digest = buildDigest(wakeOrdinal);
24776
25346
  const reserveBaseline = orchestratorAccount === void 0 ? 0 : internals.budget.accountView(orchestratorAccount)?.spentUsd ?? 0;
24777
25347
  const dispatched = await runtime.runInScope(finalState, () => ctx.agent([
@@ -24845,6 +25415,7 @@ function makeOrchestratorWorkflow(goal, opts) {
24845
25415
  ].join("\n");
24846
25416
  const noteState = { ...callingState };
24847
25417
  if (orchestratorAccount !== void 0) noteState.budgetScope = orchestratorAccount;
25418
+ noteState.phase = noteState.phase ?? "composition";
24848
25419
  const noteOpts = {
24849
25420
  role: "synthesize",
24850
25421
  result: "full",
@@ -25339,6 +25910,7 @@ function makeOrchestratorWorkflow(goal, opts) {
25339
25910
  ].join("\n");
25340
25911
  const judgeState = { ...callingState };
25341
25912
  if (orchestratorAccount !== void 0) judgeState.budgetScope = orchestratorAccount;
25913
+ judgeState.phase = judgeState.phase ?? "judge";
25342
25914
  const judgeOpts = {
25343
25915
  role: "synthesize",
25344
25916
  result: "full",
@@ -25434,7 +26006,7 @@ function makeOrchestratorWorkflow(goal, opts) {
25434
26006
  ...snapshot ?? {}
25435
26007
  } });
25436
26008
  };
25437
- const runSynthesis = async (draft) => {
26009
+ const runSynthesis = async (draft, stagePhase = "composition") => {
25438
26010
  const spec = opts?.synthesis;
25439
26011
  if (spec === void 0) return draft;
25440
26012
  await recoveryDone;
@@ -25608,7 +26180,7 @@ function makeOrchestratorWorkflow(goal, opts) {
25608
26180
  const synthesisToolNames = /* @__PURE__ */ new Set([FINISH_TOOL_NAME, ...exposeTools ? [GET_CHILD_RESULT_TOOL_NAME, READ_CHILD_ARTIFACT_TOOL_NAME] : []]);
25609
26181
  const synthesisTools = buildOrchestratorTools(orchestratorRuntime, fullCardText, {
25610
26182
  childResultTools: exposeTools,
25611
- sectionalFinish: synthSectionalFinish
26183
+ sectionalFinish: synthSectionalFinish || sectionalRoundContext !== void 0
25612
26184
  }).filter((tool) => synthesisToolNames.has(tool.name));
25613
26185
  if (finishSectional !== void 0 && synthSectionalFinish) finishSectional.retain(draft);
25614
26186
  const settledEntries = [...byOrdinal.values()].filter((record) => record.settled !== void 0).sort((a, b) => a.spawnOrdinal - b.spawnOrdinal).map((record) => [record.handle, record]);
@@ -25686,6 +26258,11 @@ function makeOrchestratorWorkflow(goal, opts) {
25686
26258
  ...opts?.contradictions?.onFound !== "carry" || contradictionsFound === void 0 || contradictionsFound.length === 0 ? [] : ["CHILD CONTRADICTIONS: the settled children read these cited locations differently; resolve each one EXPLICITLY in the final result (say which reading holds and why it does) instead of silently picking one. " + JSON.stringify(contradictionsFound)],
25687
26259
  ...opts?.claimConsistency?.onFound !== "carry" && opts?.claimConsistency?.onFound !== "repair" || claimFindingsFound === void 0 || claimFindingsFound.length === 0 ? [] : ["CLAIM CONTRADICTIONS: the composed draft contradicts the settled child pool at these cited locations; resolve each one EXPLICITLY in the final result (say which reading holds and why) instead of keeping the inverted claim. " + JSON.stringify(claimFindingsFound)],
25688
26260
  ...opts?.claimConsistency?.onFound !== "carry" && opts?.claimConsistency?.onFound !== "repair" || claimFindingsFound === void 0 || claimFindingsFound.length === 0 ? [] : hostValidationLessons(),
26261
+ ...sectionalRoundContext === void 0 ? [] : [
26262
+ `RETAINED FINAL: ${JSON.stringify(sectionalRoundContext.base)}`,
26263
+ "SECTIONAL ROUND: the accepted document above is RETAINED; repair ONLY the sections owning the contradicted claims by calling finish({ sections: { \"<marker>\": \"<new section body>\" } }). Unchanged sections are spliced from the retained document byte for byte and the spliced whole is validated and judged. Target sections: " + JSON.stringify(sectionalRoundContext.targets) + ". Declared markers: " + JSON.stringify(sectionalRoundContext.sections) + ". Resubmit the full document as result only when a targeted repair is impossible.",
26264
+ "Rewritten sections must keep the retained evidence discipline: a sentence making a verified or confirmed grade claim carries the run id or a file:line citation INSIDE the sentence, exactly like the retained sections do; a rewritten sentence that drops it fails the finish contract mechanically."
26265
+ ],
25689
26266
  ...spec.policyFacts === true ? [(() => {
25690
26267
  const byStatus = {};
25691
26268
  let extensionsGranted = 0;
@@ -25786,6 +26363,7 @@ function makeOrchestratorWorkflow(goal, opts) {
25786
26363
  const configuredReserveUsd = opts?.budget?.synthesisReserveUsd ?? 0;
25787
26364
  const heldReserveUsd = orchestratorAccount === void 0 ? 0 : internals.budget.accountView(orchestratorAccount)?.synthesisReserveUsd ?? 0;
25788
26365
  const synthesisState = { ...callingState };
26366
+ synthesisState.phase = synthesisState.phase ?? stagePhase;
25789
26367
  if (orchestratorAccount !== void 0) {
25790
26368
  synthesisState.budgetScope = orchestratorAccount;
25791
26369
  internals.budget.releaseSynthesisReserve(orchestratorAccount);
@@ -26533,6 +27111,10 @@ function makeOrchestratorWorkflow(goal, opts) {
26533
27111
  if (claimStage !== "draft") {
26534
27112
  claimConsistencyDraftMeta = claimStage === "both" ? claimConsistencyMeta : void 0;
26535
27113
  await runClaimConsistencyPass(synthesizedFinal, acceptanceSnapshot, "final");
27114
+ if ((opts?.claimConsistency?.onFound ?? "report") === "repair" && claimConsistencyMeta !== void 0) {
27115
+ claimConsistencyMeta.passes = 1;
27116
+ claimConsistencyMeta.semanticRepairRounds = 0;
27117
+ }
26536
27118
  if ((opts?.claimConsistency?.onFound ?? "report") === "repair" && claimFindingsFound !== void 0 && claimFindingsFound.length > 0) {
26537
27119
  const hashOfDocument = (value) => createHash("sha256").update(jcsSerialize(value ?? null), "utf8").digest("hex");
26538
27120
  const preRepairHash = hashOfDocument(synthesizedFinal);
@@ -26540,8 +27122,32 @@ function makeOrchestratorWorkflow(goal, opts) {
26540
27122
  const convergenceHoldUsd = opts?.claimConsistency?.judge?.estCost ?? observedFinalJudgeCostUsd ?? 0;
26541
27123
  const convergenceScope = orchestratorAccount ?? "run";
26542
27124
  if (convergenceHoldUsd > 0) internals.budget.commitConvergenceReserve(convergenceScope, convergenceHoldUsd);
27125
+ const repairHoldUsd = validationSpec === void 0 ? 0 : validationSpec.estRepairCostUsd ?? lastMechanicalRepairCostUsd(internals.replayer.snapshot(), (servedBy, usage) => internals.priceUsd(servedBy, usage)) ?? 0;
27126
+ if (repairHoldUsd > 0) {
27127
+ internals.budget.commitRepairReserve(convergenceScope, repairHoldUsd);
27128
+ releaseRepairLeg = () => {
27129
+ releaseRepairLeg = void 0;
27130
+ internals.budget.releaseRepairReserve(convergenceScope);
27131
+ };
27132
+ }
27133
+ const roundPlan = validationSpec !== void 0 && typeof synthesizedFinal === "string" ? sectionalRoundPlan(synthesizedFinal, carried.map((finding) => finding.draftExcerpt)) : void 0;
27134
+ if (roundPlan !== void 0) {
27135
+ sectionalRoundContext = {
27136
+ base: synthesizedFinal,
27137
+ ...roundPlan
27138
+ };
27139
+ internals.events.emit({
27140
+ type: "log",
27141
+ level: "debug",
27142
+ msg: "orchestrator sectional round armed",
27143
+ data: {
27144
+ targets: roundPlan.targets,
27145
+ sections: roundPlan.sections.length
27146
+ }
27147
+ }, callingState.spanId);
27148
+ }
26543
27149
  try {
26544
- synthesizedFinal = await runSynthesis(result.output);
27150
+ synthesizedFinal = await runSynthesis(result.output, "repair");
26545
27151
  } catch (thrown) {
26546
27152
  await journalSynthesisAdmissionDecline(thrown);
26547
27153
  const hostRejection = thrown instanceof FailRunError && typeof thrown.data === "object" && thrown.data !== null && !Array.isArray(thrown.data) && thrown.data.source === "orchestrator_finish_validation" ? thrown.data : void 0;
@@ -26572,10 +27178,18 @@ function makeOrchestratorWorkflow(goal, opts) {
26572
27178
  ...acceptanceSnapshot
26573
27179
  } });
26574
27180
  } finally {
27181
+ sectionalRoundContext = void 0;
27182
+ releaseRepairLeg = void 0;
27183
+ if (repairHoldUsd > 0) internals.budget.releaseRepairReserve(convergenceScope);
26575
27184
  if (convergenceHoldUsd > 0) internals.budget.releaseConvergenceReserve(convergenceScope);
26576
27185
  }
26577
27186
  try {
26578
27187
  await runClaimConsistencyPass(synthesizedFinal, acceptanceSnapshot, "final");
27188
+ if (claimConsistencyMeta !== void 0) {
27189
+ claimConsistencyMeta.passes = 2;
27190
+ claimConsistencyMeta.firstPassFindings = carried.length;
27191
+ claimConsistencyMeta.semanticRepairRounds = 1;
27192
+ }
26579
27193
  } catch (thrown) {
26580
27194
  if (thrown instanceof FailRunError && typeof thrown.data === "object" && thrown.data !== null && !Array.isArray(thrown.data) && thrown.data.source === "orchestrator_claim_consistency") throw new FailRunError(thrown.message, { data: {
26581
27195
  ...thrown.data,
@@ -26611,6 +27225,14 @@ function makeOrchestratorWorkflow(goal, opts) {
26611
27225
  };
26612
27226
  })();
26613
27227
  const envelopeRejectedCandidates = rejectedFinishCandidates();
27228
+ const acceptedRepairs = validationDecisions().map((verdict) => verdict.deterministicRepair).filter((repair) => repair !== void 0 && repair.outcome === "accepted");
27229
+ const lastAcceptedRepair = acceptedRepairs.at(-1);
27230
+ const deterministicPatches = lastAcceptedRepair === void 0 ? void 0 : {
27231
+ decisions: acceptedRepairs.length,
27232
+ patches: acceptedRepairs.reduce((sum, repair) => sum + repair.patches.length, 0),
27233
+ lastBeforeHash: lastAcceptedRepair.beforeHash,
27234
+ lastAfterHash: lastAcceptedRepair.afterHash
27235
+ };
26614
27236
  return {
26615
27237
  result: synthesizedFinal,
26616
27238
  completion: decision.completion,
@@ -26618,6 +27240,7 @@ function makeOrchestratorWorkflow(goal, opts) {
26618
27240
  ...deliverable.deliverableAccepted === void 0 ? {} : { deliverableAccepted: deliverable.deliverableAccepted },
26619
27241
  ...deliverable.acceptedArtifactRef === void 0 ? {} : { acceptedArtifactRef: deliverable.acceptedArtifactRef },
26620
27242
  ...envelopeRejectedCandidates.length === 0 ? {} : { rejectedFinishCandidates: envelopeRejectedCandidates },
27243
+ ...deterministicPatches === void 0 ? {} : { deterministicPatches },
26621
27244
  childStatusCounts: decision.childStatusCounts,
26622
27245
  degradedReasons: decision.degradedReasons,
26623
27246
  ...decision.salvagedPartialChildren === void 0 ? {} : { salvagedPartialChildren: decision.salvagedPartialChildren },
@@ -26671,9 +27294,9 @@ function makeOrchestratorWorkflow(goal, opts) {
26671
27294
  * Top-level surface: creates a run. `runOptions` are the ordinary
26672
27295
  * engine {@link RunOptions} of the created run; in particular
26673
27296
  * `runOptions.budgetUsd` is the ROOT hard ceiling over the WHOLE tree
26674
- * (the orchestrator and every child), immutable after start, while
26675
- * `opts.budget` only shapes the orchestrator's own sub-account inside
26676
- * that ceiling. The shortcut previously accepted no RunOptions at all,
27297
+ * (the orchestrator and every child), immutable within a segment,
27298
+ * while `opts.budget` only shapes the orchestrator's own sub-account
27299
+ * inside that ceiling. The shortcut previously accepted no RunOptions at all,
26677
27300
  * so the canonical entry point could not set a root ceiling without
26678
27301
  * dropping to `engine.run(makeOrchestratorWorkflow(...))` (v1.18.0
26679
27302
  * review P1-5).
@@ -28604,6 +29227,7 @@ function createEngine(options) {
28604
29227
  if (opts?.configFingerprint !== void 0) requireConfigFingerprint(opts.configFingerprint, "RunOptions.configFingerprint");
28605
29228
  if (opts?.clampTurnToExposure !== void 0 && typeof opts.clampTurnToExposure !== "boolean") throw new ConfigError("RunOptions.clampTurnToExposure must be a boolean; got " + JSON.stringify(opts.clampTurnToExposure));
28606
29229
  if (opts?.strictPricing !== void 0 && typeof opts.strictPricing !== "boolean" && (typeof opts.strictPricing !== "object" || opts.strictPricing === null || Array.isArray(opts.strictPricing))) throw new ConfigError("RunOptions.strictPricing must be a boolean or an options object; got " + JSON.stringify(opts.strictPricing));
29230
+ if (opts?.budgetPolicy !== void 0 && opts.budgetPolicy !== "segment" && opts.budgetPolicy !== "immutable-lifetime") throw new ConfigError("RunOptions.budgetPolicy must be 'segment' or 'immutable-lifetime'; got " + JSON.stringify(opts.budgetPolicy));
28607
29231
  if (opts?.limits !== void 0) validateUsageLimits(opts.limits, "RunOptions.limits");
28608
29232
  const deadlineAtMs = opts?.deadlineAt === void 0 ? void 0 : parseDeadlineAt(opts.deadlineAt);
28609
29233
  const compiled = wf.kind === "compiled-workflow" ? wf : void 0;
@@ -28638,6 +29262,7 @@ function createEngine(options) {
28638
29262
  ...opts.strictPricing.allowUnpriced === void 0 ? {} : { allowUnpriced: [...opts.strictPricing.allowUnpriced] }
28639
29263
  };
28640
29264
  const configFingerprint = opts?.configFingerprint ?? resumeCtx?.configFingerprint;
29265
+ const budgetPolicy = opts?.budgetPolicy ?? resumeCtx?.budgetPolicy;
28641
29266
  const makeBudget = () => new RunBudget({
28642
29267
  ...ceilingUsd === void 0 ? {} : { ceilingUsd },
28643
29268
  ...exposureCapUsd === void 0 ? {} : { maxInFlightExposureUsd: exposureCapUsd },
@@ -28775,6 +29400,7 @@ function createEngine(options) {
28775
29400
  byModel: /* @__PURE__ */ new Map(),
28776
29401
  byPhase: /* @__PURE__ */ new Map(),
28777
29402
  byAgentType: /* @__PURE__ */ new Map(),
29403
+ byScope: /* @__PURE__ */ new Map(),
28778
29404
  byRole: /* @__PURE__ */ new Map(),
28779
29405
  unpriced: [],
28780
29406
  orchestrator: {
@@ -28819,6 +29445,7 @@ function createEngine(options) {
28819
29445
  ...ceilingUsd === void 0 ? {} : { budgetUsd: ceilingUsd },
28820
29446
  ...exposureCapUsd === void 0 ? {} : { maxInFlightExposureUsd: exposureCapUsd },
28821
29447
  ...strictPricing === void 0 ? {} : { strictPricing },
29448
+ ...budgetPolicy === "immutable-lifetime" ? { budgetPolicy } : {},
28822
29449
  ...configFingerprint === void 0 ? {} : { configFingerprint },
28823
29450
  ...argsBinding.argsProvided === void 0 ? {} : { argsProvided: argsBinding.argsProvided },
28824
29451
  ...argsBinding.argsHash === void 0 ? {} : { argsHash: argsBinding.argsHash },
@@ -29246,6 +29873,7 @@ function createEngine(options) {
29246
29873
  ...runOverride.budgetUsd === void 0 ? {} : { budgetUsd: runOverride.budgetUsd },
29247
29874
  ...runOverride.maxInFlightExposureUsd === void 0 ? {} : { maxInFlightExposureUsd: runOverride.maxInFlightExposureUsd }
29248
29875
  };
29876
+ if (budgetOverride !== void 0 && meta?.budgetPolicy === "immutable-lifetime") throw new ConfigError(`run '${runId}' was started with budgetPolicy 'immutable-lifetime': the recorded ceilings are immutable for the whole life of the run and ResumeOptions.run is refused, raising and lowering alike; cancel the run (or start a new one) instead of editing its ceilings`);
29249
29877
  return run(bound, resumeOptions?.args, void 0, {
29250
29878
  runId,
29251
29879
  priorEntries,
@@ -29256,6 +29884,7 @@ function createEngine(options) {
29256
29884
  ...typeof meta?.budgetUsd === "number" ? { budgetUsd: meta.budgetUsd } : {},
29257
29885
  ...typeof meta?.maxInFlightExposureUsd === "number" ? { maxInFlightExposureUsd: meta.maxInFlightExposureUsd } : {},
29258
29886
  ...typeof meta?.strictPricing === "object" && meta.strictPricing !== null ? { strictPricing: meta.strictPricing } : {},
29887
+ ...meta?.budgetPolicy === "immutable-lifetime" ? { budgetPolicy: meta.budgetPolicy } : {},
29259
29888
  segmentsBefore: typeof meta?.segments === "number" && meta.segments > 0 ? Math.floor(meta.segments) : 1,
29260
29889
  ...typeof meta?.argsProvided === "boolean" ? { argsProvided: meta.argsProvided } : {},
29261
29890
  ...typeof meta?.argsHash === "string" ? { argsHash: meta.argsHash } : {},
@@ -29732,4 +30361,4 @@ function createSandboxBridge(ctx, options) {
29732
30361
  };
29733
30362
  }
29734
30363
  //#endregion
29735
- export { AWAIT_SCHEMA, AdmissionController, AdmissionRejectedError, AgentCallError, BUDGET_ABORT_REASON, BudgetExhaustedError, CANCEL_AGENT_SCHEMA, CHECKPOINT_FORMAT_V1, CLAIM_JUDGE_LABEL, CLAIM_STATEMENT_MAX_CHARS, CLAIM_TTL_DAYS, COMPACTION_SUMMARY_PREFIX, CURRENT_HASH_VERSION, ConfigError, DECISION_CHAIN_KINDS, DEFAULT_ANCHOR_PATTERN, DEFAULT_ARTIFACT_PATTERN, DEFAULT_CHILD_BUDGET_FRACTION, DEFAULT_CHILD_RESULT_PAGE_CHARS, DEFAULT_CITATION_PATTERN, DEFAULT_CITATION_SAMPLE, DEFAULT_CLAIM_JUDGE_MAX_TURNS, DEFAULT_COMPACTION_THRESHOLD, DEFAULT_ESCALATION_LIMITS, DEFAULT_EVIDENCE_CALLS_PER_ENTRY, DEFAULT_EVIDENCE_GRADE_PHRASES, DEFAULT_EVIDENCE_MIN_SHARE, DEFAULT_EVIDENCE_OVERHEAD_CALLS, DEFAULT_FINISH_MAX_REPAIRS, DEFAULT_FLAT_RESERVE_USD, DEFAULT_MAX_CHILDREN_PER_NODE, DEFAULT_MAX_CLAIM_PAIRS, DEFAULT_MAX_CONTRADICTIONS, DEFAULT_MAX_DEPTH, DEFAULT_MAX_EXCERPT_CHARS, DEFAULT_MAX_OSCILLATIONS_PER_KEY, DEFAULT_MAX_PAIR_EXCERPT_CHARS, DEFAULT_MAX_PINNED_WORKTREES, DEFAULT_MAX_POOL_PER_PAIR, DEFAULT_MAX_QUOTA_DENIALS, DEFAULT_MAX_REVISIONS_PER_RUN, DEFAULT_MAX_RUN_FACT_PAIRS, DEFAULT_MAX_TOTAL_SPAWNS, DEFAULT_MAX_TURNS, DEFAULT_MODEL_RETRY_ATTEMPTS, DEFAULT_NO_PROGRESS_TURNS, DEFAULT_PER_RUN_CONCURRENCY, DEFAULT_RETRY_POLICY, DEFAULT_STREAM_IDLE_TIMEOUT_MS, DEFAULT_SYNTHESIS_MAX_TURNS, DEFAULT_SYNTHESIS_NOTE_MAX_TURNS, DedupIndex, DeterminismError, EMIT_RESULT_TOOL, EMPTY_AUTHORITY_HASH, EMPTY_SCHEMA_HASH, EMPTY_TOOLSET_HASH, ESCALATE_TOOL_NAME, ESCALATION_REPORT_SCHEMA, ESCALATION_REQUEST_SCHEMA, EVENT_SEGMENT_STRIDE, EXPOSURE_WAIT_SWEEP_MS, EscalationDecisionAbortedError, EventBus, ExternalRegistry, FINALIZE_SYNTHESIS_INSTRUCTION, FINAL_COMPOSITION_LABEL, FINISH_LESSON_CAP_CHARS, FINISH_SCHEMA, FINISH_SECTIONAL_SCHEMA, FINISH_TOOL_NAME, FUTURE_RATES_TOLERANCE_MS, FailRunError, FileModelKnowledgeStore, FileTranscriptStore, GET_CHILD_RESULT_SCHEMA, GET_CHILD_RESULT_TOOL_NAME, GET_SETTLED_CHILD_RESULTS_SCHEMA, GET_SETTLED_CHILD_RESULTS_TOOL_NAME, GitWorktreeProvider, IMPLEMENTATION_PROFILE_LIMITS, INBOX_PROPOSAL_TTL_DAYS, IN_FLIGHT_EXPOSURE_REFUSAL_PREFIX, InMemoryStore, InMemoryTranscriptStore, InProcessRunner, InvalidResolutionError, JOURNAL_ENVELOPE_MARKER, JournalCompatibilityError, JournalIntegrityError, JournalMatcher, JournalMissError, JournalOrderViolation, JournalSealedError, JsonlFileStore, KB_ACTIVE_CLAIMS_CAP, KB_CARD_RENDER_BUDGET_CHARS, KeyedLimiter, KnowledgeCasError, LARGE_VALUE_WARN_BYTES, LEGACY_LTID_PREFIX, LEGACY_SIGNATURE_INPUTS, LINEAGE_SIG_VERSION, LeaseHeldError, LineageIndex, MASKED_SECRET, MAX_CHILD_RESULT_PAGE_CHARS, MAX_CRITICAL_UNCOVERED, MAX_DEPTH_CEILING, MAX_RUN_FACTS_SHEET_CHARS, MAX_RUN_ID_LENGTH, MAX_TIMER_DELAY_MS, ModelRetry, NoProgressDetector, NonSerializableValueError, ORCHESTRATE_WORKFLOW_NAME, OrchestratorCapConfigError, PARALLEL_AGENTS_SCHEMA, PROGRESS_REPORT_TOOL_NAME, ParallelSiteCounter, PlanInvariantError, QUOTA_WINDOW_MS, READ_CHILD_ARTIFACT_SCHEMA, READ_CHILD_ARTIFACT_TOOL_NAME, RESEARCH_PROFILE_LIMITS, REVIEW_PROFILE_LIMITS, ROLE_EFFORT_DEFAULTS, ROOT_ACCOUNT, ROOT_SCOPE, RUN_FACTS_ANCHOR, RUN_PROFILES, RUN_SETTLE_DECISION_TYPE, ReplayPlanHashMismatch, Replayer, ResolutionArbiter, ResolutionFold, RulvarError, RunBudget, SANDBOX_AGENT_OPT_KEYS, SPAWN_ADMISSION_DECISION_TYPE, SPAWN_AGENT_SCHEMA, SYNTHESIS_NOTE_LABEL, SandboxError, ScriptRejected, Semaphore, SettlementError, SpanRegistry, SupersededError, TERMINAL_TELEMETRY_SCOPE, TOOL_NAME_PATTERN, TerminationAccount, WAIT_FOR_EVENTS_SCHEMA, WAIT_FOR_EVENTS_TOOL_NAME, WAKE_SUMMARY_RENDER_BUDGET_CHARS, accountSpendFromJournal, admissionReserveUsd, affordableOutputTokens, agentErrorFromWire, agentErrorToWire, agentResultWire, agentScope, applyClaimOps, applyStructuredOutputTier, approachSigCoarse, approachSigOf, archiveDeprecatedModelOps, assertFencedWrites, assertSafeRunId, atCompactionThreshold, attestToolset, attributionBucket, auditRun, auditRuns, buildAbandonFold, buildAdapterRegistry, buildCostReport, buildDeriverRegistry, buildOrchestratorTools, buildTerminationInitValue, buildToolContext, canRideLoopTurn, canonicalIsolationTag, canonicalizeLadder, canonicalizeSchema, capIssues, capsHashOf, checkFloors, checkpointRefFor, childCoveragePrefix, childRostersFromJournal, citationTargetsValidator, citedValueValidator, claimCoverageOf, claimExpired, claimExpiry, claimIssues, claimJudgeStageOf, claimOpIssues, classifyAgentError, classifyAttemptOutcome, collectDeclaredLadders, compactMessages, compareRates, compilePermissionChain, compilePermissionPreset, compileSecretMasker, compileVerifiedLayer, constantTimeEqual, costReportFromJournal, countsAgainstLimit, createCanonicalIdMinter, createCtx, createEngine, createEnvelopeEncryption, createSandboxBridge, criticalPathFromJournal, currentOnlyKeyRing, decodeCheckpoint, dedupeRepeatedClaims, defineWorkflow, deriveContentKey, deriverV1, deriverV2, digestOf, dispatchProjectionReserveUsd, dispositionHook, emptyDigestBlocks, emptyToolset, encodeCheckpoint, enforceToolsetAttestation, entryUsageSlices, escalateTool, evaluatePermission, evaluateReuse, evidenceGradeValidator, evidencePreservedValidator, executeWorkflow, executionFactsOf, exhaustionCodeOf, extractCandidate, failoverTriggerOf, fallbackTriggerOf, filterClaimsForRun, finalizeFires, findContradictions, finishContract, foldLedger, foldTermination, formatCharacterValidator, formatRePrompt, formatScopePath, hasFencedWrites, hasMetaLookup, hashRunArgs, hashRunOutput, hashWorkflowBody, hashWorkflowSource, headingStructureValidator, identityJcs, implementationAgentProfile, invoiceFromJournal, isClaimJudgeLabel, isEscalated, isSchemaPairSpec, isStandardSchemaSpec, isStrictCompatibleSchema, journalPricingSnapshot, kMaxOf, knowledgeHash, ladderLengthOf, ladderRungChoice, lastRunSettle, latestProgressReport, lexShellCommand, liftRetainedParts, lineageWeightOf, localKeyProvider, logicalRunTelemetry, makeOrchestratorWorkflow, manifestValidators, maskSecrets, maskSecretsDeep, maskSecretsJson, matchArgvPattern, matchShellCommand, mcp, memoryQuotaLimiter, mergeQuotaDenial, mergeUsageLimits, metaMatchesFilter, minMatchesValidator, modelEpochOf, modelKnowledgeCard, modelSpecIdentity, needsSeparateExtract, nextFailover, nodeLinkKey, normalizeApproachTag, normalizeEntry, normalizeFallbacks, orchestrate, orchestratorAdmissionEstCostUsd, pairDraftClaims, pairRunFactClaims, parallelScope, parseModelRef, parseScopePath, persistedTerminalEnvelope, phiInitialOf, pilotAgentProfile, pipelineScope, planNodeScope, preflightEstimate, priceComponentsOf, priceEntryBilling, priceEntryUsage, priceUsdOf, profileCard, profileRegistrySnapshotHash, progressReportTool, projectHistory, projectIdentity, projectToJsonSchema, proposalStatement, providerOf, quotaActualRequestsDelta, quotaActualTokens, quotaEstimateTokens, quotaRuleAdmission, quotaRuleKey, quotaRuleMatches, readRunMeta, readTerminationInit, reconcileRunMeta, reconcileStatement, reduceAuditTrail, reduceCriticalPath, reduceDecisionChain, reduceInvocationTable, registryKeyRing, remeasureQueue, renderContractRequirements, replayDisposition, repositoryResearchToolset, requiredFieldsValidator, requiredMentionsValidator, requiredSectionsValidator, researchAgentProfile, resolveModelInvocation, resolvePricing, resolveToolset, retryClassOf, retryDelayMs, reviewAgentProfile, roleConfiguredInRouting, roundOneDisposition, runAgent, runProfile, sanitizeTerminalText, sanitizeTokenCount, sanitizeUsage, sanitizeUsageDelta, scanJournalCompatibility, schemaHash, schemaHashOfSpec, sectionCitationsValidator, sectionPatternCountValidator, selectStructuredOutputTier, selfTestFinishValidation, shouldCompact, snapshotQuotaRules, snapshotUsage, spawnDepthOf, spliceSections, statementFromRows, statementRowsFromDelimited, stripFencedBlocks, sumUsage, summarizeInstruction, summarizeOutput, synthesisCandidatesFromJournal, terminalEnvelopeOf, terminationConfigDrift, tierWithinCaps, toApprovalDecision, toJournalValue, tool, toolAuthority, toolCalibrationFromJournal, toolContract, toolContractHash, toolsetAuthorityHash, toolsetHash, ttlState, unionOfIntervalsMs, usageViolations, validateDetachedResolution, validateEditorialCommit, validateEngineQuotaConfig, validateEntryShape, validateEscalationLimits, validateEscalationReport, validateQuotaRules, validateRetryPolicy, validateSchemaSpec, validateTerminationLimits, validateToolsetAttestation, validateUsageLimits, wordCountValidator, workflowScope, workflowSourceRef, wrapJournalStore, wrapTranscriptStore };
30364
+ export { AWAIT_SCHEMA, AdmissionController, AdmissionRejectedError, AgentCallError, BUDGET_ABORT_REASON, BudgetExhaustedError, CANCEL_AGENT_SCHEMA, CHECKPOINT_FORMAT_V1, CLAIM_JUDGE_LABEL, CLAIM_STATEMENT_MAX_CHARS, CLAIM_TTL_DAYS, COMPACTION_SUMMARY_PREFIX, CURRENT_HASH_VERSION, ConfigError, DECISION_CHAIN_KINDS, DEFAULT_ANCHOR_PATTERN, DEFAULT_ARTIFACT_PATTERN, DEFAULT_CHILD_BUDGET_FRACTION, DEFAULT_CHILD_RESULT_PAGE_CHARS, DEFAULT_CITATION_PATTERN, DEFAULT_CITATION_SAMPLE, DEFAULT_CLAIM_JUDGE_MAX_TURNS, DEFAULT_COMPACTION_THRESHOLD, DEFAULT_ESCALATION_LIMITS, DEFAULT_EVIDENCE_CALLS_PER_ENTRY, DEFAULT_EVIDENCE_GRADE_PHRASES, DEFAULT_EVIDENCE_MIN_SHARE, DEFAULT_EVIDENCE_OVERHEAD_CALLS, DEFAULT_FINISH_MAX_REPAIRS, DEFAULT_FLAT_RESERVE_USD, DEFAULT_MAX_CHILDREN_PER_NODE, DEFAULT_MAX_CLAIM_PAIRS, DEFAULT_MAX_CONTRADICTIONS, DEFAULT_MAX_DEPTH, DEFAULT_MAX_EXCERPT_CHARS, DEFAULT_MAX_OSCILLATIONS_PER_KEY, DEFAULT_MAX_PAIR_EXCERPT_CHARS, DEFAULT_MAX_PINNED_WORKTREES, DEFAULT_MAX_POOL_PER_PAIR, DEFAULT_MAX_QUOTA_DENIALS, DEFAULT_MAX_REVISIONS_PER_RUN, DEFAULT_MAX_RUN_FACT_PAIRS, DEFAULT_MAX_TOTAL_SPAWNS, DEFAULT_MAX_TURNS, DEFAULT_MODEL_RETRY_ATTEMPTS, DEFAULT_NO_PROGRESS_TURNS, DEFAULT_PER_RUN_CONCURRENCY, DEFAULT_RETRY_POLICY, DEFAULT_STREAM_IDLE_TIMEOUT_MS, DEFAULT_SYNTHESIS_MAX_TURNS, DEFAULT_SYNTHESIS_NOTE_MAX_TURNS, DedupIndex, DeterminismError, EMIT_RESULT_TOOL, EMPTY_AUTHORITY_HASH, EMPTY_SCHEMA_HASH, EMPTY_TOOLSET_HASH, ESCALATE_TOOL_NAME, ESCALATION_REPORT_SCHEMA, ESCALATION_REQUEST_SCHEMA, EVENT_SEGMENT_STRIDE, EXPOSURE_WAIT_SWEEP_MS, EscalationDecisionAbortedError, EventBus, ExternalRegistry, FINALIZE_SYNTHESIS_INSTRUCTION, FINAL_COMPOSITION_LABEL, FINISH_LESSON_CAP_CHARS, FINISH_SCHEMA, FINISH_SECTIONAL_SCHEMA, FINISH_TOOL_NAME, FUTURE_RATES_TOLERANCE_MS, FailRunError, FileModelKnowledgeStore, FileTranscriptStore, GET_CHILD_RESULT_SCHEMA, GET_CHILD_RESULT_TOOL_NAME, GET_SETTLED_CHILD_RESULTS_SCHEMA, GET_SETTLED_CHILD_RESULTS_TOOL_NAME, GitWorktreeProvider, IMPLEMENTATION_PROFILE_LIMITS, INBOX_PROPOSAL_TTL_DAYS, IN_FLIGHT_EXPOSURE_REFUSAL_PREFIX, InMemoryStore, InMemoryTranscriptStore, InProcessRunner, InvalidResolutionError, JOURNAL_ENVELOPE_MARKER, JournalCompatibilityError, JournalIntegrityError, JournalMatcher, JournalMissError, JournalOrderViolation, JournalSealedError, JsonlFileStore, KB_ACTIVE_CLAIMS_CAP, KB_CARD_RENDER_BUDGET_CHARS, KeyedLimiter, KnowledgeCasError, LARGE_VALUE_WARN_BYTES, LEGACY_LTID_PREFIX, LEGACY_SIGNATURE_INPUTS, LINEAGE_SIG_VERSION, LeaseHeldError, LineageIndex, MASKED_SECRET, MAX_CHILD_RESULT_PAGE_CHARS, MAX_CRITICAL_UNCOVERED, MAX_DEPTH_CEILING, MAX_RUN_FACTS_SHEET_CHARS, MAX_RUN_ID_LENGTH, MAX_TIMER_DELAY_MS, ModelRetry, NoProgressDetector, NonSerializableValueError, ORCHESTRATE_WORKFLOW_NAME, OrchestratorCapConfigError, PARALLEL_AGENTS_SCHEMA, PROGRESS_REPORT_TOOL_NAME, ParallelSiteCounter, PlanInvariantError, QUOTA_WINDOW_MS, READ_CHILD_ARTIFACT_SCHEMA, READ_CHILD_ARTIFACT_TOOL_NAME, RESEARCH_PROFILE_LIMITS, REVIEW_PROFILE_LIMITS, ROLE_EFFORT_DEFAULTS, ROOT_ACCOUNT, ROOT_SCOPE, RUN_FACTS_ANCHOR, RUN_PROFILES, RUN_SETTLE_DECISION_TYPE, ReplayPlanHashMismatch, Replayer, ResolutionArbiter, ResolutionFold, RulvarError, RunBudget, SANDBOX_AGENT_OPT_KEYS, SPAWN_ADMISSION_DECISION_TYPE, SPAWN_AGENT_SCHEMA, SYNTHESIS_NOTE_LABEL, SandboxError, ScriptRejected, Semaphore, SettlementError, SpanRegistry, SupersededError, TERMINAL_TELEMETRY_SCOPE, TOOL_NAME_PATTERN, TerminationAccount, WAIT_FOR_EVENTS_SCHEMA, WAIT_FOR_EVENTS_TOOL_NAME, WAKE_SUMMARY_RENDER_BUDGET_CHARS, accountSpendFromJournal, admissionReserveUsd, affordableOutputTokens, agentErrorFromWire, agentErrorToWire, agentResultWire, agentScope, applyClaimOps, applyFinishRepairHints, applyStructuredOutputTier, approachSigCoarse, approachSigOf, archiveDeprecatedModelOps, assertFencedWrites, assertSafeRunId, atCompactionThreshold, attestToolset, attributionBucket, auditRun, auditRuns, buildAbandonFold, buildAdapterRegistry, buildCostReport, buildDeriverRegistry, buildOrchestratorTools, buildTerminationInitValue, buildToolContext, canRideLoopTurn, canonicalIsolationTag, canonicalizeLadder, canonicalizeSchema, capIssues, capsHashOf, checkFloors, checkpointRefFor, childCoveragePrefix, childRostersFromJournal, citationTargetsValidator, citedValueValidator, claimCoverageOf, claimExpired, claimExpiry, claimIssues, claimJudgeStageOf, claimOpIssues, classifyAgentError, classifyAttemptOutcome, collectDeclaredLadders, compactMessages, compareRates, compilePermissionChain, compilePermissionPreset, compileSecretMasker, compileVerifiedLayer, constantTimeEqual, costReportFromJournal, countsAgainstLimit, createCanonicalIdMinter, createCtx, createEngine, createEnvelopeEncryption, createSandboxBridge, criticalPathFromJournal, currentOnlyKeyRing, decodeCheckpoint, dedupeRepeatedClaims, defineWorkflow, deriveContentKey, deriverV1, deriverV2, digestOf, dispatchProjectionReserveUsd, dispositionHook, emptyDigestBlocks, emptyToolset, encodeCheckpoint, enforceToolsetAttestation, entryUsageSlices, escalateTool, evaluatePermission, evaluateReuse, evidenceGradeValidator, evidencePreservedValidator, executeWorkflow, executionFactsOf, exhaustionCodeOf, extractCandidate, failoverTriggerOf, fallbackTriggerOf, filterClaimsForRun, finalizeFires, findContradictions, finishContract, foldLedger, foldTermination, formatCharacterValidator, formatRePrompt, formatScopePath, hasFencedWrites, hasMetaLookup, hashRunArgs, hashRunOutput, hashWorkflowBody, hashWorkflowSource, headingStructureValidator, identityJcs, implementationAgentProfile, insertRunIdIntoSentence, invoiceFromJournal, isClaimJudgeLabel, isEscalated, isSchemaPairSpec, isStandardSchemaSpec, isStrictCompatibleSchema, journalPricingSnapshot, kMaxOf, knowledgeHash, ladderLengthOf, ladderRungChoice, lastMechanicalRepairCostUsd, lastRunSettle, latestProgressReport, lexShellCommand, liftRetainedParts, lineageWeightOf, localKeyProvider, logicalRunTelemetry, makeOrchestratorWorkflow, manifestValidators, maskSecrets, maskSecretsDeep, maskSecretsJson, matchArgvPattern, matchShellCommand, mcp, memoryQuotaLimiter, mergeQuotaDenial, mergeUsageLimits, metaMatchesFilter, minMatchesValidator, modelEpochOf, modelKnowledgeCard, modelSpecIdentity, needsSeparateExtract, nextFailover, nodeLinkKey, normalizeApproachTag, normalizeEntry, normalizeFallbacks, orchestrate, orchestratorAdmissionEstCostUsd, pairDraftClaims, pairRunFactClaims, parallelScope, parseModelRef, parseScopePath, parseTerminalEnvelope, persistedTerminalEnvelope, phiInitialOf, pilotAgentProfile, pipelineScope, planNodeScope, preflightEstimate, priceComponentsOf, priceEntryBilling, priceEntryUsage, priceUsdOf, profileCard, profileRegistrySnapshotHash, progressReportTool, projectHistory, projectIdentity, projectToJsonSchema, proposalStatement, providerOf, quotaActualRequestsDelta, quotaActualTokens, quotaEstimateTokens, quotaRuleAdmission, quotaRuleKey, quotaRuleMatches, readRunMeta, readTerminationInit, reconcileRunMeta, reconcileStatement, reduceAuditTrail, reduceCriticalPath, reduceDecisionChain, reduceInvocationTable, registryKeyRing, remeasureQueue, renderContractRequirements, replayDisposition, repositoryResearchToolset, requiredFieldsValidator, requiredMentionsValidator, requiredSectionsValidator, researchAgentProfile, resolveModelInvocation, resolvePricing, resolveToolset, retryClassOf, retryDelayMs, reviewAgentProfile, roleConfiguredInRouting, roundOneDisposition, runAgent, runProfile, sanitizeTerminalText, sanitizeTokenCount, sanitizeUsage, sanitizeUsageDelta, scanJournalCompatibility, schemaHash, schemaHashOfSpec, scopeBucket, sectionCitationsValidator, sectionPatternCountValidator, sectionalRoundPlan, selectStructuredOutputTier, selfTestFinishValidation, shouldCompact, snapshotQuotaRules, snapshotUsage, spawnDepthOf, spliceSections, statementFromRows, statementRowsFromDelimited, stripFencedBlocks, sumUsage, summarizeInstruction, summarizeOutput, synthesisCandidatesFromJournal, terminalEnvelopeOf, terminationConfigDrift, tierWithinCaps, toApprovalDecision, toJournalValue, tool, toolAuthority, toolCalibrationFromJournal, toolContract, toolContractHash, toolsetAuthorityHash, toolsetHash, ttlState, unionOfIntervalsMs, usageViolations, validateDetachedResolution, validateEditorialCommit, validateEngineQuotaConfig, validateEntryShape, validateEscalationLimits, validateEscalationReport, validateQuotaRules, validateRetryPolicy, validateSchemaSpec, validateTerminationLimits, validateToolsetAttestation, validateUsageLimits, wordCountValidator, workflowScope, workflowSourceRef, wrapJournalStore, wrapTranscriptStore };