@rulvar/evals 1.238.0 → 1.239.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 (2) hide show
  1. package/dist/index.js +552 -309
  2. package/package.json +6 -6
package/dist/index.js CHANGED
@@ -7,7 +7,7 @@ import { join } from "node:path";
7
7
  import { ANTHROPIC_PRICING, anthropic } from "@rulvar/anthropic";
8
8
  import { reconcileStatement } from "@rulvar/openai";
9
9
  import { orchestratePlanned } from "@rulvar/plan";
10
- import { FAKE_MODEL_REF, FakeAdapter, fakeToolCalls } from "@rulvar/testing";
10
+ import { FAKE_MODEL_REF, FakeAdapter, fakeToolCalls, fakeWireError } from "@rulvar/testing";
11
11
  //#region src/envelope.ts
12
12
  /**
13
13
  * The debit-only aggregate spend envelope (v1.16.2 review P1-2). A
@@ -3107,305 +3107,171 @@ const scriptedCaps = () => ({
3107
3107
  outputUsdPerMTok: 10
3108
3108
  }
3109
3109
  });
3110
- const SCENARIOS = [
3111
- inFlightExposure,
3112
- duplicateQuotaRule,
3113
- tornJsonlTail,
3114
- gluedJsonlTail,
3115
- crashResumeSettleBoundary,
3116
- pricingRotationUncoveredTail,
3117
- unknownProviderId,
3118
- nanStatementRefusal,
3119
- tokenMismatchDivergence,
3120
- auditMissingFieldFinding,
3121
- anthropic1hPriced,
3122
- pauseTurnUnits,
3123
- preAdmissionCountRefusal,
3124
- forcedFinishCompletion,
3125
- settlementTerminalHonesty,
3126
- ttlLiveBudgetParity,
3127
- pauseTurnRealAdapter,
3128
- statementSettleableGuard,
3129
- supersededTerminalHonesty,
3130
- tierCrossingLiveParity,
3131
- benchmarkPrimaryPreflightParity,
3132
- benchmarkRecoveryRootExposure,
3133
- parityQuiescenceDeadlock,
3134
- paritySequentialRosterFloor,
3135
- {
3136
- name: "parity-reserve-line-redemption",
3137
- doctrine: "a coordination turn refused at the reserve line folds typed 'budget-floor' and the held synthesis reserve funds the redemption whose result rides the partial envelope (RV2101); the PlanRunner extension arm produces the same fold and the same redeemed result (DEF-7)",
3138
- async run() {
3139
- const runArm = async (mode) => {
3140
- const calls = [];
3141
- const adapter = {
3142
- id: "fake",
3143
- calls,
3144
- caps: scriptedCaps,
3145
- async *stream(req) {
3146
- const call = calls.length;
3147
- calls.push(req);
3148
- await Promise.resolve();
3149
- if (scriptedAgentType(req) !== "") {
3150
- yield {
3151
- type: "text-delta",
3152
- text: "settled evidence"
3153
- };
3154
- yield {
3155
- type: "finish",
3156
- finish: { reason: "stop" },
3157
- usage: {
3158
- inputTokens: 10,
3159
- outputTokens: 5,
3160
- cacheReadTokens: 0,
3161
- cacheWriteTokens: 0
3162
- }
3163
- };
3164
- return;
3165
- }
3166
- if (!(req.tools ?? []).some((tool) => tool.name === "spawn_agent")) {
3167
- for (const event of scriptedToolEvents("finish", { result: "the redeemed synthesis" }, `id-${String(call)}-0`)) yield event;
3168
- yield {
3169
- type: "finish",
3170
- finish: { reason: "tool-calls" },
3171
- usage: {
3172
- inputTokens: 12,
3173
- outputTokens: 8,
3174
- cacheReadTokens: 0,
3175
- cacheWriteTokens: 0
3176
- }
3177
- };
3178
- return;
3179
- }
3180
- const turn = calls.filter((prior) => scriptedAgentType(prior) === "" && (prior.tools ?? []).some((tool) => tool.name === "spawn_agent")).length === 1 ? scriptedToolEvents("spawn_agent", {
3181
- agentType: "worker",
3182
- prompt: "gather A"
3183
- }, `id-${String(call)}-0`).concat(scriptedToolEvents("spawn_agent", {
3184
- agentType: "worker",
3185
- prompt: "gather B"
3186
- }, `id-${String(call)}-1`)) : scriptedToolEvents("finish", { result: "unreachable" }, `id-${String(call)}-0`);
3187
- for (const event of turn) yield event;
3110
+ /**
3111
+ * The reserve line and its redemption, in BOTH drive modes (RV2101,
3112
+ * DEF-7). The first paid parity runs died bare exactly here: the
3113
+ * coordination turn whose spent + held synthesis reserve + proposed
3114
+ * crossed the orchestrator cap tore the run down with the reserve
3115
+ * intact and unreachable. The fold is now typed 'budget-floor' and the
3116
+ * held reserve FUNDS the synthesis the run kept it for; the PlanRunner
3117
+ * extension arm must produce the same fold and the same redeemed
3118
+ * result, which is the DEF-7 parity this scenario documents.
3119
+ */
3120
+ const parityReserveLineRedemption = {
3121
+ name: "parity-reserve-line-redemption",
3122
+ doctrine: "a coordination turn refused at the reserve line folds typed 'budget-floor' and the held synthesis reserve funds the redemption whose result rides the partial envelope (RV2101); the PlanRunner extension arm produces the same fold and the same redeemed result (DEF-7)",
3123
+ async run() {
3124
+ const runArm = async (mode) => {
3125
+ const calls = [];
3126
+ const adapter = {
3127
+ id: "fake",
3128
+ calls,
3129
+ caps: scriptedCaps,
3130
+ async *stream(req) {
3131
+ const call = calls.length;
3132
+ calls.push(req);
3133
+ await Promise.resolve();
3134
+ if (scriptedAgentType(req) !== "") {
3135
+ yield {
3136
+ type: "text-delta",
3137
+ text: "settled evidence"
3138
+ };
3188
3139
  yield {
3189
3140
  type: "finish",
3190
- finish: { reason: "tool-calls" },
3141
+ finish: { reason: "stop" },
3191
3142
  usage: {
3192
3143
  inputTokens: 10,
3193
- outputTokens: 1e3,
3144
+ outputTokens: 5,
3194
3145
  cacheReadTokens: 0,
3195
3146
  cacheWriteTokens: 0
3196
3147
  }
3197
3148
  };
3149
+ return;
3198
3150
  }
3199
- };
3200
- const store = new InMemoryStore();
3201
- const engine = createEngine({
3202
- adapters: [adapter],
3203
- stores: { journal: store },
3204
- defaults: {
3205
- routing: {
3206
- loop: "fake:model",
3207
- orchestrate: "fake:model",
3208
- synthesize: "fake:model"
3209
- },
3210
- profiles: { worker: { description: "the cheap gatherer" } }
3211
- }
3212
- });
3213
- const opts = {
3214
- limits: { maxOutputTokensPerTurn: 1e3 },
3215
- synthesis: {
3216
- estCost: .006,
3217
- limits: { maxOutputTokensPerTurn: 500 }
3218
- },
3219
- budget: {
3220
- capUsd: .03,
3221
- synthesisReserveUsd: .02,
3222
- finalizeReserveUsd: 0
3223
- }
3224
- };
3225
- const runId = `fault-reserve-line-${mode}`;
3226
- const outcome = mode === "workflow" ? await engine.run(makeOrchestratorWorkflow("the reserve line shape", opts), void 0, {
3227
- runId,
3228
- budgetUsd: 10
3229
- }).result : await orchestratePlanned(engine, "the reserve line shape", opts, { runId }).result;
3230
- const entries = await store.load(runId);
3231
- const fallback = entries.find((entry) => entry.kind === "decision" && entry.value?.decisionType === "orchestrator_finalize_fallback");
3232
- const settle = entries.some((entry) => entry.kind === "decision" && entry.value?.decisionType === "run_settle");
3233
- const value = outcome.value;
3234
- return {
3235
- status: outcome.status,
3236
- error: outcome.error?.message,
3237
- forcedFinishFallback: value?.forcedFinishFallback,
3238
- completion: value?.completion,
3239
- result: value?.result,
3240
- fallbackReason: (fallback?.value)?.reason,
3241
- rootClassCalls: calls.filter((req) => scriptedAgentType(req) === "").length,
3242
- workerOkTerminals: entries.filter((entry) => entry.kind === "agent" && entry.status === "ok").length,
3243
- settleRecorded: settle,
3244
- entries
3245
- };
3246
- };
3247
- const arms = {
3248
- workflow: await runArm("workflow"),
3249
- extension: await runArm("extension")
3250
- };
3251
- const armMatched = (arm) => arm.status === "exhausted" && arm.forcedFinishFallback === true && arm.completion === "partial" && arm.result === "the redeemed synthesis" && arm.fallbackReason === "budget-floor" && arm.rootClassCalls === 2 && arm.settleRecorded;
3252
- return {
3253
- observation: {
3254
- matched: armMatched(arms.workflow) && armMatched(arms.extension),
3255
- detail: `workflow arm '${arms.workflow.status}' reason=${String(arms.workflow.fallbackReason)} result=${JSON.stringify(arms.workflow.result)} rootCalls=${String(arms.workflow.rootClassCalls)}; extension arm '${arms.extension.status}' reason=${String(arms.extension.fallbackReason)} result=${JSON.stringify(arms.extension.result)} rootCalls=${String(arms.extension.rootClassCalls)} (DEF-7 parity: both arms fold 'budget-floor' and both redeem the synthesis from the held reserve)`
3256
- },
3257
- artifacts: [
3258
- jsonArtifact("arms.json", {
3259
- workflow: {
3260
- ...arms.workflow,
3261
- entries: void 0
3262
- },
3263
- extension: {
3264
- ...arms.extension,
3265
- entries: void 0
3266
- }
3267
- }),
3268
- jsonArtifact("journal-workflow.json", arms.workflow.entries),
3269
- jsonArtifact("journal-extension.json", arms.extension.entries)
3270
- ]
3271
- };
3272
- }
3273
- },
3274
- {
3275
- name: "resume-spawn-famine",
3276
- doctrine: "a resume re-admits recovered agents without re-counting them against lifetimeSpawnCap (RV2201): the kill-mid-fan-out journal resumes to the finished dossier at the EXACT cap, with no 'lifetime spawn cap' decline journaled and only the unsettled workers re-paid; the c7 resume starved its judge and synthesis on re-counted admissions",
3277
- async run() {
3278
- const makeAdapter = () => {
3279
- const calls = [];
3280
- return {
3281
- id: "fake",
3282
- calls,
3283
- caps: scriptedCaps,
3284
- async *stream(req) {
3285
- const call = calls.length;
3286
- calls.push(req);
3287
- await Promise.resolve();
3288
- if (scriptedAgentType(req) !== "") {
3289
- yield {
3290
- type: "text-delta",
3291
- text: "gathered evidence"
3292
- };
3293
- yield {
3294
- type: "finish",
3295
- finish: { reason: "stop" },
3296
- usage: {
3297
- inputTokens: 10,
3298
- outputTokens: 5,
3299
- cacheReadTokens: 0,
3300
- cacheWriteTokens: 0
3301
- }
3302
- };
3303
- return;
3304
- }
3305
- if (!(req.tools ?? []).some((tool) => tool.name === "spawn_agent")) {
3306
- for (const event of scriptedToolEvents("finish", { result: "the resumed dossier" }, `id-${String(call)}-0`)) yield event;
3307
- yield {
3308
- type: "finish",
3309
- finish: { reason: "tool-calls" },
3310
- usage: {
3311
- inputTokens: 12,
3312
- outputTokens: 8,
3313
- cacheReadTokens: 0,
3314
- cacheWriteTokens: 0
3315
- }
3316
- };
3317
- return;
3318
- }
3319
- const turn = calls.filter((prior) => scriptedAgentType(prior) === "" && (prior.tools ?? []).some((tool) => tool.name === "spawn_agent")).length === 1 ? scriptedToolEvents("spawn_agent", {
3320
- agentType: "worker",
3321
- prompt: "gather A"
3322
- }, `id-${String(call)}-0`).concat(scriptedToolEvents("spawn_agent", {
3323
- agentType: "worker",
3324
- prompt: "gather B"
3325
- }, `id-${String(call)}-1`), scriptedToolEvents("spawn_agent", {
3326
- agentType: "worker",
3327
- prompt: "gather C"
3328
- }, `id-${String(call)}-2`)) : scriptedToolEvents("finish", { result: "the coordination draft" }, `id-${String(call)}-0`);
3329
- for (const event of turn) yield event;
3151
+ if (!(req.tools ?? []).some((tool) => tool.name === "spawn_agent")) {
3152
+ for (const event of scriptedToolEvents("finish", { result: "the redeemed synthesis" }, `id-${String(call)}-0`)) yield event;
3330
3153
  yield {
3331
3154
  type: "finish",
3332
3155
  finish: { reason: "tool-calls" },
3333
3156
  usage: {
3334
- inputTokens: 10,
3335
- outputTokens: 5,
3157
+ inputTokens: 12,
3158
+ outputTokens: 8,
3336
3159
  cacheReadTokens: 0,
3337
3160
  cacheWriteTokens: 0
3338
3161
  }
3339
3162
  };
3163
+ return;
3340
3164
  }
3341
- };
3165
+ const turn = calls.filter((prior) => scriptedAgentType(prior) === "" && (prior.tools ?? []).some((tool) => tool.name === "spawn_agent")).length === 1 ? scriptedToolEvents("spawn_agent", {
3166
+ agentType: "worker",
3167
+ prompt: "gather A"
3168
+ }, `id-${String(call)}-0`).concat(scriptedToolEvents("spawn_agent", {
3169
+ agentType: "worker",
3170
+ prompt: "gather B"
3171
+ }, `id-${String(call)}-1`)) : scriptedToolEvents("finish", { result: "unreachable" }, `id-${String(call)}-0`);
3172
+ for (const event of turn) yield event;
3173
+ yield {
3174
+ type: "finish",
3175
+ finish: { reason: "tool-calls" },
3176
+ usage: {
3177
+ inputTokens: 10,
3178
+ outputTokens: 1e3,
3179
+ cacheReadTokens: 0,
3180
+ cacheWriteTokens: 0
3181
+ }
3182
+ };
3183
+ }
3342
3184
  };
3343
- const LIFETIME_SPAWNS = 5;
3344
- const wf = makeOrchestratorWorkflow("the resumable fan-out", {
3345
- synthesis: {
3346
- estCost: .006,
3347
- limits: { maxOutputTokensPerTurn: 500 }
3348
- },
3349
- budget: { finalizeReserveUsd: 0 }
3350
- });
3351
- const makeEngine = (adapter, store) => createEngine({
3185
+ const store = new InMemoryStore();
3186
+ const engine = createEngine({
3352
3187
  adapters: [adapter],
3353
3188
  stores: { journal: store },
3354
- budgetDefaults: { lifetimeSpawnCap: LIFETIME_SPAWNS },
3355
3189
  defaults: {
3356
3190
  routing: {
3357
3191
  loop: "fake:model",
3358
3192
  orchestrate: "fake:model",
3359
3193
  synthesize: "fake:model"
3360
3194
  },
3361
- profiles: { worker: { description: "the resumable gatherer" } }
3195
+ profiles: { worker: { description: "the cheap gatherer" } }
3362
3196
  }
3363
3197
  });
3364
- const storeA = new InMemoryStore();
3365
- const seeded = await makeEngine(makeAdapter(), storeA).run(wf, void 0, {
3366
- runId: "fault-resume-famine",
3198
+ const opts = {
3199
+ limits: { maxOutputTokensPerTurn: 1e3 },
3200
+ synthesis: {
3201
+ estCost: .006,
3202
+ limits: { maxOutputTokensPerTurn: 500 }
3203
+ },
3204
+ budget: {
3205
+ capUsd: .03,
3206
+ synthesisReserveUsd: .02,
3207
+ finalizeReserveUsd: 0
3208
+ }
3209
+ };
3210
+ const runId = `fault-reserve-line-${mode}`;
3211
+ const outcome = mode === "workflow" ? await engine.run(makeOrchestratorWorkflow("the reserve line shape", opts), void 0, {
3212
+ runId,
3367
3213
  budgetUsd: 10
3368
- }).result;
3369
- if (seeded.status !== "ok") throw new Error(`fault kit: the seeding run settled '${seeded.status}' instead of ok`);
3370
- const entriesA = await storeA.load("fault-resume-famine");
3371
- const firstWorkerOk = entriesA.findIndex((entry) => entry.kind === "agent" && entry.status === "ok");
3372
- if (firstWorkerOk < 0) throw new Error("fault kit: the seeding journal carries no worker terminal to cut at");
3373
- const cut = entriesA.slice(0, firstWorkerOk + 1);
3374
- const storeB = new InMemoryStore();
3375
- for (const entry of cut) await storeB.append("fault-resume-famine", entry);
3376
- const resumeAdapter = makeAdapter();
3377
- const resumed = await makeEngine(resumeAdapter, storeB).resume("fault-resume-famine", wf).result;
3378
- const entriesB = await storeB.load("fault-resume-famine");
3379
- const capDeclines = entriesB.filter((entry) => entry.kind === "decision" && JSON.stringify(entry.value ?? {}).includes("lifetime spawn cap"));
3380
- const redemptionDeclines = entriesB.filter((entry) => entry.kind === "decision" && entry.value?.decisionType === "orchestrator_synthesis_redemption_declined");
3381
- const liveWorkerCalls = resumeAdapter.calls.filter((req) => scriptedAgentType(req) !== "").length;
3382
- const distinctAgentScopes = new Set(entriesB.filter((entry) => entry.kind === "agent" && entry.status === "running").map((entry) => `${entry.scope}#${String(entry.key)}`)).size;
3214
+ }).result : await orchestratePlanned(engine, "the reserve line shape", opts, { runId }).result;
3215
+ const entries = await store.load(runId);
3216
+ const fallback = entries.find((entry) => entry.kind === "decision" && entry.value?.decisionType === "orchestrator_finalize_fallback");
3217
+ const settle = entries.some((entry) => entry.kind === "decision" && entry.value?.decisionType === "run_settle");
3218
+ const value = outcome.value;
3383
3219
  return {
3384
- observation: {
3385
- matched: resumed.status === "ok" && resumed.value === "the resumed dossier" && capDeclines.length === 0 && redemptionDeclines.length === 0 && liveWorkerCalls === 2 && distinctAgentScopes === LIFETIME_SPAWNS,
3386
- detail: `resumed '${resumed.status}' result=${JSON.stringify(resumed.value)} at lifetimeSpawnCap ${String(LIFETIME_SPAWNS)} (${String(distinctAgentScopes)} distinct lifetime agent scopes); cap declines journaled=${String(capDeclines.length)}, redemption declines=${String(redemptionDeclines.length)}, live worker calls in the resumed segment=${String(liveWorkerCalls)} (the settled worker replayed free)`
3387
- },
3388
- artifacts: [
3389
- jsonArtifact("journal-cut.json", cut),
3390
- jsonArtifact("resume-outcome.json", {
3391
- status: resumed.status,
3392
- value: resumed.value ?? null,
3393
- liveWorkerCalls
3394
- }),
3395
- jsonArtifact("journal-resumed.json", entriesB)
3396
- ]
3220
+ status: outcome.status,
3221
+ error: outcome.error?.message,
3222
+ forcedFinishFallback: value?.forcedFinishFallback,
3223
+ completion: value?.completion,
3224
+ result: value?.result,
3225
+ fallbackReason: (fallback?.value)?.reason,
3226
+ rootClassCalls: calls.filter((req) => scriptedAgentType(req) === "").length,
3227
+ workerOkTerminals: entries.filter((entry) => entry.kind === "agent" && entry.status === "ok").length,
3228
+ settleRecorded: settle,
3229
+ entries
3397
3230
  };
3398
- }
3399
- },
3400
- {
3401
- name: "validator-guidance-conflict",
3402
- doctrine: "the evidence-grade reason names the SAFE composition against its cited-value sibling and names the run id it wants written (RV2202, RV2501, RV2502): the c3 trap finish repairs in ONE round by carrying THIS run's own id in the graded sentence, beside a source citation, with cited-value reading that id as identity and never rejecting; the third subscription run burned both repairs between the two verdicts, and the 1.226.0 comparison run burned both again on an id no artifact pattern could match",
3403
- async run() {
3404
- const TRAP_FINISH = "The reserve fold is live-observed under sustained load. The engine seals the journal at settle (`README.md:3`).";
3405
- const FIXED_FINISH = "The reserve fold is live-observed under sustained load in run `fault-guidance-conflict`, where the engine seals the journal at settle (`README.md:3`).";
3231
+ };
3232
+ const arms = {
3233
+ workflow: await runArm("workflow"),
3234
+ extension: await runArm("extension")
3235
+ };
3236
+ const armMatched = (arm) => arm.status === "exhausted" && arm.forcedFinishFallback === true && arm.completion === "partial" && arm.result === "the redeemed synthesis" && arm.fallbackReason === "budget-floor" && arm.rootClassCalls === 2 && arm.settleRecorded;
3237
+ return {
3238
+ observation: {
3239
+ matched: armMatched(arms.workflow) && armMatched(arms.extension),
3240
+ detail: `workflow arm '${arms.workflow.status}' reason=${String(arms.workflow.fallbackReason)} result=${JSON.stringify(arms.workflow.result)} rootCalls=${String(arms.workflow.rootClassCalls)}; extension arm '${arms.extension.status}' reason=${String(arms.extension.fallbackReason)} result=${JSON.stringify(arms.extension.result)} rootCalls=${String(arms.extension.rootClassCalls)} (DEF-7 parity: both arms fold 'budget-floor' and both redeem the synthesis from the held reserve)`
3241
+ },
3242
+ artifacts: [
3243
+ jsonArtifact("arms.json", {
3244
+ workflow: {
3245
+ ...arms.workflow,
3246
+ entries: void 0
3247
+ },
3248
+ extension: {
3249
+ ...arms.extension,
3250
+ entries: void 0
3251
+ }
3252
+ }),
3253
+ jsonArtifact("journal-workflow.json", arms.workflow.entries),
3254
+ jsonArtifact("journal-extension.json", arms.extension.entries)
3255
+ ]
3256
+ };
3257
+ }
3258
+ };
3259
+ /**
3260
+ * The c7 resume famine, closed (RV2201). The kill-mid-fan-out journal
3261
+ * of the seventh subscription run resumed to an ACCEPTED acceptance and
3262
+ * then starved: recovered agents were re-counted against
3263
+ * lifetimeSpawnCap, the judge fell to a typed decline naming the cap,
3264
+ * and the synthesis spawn died exhausted with the money reserve intact.
3265
+ * The counter now counts a scope a single time across the run's whole
3266
+ * life, so the exact-cap resume finishes its dossier.
3267
+ */
3268
+ const resumeSpawnFamine = {
3269
+ name: "resume-spawn-famine",
3270
+ doctrine: "a resume re-admits recovered agents without re-counting them against lifetimeSpawnCap (RV2201): the kill-mid-fan-out journal resumes to the finished dossier at the EXACT cap, with no 'lifetime spawn cap' decline journaled and only the unsettled workers re-paid; the c7 resume starved its judge and synthesis on re-counted admissions",
3271
+ async run() {
3272
+ const makeAdapter = () => {
3406
3273
  const calls = [];
3407
- let finishAttempts = 0;
3408
- const adapter = {
3274
+ return {
3409
3275
  id: "fake",
3410
3276
  calls,
3411
3277
  caps: scriptedCaps,
@@ -3413,66 +3279,443 @@ const SCENARIOS = [
3413
3279
  const call = calls.length;
3414
3280
  calls.push(req);
3415
3281
  await Promise.resolve();
3416
- finishAttempts += 1;
3417
- const result = finishAttempts === 1 ? TRAP_FINISH : FIXED_FINISH;
3418
- for (const event of scriptedToolEvents("finish", { result }, `id-${String(call)}-0`)) yield event;
3282
+ if (scriptedAgentType(req) !== "") {
3283
+ yield {
3284
+ type: "text-delta",
3285
+ text: "gathered evidence"
3286
+ };
3287
+ yield {
3288
+ type: "finish",
3289
+ finish: { reason: "stop" },
3290
+ usage: {
3291
+ inputTokens: 10,
3292
+ outputTokens: 5,
3293
+ cacheReadTokens: 0,
3294
+ cacheWriteTokens: 0
3295
+ }
3296
+ };
3297
+ return;
3298
+ }
3299
+ if (!(req.tools ?? []).some((tool) => tool.name === "spawn_agent")) {
3300
+ for (const event of scriptedToolEvents("finish", { result: "the resumed dossier" }, `id-${String(call)}-0`)) yield event;
3301
+ yield {
3302
+ type: "finish",
3303
+ finish: { reason: "tool-calls" },
3304
+ usage: {
3305
+ inputTokens: 12,
3306
+ outputTokens: 8,
3307
+ cacheReadTokens: 0,
3308
+ cacheWriteTokens: 0
3309
+ }
3310
+ };
3311
+ return;
3312
+ }
3313
+ const turn = calls.filter((prior) => scriptedAgentType(prior) === "" && (prior.tools ?? []).some((tool) => tool.name === "spawn_agent")).length === 1 ? scriptedToolEvents("spawn_agent", {
3314
+ agentType: "worker",
3315
+ prompt: "gather A"
3316
+ }, `id-${String(call)}-0`).concat(scriptedToolEvents("spawn_agent", {
3317
+ agentType: "worker",
3318
+ prompt: "gather B"
3319
+ }, `id-${String(call)}-1`), scriptedToolEvents("spawn_agent", {
3320
+ agentType: "worker",
3321
+ prompt: "gather C"
3322
+ }, `id-${String(call)}-2`)) : scriptedToolEvents("finish", { result: "the coordination draft" }, `id-${String(call)}-0`);
3323
+ for (const event of turn) yield event;
3419
3324
  yield {
3420
3325
  type: "finish",
3421
3326
  finish: { reason: "tool-calls" },
3422
3327
  usage: {
3423
3328
  inputTokens: 10,
3424
- outputTokens: 40,
3329
+ outputTokens: 5,
3425
3330
  cacheReadTokens: 0,
3426
3331
  cacheWriteTokens: 0
3427
3332
  }
3428
3333
  };
3429
3334
  }
3430
3335
  };
3431
- const store = new InMemoryStore();
3432
- const engine = createEngine({
3433
- adapters: [adapter],
3434
- stores: { journal: store },
3435
- defaults: { routing: {
3336
+ };
3337
+ const LIFETIME_SPAWNS = 5;
3338
+ const wf = makeOrchestratorWorkflow("the resumable fan-out", {
3339
+ synthesis: {
3340
+ estCost: .006,
3341
+ limits: { maxOutputTokensPerTurn: 500 }
3342
+ },
3343
+ budget: { finalizeReserveUsd: 0 }
3344
+ });
3345
+ const makeEngine = (adapter, store) => createEngine({
3346
+ adapters: [adapter],
3347
+ stores: { journal: store },
3348
+ budgetDefaults: { lifetimeSpawnCap: LIFETIME_SPAWNS },
3349
+ defaults: {
3350
+ routing: {
3436
3351
  loop: "fake:model",
3437
- orchestrate: "fake:model"
3438
- } }
3352
+ orchestrate: "fake:model",
3353
+ synthesize: "fake:model"
3354
+ },
3355
+ profiles: { worker: { description: "the resumable gatherer" } }
3356
+ }
3357
+ });
3358
+ const storeA = new InMemoryStore();
3359
+ const seeded = await makeEngine(makeAdapter(), storeA).run(wf, void 0, {
3360
+ runId: "fault-resume-famine",
3361
+ budgetUsd: 10
3362
+ }).result;
3363
+ if (seeded.status !== "ok") throw new Error(`fault kit: the seeding run settled '${seeded.status}' instead of ok`);
3364
+ const entriesA = await storeA.load("fault-resume-famine");
3365
+ const firstWorkerOk = entriesA.findIndex((entry) => entry.kind === "agent" && entry.status === "ok");
3366
+ if (firstWorkerOk < 0) throw new Error("fault kit: the seeding journal carries no worker terminal to cut at");
3367
+ const cut = entriesA.slice(0, firstWorkerOk + 1);
3368
+ const storeB = new InMemoryStore();
3369
+ for (const entry of cut) await storeB.append("fault-resume-famine", entry);
3370
+ const resumeAdapter = makeAdapter();
3371
+ const resumed = await makeEngine(resumeAdapter, storeB).resume("fault-resume-famine", wf).result;
3372
+ const entriesB = await storeB.load("fault-resume-famine");
3373
+ const capDeclines = entriesB.filter((entry) => entry.kind === "decision" && JSON.stringify(entry.value ?? {}).includes("lifetime spawn cap"));
3374
+ const redemptionDeclines = entriesB.filter((entry) => entry.kind === "decision" && entry.value?.decisionType === "orchestrator_synthesis_redemption_declined");
3375
+ const liveWorkerCalls = resumeAdapter.calls.filter((req) => scriptedAgentType(req) !== "").length;
3376
+ const distinctAgentScopes = new Set(entriesB.filter((entry) => entry.kind === "agent" && entry.status === "running").map((entry) => `${entry.scope}#${String(entry.key)}`)).size;
3377
+ return {
3378
+ observation: {
3379
+ matched: resumed.status === "ok" && resumed.value === "the resumed dossier" && capDeclines.length === 0 && redemptionDeclines.length === 0 && liveWorkerCalls === 2 && distinctAgentScopes === LIFETIME_SPAWNS,
3380
+ detail: `resumed '${resumed.status}' result=${JSON.stringify(resumed.value)} at lifetimeSpawnCap ${String(LIFETIME_SPAWNS)} (${String(distinctAgentScopes)} distinct lifetime agent scopes); cap declines journaled=${String(capDeclines.length)}, redemption declines=${String(redemptionDeclines.length)}, live worker calls in the resumed segment=${String(liveWorkerCalls)} (the settled worker replayed free)`
3381
+ },
3382
+ artifacts: [
3383
+ jsonArtifact("journal-cut.json", cut),
3384
+ jsonArtifact("resume-outcome.json", {
3385
+ status: resumed.status,
3386
+ value: resumed.value ?? null,
3387
+ liveWorkerCalls
3388
+ }),
3389
+ jsonArtifact("journal-resumed.json", entriesB)
3390
+ ]
3391
+ };
3392
+ }
3393
+ };
3394
+ /**
3395
+ * The c3 validator trap, converging (RV2202). The third subscription
3396
+ * run was pinned between two verdicts: evidence-grade demanded a run id
3397
+ * beside the live-observed claim, the model wove the id into a cited
3398
+ * sentence, cited-value lawfully rejected the id as a value absent from
3399
+ * the cited window, and both repairs burned without an exit. The
3400
+ * evidence-grade reason now NAMES the safe composition, so the same
3401
+ * trap converges in one repair round with cited-value silent. It also
3402
+ * names the id ITSELF (RV2501): the 1.226.0 comparison run obeyed the
3403
+ * same reason with an id no artifact pattern could match, so the
3404
+ * instruction was unexecutable and both repairs burned again. And the
3405
+ * composition it names is now the DIRECT one (RV2502): with the id in
3406
+ * hand cited-value reads it as identity rather than as a value asserted
3407
+ * about the cited line, so the corrected finish here writes this run's
3408
+ * own id in the graded sentence BESIDE the citation, the exact shape
3409
+ * the old bundle could not accept from either side.
3410
+ */
3411
+ const validatorGuidanceConflict = {
3412
+ name: "validator-guidance-conflict",
3413
+ doctrine: "the evidence-grade reason names the SAFE composition against its cited-value sibling and names the run id it wants written (RV2202, RV2501, RV2502): the c3 trap finish repairs in ONE round by carrying THIS run's own id in the graded sentence, beside a source citation, with cited-value reading that id as identity and never rejecting; the third subscription run burned both repairs between the two verdicts, and the 1.226.0 comparison run burned both again on an id no artifact pattern could match",
3414
+ async run() {
3415
+ const TRAP_FINISH = "The reserve fold is live-observed under sustained load. The engine seals the journal at settle (`README.md:3`).";
3416
+ const FIXED_FINISH = "The reserve fold is live-observed under sustained load in run `fault-guidance-conflict`, where the engine seals the journal at settle (`README.md:3`).";
3417
+ const calls = [];
3418
+ let finishAttempts = 0;
3419
+ const adapter = {
3420
+ id: "fake",
3421
+ calls,
3422
+ caps: scriptedCaps,
3423
+ async *stream(req) {
3424
+ const call = calls.length;
3425
+ calls.push(req);
3426
+ await Promise.resolve();
3427
+ finishAttempts += 1;
3428
+ const result = finishAttempts === 1 ? TRAP_FINISH : FIXED_FINISH;
3429
+ for (const event of scriptedToolEvents("finish", { result }, `id-${String(call)}-0`)) yield event;
3430
+ yield {
3431
+ type: "finish",
3432
+ finish: { reason: "tool-calls" },
3433
+ usage: {
3434
+ inputTokens: 10,
3435
+ outputTokens: 40,
3436
+ cacheReadTokens: 0,
3437
+ cacheWriteTokens: 0
3438
+ }
3439
+ };
3440
+ }
3441
+ };
3442
+ const store = new InMemoryStore();
3443
+ const engine = createEngine({
3444
+ adapters: [adapter],
3445
+ stores: { journal: store },
3446
+ defaults: { routing: {
3447
+ loop: "fake:model",
3448
+ orchestrate: "fake:model"
3449
+ } }
3450
+ });
3451
+ const resolveSource = (target) => target.path === "README.md" ? "the rulvar engine\nholds one denominator\nthe engine seals the journal at settle\n" : void 0;
3452
+ const wf = makeOrchestratorWorkflow("the guidance trap", { finishValidation: {
3453
+ validators: [evidenceGradeValidator(), citedValueValidator({
3454
+ resolve: resolveSource,
3455
+ window: 2
3456
+ })],
3457
+ maxRepairs: 2,
3458
+ repairTurnReserve: 2
3459
+ } });
3460
+ const outcome = await engine.run(wf, void 0, {
3461
+ runId: "fault-guidance-conflict",
3462
+ budgetUsd: 10
3463
+ }).result;
3464
+ const entries = await store.load("fault-guidance-conflict");
3465
+ const repairRequest = calls[1];
3466
+ const repairBytes = JSON.stringify(repairRequest?.messages ?? []);
3467
+ const guidanceQuoted = repairBytes.includes("write this run's id fault-guidance-conflict") && repairBytes.includes("may share a sentence with a source citation");
3468
+ const citedValueNamed = repairBytes.includes("cited-value reads a run id as identity");
3469
+ const decisionsText = JSON.stringify(entries.filter((entry) => entry.kind === "decision").map((entry) => entry.value ?? null));
3470
+ const citedValueRejected = decisionsText.includes("\"cited-value\"") ? decisionsText.includes("not present inside the cited window") : false;
3471
+ return {
3472
+ observation: {
3473
+ matched: outcome.status === "ok" && outcome.value === FIXED_FINISH && finishAttempts === 2 && guidanceQuoted && citedValueNamed && !citedValueRejected,
3474
+ detail: `run '${outcome.status}' after ${String(finishAttempts)} finish attempt(s); the repair exchange named the run id and the shared-sentence composition (${String(guidanceQuoted)}) and named the identity reading (${String(citedValueNamed)}); cited-value rejected=${String(citedValueRejected)}; final result carries this run's own id beside the citation in the graded sentence: ${String(outcome.value === FIXED_FINISH)}`
3475
+ },
3476
+ artifacts: [
3477
+ jsonArtifact("outcome.json", {
3478
+ status: outcome.status,
3479
+ value: outcome.value ?? null
3480
+ }),
3481
+ {
3482
+ name: "repair-request.json",
3483
+ content: repairBytes
3484
+ },
3485
+ jsonArtifact("journal.json", entries)
3486
+ ]
3487
+ };
3488
+ }
3489
+ };
3490
+ const TAIL_POOL_READING = "A failed audit write does not mask success (`src/exec.ts:256-296`).";
3491
+ const TAIL_DRAFT_INVERTED = "draft: an audit-write failure does not turn success into failure [src/exec.ts:256-296].";
3492
+ const TAIL_FINAL_INVERTED = "final: an audit-write failure does not turn success into failure [src/exec.ts:256-296].";
3493
+ const TAIL_FINAL_STILL_INVERTED = "final: the repaired text still flips the recorded outcome [src/exec.ts:256-296].";
3494
+ const TAIL_FINAL_CLEAN = "final: a failed audit write does not mask success [src/exec.ts:256-296].";
3495
+ const TAIL_FINDS = { contradictions: [{
3496
+ pair: 0,
3497
+ reason: "the draft inverts the recorded reading"
3498
+ }] };
3499
+ const TAIL_AGREES = { contradictions: [] };
3500
+ function tailHandles(req) {
3501
+ const handles = [];
3502
+ for (const msg of req.messages) for (const part of msg.parts) {
3503
+ if (part.type !== "tool-result") continue;
3504
+ const result = part.result;
3505
+ if (typeof result?.handle === "number") handles.push(result.handle);
3506
+ if (Array.isArray(result?.handles)) handles.push(...result.handles.filter((h) => typeof h === "number"));
3507
+ }
3508
+ return handles;
3509
+ }
3510
+ /**
3511
+ * One worker reads the span, the loop finishes with the inverted
3512
+ * draft, the composition finishes with `finals` in call order, and the
3513
+ * final stage judge answers through `judge` (a structured verdict or a
3514
+ * scripted wire death). Label keys ride first so the judge and the
3515
+ * composition route exactly, never through the prompt regex.
3516
+ */
3517
+ function tailAdapter(options) {
3518
+ let judgeCalls = 0;
3519
+ let synthCalls = 0;
3520
+ let loopTurns = 0;
3521
+ return new FakeAdapter({ agents: {
3522
+ "claim-consistency-judge-final": () => options.judge(judgeCalls += 1),
3523
+ "final-composition": () => fakeToolCalls({
3524
+ name: "finish",
3525
+ args: { result: options.finals[Math.min(synthCalls++, options.finals.length - 1)] }
3526
+ }),
3527
+ worker: TAIL_POOL_READING,
3528
+ "*": (call) => {
3529
+ loopTurns += 1;
3530
+ if (loopTurns === 1) return fakeToolCalls({
3531
+ name: "spawn_agent",
3532
+ args: {
3533
+ agentType: "worker",
3534
+ prompt: "read the recorded span"
3535
+ }
3536
+ });
3537
+ if (loopTurns === 2) return fakeToolCalls({
3538
+ name: "await_all",
3539
+ args: { handles: tailHandles(call.req) }
3540
+ });
3541
+ return fakeToolCalls({
3542
+ name: "finish",
3543
+ args: { result: TAIL_DRAFT_INVERTED }
3439
3544
  });
3440
- const resolveSource = (target) => target.path === "README.md" ? "the rulvar engine\nholds one denominator\nthe engine seals the journal at settle\n" : void 0;
3441
- const wf = makeOrchestratorWorkflow("the guidance trap", { finishValidation: {
3442
- validators: [evidenceGradeValidator(), citedValueValidator({
3443
- resolve: resolveSource,
3444
- window: 2
3445
- })],
3446
- maxRepairs: 2,
3447
- repairTurnReserve: 2
3448
- } });
3449
- const outcome = await engine.run(wf, void 0, {
3450
- runId: "fault-guidance-conflict",
3545
+ }
3546
+ } });
3547
+ }
3548
+ function tailEngine(adapter) {
3549
+ const store = new InMemoryStore();
3550
+ return {
3551
+ engine: createEngine({
3552
+ adapters: [adapter],
3553
+ stores: { journal: store },
3554
+ defaults: {
3555
+ routing: {
3556
+ loop: FAKE_MODEL_REF,
3557
+ orchestrate: FAKE_MODEL_REF,
3558
+ synthesize: FAKE_MODEL_REF,
3559
+ extract: FAKE_MODEL_REF
3560
+ },
3561
+ profiles: { worker: { description: "reads one span" } }
3562
+ }
3563
+ }),
3564
+ store
3565
+ };
3566
+ }
3567
+ const TAIL_OPTS = {
3568
+ acceptance: { childPolicy: "all-ok" },
3569
+ synthesis: { limits: { maxTurns: 3 } }
3570
+ };
3571
+ function tailSpans(entries) {
3572
+ const settled = entries.filter((entry) => entry.kind === "agent" && entry.status !== "running");
3573
+ return {
3574
+ compositions: settled.filter((entry) => entry.costAttribution?.label === "final-composition"),
3575
+ judges: settled.filter((entry) => entry.costAttribution?.label === "claim-consistency-judge-final")
3576
+ };
3577
+ }
3578
+ const SCENARIOS = [
3579
+ inFlightExposure,
3580
+ duplicateQuotaRule,
3581
+ tornJsonlTail,
3582
+ gluedJsonlTail,
3583
+ crashResumeSettleBoundary,
3584
+ pricingRotationUncoveredTail,
3585
+ unknownProviderId,
3586
+ nanStatementRefusal,
3587
+ tokenMismatchDivergence,
3588
+ auditMissingFieldFinding,
3589
+ anthropic1hPriced,
3590
+ pauseTurnUnits,
3591
+ preAdmissionCountRefusal,
3592
+ forcedFinishCompletion,
3593
+ settlementTerminalHonesty,
3594
+ ttlLiveBudgetParity,
3595
+ pauseTurnRealAdapter,
3596
+ statementSettleableGuard,
3597
+ supersededTerminalHonesty,
3598
+ tierCrossingLiveParity,
3599
+ benchmarkPrimaryPreflightParity,
3600
+ benchmarkRecoveryRootExposure,
3601
+ parityQuiescenceDeadlock,
3602
+ paritySequentialRosterFloor,
3603
+ parityReserveLineRedemption,
3604
+ resumeSpawnFamine,
3605
+ validatorGuidanceConflict,
3606
+ {
3607
+ name: "repair-round-honesty",
3608
+ doctrine: "the bounded post judge repair consumes the named finding (RV3307): one more composition carries the findings, the re-judge clears it, the run settles ok with the meta describing the repaired document (judgedStage 'final', findings 0, judgedHash equal to the shipped finalHash), two compositions and two final judge passes in the journal, and the invoice in the same denominator as the envelope",
3609
+ async run() {
3610
+ const { engine, store } = tailEngine(tailAdapter({
3611
+ judge: (call) => call === 1 ? TAIL_FINDS : TAIL_AGREES,
3612
+ finals: [TAIL_FINAL_INVERTED, TAIL_FINAL_CLEAN]
3613
+ }));
3614
+ const outcome = await engine.run(makeOrchestratorWorkflow("audit the executor", {
3615
+ ...TAIL_OPTS,
3616
+ claimConsistency: {
3617
+ stage: "final",
3618
+ onFound: "repair"
3619
+ }
3620
+ }), void 0, {
3621
+ runId: "fault-repair-honesty",
3451
3622
  budgetUsd: 10
3452
3623
  }).result;
3453
- const entries = await store.load("fault-guidance-conflict");
3454
- const repairRequest = calls[1];
3455
- const repairBytes = JSON.stringify(repairRequest?.messages ?? []);
3456
- const guidanceQuoted = repairBytes.includes("write this run's id fault-guidance-conflict") && repairBytes.includes("may share a sentence with a source citation");
3457
- const citedValueNamed = repairBytes.includes("cited-value reads a run id as identity");
3458
- const decisionsText = JSON.stringify(entries.filter((entry) => entry.kind === "decision").map((entry) => entry.value ?? null));
3459
- const citedValueRejected = decisionsText.includes("\"cited-value\"") ? decisionsText.includes("not present inside the cited window") : false;
3624
+ const value = outcome.value;
3625
+ const entries = await store.load("fault-repair-honesty");
3626
+ const { compositions, judges } = tailSpans(entries);
3627
+ const invoice = invoiceFromJournal(entries, () => 0);
3460
3628
  return {
3461
3629
  observation: {
3462
- matched: outcome.status === "ok" && outcome.value === FIXED_FINISH && finishAttempts === 2 && guidanceQuoted && citedValueNamed && !citedValueRejected,
3463
- detail: `run '${outcome.status}' after ${String(finishAttempts)} finish attempt(s); the repair exchange named the run id and the shared-sentence composition (${String(guidanceQuoted)}) and named the identity reading (${String(citedValueNamed)}); cited-value rejected=${String(citedValueRejected)}; final result carries this run's own id beside the citation in the graded sentence: ${String(outcome.value === FIXED_FINISH)}`
3630
+ matched: outcome.status === "ok" && value?.result === TAIL_FINAL_CLEAN && Array.isArray(value.claimContradictions) && value.claimContradictions.length === 0 && value.claimConsistencyMeta?.judgedStage === "final" && value.claimConsistencyMeta.findings === 0 && typeof value.claimConsistencyMeta.judgedHash === "string" && value.claimConsistencyMeta.judgedHash === value.draftToFinal?.finalHash && compositions.length === 2 && judges.length === 2 && [...compositions, ...judges].every((entry) => entry.status === "ok") && typeof outcome.envelope.wireRequests === "number" && outcome.envelope.wireRequests === invoice.cardinality.wireRequests,
3631
+ detail: `run '${outcome.status}' shipped ${value?.result === TAIL_FINAL_CLEAN ? "the repaired document" : "an unexpected document"}; meta judgedStage='${String(value?.claimConsistencyMeta?.judgedStage)}' findings=${String(value?.claimConsistencyMeta?.findings)} judgedHash==finalHash=${String(value?.claimConsistencyMeta?.judgedHash === value?.draftToFinal?.finalHash)}; ${String(compositions.length)} composition(s), ${String(judges.length)} final judge pass(es); wires ${String(outcome.envelope.wireRequests)} == invoice ` + String(invoice.cardinality.wireRequests)
3464
3632
  },
3465
- artifacts: [
3466
- jsonArtifact("outcome.json", {
3467
- status: outcome.status,
3468
- value: outcome.value ?? null
3469
- }),
3470
- {
3471
- name: "repair-request.json",
3472
- content: repairBytes
3473
- },
3474
- jsonArtifact("journal.json", entries)
3475
- ]
3633
+ artifacts: [jsonArtifact("outcome.json", {
3634
+ status: outcome.status,
3635
+ value: outcome.value ?? null,
3636
+ envelope: outcome.envelope
3637
+ }), jsonArtifact("journal.json", entries)]
3638
+ };
3639
+ }
3640
+ },
3641
+ {
3642
+ name: "repair-survivor-refusal",
3643
+ doctrine: "findings that survive the bounded repair round fail the run typed (RV3307): source 'orchestrator_claim_consistency', repairsUsed 1, preRepairHash distinct from repairedHash (the round demonstrably produced a different document and the judge still refused it), two compositions and two final judge passes paid, never a silent ok over the surviving contradiction",
3644
+ async run() {
3645
+ const { engine, store } = tailEngine(tailAdapter({
3646
+ judge: () => TAIL_FINDS,
3647
+ finals: [TAIL_FINAL_INVERTED, TAIL_FINAL_STILL_INVERTED]
3648
+ }));
3649
+ const outcome = await engine.run(makeOrchestratorWorkflow("audit the executor", {
3650
+ ...TAIL_OPTS,
3651
+ claimConsistency: {
3652
+ stage: "final",
3653
+ onFound: "repair"
3654
+ }
3655
+ }), void 0, {
3656
+ runId: "fault-repair-survivor",
3657
+ budgetUsd: 10
3658
+ }).result;
3659
+ const data = outcome.error?.data ?? {};
3660
+ const entries = await store.load("fault-repair-survivor");
3661
+ const { compositions, judges } = tailSpans(entries);
3662
+ return {
3663
+ observation: {
3664
+ matched: outcome.status === "error" && (outcome.error?.message ?? "").includes("after the bounded repair round") && data.source === "orchestrator_claim_consistency" && data.repairsUsed === 1 && typeof data.preRepairHash === "string" && typeof data.repairedHash === "string" && data.preRepairHash !== data.repairedHash && compositions.length === 2 && judges.length === 2,
3665
+ detail: `run '${outcome.status}': ${outcome.error?.message ?? ""}; repairsUsed=${String(data.repairsUsed)}, hashes distinct=${String(data.preRepairHash !== data.repairedHash)}, ${String(compositions.length)} composition(s), ${String(judges.length)} final judge pass(es)`
3666
+ },
3667
+ artifacts: [jsonArtifact("outcome.json", {
3668
+ status: outcome.status,
3669
+ error: outcome.error ?? null
3670
+ }), jsonArtifact("journal.json", entries)]
3671
+ };
3672
+ }
3673
+ },
3674
+ {
3675
+ name: "claim-judge-dead-armed-refusal",
3676
+ doctrine: "a final stage judge that dies on the wire under an armed posture fails the run typed for both 'fail' and 'repair' (RV3307), each message naming its armed posture, with exactly one composition paid and no repair round dispatched, never a silent settle over findings nobody ruled on",
3677
+ async run() {
3678
+ const judgeDeath = () => fakeWireError({
3679
+ code: "agent",
3680
+ message: "the judge died mid stream",
3681
+ retryable: false,
3682
+ data: {}
3683
+ });
3684
+ const runs = [];
3685
+ const journals = {};
3686
+ for (const posture of ["fail", "repair"]) {
3687
+ const { engine, store } = tailEngine(tailAdapter({
3688
+ judge: judgeDeath,
3689
+ finals: [TAIL_FINAL_INVERTED]
3690
+ }));
3691
+ const runId = `fault-dead-judge-${posture}`;
3692
+ const outcome = await engine.run(makeOrchestratorWorkflow("audit the executor", {
3693
+ ...TAIL_OPTS,
3694
+ claimConsistency: {
3695
+ stage: "final",
3696
+ onFound: posture
3697
+ }
3698
+ }), void 0, {
3699
+ runId,
3700
+ budgetUsd: 10
3701
+ }).result;
3702
+ const entries = await store.load(runId);
3703
+ const { compositions, judges } = tailSpans(entries);
3704
+ journals[posture] = entries;
3705
+ runs.push({
3706
+ posture,
3707
+ status: outcome.status,
3708
+ message: outcome.error?.message ?? "",
3709
+ compositions: compositions.length,
3710
+ judges: judges.length
3711
+ });
3712
+ }
3713
+ return {
3714
+ observation: {
3715
+ matched: runs.every((run) => run.status === "error" && run.message.includes(`armed ${run.posture} posture`) && run.compositions === 1 && run.judges === 1),
3716
+ detail: runs.map((run) => `${run.posture}: '${run.status}' (${run.compositions} composition(s), ${run.judges} judge span(s)) ${run.message.slice(0, 120)}`).join(" | ")
3717
+ },
3718
+ artifacts: [jsonArtifact("runs.json", runs), jsonArtifact("journals.json", journals)]
3476
3719
  };
3477
3720
  }
3478
3721
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rulvar/evals",
3
- "version": "1.238.0",
3
+ "version": "1.239.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/anthropic": "1.238.0",
26
- "@rulvar/openai": "1.238.0",
27
- "@rulvar/core": "1.238.0",
28
- "@rulvar/plan": "1.238.0",
29
- "@rulvar/testing": "1.238.0"
25
+ "@rulvar/anthropic": "1.239.0",
26
+ "@rulvar/core": "1.239.0",
27
+ "@rulvar/openai": "1.239.0",
28
+ "@rulvar/testing": "1.239.0",
29
+ "@rulvar/plan": "1.239.0"
30
30
  },
31
31
  "devDependencies": {
32
32
  "@types/node": "^22.20.1",