@rulvar/core 1.76.0 → 1.77.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.
- package/dist/index.d.ts +28 -2
- package/dist/index.js +116 -24
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -4197,6 +4197,16 @@ interface AgentResult<T> {
|
|
|
4197
4197
|
* seeing a bare 'terminal status limit'.
|
|
4198
4198
|
*/
|
|
4199
4199
|
partial?: ProgressReport;
|
|
4200
|
+
/**
|
|
4201
|
+
* Terminal-tool exchanges whose ARGUMENTS died at the schema gate
|
|
4202
|
+
* (the unparsed second chance included, when it did not recover): the
|
|
4203
|
+
* v1.74 experiment lost six finish payloads to exactly this class,
|
|
4204
|
+
* and nothing outside the transcript said so (host validation
|
|
4205
|
+
* rejections, by contrast, journal decision entries). Derived from
|
|
4206
|
+
* the message window like the repair-reserve grants, so live and
|
|
4207
|
+
* resumed segments count the same total; absent when zero.
|
|
4208
|
+
*/
|
|
4209
|
+
schemaRejectedTerminalExchanges?: number;
|
|
4200
4210
|
}
|
|
4201
4211
|
/** One 429's provider-normalized limits, per (provider, model). */
|
|
4202
4212
|
interface RateLimitObservation {
|
|
@@ -7162,8 +7172,17 @@ interface FinishValidationSpec {
|
|
|
7162
7172
|
* hash and the validator names. A resumed segment whose live
|
|
7163
7173
|
* contract hash differs appends a SUPERSEDING descriptor instead of
|
|
7164
7174
|
* failing, because fixing a stale validator and resuming is the
|
|
7165
|
-
* intended remedy, never a fault.
|
|
7166
|
-
*
|
|
7175
|
+
* intended remedy, never a fault. The remedy is generation-scoped
|
|
7176
|
+
* (cycle 73): every decision entry written under a contract carries
|
|
7177
|
+
* `contractHash`, and only the CURRENT generation is judged, so
|
|
7178
|
+
* repairsUsed restarts under a fixed contract and a final rejection
|
|
7179
|
+
* a superseded generation left in the crash window neither rolls
|
|
7180
|
+
* forward at boot nor re-arms on replay (its exchange replays byte
|
|
7181
|
+
* identical and the loop continues to a live repair turn). Decisions
|
|
7182
|
+
* recorded before 1.77 carry no hash and bind to the current
|
|
7183
|
+
* contract only while the journal holds a single bundle descriptor;
|
|
7184
|
+
* once a supersession is recorded they are stale. Absent = byte
|
|
7185
|
+
* identical pre 1.72 behavior.
|
|
7167
7186
|
*/
|
|
7168
7187
|
contract?: FinishContract;
|
|
7169
7188
|
/**
|
|
@@ -8964,6 +8983,13 @@ interface PreflightInput {
|
|
|
8964
8983
|
* runtime would actually grant.
|
|
8965
8984
|
*/
|
|
8966
8985
|
repairTurnReserve?: number;
|
|
8986
|
+
/**
|
|
8987
|
+
* Mirrors FinishValidationSpec.maxRepairs (default
|
|
8988
|
+
* {@link DEFAULT_FINISH_MAX_REPAIRS}): with zero, the first
|
|
8989
|
+
* rejection is final and there is no repair exchange to fund, so
|
|
8990
|
+
* the repair-reserve-unfunded warning stays silent.
|
|
8991
|
+
*/
|
|
8992
|
+
maxRepairs?: number;
|
|
8967
8993
|
};
|
|
8968
8994
|
}
|
|
8969
8995
|
/** One linter verdict; `spawn` names the wave entry it is about. */
|
package/dist/index.js
CHANGED
|
@@ -10181,6 +10181,15 @@ function estimateInputTokens(messages) {
|
|
|
10181
10181
|
return Math.ceil(chars / 4);
|
|
10182
10182
|
}
|
|
10183
10183
|
/**
|
|
10184
|
+
* The terminal tool's schema-rejection feedback line. One producer, two
|
|
10185
|
+
* readers: the interception writes it as the error result, and the
|
|
10186
|
+
* window-derived schemaRejectedTerminalExchanges counter recognizes the
|
|
10187
|
+
* exchange by exactly these bytes, so the two can never drift.
|
|
10188
|
+
*/
|
|
10189
|
+
function terminalSchemaRejectionMessage(name) {
|
|
10190
|
+
return `the '${name}' call failed validation`;
|
|
10191
|
+
}
|
|
10192
|
+
/**
|
|
10184
10193
|
* The serving model's declared minimum request output cap, default one.
|
|
10185
10194
|
* OpenAI's Responses API rejects max_output_tokens below 16, so a
|
|
10186
10195
|
* below-floor dispatch is a guaranteed provider 400: the v1.74
|
|
@@ -10870,7 +10879,7 @@ async function runAgent(options) {
|
|
|
10870
10879
|
durationMs: now() - gateStartedAt
|
|
10871
10880
|
});
|
|
10872
10881
|
parts.push(errorPart(call, {
|
|
10873
|
-
error:
|
|
10882
|
+
error: terminalSchemaRejectionMessage(gatedCall.name),
|
|
10874
10883
|
issues: validation === void 0 ? [] : validation.issues.map((i) => i.message)
|
|
10875
10884
|
}));
|
|
10876
10885
|
continue;
|
|
@@ -12008,6 +12017,9 @@ async function runAgent(options) {
|
|
|
12008
12017
|
if (errorMessage !== void 0) result.errorMessage = errorMessage;
|
|
12009
12018
|
if (guard !== void 0) result.exploration = guard.summary(toolCallsUsed);
|
|
12010
12019
|
if (limitPartial !== void 0) result.partial = limitPartial;
|
|
12020
|
+
const terminalName = options.terminalTool?.name;
|
|
12021
|
+
const schemaRejectedTerminalExchanges = terminalName === void 0 ? 0 : messages.reduce((count, message) => count + message.parts.filter((part) => part.type === "tool-result" && part.name === terminalName && part.isError === true && part.result?.error === terminalSchemaRejectionMessage(terminalName)).length, 0);
|
|
12022
|
+
if (schemaRejectedTerminalExchanges > 0) result.schemaRejectedTerminalExchanges = schemaRejectedTerminalExchanges;
|
|
12011
12023
|
if (usageApprox) result.usageApprox = true;
|
|
12012
12024
|
if (transportRetries > 0) result.transportRetries = transportRetries;
|
|
12013
12025
|
if (rateLimitObservations.size > 0) result.rateLimitObservations = [...rateLimitObservations.values()];
|
|
@@ -16869,6 +16881,12 @@ function makeOrchestratorWorkflow(goal, opts) {
|
|
|
16869
16881
|
const validationSpec = opts?.finishValidation;
|
|
16870
16882
|
const validationAbort = new AbortController();
|
|
16871
16883
|
let validationTermination;
|
|
16884
|
+
/**
|
|
16885
|
+
* The synthesis invocation's schema-dead finish exchanges (cycle
|
|
16886
|
+
* 73), captured from its full agent result so the failure
|
|
16887
|
+
* enrichment can fold BOTH windows into one honest counter.
|
|
16888
|
+
*/
|
|
16889
|
+
let synthesisSchemaRejectedExchanges = 0;
|
|
16872
16890
|
const finishValidationError = (decision) => new FailRunError(`the orchestrator finish failed host validation with all ${String(decision.maxRepairs)} repair attempts spent: ` + decision.failed.map((f) => `validator '${f.name}' rejected: ${f.reasons.join("; ")}`).join("; "), { data: {
|
|
16873
16891
|
source: "orchestrator_finish_validation",
|
|
16874
16892
|
callId: decision.callId,
|
|
@@ -16877,6 +16895,22 @@ function makeOrchestratorWorkflow(goal, opts) {
|
|
|
16877
16895
|
maxRepairs: decision.maxRepairs
|
|
16878
16896
|
} });
|
|
16879
16897
|
const validationDecisions = () => internals.replayer.snapshot().filter((entry) => entry.kind === "decision" && entry.scope === callingState.scope && entry.value?.decisionType === "orchestrator_finish_validation").map((entry) => entry.value);
|
|
16898
|
+
/**
|
|
16899
|
+
* The contract generation membership test (cycle 73). Without a
|
|
16900
|
+
* contract there are no generations and every decision is current
|
|
16901
|
+
* (the pre 1.77 behavior, byte identical). With one, a decision
|
|
16902
|
+
* belongs to the current generation when its journaled hash matches
|
|
16903
|
+
* the live contract; a pre 1.77 decision carries no hash and counts
|
|
16904
|
+
* as current only while the journal has never recorded a
|
|
16905
|
+
* superseding bundle descriptor, because a single descriptor means
|
|
16906
|
+
* every decision was necessarily rendered under it.
|
|
16907
|
+
*/
|
|
16908
|
+
const contractGenerationCurrent = (decision) => {
|
|
16909
|
+
const hash = validationSpec?.contract?.hash;
|
|
16910
|
+
if (hash === void 0) return true;
|
|
16911
|
+
if (decision.contractHash !== void 0) return decision.contractHash === hash;
|
|
16912
|
+
return internals.replayer.snapshot().filter((entry) => entry.kind === "decision" && entry.scope === callingState.scope && entry.value?.decisionType === "orchestrator_finish_validation_bundle").length <= 1;
|
|
16913
|
+
};
|
|
16880
16914
|
const validateFinish = async (call) => {
|
|
16881
16915
|
if (validationSpec === void 0) return { ok: true };
|
|
16882
16916
|
const maxRepairs = validationSpec.maxRepairs ?? 1;
|
|
@@ -16915,14 +16949,15 @@ function makeOrchestratorWorkflow(goal, opts) {
|
|
|
16915
16949
|
reasons: verdict.reasons
|
|
16916
16950
|
});
|
|
16917
16951
|
}
|
|
16918
|
-
const repairsUsed = known.filter((candidate) => candidate.verdict !== "accepted").length;
|
|
16952
|
+
const repairsUsed = known.filter((candidate) => candidate.verdict !== "accepted" && contractGenerationCurrent(candidate)).length;
|
|
16919
16953
|
decision = {
|
|
16920
16954
|
decisionType: "orchestrator_finish_validation",
|
|
16921
16955
|
callId: call.id,
|
|
16922
16956
|
verdict: failed.length === 0 ? "accepted" : repairsUsed < maxRepairs ? "repair" : "rejected",
|
|
16923
16957
|
failed,
|
|
16924
16958
|
repairsUsed,
|
|
16925
|
-
maxRepairs
|
|
16959
|
+
maxRepairs,
|
|
16960
|
+
...validationSpec.contract === void 0 ? {} : { contractHash: validationSpec.contract.hash }
|
|
16926
16961
|
};
|
|
16927
16962
|
await internals.replayer.appendSinglePhase({
|
|
16928
16963
|
scope: callingState.scope,
|
|
@@ -16936,8 +16971,10 @@ function makeOrchestratorWorkflow(goal, opts) {
|
|
|
16936
16971
|
}
|
|
16937
16972
|
if (decision.verdict === "accepted") return { ok: true };
|
|
16938
16973
|
if (decision.verdict === "rejected") {
|
|
16939
|
-
|
|
16940
|
-
|
|
16974
|
+
if (contractGenerationCurrent(decision)) {
|
|
16975
|
+
validationTermination = finishValidationError(decision);
|
|
16976
|
+
validationAbort.abort("rulvar:finish-validation");
|
|
16977
|
+
}
|
|
16941
16978
|
return {
|
|
16942
16979
|
ok: false,
|
|
16943
16980
|
feedback: {
|
|
@@ -17357,6 +17394,7 @@ function makeOrchestratorWorkflow(goal, opts) {
|
|
|
17357
17394
|
}
|
|
17358
17395
|
};
|
|
17359
17396
|
const synthesized = await runtime.runInScope(synthesisState, () => ctx.agent(prompt, synthesisOpts));
|
|
17397
|
+
synthesisSchemaRejectedExchanges = synthesized.schemaRejectedTerminalExchanges ?? 0;
|
|
17360
17398
|
if (validationTermination !== void 0) throw validationTermination;
|
|
17361
17399
|
if (synthesized.status === "ok") return synthesized.output;
|
|
17362
17400
|
if (validationSpec !== void 0) throw new FailRunError(`the synthesis invocation terminated with status '${synthesized.status}'` + (synthesized.errorMessage === void 0 ? "" : `: ${synthesized.errorMessage}`) + "; finish validators are configured, so the unvalidated draft cannot stand", { data: {
|
|
@@ -17419,7 +17457,10 @@ function makeOrchestratorWorkflow(goal, opts) {
|
|
|
17419
17457
|
if (capDecisionRef !== void 0) return await settleCapOutcome();
|
|
17420
17458
|
if (validationSpec !== void 0) {
|
|
17421
17459
|
const priorRejection = validationDecisions().find((decision) => decision.verdict === "rejected");
|
|
17422
|
-
if (priorRejection !== void 0)
|
|
17460
|
+
if (priorRejection !== void 0) {
|
|
17461
|
+
const settle = lastRunSettle(internals.replayer.snapshot());
|
|
17462
|
+
if (settle !== void 0 && settle.runStatus !== "running" && settle.runStatus !== "suspended" || contractGenerationCurrent(priorRejection)) throw finishValidationError(priorRejection);
|
|
17463
|
+
}
|
|
17423
17464
|
}
|
|
17424
17465
|
const promptLines = [
|
|
17425
17466
|
...extension?.promptLines?.() ?? [],
|
|
@@ -17430,28 +17471,28 @@ function makeOrchestratorWorkflow(goal, opts) {
|
|
|
17430
17471
|
const liveTermination = extensionTermination;
|
|
17431
17472
|
if (liveTermination !== void 0) throw liveTermination;
|
|
17432
17473
|
if (capDecisionRef !== void 0) return await settleCapOutcome();
|
|
17433
|
-
if (validationTermination !== void 0) throw validationTermination;
|
|
17434
|
-
if (orchestratorAccount !== void 0) internals.cost.orchestrator.spentUsd = internals.budget.accountView(orchestratorAccount)?.spentUsd ?? 0;
|
|
17435
|
-
if (result.status !== "ok") throw new ConfigError(`the orchestrator agent terminated with status '${result.status}'` + (result.errorMessage === void 0 ? "" : `: ${result.errorMessage}`));
|
|
17436
17474
|
/**
|
|
17437
|
-
* The
|
|
17438
|
-
* P0.8 remainder + P1.7): every typed
|
|
17439
|
-
*
|
|
17440
|
-
* from the JOURNALED validation decisions
|
|
17441
|
-
*
|
|
17442
|
-
*
|
|
17443
|
-
*
|
|
17444
|
-
*
|
|
17445
|
-
*
|
|
17446
|
-
*
|
|
17447
|
-
*
|
|
17448
|
-
*
|
|
17475
|
+
* The finish-validation failure enrichment (the v1.71 experiment
|
|
17476
|
+
* review, P0.8 remainder + P1.7; widened by cycle 73): every typed
|
|
17477
|
+
* failure a finish rejection produces gains the verdict-derived
|
|
17478
|
+
* repair taxonomy read from the JOURNALED validation decisions of
|
|
17479
|
+
* the CURRENT contract generation (identical live and on replay),
|
|
17480
|
+
* the schema-dead finish exchange counter derived from the
|
|
17481
|
+
* coordination and synthesis windows (the class the v1.74 run lost
|
|
17482
|
+
* six payloads to, invisible in every other field), and, when an
|
|
17483
|
+
* acceptance verdict exists, the acceptance snapshot the children
|
|
17484
|
+
* already earned: completion and childStatusCounts, and now the
|
|
17485
|
+
* degradation facts beside them (degradedReasons and the salvage
|
|
17486
|
+
* lists), exactly what the ok envelope reports. The
|
|
17487
|
+
* rejection-past-the-bound error keeps its own
|
|
17488
|
+
* repairsUsed/maxRepairs/failed untouched.
|
|
17449
17489
|
*/
|
|
17450
17490
|
const enrichSynthesisFailure = (thrown, snapshot) => {
|
|
17451
17491
|
if (!(thrown instanceof FailRunError)) throw thrown;
|
|
17452
17492
|
const base = thrown.data ?? {};
|
|
17453
|
-
const spent = validationDecisions().filter((candidate) => candidate.verdict !== "accepted");
|
|
17493
|
+
const spent = validationDecisions().filter((candidate) => candidate.verdict !== "accepted" && contractGenerationCurrent(candidate));
|
|
17454
17494
|
const rejectedValidators = [...new Set(spent.flatMap((candidate) => candidate.failed.map((f) => f.name)))];
|
|
17495
|
+
const schemaRejected = (result.schemaRejectedTerminalExchanges ?? 0) + synthesisSchemaRejectedExchanges;
|
|
17455
17496
|
throw new FailRunError(thrown.message, { data: {
|
|
17456
17497
|
...base,
|
|
17457
17498
|
...snapshot ?? {},
|
|
@@ -17459,9 +17500,13 @@ function makeOrchestratorWorkflow(goal, opts) {
|
|
|
17459
17500
|
repairsUsed: spent.length,
|
|
17460
17501
|
maxRepairs: validationSpec?.maxRepairs ?? 1,
|
|
17461
17502
|
rejectedValidators
|
|
17462
|
-
}
|
|
17503
|
+
},
|
|
17504
|
+
...schemaRejected === 0 || base.schemaRejectedFinishExchanges !== void 0 ? {} : { schemaRejectedFinishExchanges: schemaRejected }
|
|
17463
17505
|
} });
|
|
17464
17506
|
};
|
|
17507
|
+
if (validationTermination !== void 0) enrichSynthesisFailure(validationTermination);
|
|
17508
|
+
if (orchestratorAccount !== void 0) internals.cost.orchestrator.spentUsd = internals.budget.accountView(orchestratorAccount)?.spentUsd ?? 0;
|
|
17509
|
+
if (result.status !== "ok") throw new ConfigError(`the orchestrator agent terminated with status '${result.status}'` + (result.errorMessage === void 0 ? "" : `: ${result.errorMessage}`));
|
|
17465
17510
|
if (opts?.acceptance === void 0) try {
|
|
17466
17511
|
return await runSynthesis(result.output);
|
|
17467
17512
|
} catch (thrown) {
|
|
@@ -17545,7 +17590,10 @@ function makeOrchestratorWorkflow(goal, opts) {
|
|
|
17545
17590
|
} catch (thrown) {
|
|
17546
17591
|
enrichSynthesisFailure(thrown, {
|
|
17547
17592
|
completion: decision.completion,
|
|
17548
|
-
childStatusCounts: decision.childStatusCounts
|
|
17593
|
+
childStatusCounts: decision.childStatusCounts,
|
|
17594
|
+
degradedReasons: decision.degradedReasons,
|
|
17595
|
+
...decision.salvagedPartialChildren === void 0 ? {} : { salvagedPartialChildren: decision.salvagedPartialChildren },
|
|
17596
|
+
...decision.salvagedTerminalOutputChildren === void 0 ? {} : { salvagedTerminalOutputChildren: decision.salvagedTerminalOutputChildren }
|
|
17549
17597
|
});
|
|
17550
17598
|
}
|
|
17551
17599
|
return {
|
|
@@ -17677,6 +17725,39 @@ function preflightEstimate(input) {
|
|
|
17677
17725
|
const say = (finding) => {
|
|
17678
17726
|
findings.push(finding);
|
|
17679
17727
|
};
|
|
17728
|
+
/**
|
|
17729
|
+
* The contract turn feasibility check (the v1.74 experiment review,
|
|
17730
|
+
* cycle 73), run against the invocation the validators bind. The
|
|
17731
|
+
* floor is the contract's own minimal accepting payload, serialized
|
|
17732
|
+
* exactly as the model must emit it ({ result }) and priced at the
|
|
17733
|
+
* loop's four-characters-per-token output heuristic: the v1.74 run's
|
|
17734
|
+
* conforming payloads truncated at their 9000 token turn cap, and its
|
|
17735
|
+
* contract's minimum alone prices above that cap. A minimum at or
|
|
17736
|
+
* over the bound is an error (every conforming finish truncates mid
|
|
17737
|
+
* payload); a minimum within double of the bound is a warning,
|
|
17738
|
+
* because real conforming payloads run richer than the minimum.
|
|
17739
|
+
*/
|
|
17740
|
+
const contractFeasibilityFindings = (outputBound, spawn, servedBy) => {
|
|
17741
|
+
const contract = input.finishValidation?.contract;
|
|
17742
|
+
if (contract === void 0 || outputBound === void 0) return;
|
|
17743
|
+
const minTokens = Math.ceil(JSON.stringify({ result: contract.goldenAccept.text }).length / 4);
|
|
17744
|
+
const which = spawn === "synthesis" ? "the synthesis invocation" : "the coordination loop";
|
|
17745
|
+
if (minTokens >= outputBound) {
|
|
17746
|
+
say({
|
|
17747
|
+
severity: "error",
|
|
17748
|
+
code: "output-contract-turn-infeasible",
|
|
17749
|
+
message: `the finish contract's minimal accepting payload is about ${String(minTokens)} tokens (four characters per token over the golden accept fixture) but ${which} dispatches at most ${String(outputBound)} output tokens per turn ('${servedBy}'): every conforming finish truncates mid payload; raise maxOutputTokensPerTurn or shrink the contract`,
|
|
17750
|
+
spawn
|
|
17751
|
+
});
|
|
17752
|
+
return;
|
|
17753
|
+
}
|
|
17754
|
+
if (minTokens * 2 > outputBound) say({
|
|
17755
|
+
severity: "warning",
|
|
17756
|
+
code: "output-contract-turn-headroom",
|
|
17757
|
+
message: `the finish contract's minimal accepting payload is about ${String(minTokens)} tokens against the ${String(outputBound)} token output bound of ${which} ('${servedBy}'): real conforming payloads run richer than the minimum and the margin is under double; raise the bound or trim the contract`,
|
|
17758
|
+
spawn
|
|
17759
|
+
});
|
|
17760
|
+
};
|
|
17680
17761
|
const adapters = new Map((engine.adapters ?? []).map((adapter) => [adapter.id, adapter]));
|
|
17681
17762
|
const capsOf = (ref) => {
|
|
17682
17763
|
const { adapterId, model } = parseModelRef(ref);
|
|
@@ -17922,6 +18003,7 @@ function preflightEstimate(input) {
|
|
|
17922
18003
|
message: `the orchestrator sets maxOutputTokensPerTurn ${String(orchLimits.maxOutputTokensPerTurn)} below the ${String(caps.minOutputTokensPerTurn)} token output floor of '${servedBy}': every dispatch would be refused typed before the wire; raise the cap to at least the floor`,
|
|
17923
18004
|
spawn: "orchestrator"
|
|
17924
18005
|
});
|
|
18006
|
+
if (input.orchestrator.synthesis === void 0) contractFeasibilityFindings(outputBound, "orchestrator", servedBy);
|
|
17925
18007
|
const { adapterId, model } = parseModelRef(servedBy);
|
|
17926
18008
|
const unit = {
|
|
17927
18009
|
label: "orchestrator",
|
|
@@ -17990,6 +18072,7 @@ function preflightEstimate(input) {
|
|
|
17990
18072
|
message: `the synthesis invocation sets maxOutputTokensPerTurn ${String(merged.maxOutputTokensPerTurn)} below the ${String(caps.minOutputTokensPerTurn)} token output floor of '${servedBy}': every dispatch would be refused typed before the wire; raise the cap to at least the floor`,
|
|
17991
18073
|
spawn: "synthesis"
|
|
17992
18074
|
});
|
|
18075
|
+
contractFeasibilityFindings(outputBound, "synthesis", servedBy);
|
|
17993
18076
|
const projected = projectedProviderTurnsOf(merged, overallExecutedCeiling(merged, toolCeilingsOf(merged))) + finishRepairReserve;
|
|
17994
18077
|
if (orchestratorEcho !== void 0) orchestratorEcho.synthesis = {
|
|
17995
18078
|
projectedProviderTurns: projected,
|
|
@@ -18214,6 +18297,15 @@ function preflightEstimate(input) {
|
|
|
18214
18297
|
names.add(validator.name);
|
|
18215
18298
|
}
|
|
18216
18299
|
if (fv.repairTurnReserve !== void 0) requireNonNegativeInteger(fv.repairTurnReserve, "preflight finishValidation.repairTurnReserve");
|
|
18300
|
+
if (fv.maxRepairs !== void 0) requireNonNegativeInteger(fv.maxRepairs, "preflight finishValidation.maxRepairs");
|
|
18301
|
+
{
|
|
18302
|
+
const grantedRepairs = fv.maxRepairs ?? 1;
|
|
18303
|
+
if (grantedRepairs > 0 && fv.repairTurnReserve === void 0) findings.push({
|
|
18304
|
+
severity: "warning",
|
|
18305
|
+
code: "repair-reserve-unfunded",
|
|
18306
|
+
message: `finishValidation grants up to ${String(grantedRepairs)} repair exchange(s) but declares no repairTurnReserve: a rejected finish burns an ordinary turn and a window at maxTurns settles 'limit' with the repair unspent; set finishValidation.repairTurnReserve to fund the repair exchanges`
|
|
18307
|
+
});
|
|
18308
|
+
}
|
|
18217
18309
|
if (fv.contract !== void 0) {
|
|
18218
18310
|
for (const contractValidator of fv.contract.validators) if (!names.has(contractValidator.name)) findings.push({
|
|
18219
18311
|
severity: "error",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rulvar/core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.77.0",
|
|
4
4
|
"description": "Rulvar core: L0 contracts, journal kernel, ctx primitives, agent runtime, model router, tool system, dynamic orchestrator, InMemory and JSONL stores, event stream.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|