@rulvar/evals 1.243.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.
- package/dist/index.d.ts +7 -2
- package/dist/index.js +122 -6
- package/package.json +6 -6
package/dist/index.d.ts
CHANGED
|
@@ -849,9 +849,14 @@ declare function runFaultInjection(options?: RunFaultInjectionOptions): Promise<
|
|
|
849
849
|
* figure whose premise contradicts the declared input (2,000 slots
|
|
850
850
|
* computed from a 30 minute window where the input declares a 20
|
|
851
851
|
* minute burst), and 'cost-basis' prints a locally estimated total as
|
|
852
|
-
* the provider's bill.
|
|
852
|
+
* the provider's bill. The fourth comparison experiment named the
|
|
853
|
+
* decisive one (RV3909): 'stale-doctrine-echo' is a draft echoing a
|
|
854
|
+
* DOCUMENTED doctrine while the pool holds the diverging source fact,
|
|
855
|
+
* both sides cited; the experiment's answer echoed the retired
|
|
856
|
+
* budget-immutability wording from a guide six weeks stale, and no
|
|
857
|
+
* judge could flag it because the pool never carried the source side.
|
|
853
858
|
*/
|
|
854
|
-
type ClaimCorpusClass = "live-fact" | "package-identity" | "inverted-default" | "numeric-range" | "negation" | "bounded-coverage" | "modality-overclaim" | "scope-ambiguity" | "bound-conflation" | "derived-premise" | "cost-basis";
|
|
859
|
+
type ClaimCorpusClass = "live-fact" | "package-identity" | "inverted-default" | "numeric-range" | "negation" | "bounded-coverage" | "modality-overclaim" | "scope-ambiguity" | "bound-conflation" | "derived-premise" | "cost-basis" | "stale-doctrine-echo";
|
|
855
860
|
/** One adversarial case: a draft, its contradicting evidence, and the mechanical expectations. */
|
|
856
861
|
interface ClaimCorpusCase {
|
|
857
862
|
id: string;
|
package/dist/index.js
CHANGED
|
@@ -3950,12 +3950,13 @@ const sectionalRepairRound = {
|
|
|
3950
3950
|
const { compositions, judges } = tailSpans(entries);
|
|
3951
3951
|
const verdictRows = entries.filter((entry) => entry.kind === "decision" && entry.value?.decisionType === "orchestrator_finish_validation").map((entry) => entry.value);
|
|
3952
3952
|
const roundPrompts = adapter.calls.filter((call) => call.label === "final-composition").map((call) => call.prompt);
|
|
3953
|
-
const sectionalPrompt = roundPrompts.length === 2 && roundPrompts[0]?.includes("SECTIONAL ROUND") === false && roundPrompts[1]?.includes("SECTIONAL ROUND") === true && roundPrompts[1]?.includes("\"## Verdict\"") === true;
|
|
3953
|
+
const sectionalPrompt = roundPrompts.length === 2 && roundPrompts[0]?.includes("SECTIONAL ROUND") === false && roundPrompts[1]?.includes("SECTIONAL ROUND") === true && roundPrompts[1]?.includes("\"## Verdict\"") === true && roundPrompts[0]?.includes("retained evidence discipline") === false && roundPrompts[1]?.includes("retained evidence discipline") === true;
|
|
3954
3954
|
const byteIdentity = value?.result === SECTIONAL_SPLICED && String(value.result).startsWith(SECTIONAL_PREFIX);
|
|
3955
|
+
const lineage = value?.claimConsistencyMeta?.passes === 2 && value.claimConsistencyMeta.firstPassFindings === 1 && value.claimConsistencyMeta.semanticRepairRounds === 1;
|
|
3955
3956
|
return {
|
|
3956
3957
|
observation: {
|
|
3957
|
-
matched: outcome.status === "ok" && byteIdentity && value.claimConsistencyMeta?.findings === 0 && verdictRows.map((row) => row.verdict).join(",") === "accepted,accepted" && verdictRows.map((row) => String(row.repairsUsed)).join(",") === "0,0" && sectionalPrompt && compositions.length === 2 && judges.length === 2,
|
|
3958
|
-
detail: `run '${outcome.status}' shipped ${value?.result === SECTIONAL_SPLICED ? "the spliced whole" : "an unexpected document"}; byte identity=${String(byteIdentity)}; sectional prompt=${String(sectionalPrompt)}; verdicts [${verdictRows.map((row) => row.verdict).join(",")}]; ${String(compositions.length)} composition(s), ${String(judges.length)} final judge pass(es)`
|
|
3958
|
+
matched: outcome.status === "ok" && byteIdentity && value.claimConsistencyMeta?.findings === 0 && lineage && verdictRows.map((row) => row.verdict).join(",") === "accepted,accepted" && verdictRows.map((row) => String(row.repairsUsed)).join(",") === "0,0" && sectionalPrompt && compositions.length === 2 && judges.length === 2,
|
|
3959
|
+
detail: `run '${outcome.status}' shipped ${value?.result === SECTIONAL_SPLICED ? "the spliced whole" : "an unexpected document"}; byte identity=${String(byteIdentity)}; sectional prompt=${String(sectionalPrompt)}; lineage=${String(lineage)}; verdicts [${verdictRows.map((row) => row.verdict).join(",")}]; ${String(compositions.length)} composition(s), ${String(judges.length)} final judge pass(es)`
|
|
3959
3960
|
},
|
|
3960
3961
|
artifacts: [jsonArtifact("outcome.json", {
|
|
3961
3962
|
status: outcome.status,
|
|
@@ -4146,10 +4147,11 @@ const SCENARIOS = [
|
|
|
4146
4147
|
const judgeSawPatched = adapter.calls.filter((call) => call.label === "claim-consistency-judge-final").map((call) => call.prompt)[0]?.includes(`(run ${PATCH_RUN_ID})`) === true;
|
|
4147
4148
|
const roundPrompts = adapter.calls.filter((call) => call.label === "final-composition").map((call) => call.prompt);
|
|
4148
4149
|
const lessonCarried = roundPrompts.length === 2 && roundPrompts[0]?.includes("HOST VALIDATION LESSONS") === false && roundPrompts[1]?.includes("HOST VALIDATION LESSONS") === true && roundPrompts[1]?.includes("evidence-grade") === true;
|
|
4150
|
+
const aggregate = value?.deterministicPatches?.decisions === 1 && typeof value.deterministicPatches.patches === "number" && value.deterministicPatches.patches >= 1 && /^[0-9a-f]{64}$/u.test(String(value.deterministicPatches.lastAfterHash)) && value.deterministicPatches.lastAfterHash !== value.deterministicPatches.lastBeforeHash;
|
|
4149
4151
|
return {
|
|
4150
4152
|
observation: {
|
|
4151
|
-
matched: outcome.status === "ok" && value?.result === TAIL_FINAL_CLEAN && value.claimConsistencyMeta?.findings === 0 && verdicts === "accepted,accepted" && pools === "0,0" && patch?.outcome === "accepted" && patch.healed?.map((healed) => healed.name).join(",") === "evidence-grade" && judgeSawPatched && lessonCarried && compositions.length === 2 && judges.length === 2,
|
|
4152
|
-
detail: `run '${outcome.status}' shipped ${value?.result === TAIL_FINAL_CLEAN ? "the clean round document" : "an unexpected document"}; verdicts [${verdicts}], repairsUsed [${pools}] (no wire, no pool spent); patch outcome='${String(patch?.outcome)}'; judge saw patched=${String(judgeSawPatched)}; lesson carried=${String(lessonCarried)}; ${String(compositions.length)} composition(s), ${String(judges.length)} final judge pass(es)`
|
|
4153
|
+
matched: outcome.status === "ok" && value?.result === TAIL_FINAL_CLEAN && value.claimConsistencyMeta?.findings === 0 && aggregate && verdicts === "accepted,accepted" && pools === "0,0" && patch?.outcome === "accepted" && patch.healed?.map((healed) => healed.name).join(",") === "evidence-grade" && judgeSawPatched && lessonCarried && compositions.length === 2 && judges.length === 2,
|
|
4154
|
+
detail: `run '${outcome.status}' shipped ${value?.result === TAIL_FINAL_CLEAN ? "the clean round document" : "an unexpected document"}; verdicts [${verdicts}], repairsUsed [${pools}] (no wire, no pool spent); patch outcome='${String(patch?.outcome)}'; envelope aggregate=${String(aggregate)}; judge saw patched=${String(judgeSawPatched)}; lesson carried=${String(lessonCarried)}; ${String(compositions.length)} composition(s), ${String(judges.length)} final judge pass(es)`
|
|
4153
4155
|
},
|
|
4154
4156
|
artifacts: [jsonArtifact("outcome.json", {
|
|
4155
4157
|
status: outcome.status,
|
|
@@ -4159,7 +4161,106 @@ const SCENARIOS = [
|
|
|
4159
4161
|
};
|
|
4160
4162
|
}
|
|
4161
4163
|
},
|
|
4162
|
-
claimJudgeDeadArmedRefusal
|
|
4164
|
+
claimJudgeDeadArmedRefusal,
|
|
4165
|
+
{
|
|
4166
|
+
name: "acceptance-reserve-refusal",
|
|
4167
|
+
doctrine: "budget.acceptanceReserve 'require' refuses the run typed BEFORE the first wire when the declared acceptance tail (synthesis hold + judge passes + mechanical repair + round composition + working room) does not fit the effective cap, and the refusal journals every term; the same config under the default warn posture dispatches",
|
|
4168
|
+
async run() {
|
|
4169
|
+
const store = new InMemoryStore();
|
|
4170
|
+
const adapter = new FakeAdapter({ agents: { "*": "never dispatched" } });
|
|
4171
|
+
const outcome = await createEngine({
|
|
4172
|
+
adapters: [adapter],
|
|
4173
|
+
stores: { journal: store },
|
|
4174
|
+
defaults: { routing: {
|
|
4175
|
+
loop: FAKE_MODEL_REF,
|
|
4176
|
+
orchestrate: FAKE_MODEL_REF,
|
|
4177
|
+
synthesize: FAKE_MODEL_REF,
|
|
4178
|
+
extract: FAKE_MODEL_REF
|
|
4179
|
+
} }
|
|
4180
|
+
}).run(makeOrchestratorWorkflow("audit the executor", {
|
|
4181
|
+
synthesis: { estCost: .15 },
|
|
4182
|
+
claimConsistency: {
|
|
4183
|
+
stage: "final",
|
|
4184
|
+
onFound: "repair",
|
|
4185
|
+
judge: { estCost: .2 }
|
|
4186
|
+
},
|
|
4187
|
+
finishValidation: {
|
|
4188
|
+
validators: [{
|
|
4189
|
+
name: "anything",
|
|
4190
|
+
validate: () => ({ ok: true })
|
|
4191
|
+
}],
|
|
4192
|
+
estRepairCostUsd: .1
|
|
4193
|
+
},
|
|
4194
|
+
budget: {
|
|
4195
|
+
synthesisReserveUsd: 1,
|
|
4196
|
+
acceptanceReserve: "require"
|
|
4197
|
+
}
|
|
4198
|
+
}), void 0, {
|
|
4199
|
+
runId: "fault-acceptance-reserve",
|
|
4200
|
+
budgetUsd: 10
|
|
4201
|
+
}).result;
|
|
4202
|
+
const refusal = (await store.load("fault-acceptance-reserve")).find((entry) => entry.value?.decisionType === "acceptance_reserve_refused");
|
|
4203
|
+
const terms = refusal?.value;
|
|
4204
|
+
return {
|
|
4205
|
+
observation: {
|
|
4206
|
+
matched: outcome.status === "error" && (outcome.error?.message ?? "").includes("acceptanceReserve 'require'") && adapter.calls.length === 0 && terms !== void 0 && Math.abs((terms.requiredUsd ?? 0) - 2.15) < 1e-9 && Math.abs((terms.effectiveCapUsd ?? 0) - 2) < 1e-9 && terms.judgePasses === 2,
|
|
4207
|
+
detail: `run '${outcome.status}'; dispatches=${String(adapter.calls.length)}; refusal decision=${String(refusal !== void 0)} (required ${String(terms?.requiredUsd)} vs cap ${String(terms?.effectiveCapUsd)}, ` + `judge passes ${String(terms?.judgePasses)}); ${outcome.error?.message ?? ""}`.slice(0, 400)
|
|
4208
|
+
},
|
|
4209
|
+
artifacts: [jsonArtifact("refusal.json", {
|
|
4210
|
+
error: outcome.error ?? null,
|
|
4211
|
+
decision: refusal?.value ?? null
|
|
4212
|
+
})]
|
|
4213
|
+
};
|
|
4214
|
+
}
|
|
4215
|
+
},
|
|
4216
|
+
{
|
|
4217
|
+
name: "budget-policy-immutable",
|
|
4218
|
+
doctrine: "budgetPolicy 'immutable-lifetime' refuses a resume-time ceiling override typed before ownership, raise and lower alike, with zero provider dispatches and zero durable mutations; a bare resume of the same run stays a pure replay",
|
|
4219
|
+
async run() {
|
|
4220
|
+
const store = new InMemoryStore();
|
|
4221
|
+
const seeded = await createEngine({
|
|
4222
|
+
adapters: [new FakeAdapter({ agents: { "*": "answered" } })],
|
|
4223
|
+
stores: { journal: store },
|
|
4224
|
+
defaults: ROUTING
|
|
4225
|
+
}).run(echoWorkflow, void 0, {
|
|
4226
|
+
runId: "fault-budget-policy",
|
|
4227
|
+
budgetUsd: 1,
|
|
4228
|
+
budgetPolicy: "immutable-lifetime"
|
|
4229
|
+
}).result;
|
|
4230
|
+
const entriesBefore = (await store.load("fault-budget-policy")).length;
|
|
4231
|
+
const overrideAdapter = new FakeAdapter({ agents: { "*": "never dispatched" } });
|
|
4232
|
+
let refusalText = "the override was not refused";
|
|
4233
|
+
let refusedTyped = false;
|
|
4234
|
+
try {
|
|
4235
|
+
await createEngine({
|
|
4236
|
+
adapters: [overrideAdapter],
|
|
4237
|
+
stores: { journal: store },
|
|
4238
|
+
defaults: ROUTING
|
|
4239
|
+
}).resume("fault-budget-policy", echoWorkflow, { run: { budgetUsd: 2 } }).result;
|
|
4240
|
+
} catch (thrown) {
|
|
4241
|
+
refusalText = errorText(thrown);
|
|
4242
|
+
refusedTyped = thrown instanceof ConfigError && refusalText.includes("immutable-lifetime");
|
|
4243
|
+
}
|
|
4244
|
+
const entriesAfterRefusal = (await store.load("fault-budget-policy")).length;
|
|
4245
|
+
const metaAfterRefusal = await store.getMeta("fault-budget-policy");
|
|
4246
|
+
const bare = await createEngine({
|
|
4247
|
+
adapters: [new FakeAdapter({ agents: { "*": "never dispatched either" } })],
|
|
4248
|
+
stores: { journal: store },
|
|
4249
|
+
defaults: ROUTING
|
|
4250
|
+
}).resume("fault-budget-policy", echoWorkflow).result;
|
|
4251
|
+
return {
|
|
4252
|
+
observation: {
|
|
4253
|
+
matched: seeded.status === "ok" && refusedTyped && overrideAdapter.calls.length === 0 && entriesAfterRefusal === entriesBefore && metaAfterRefusal?.budgetUsd === 1 && metaAfterRefusal.budgetPolicy === "immutable-lifetime" && bare.status === "ok",
|
|
4254
|
+
detail: `seed '${seeded.status}'; refusal typed=${String(refusedTyped)} (${refusalText.slice(0, 160)}); override dispatches=${String(overrideAdapter.calls.length)}; entries ${String(entriesBefore)} -> ${String(entriesAfterRefusal)}; meta budgetUsd=${String(metaAfterRefusal?.budgetUsd)} policy=${String(metaAfterRefusal?.budgetPolicy)}; bare resume '${bare.status}'`
|
|
4255
|
+
},
|
|
4256
|
+
artifacts: [jsonArtifact("refusal.json", {
|
|
4257
|
+
refusalText,
|
|
4258
|
+
entriesBefore,
|
|
4259
|
+
entriesAfterRefusal
|
|
4260
|
+
}), jsonArtifact("meta.json", metaAfterRefusal ?? null)]
|
|
4261
|
+
};
|
|
4262
|
+
}
|
|
4263
|
+
}
|
|
4163
4264
|
];
|
|
4164
4265
|
/** The scenario names in run order. */
|
|
4165
4266
|
const FAULT_SCENARIO_NAMES = SCENARIOS.map((scenario) => scenario.name);
|
|
@@ -4377,6 +4478,21 @@ const CLAIM_CORPUS = [
|
|
|
4377
4478
|
},
|
|
4378
4479
|
runFactTerms: ["provider bill", "charged and settled"],
|
|
4379
4480
|
expect: { minRunFactPairs: 1 }
|
|
4481
|
+
},
|
|
4482
|
+
{
|
|
4483
|
+
id: "stale-doctrine-echo-budget-override",
|
|
4484
|
+
class: "stale-doctrine-echo",
|
|
4485
|
+
draft: "The run budget ceiling is documented as immutable after start: resume accepts no budget parameter, so an exhausted run can never continue under a raised ceiling (docs/guide/budgets.md:43; packages/core/src/engine/engine.ts:588).",
|
|
4486
|
+
pool: [{
|
|
4487
|
+
nodeId: "agent:3",
|
|
4488
|
+
text: "The budgets guide historically taught \"immutable after start\" (docs/guide/budgets.md:43), but ResumeOptions.run raises budgetUsd and maxInFlightExposureUsd at resume, validated and journaled as a run_budget_override decision with a typed floor at the settled spend (packages/core/src/engine/engine.ts:588-604); the doctrine in force is immutability WITHIN a segment."
|
|
4489
|
+
}],
|
|
4490
|
+
critical: ["packages/core/src/engine/engine.ts"],
|
|
4491
|
+
expect: {
|
|
4492
|
+
minPairs: 1,
|
|
4493
|
+
anchors: ["packages/core/src/engine/engine.ts:588"],
|
|
4494
|
+
coverage: "full"
|
|
4495
|
+
}
|
|
4380
4496
|
}
|
|
4381
4497
|
];
|
|
4382
4498
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rulvar/evals",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.244.0",
|
|
4
4
|
"description": "Rulvar evals: eval cases, golden outputs, rubric and judge graders, matrix sweeps, canary fingerprint.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -22,11 +22,11 @@
|
|
|
22
22
|
"access": "public"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@rulvar/
|
|
26
|
-
"@rulvar/openai": "1.
|
|
27
|
-
"@rulvar/
|
|
28
|
-
"@rulvar/
|
|
29
|
-
"@rulvar/
|
|
25
|
+
"@rulvar/anthropic": "1.244.0",
|
|
26
|
+
"@rulvar/openai": "1.244.0",
|
|
27
|
+
"@rulvar/core": "1.244.0",
|
|
28
|
+
"@rulvar/plan": "1.244.0",
|
|
29
|
+
"@rulvar/testing": "1.244.0"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"@types/node": "^22.20.1",
|