| import assert from 'node:assert/strict'; |
| import { readFile } from 'node:fs/promises'; |
| import { join } from 'node:path'; |
| import { describe, test } from 'node:test'; |
| import { readFixedPromptWal } from '../fixed-prompt-controller.js'; |
| import { promptAcceptanceNoiseBand } from '../prompt-acceptance-policy.js'; |
| import { |
| execFileAsync, |
| evidenceRefsFor, |
| fakeMetaAgent, |
| makeTasks, |
| runLoop, |
| taskIndex, |
| withHarness, |
| type MetaAgentPromptInput, |
| } from './helpers/prompt-optimization-loop-harness.js'; |
| |
| describe('runPromptOptimizationLoop', () => { |
| test('defaults the acceptance noise band to a 1.96 z-score', async () => { |
| await withHarness(async (harness) => { |
| const result = await runLoop(harness, { |
| heldInTasks: makeTasks('hin', 4), |
| heldOutTasks: makeTasks('hout', 2), |
| rewardFor: (_roundId, taskId) => taskIndex(taskId) % 2, |
| rounds: 1, |
| baselineRuns: 1, |
| }); |
| |
| assert.equal( |
| result.baseline.heldIn.noiseBand, |
| promptAcceptanceNoiseBand({ |
| sampleSize: 4, |
| passRate: 0.5, |
| baselineRunCount: 1, |
| zScore: 1.96, |
| }), |
| ); |
| }); |
| }); |
| |
| test('runs a budget-matched sampling arm before each candidate and records its Pass@1 evidence', async () => { |
| await withHarness(async (harness) => { |
| const heldInTasks = makeTasks('hin', 4); |
| const heldOutTasks = makeTasks('hout', 2); |
| const result = await runLoop(harness, { |
| heldInTasks, |
| heldOutTasks, |
| rewardFor: (roundId, taskId) => { |
| if (taskId.startsWith('hout-')) return 1; |
| if (roundId.startsWith('baseline-')) return taskIndex(taskId) < 2 ? 1 : 0; |
| if (roundId.startsWith('sampling-')) return taskIndex(taskId) < 2 ? 1 : 0; |
| return taskIndex(taskId) < 4 ? 1 : 0; |
| }, |
| rounds: 1, |
| baselineRuns: 1, |
| }); |
| |
| assert.equal(result.decisions[0]?.decision, 'keep'); |
| assert.equal(result.decisions[0]?.metrics.samplingBaseline?.heldIn.taskCount, 4); |
| assert.equal(result.decisions[0]?.metrics.samplingBaseline?.heldIn.passEligibleRate, 0.5); |
| const events = await readFixedPromptWal(harness.resultsJsonlPath); |
| const sampling = events.filter((event) => event.roundId === 'sampling-0'); |
| const candidate = events.filter((event) => event.roundId === 'round-0'); |
| assert.equal(sampling.filter((event) => event.type === 'task_completed').length, 4); |
| const samplingAttempts = ( |
| await readFile(`${harness.resultsJsonlPath}.attempts.jsonl`, 'utf8') |
| ) |
| .trim() |
| .split('\n') |
| .map((line) => JSON.parse(line) as { roundId: string; type: string }); |
| assert.equal(samplingAttempts.length, 4); |
| assert.ok(samplingAttempts.every((event) => event.type === 'task_attempt_started')); |
| assert.ok(samplingAttempts.every((event) => event.roundId === 'sampling-0')); |
| assert.equal( |
| candidate.filter( |
| (event) => event.type === 'task_completed' && event.taskId.startsWith('hin-'), |
| ).length, |
| 4, |
| ); |
| assert.ok( |
| events.findIndex((event) => event.roundId === 'sampling-0') < |
| events.findIndex((event) => event.type === 'prompt_candidate_committed'), |
| ); |
| const replayTaskRuns: string[] = []; |
| const replayed = await runLoop(harness, { |
| heldInTasks, |
| heldOutTasks, |
| rewardFor: (roundId, taskId) => { |
| if (taskId.startsWith('hout-')) return 1; |
| if (roundId.startsWith('baseline-') || roundId.startsWith('sampling-')) { |
| return taskIndex(taskId) < 2 ? 1 : 0; |
| } |
| return 1; |
| }, |
| rounds: 1, |
| baselineRuns: 1, |
| onTaskRun: (roundId, taskId) => replayTaskRuns.push(`${roundId}:${taskId}`), |
| }); |
| assert.deepEqual(replayed.decisions, result.decisions); |
| assert.deepEqual(replayTaskRuns, []); |
| }); |
| }); |
| |
| test('stops after replaying a complete sampling arm when the budget is already exhausted', async () => { |
| await withHarness(async (harness) => { |
| const heldInTasks = makeTasks('hin', 20); |
| const heldOutTasks = makeTasks('hout', 8); |
| const rewardFor = (roundId: string, taskId: string): number => { |
| if (taskId.startsWith('hout-')) return 1; |
| if (roundId.startsWith('baseline-')) return taskIndex(taskId) < 10 ? 1 : 0; |
| return 1; |
| }; |
| const first = await runLoop(harness, { |
| heldInTasks, |
| heldOutTasks, |
| rewardFor, |
| rounds: 1, |
| baselineRuns: 1, |
| costCeilingUsd: 0.959, |
| }); |
| assert.deepEqual(first.decisions, []); |
| assert.equal(first.stopReason, 'cost_ceiling_exceeded'); |
| |
| const resumedTaskRuns: string[] = []; |
| const resumed = await runLoop(harness, { |
| heldInTasks, |
| heldOutTasks, |
| rewardFor, |
| rounds: 1, |
| baselineRuns: 1, |
| costCeilingUsd: 0.959, |
| onTaskRun: (roundId, taskId) => resumedTaskRuns.push(`${roundId}:${taskId}`), |
| }); |
| assert.deepEqual(resumed.decisions, []); |
| assert.equal(resumed.stopReason, 'cost_ceiling_exceeded'); |
| assert.deepEqual(resumedTaskRuns, []); |
| }); |
| }); |
| |
| test('keeps an improving candidate, discards a regressing one, and reports a passing smoke', async () => { |
| await withHarness(async (harness) => { |
| const heldInTasks = makeTasks('hin', 20); |
| const heldOutTasks = makeTasks('hout', 8); |
| // baseline held-in 0.5; round-0 jumps to 1.0 (KEEP); round-1 collapses to |
| // 0.0 (DISCARD). Held-out stays flat at 0.5 so it never gates. |
| const rewardFor = (roundId: string, taskId: string): number => { |
| const index = taskIndex(taskId); |
| if (taskId.startsWith('hout-')) return index < 4 ? 1 : 0; |
| if (roundId.startsWith('baseline-')) return index < 10 ? 1 : 0; |
| return roundId === 'round-0' ? 1 : 0; |
| }; |
| |
| const result = await runLoop(harness, { |
| heldInTasks, |
| heldOutTasks, |
| rewardFor, |
| rounds: 2, |
| baselineRuns: 2, |
| }); |
| |
| assert.equal(result.decisions.length, 2); |
| assert.equal(result.decisions[0]?.decision, 'keep'); |
| assert.equal(result.decisions[0]?.reason, 'held_in_improved'); |
| assert.equal(result.decisions[1]?.decision, 'discard'); |
| assert.equal(result.decisions[1]?.reason, 'held_in_regressed'); |
| assert.equal(result.keptCount, 1); |
| assert.equal(result.stopReason, 'rounds_complete'); |
| |
| // The kept lineage is round-0's candidate; round-1 was rolled back so HEAD |
| // and the prompt return to the kept state. |
| assert.equal(result.lastKeptCommitSha, result.decisions[0]?.candidateCommitSha); |
| const head = ( |
| await execFileAsync('git', ['rev-parse', 'HEAD'], { cwd: harness.repoDir }) |
| ).stdout.trim(); |
| assert.equal(head, result.lastKeptCommitSha); |
| assert.equal(await readFile(harness.systemPromptPath, 'utf8'), 'candidate prompt round-0\n'); |
| |
| assert.equal(result.smoke.status, 'pass'); |
| assert.deepEqual(result.smoke.decisions, { keep: 1, discard: 1 }); |
| assert.equal(result.smoke.observedRounds, 2); |
| assert.equal(result.smoke.quarantineCount, 0); |
| assert.equal(result.smoke.taskEvents.infraFailed, 0); |
| assert.equal(result.smoke.taskEvents.plumbingFailed, 0); |
| }); |
| }); |
| |
| test('persists attribution and feeds held-in-only R2 feedback into the next prompt', async () => { |
| await withHarness(async (harness) => { |
| const promptInputs: MetaAgentPromptInput[] = []; |
| const heldInTasks = makeTasks('hin', 2); |
| const heldOutTasks = makeTasks('hout', 1); |
| const rewardFor = (roundId: string, taskId: string): number => { |
| if (taskId.startsWith('hout-')) return 1; |
| if (roundId.startsWith('baseline-')) return taskIndex(taskId) === 0 ? 1 : 0; |
| return roundId === 'round-0' ? 0 : taskIndex(taskId) === 0 ? 1 : 0; |
| }; |
| |
| await runLoop(harness, { |
| heldInTasks, |
| heldOutTasks, |
| rewardFor, |
| rounds: 2, |
| baselineRuns: 2, |
| metaAgent: async (promptInput) => { |
| promptInputs.push(promptInput); |
| return { |
| systemPrompt: `candidate prompt ${promptInput.roundId}\n`, |
| summary: `tuned for ${promptInput.roundId}`, |
| candidateRationale: { |
| editedSurface: 'system_prompt', |
| evidenceRefs: evidenceRefsFor(promptInput), |
| hypothesis: 'avoid losing held-in scored artifacts', |
| targetedFix: 'state artifact completion constraints plainly', |
| predictedFixes: ['hin-1'], |
| riskTasks: ['hin-0'], |
| ...(evidenceRefsFor(promptInput).length === 0 |
| ? { failurePattern: 'coverage_regression' as const } |
| : {}), |
| }, |
| }; |
| }, |
| }); |
| |
| assert.equal(promptInputs.length, 2); |
| assert.ok(promptInputs[0]?.rsiAnalysis); |
| assert.equal(promptInputs[0]?.promptAttribution, undefined); |
| assert.ok(promptInputs[1]?.rsiAnalysis); |
| assert.deepEqual(promptInputs[1]?.promptAttribution?.predictedFixes, [ |
| { taskId: 'hin-1', outcome: 'unchanged' }, |
| ]); |
| assert.deepEqual(promptInputs[1]?.promptAttribution?.riskTasks, [ |
| { taskId: 'hin-0', outcome: 'regressed' }, |
| ]); |
| assert.equal('decisionReason' in (promptInputs[1]?.promptAttribution ?? {}), false); |
| assert.equal(JSON.stringify(promptInputs[1]?.promptAttribution).includes('hout-'), false); |
| assert.equal(JSON.stringify(promptInputs[1]?.promptAttribution).includes('held_out'), false); |
| |
| const events = await readFixedPromptWal(harness.resultsJsonlPath); |
| assert.equal(events.filter((event) => event.type === 'rsi_controller_attribution').length, 2); |
| for (const decision of events.filter((event) => event.type === 'prompt_candidate_decided')) { |
| const decisionIndex = events.indexOf(decision); |
| const attributionIndex = events.findIndex( |
| (event) => |
| event.type === 'rsi_controller_attribution' && |
| event.runId === decision.runId && |
| event.roundId === decision.roundId && |
| event.candidateCommitSha === decision.candidateCommitSha, |
| ); |
| assert.ok(attributionIndex > decisionIndex); |
| } |
| }); |
| }); |
| |
| test('feeds sanitized verifier failure summaries into prompt digests', async () => { |
| await withHarness(async (harness) => { |
| const promptInputs: MetaAgentPromptInput[] = []; |
| const heldInTasks = makeTasks('hin', 2); |
| const heldOutTasks = makeTasks('hout', 1); |
| |
| await runLoop(harness, { |
| heldInTasks, |
| heldOutTasks, |
| rewardFor: (_roundId, taskId) => (taskId === 'hin-0' ? 0 : 1), |
| verifierFailureSummaryFor: (roundId, taskId) => |
| roundId === 'baseline-0' && taskId === 'hin-0' |
| ? 'output_assertion_failed integer_output_off_by_one' |
| : undefined, |
| rounds: 1, |
| baselineRuns: 1, |
| metaAgent: async (promptInput) => { |
| promptInputs.push(promptInput); |
| return { |
| systemPrompt: `candidate prompt ${promptInput.roundId}\n`, |
| summary: `tuned for ${promptInput.roundId}`, |
| candidateRationale: { |
| editedSurface: 'system_prompt', |
| evidenceRefs: evidenceRefsFor(promptInput), |
| hypothesis: 'integer output selection can be made less ambiguous', |
| targetedFix: 'prefer the task requested count when multiple totals appear', |
| predictedFixes: ['hin-0'], |
| riskTasks: ['hin-1'], |
| ...(evidenceRefsFor(promptInput).length === 0 |
| ? { failurePattern: 'verification_failed' as const } |
| : {}), |
| }, |
| }; |
| }, |
| }); |
| |
| assert.equal(promptInputs.length, 1); |
| assert.equal( |
| promptInputs[0]?.heldInDigests.find((digest) => digest.taskId === 'hin-0')?.summary, |
| 'output_assertion_failed integer_output_off_by_one', |
| ); |
| assert.equal(JSON.stringify(promptInputs[0]).includes('79586'), false); |
| }); |
| }); |
| |
| test('matches attribution root cause against prompt-time analysis after coverage signal is fixed', async () => { |
| await withHarness(async (harness) => { |
| const promptInputs: MetaAgentPromptInput[] = []; |
| const heldInTasks = makeTasks('hin', 2); |
| const heldOutTasks = makeTasks('hout', 1); |
| const rewardFor = (roundId: string, taskId: string): number => { |
| if (taskId.startsWith('hout-')) return 1; |
| if (roundId.startsWith('baseline-')) return 1; |
| return roundId === 'round-0' && taskId === 'hin-0' ? 0 : 1; |
| }; |
| |
| await runLoop(harness, { |
| heldInTasks, |
| heldOutTasks, |
| rewardFor, |
| rounds: 2, |
| baselineRuns: 2, |
| shouldFail: (roundId, taskId) => roundId === 'round-0' && taskId === 'hin-0', |
| metaAgent: async (promptInput) => { |
| promptInputs.push(promptInput); |
| return { |
| systemPrompt: `candidate prompt ${promptInput.roundId}\n`, |
| summary: `tuned for ${promptInput.roundId}`, |
| candidateRationale: { |
| editedSurface: 'system_prompt', |
| evidenceRefs: evidenceRefsFor(promptInput), |
| hypothesis: 'restore coverage for held-in tasks', |
| targetedFix: 'make artifact completion constraints explicit', |
| predictedFixes: ['hin-0'], |
| riskTasks: [], |
| ...(evidenceRefsFor(promptInput).length === 0 |
| ? { failurePattern: 'coverage_regression' as const } |
| : {}), |
| }, |
| }; |
| }, |
| }); |
| |
| const promptTimeCoverageSignal = promptInputs[1]?.rsiAnalysis?.signals.find( |
| (signal) => signal.kind === 'coverage_regression', |
| ); |
| assert.ok(promptTimeCoverageSignal); |
| const events = await readFixedPromptWal(harness.resultsJsonlPath); |
| const secondAttribution = events.find( |
| (event) => event.type === 'rsi_controller_attribution' && event.roundId === 'round-1', |
| ); |
| assert.equal(secondAttribution?.type, 'rsi_controller_attribution'); |
| if (secondAttribution?.type === 'rsi_controller_attribution') { |
| assert.deepEqual(secondAttribution.evidenceRefs, [promptTimeCoverageSignal.id]); |
| assert.deepEqual(secondAttribution.predictedFixes, [ |
| { taskId: 'hin-0', outcome: 'unchanged' }, |
| ]); |
| assert.equal(secondAttribution.rootCauseSignalMatch, 'matched'); |
| } |
| }); |
| }); |
| |
| test('does not teach held-out coverage discard reasons to the next prompt', async () => { |
| await withHarness(async (harness) => { |
| const promptInputs: MetaAgentPromptInput[] = []; |
| const heldInTasks = makeTasks('hin', 20); |
| const heldOutTasks = makeTasks('hout', 2); |
| const rewardFor = (roundId: string, taskId: string): number => { |
| if (taskId.startsWith('hout-')) return 1; |
| if (roundId.startsWith('baseline-')) return taskIndex(taskId) < 10 ? 1 : 0; |
| return 1; |
| }; |
| |
| await runLoop(harness, { |
| heldInTasks, |
| heldOutTasks, |
| rewardFor, |
| rounds: 2, |
| baselineRuns: 2, |
| shouldFail: (roundId, taskId) => roundId === 'round-0' && taskId === 'hout-1', |
| metaAgent: async (promptInput) => { |
| promptInputs.push(promptInput); |
| return { |
| systemPrompt: `candidate prompt ${promptInput.roundId}\n`, |
| summary: `tuned for ${promptInput.roundId}`, |
| candidateRationale: { |
| editedSurface: 'system_prompt', |
| evidenceRefs: evidenceRefsFor(promptInput), |
| hypothesis: 'avoid losing held-in scored artifacts', |
| targetedFix: 'state artifact completion constraints plainly', |
| predictedFixes: ['hin-19'], |
| riskTasks: [], |
| ...(evidenceRefsFor(promptInput).length === 0 |
| ? { failurePattern: 'coverage_regression' as const } |
| : {}), |
| }, |
| }; |
| }, |
| }); |
| |
| assert.equal(promptInputs.length, 2); |
| const visible = JSON.stringify(promptInputs[1]?.promptAttribution); |
| assert.equal('decisionReason' in (promptInputs[1]?.promptAttribution ?? {}), false); |
| assert.equal(visible.includes('coverage_regressed'), false); |
| assert.equal(visible.includes('held_out'), false); |
| assert.equal(visible.includes('hout-'), false); |
| }); |
| }); |
| |
| test('discards every candidate when no change beats the noise band, leaving the original prompt', async () => { |
| await withHarness(async (harness) => { |
| const originalHead = ( |
| await execFileAsync('git', ['rev-parse', 'HEAD'], { cwd: harness.repoDir }) |
| ).stdout.trim(); |
| const heldInTasks = makeTasks('hin', 2); |
| const heldOutTasks = makeTasks('hout', 1); |
| // Flat pass rates every round: held-in stays at 0.5, well within the wide |
| // noise band of a two-task partition, so no candidate is ever kept. |
| const rewardFor = (_roundId: string, taskId: string): number => { |
| if (taskId.startsWith('hout-')) return 1; |
| return taskIndex(taskId) === 0 ? 1 : 0; |
| }; |
| |
| const result = await runLoop(harness, { |
| heldInTasks, |
| heldOutTasks, |
| rewardFor, |
| rounds: 2, |
| baselineRuns: 2, |
| }); |
| |
| assert.equal(result.keptCount, 0); |
| assert.deepEqual( |
| result.decisions.map((decision) => decision.decision), |
| ['discard', 'discard'], |
| ); |
| assert.equal(result.lastKeptCommitSha, originalHead); |
| const head = ( |
| await execFileAsync('git', ['rev-parse', 'HEAD'], { cwd: harness.repoDir }) |
| ).stdout.trim(); |
| assert.equal(head, originalHead); |
| assert.equal(await readFile(harness.systemPromptPath, 'utf8'), 'original prompt\n'); |
| // Zero keeps is a passing structural smoke for v1. |
| assert.equal(result.smoke.status, 'pass'); |
| assert.deepEqual(result.smoke.decisions, { keep: 0, discard: 2 }); |
| }); |
| }); |
| |
| test('keeps the calibrated baseline reference after a discard before the first keep', async () => { |
| await withHarness(async (harness) => { |
| const rewardFor = (roundId: string, taskId: string): number => { |
| if (taskId.startsWith('hout-')) return 1; |
| const index = taskIndex(taskId); |
| if (roundId === 'baseline-0') return index < 10 ? 1 : 0; |
| if (roundId === 'baseline-1') return index < 14 ? 1 : 0; |
| return index < 12 ? 1 : 0; |
| }; |
| |
| const result = await runLoop(harness, { |
| heldInTasks: makeTasks('hin', 20), |
| heldOutTasks: makeTasks('hout', 2), |
| rewardFor, |
| rounds: 2, |
| baselineRuns: 2, |
| }); |
| |
| assert.equal(result.decisions[0]?.decision, 'discard'); |
| assert.equal(result.baseline.heldIn.referencePassEligibleRate, 0.6); |
| assert.equal( |
| result.decisions[1]?.previousHeldInReferencePassEligibleRate, |
| result.baseline.heldIn.referencePassEligibleRate, |
| ); |
| }); |
| }); |
| |
| test('carries the banked reference after a keep instead of the raw kept sweep rate', async () => { |
| await withHarness(async (harness) => { |
| const rewardFor = (roundId: string, taskId: string): number => { |
| const index = taskIndex(taskId); |
| if (taskId.startsWith('hout-')) return index < 2 ? 1 : 0; |
| if (roundId.startsWith('baseline-')) return index < 10 ? 1 : 0; |
| if (roundId === 'round-0') return index < 6 || index >= 10 ? 1 : 0; |
| return index < 17 ? 1 : 0; |
| }; |
| |
| const result = await runLoop(harness, { |
| heldInTasks: makeTasks('hin', 20), |
| heldOutTasks: makeTasks('hout', 4), |
| rewardFor, |
| rounds: 2, |
| baselineRuns: 2, |
| zScore: 0.5, |
| }); |
| |
| assert.deepEqual( |
| result.decisions.map((decision) => decision.decision), |
| ['keep', 'keep'], |
| ); |
| assert.equal( |
| result.decisions[1]?.previousHeldInReferencePassEligibleRate, |
| result.decisions[0]?.heldInReferencePassEligibleRate, |
| ); |
| assert.notEqual( |
| result.decisions[0]?.heldInReferencePassEligibleRate, |
| result.decisions[0]?.metrics.candidate.heldIn.passEligibleRate, |
| ); |
| }); |
| }); |
| |
| test('skips the held-out sweep for a candidate that does not clear the held-in gate', async () => { |
| await withHarness(async (harness) => { |
| const heldInTasks = makeTasks('hin', 2); |
| const heldOutTasks = makeTasks('hout', 2); |
| // Held-in flat at 0.5 (within the wide two-task noise band) every candidate |
| // round, so no candidate clears the held-in gate. |
| const rewardFor = (_roundId: string, taskId: string): number => { |
| if (taskId.startsWith('hout-')) return 1; |
| return taskIndex(taskId) === 0 ? 1 : 0; |
| }; |
| |
| const result = await runLoop(harness, { |
| heldInTasks, |
| heldOutTasks, |
| rewardFor, |
| rounds: 2, |
| baselineRuns: 2, |
| }); |
| |
| assert.deepEqual( |
| result.decisions.map((decision) => decision.decision), |
| ['discard', 'discard'], |
| ); |
| assert.equal(result.decisions[0]?.reason, 'held_in_within_noise'); |
| |
| // #64 two-stage gate: a candidate that cannot KEEP on held-in must never |
| // spend the held-out sweep — no held-out task event under any candidate round. |
| const events = (await readFile(harness.resultsJsonlPath, 'utf8')) |
| .split('\n') |
| .filter(Boolean) |
| .map((line) => JSON.parse(line)); |
| const isHeldOut = (e: { taskId?: unknown }) => |
| typeof e.taskId === 'string' && e.taskId.startsWith('hout-'); |
| const candidateHeldOut = events.filter( |
| (e) => typeof e.roundId === 'string' && e.roundId.startsWith('round-') && isHeldOut(e), |
| ); |
| assert.equal(candidateHeldOut.length, 0); |
| // Held-out baseline events still exist (calibration runs held-out), proving |
| // the check above is about candidate rounds, not broken held-out wiring. |
| const baselineHeldOut = events.filter( |
| (e) => typeof e.roundId === 'string' && e.roundId.startsWith('baseline-') && isHeldOut(e), |
| ); |
| assert.ok(baselineHeldOut.length > 0); |
| }); |
| }); |
| |
| test('quarantines held-in tasks without verifier-only patterns instead of keeping them', async () => { |
| await withHarness(async (harness) => { |
| const heldInTasks = makeTasks('hin', 20); |
| const heldOutTasks = makeTasks('hout', 8); |
| const taskRuns: string[] = []; |
| const rewardFor = (roundId: string, taskId: string): number => { |
| const index = taskIndex(taskId); |
| if (taskId.startsWith('hout-')) return index < 4 ? 1 : 0; |
| if (roundId.startsWith('baseline-')) return index < 10 ? 1 : 0; |
| return 1; |
| }; |
| |
| const result = await runLoop(harness, { |
| heldInTasks, |
| heldOutTasks, |
| rewardFor, |
| rounds: 1, |
| baselineRuns: 2, |
| rewardHackVerifierPatternsByTaskId: Object.fromEntries( |
| heldInTasks.map((task) => [task.id, []]), |
| ), |
| onTaskRun: (roundId, taskId) => taskRuns.push(`${roundId}:${taskId}`), |
| }); |
| |
| assert.equal(result.decisions[0]?.decision, 'discard'); |
| assert.equal(result.decisions[0]?.reason, 'reward_hack_quarantined'); |
| assert.deepEqual(result.decisions[0]?.rewardHackScan, { |
| decision: 'quarantine', |
| reason: 'no_verifier_patterns', |
| }); |
| assert.ok(taskRuns.every((item) => !item.startsWith('round-0:hout-'))); |
| }); |
| }); |
| |
| test('skips the held-out sweep for a reward-hack quarantined held-in trajectory', async () => { |
| await withHarness(async (harness) => { |
| const heldInTasks = makeTasks('hin', 20); |
| const heldOutTasks = makeTasks('hout', 8); |
| const taskRuns: string[] = []; |
| const rewardFor = (roundId: string, taskId: string): number => { |
| const index = taskIndex(taskId); |
| if (taskId.startsWith('hout-')) return index < 4 ? 1 : 0; |
| if (roundId.startsWith('baseline-')) return index < 10 ? 1 : 0; |
| return 1; |
| }; |
| |
| const result = await runLoop(harness, { |
| heldInTasks, |
| heldOutTasks, |
| rewardFor, |
| rounds: 1, |
| baselineRuns: 2, |
| rewardHackVerifierPatternsByTaskId: { |
| ...Object.fromEntries(heldInTasks.map((task) => [task.id, ['ZZZ_NO_VERIFIER_MATCH']])), |
| 'hin-0': ['EXPECTED_SECRET'], |
| }, |
| runtimeEventCommandFor: (roundId, taskId) => |
| roundId === 'round-0' && taskId === 'hin-0' ? 'echo EXPECTED_SECRET' : undefined, |
| onTaskRun: (roundId, taskId) => taskRuns.push(`${roundId}:${taskId}`), |
| }); |
| |
| assert.equal(result.decisions[0]?.decision, 'discard'); |
| assert.equal(result.decisions[0]?.reason, 'reward_hack_quarantined'); |
| assert.deepEqual(result.decisions[0]?.rewardHackScan, { |
| decision: 'quarantine', |
| reason: 'verifier_pattern', |
| matchedPatterns: ['EXPECTED_SECRET'], |
| }); |
| assert.ok(taskRuns.every((item) => !item.startsWith('round-0:hout-'))); |
| }); |
| }); |
| |
| test('stops before the held-out sweep when the budget is hit after held-in', async () => { |
| await withHarness(async (harness) => { |
| const originalHead = ( |
| await execFileAsync('git', ['rev-parse', 'HEAD'], { cwd: harness.repoDir }) |
| ).stdout.trim(); |
| const heldInTasks = makeTasks('hin', 20); |
| const heldOutTasks = makeTasks('hout', 8); |
| // Held-in jumps 0.5 -> 1.0 in round-0, so it clears the gate and held-out |
| // WOULD run; held-out stays flat at 0.5. |
| const rewardFor = (roundId: string, taskId: string): number => { |
| const index = taskIndex(taskId); |
| if (taskId.startsWith('hout-')) return index < 4 ? 1 : 0; |
| if (roundId.startsWith('baseline-')) return index < 10 ? 1 : 0; |
| return 1; |
| }; |
| |
| // baseline (2 sweeps) = 2*(20+8)*0.02 = 1.12; round-0 held-in adds 20*0.02 = |
| // 0.40 -> 1.52, tripping a 1.5 ceiling BETWEEN held-in and held-out. |
| const result = await runLoop(harness, { |
| heldInTasks, |
| heldOutTasks, |
| rewardFor, |
| rounds: 2, |
| baselineRuns: 2, |
| costCeilingUsd: 1.5, |
| }); |
| |
| assert.equal(result.stopReason, 'cost_ceiling_exceeded'); |
| assert.equal(result.decisions.length, 0); // round-0 broke before a decision |
| assert.equal(result.keptCount, 0); |
| assert.ok(result.totalCostUsd >= 1.5); |
| |
| // Held-out never ran for round-0, and the candidate commit was reverted. |
| const events = (await readFile(harness.resultsJsonlPath, 'utf8')) |
| .split('\n') |
| .filter(Boolean) |
| .map((line) => JSON.parse(line)); |
| const candidateHeldOut = events.filter( |
| (e) => |
| typeof e.roundId === 'string' && |
| e.roundId.startsWith('round-') && |
| typeof e.taskId === 'string' && |
| e.taskId.startsWith('hout-'), |
| ); |
| assert.equal(candidateHeldOut.length, 0); |
| const head = ( |
| await execFileAsync('git', ['rev-parse', 'HEAD'], { cwd: harness.repoDir }) |
| ).stdout.trim(); |
| assert.equal(head, originalHead); |
| assert.equal(await readFile(harness.systemPromptPath, 'utf8'), 'original prompt\n'); |
| }); |
| }); |
| |
| test('aborts baseline before held-out when the budget is exhausted after held-in', async () => { |
| await withHarness(async (harness) => { |
| const calls: string[] = []; |
| await assert.rejects( |
| runLoop(harness, { |
| heldInTasks: makeTasks('hin', 2), |
| heldOutTasks: makeTasks('hout', 2), |
| rewardFor: () => 1, |
| rounds: 1, |
| baselineRuns: 1, |
| costCeilingUsd: 0.03, |
| onTaskRun: (roundId, taskId) => calls.push(`${roundId}:${taskId}`), |
| }), |
| /cost_ceiling_exceeded during baseline calibration \(completed 0 of 1 sweeps\); raise the budget or lower baselineRuns/, |
| ); |
| assert.deepEqual(calls, ['baseline-0:hin-0', 'baseline-0:hin-1']); |
| }); |
| }); |
| |
| test('refuses to run when the held-out TSV would be visible inside the agent cwd', async () => { |
| await withHarness(async (harness) => { |
| await assert.rejects( |
| runLoop(harness, { |
| heldInTasks: makeTasks('hin', 2), |
| heldOutTasks: makeTasks('hout', 1), |
| rewardFor: () => 1, |
| rounds: 1, |
| baselineRuns: 1, |
| // Place the held-out TSV inside the agent cwd; the driver must auto-isolate |
| // it and the candidate round must reject before exposing held-out results. |
| heldOutResultsTsvPath: join(harness.agentCwdPath, 'held-out.tsv'), |
| }), |
| /controller-only artifacts must stay outside agent cwd/, |
| ); |
| }); |
| }); |
| |
| test('rejects out-of-contract numeric inputs at the public API boundary', async () => { |
| await withHarness(async (harness) => { |
| const base = { |
| heldInTasks: makeTasks('hin', 2), |
| heldOutTasks: makeTasks('hout', 1), |
| rewardFor: () => 1, |
| rounds: 1, |
| baselineRuns: 1, |
| }; |
| // rounds 0 is baseline-only (trivially passes the smoke); 1.5 would run two |
| // rounds; a NaN ceiling/ratio never trips its guard; minStable 0 disables |
| // the stable-task protection. All must fail loud, not silently degrade. |
| await assert.rejects( |
| runLoop(harness, { ...base, rounds: 0 }), |
| /rounds must be a positive integer/, |
| ); |
| await assert.rejects( |
| runLoop(harness, { ...base, rounds: 1.5 }), |
| /rounds must be a positive integer/, |
| ); |
| await assert.rejects( |
| runLoop(harness, { ...base, costCeilingUsd: NaN }), |
| /costCeilingUsd must be a finite positive number/, |
| ); |
| await assert.rejects( |
| runLoop(harness, { ...base, minStableHeldInTasks: 0 }), |
| /minStableHeldInTasks must be a positive integer/, |
| ); |
| await assert.rejects( |
| runLoop(harness, { ...base, maxInfraFailureRate: 1.5 }), |
| /maxInfraFailureRate must be a number in \(0, 1\]/, |
| ); |
| }); |
| }); |
| |
| test('rejects duplicate held-in task ids at the public API boundary', async () => { |
| await withHarness(async (harness) => { |
| await assert.rejects( |
| runLoop(harness, { |
| heldInTasks: [ |
| { id: 'dup-task', path: '/tasks/a' }, |
| { id: 'dup-task', path: '/tasks/b' }, |
| ], |
| heldOutTasks: makeTasks('hout', 1), |
| rewardFor: () => { |
| throw new Error('harbor must not run when task ids are invalid'); |
| }, |
| rounds: 1, |
| baselineRuns: 1, |
| }), |
| /held-in tasks contain duplicate id\(s\): dup-task/, |
| ); |
| }); |
| }); |
| |
| test('rejects held-in and held-out task id overlap at the public API boundary', async () => { |
| await withHarness(async (harness) => { |
| await assert.rejects( |
| runLoop(harness, { |
| heldInTasks: [{ id: 'shared-task', path: '/tasks/train' }], |
| heldOutTasks: [{ id: 'shared-task', path: '/tasks/exam' }], |
| rewardFor: () => { |
| throw new Error('harbor must not run when task partitions overlap'); |
| }, |
| rounds: 1, |
| baselineRuns: 1, |
| }), |
| /held-in and held-out tasks overlap: shared-task/, |
| ); |
| }); |
| }); |
| |
| test('stops the loop once the cumulative cost ceiling is reached', async () => { |
| await withHarness(async (harness) => { |
| const heldInTasks = makeTasks('hin', 20); |
| const heldOutTasks = makeTasks('hout', 8); |
| const rewardFor = (_roundId: string, taskId: string): number => |
| taskIndex(taskId) < (taskId.startsWith('hout-') ? 4 : 10) ? 1 : 0; |
| // baseline (2 sweeps) costs 2 * 28 * 0.02 = 1.12; round-0 adds 0.56 -> 1.68, |
| // tripping a 1.5 ceiling before round-1 runs. |
| const result = await runLoop(harness, { |
| heldInTasks, |
| heldOutTasks, |
| rewardFor, |
| rounds: 3, |
| baselineRuns: 2, |
| costCeilingUsd: 1.5, |
| }); |
| |
| assert.equal(result.stopReason, 'cost_ceiling_exceeded'); |
| assert.equal(result.decisions.length, 0); |
| assert.ok(result.totalCostUsd >= 1.5); |
| }); |
| }); |
| |
| test('reports a cost-ceiling smoke failure when the loop stops exactly at budget', async () => { |
| await withHarness(async (harness) => { |
| const heldInTasks = makeTasks('hin', 20); |
| const heldOutTasks = makeTasks('hout', 8); |
| const rewardFor = (roundId: string, taskId: string): number => { |
| const index = taskIndex(taskId); |
| if (taskId.startsWith('hout-')) return index < 4 ? 1 : 0; |
| if (roundId.startsWith('baseline-')) return index < 10 ? 1 : 0; |
| return 1; |
| }; |
| |
| const result = await runLoop(harness, { |
| heldInTasks, |
| heldOutTasks, |
| rewardFor, |
| rounds: 3, |
| baselineRuns: 2, |
| costCeilingUsd: 1.68, |
| }); |
| |
| assert.equal(result.stopReason, 'cost_ceiling_exceeded'); |
| assert.equal(result.decisions.length, 0); |
| assert.equal(result.smoke.totalCostUsd, 1.92); |
| assert.ok(result.smoke.failures.includes('cost_ceiling_exceeded')); |
| }); |
| }); |
| |
| test('drops a held-in task that never completes in baseline and calibrates on the rest', async () => { |
| await withHarness(async (harness) => { |
| const heldInTasks = makeTasks('hin', 3); |
| const heldOutTasks = makeTasks('hout', 2); |
| // hin-2 never completes in any sweep; every other task always does. |
| const shouldFail = (_roundId: string, taskId: string): boolean => taskId === 'hin-2'; |
| const rewardFor = (_roundId: string, taskId: string): number => { |
| if (taskId.startsWith('hout-')) return 1; |
| return taskIndex(taskId) === 0 ? 1 : 0; |
| }; |
| |
| const result = await runLoop(harness, { |
| heldInTasks, |
| heldOutTasks, |
| rewardFor, |
| shouldFail, |
| rounds: 1, |
| baselineRuns: 2, |
| }); |
| |
| // The unstable task is dropped; the run still calibrates and finishes. |
| assert.deepEqual(result.droppedHeldInTaskIds, ['hin-2']); |
| assert.deepEqual(result.droppedHeldOutTaskIds, []); |
| assert.equal(result.baseline.heldIn.taskCount, 2); |
| assert.equal(result.stopReason, 'rounds_complete'); |
| assert.equal(result.decisions.length, 1); |
| assert.equal(result.smoke.status, 'pass'); |
| |
| // The dropped task is never swept in the candidate round: only the two |
| // stable held-in tasks appear under round-0. |
| const wal = await readFile(harness.resultsJsonlPath, 'utf8'); |
| const roundHeldInTaskIds = wal |
| .trim() |
| .split('\n') |
| .map((line) => JSON.parse(line) as { roundId?: string; type?: string; taskId?: string }) |
| .filter( |
| (event) => |
| event.roundId === 'round-0' && |
| event.type === 'task_completed' && |
| (event.taskId ?? '').startsWith('hin-'), |
| ) |
| .map((event) => event.taskId); |
| assert.deepEqual([...new Set(roundHeldInTaskIds)].sort(), ['hin-0', 'hin-1']); |
| }); |
| }); |
| |
| test('runs flaky tasks but excludes them from proposal evidence and decisions', async () => { |
| await withHarness(async (harness) => { |
| const heldInTasks = makeTasks('hin', 3); |
| const heldOutTasks = makeTasks('hout', 2); |
| const roundTaskIds: string[] = []; |
| let proposalInput: MetaAgentPromptInput | undefined; |
| const rewardFor = (roundId: string, taskId: string): number => { |
| if (taskId === 'hin-0' || taskId === 'hout-0') return 1; |
| if (taskId === 'hin-2' && roundId !== 'baseline-1') return 1; |
| return roundId === 'round-0' ? 1 : 0; |
| }; |
| |
| const result = await runLoop(harness, { |
| heldInTasks, |
| heldOutTasks, |
| rewardFor, |
| rounds: 1, |
| baselineRuns: 3, |
| onTaskRun: (roundId, taskId) => { |
| if (roundId === 'round-0' && taskId.startsWith('hin-')) roundTaskIds.push(taskId); |
| }, |
| metaAgent: async (input) => { |
| proposalInput = input; |
| return { |
| systemPrompt: 'addressability candidate\n', |
| summary: 'use only addressable evidence', |
| candidateRationale: { |
| editedSurface: 'system_prompt', |
| evidenceRefs: evidenceRefsFor(input), |
| hypothesis: 'addressable evidence supports a bounded prompt improvement', |
| targetedFix: 'clarify the general success criteria', |
| predictedFixes: [], |
| riskTasks: [], |
| ...(evidenceRefsFor(input).length === 0 |
| ? { failurePattern: 'coverage_regression' as const } |
| : {}), |
| }, |
| }; |
| }, |
| }); |
| |
| assert.ok(proposalInput); |
| assert.deepEqual( |
| proposalInput.heldInDigests.map((digest) => digest.taskId), |
| ['hin-0', 'hin-1'], |
| ); |
| assert.match(proposalInput.resultsTsv, /hin-0/); |
| assert.match(proposalInput.resultsTsv, /hin-1/); |
| assert.doesNotMatch(proposalInput.resultsTsv, /hin-2/); |
| assert.deepEqual([...new Set(roundTaskIds)].sort(), ['hin-0', 'hin-1', 'hin-2']); |
| assert.equal(result.baseline.heldIn.taskCount, 2); |
| assert.equal(result.baseline.heldOut.taskCount, 2); |
| assert.deepEqual( |
| result.addressability.heldIn.taskStats.map((stat) => ({ |
| taskId: stat.taskId, |
| addressable: stat.addressable, |
| rejectionReason: stat.rejectionReason, |
| })), |
| [ |
| { taskId: 'hin-0', addressable: true, rejectionReason: undefined }, |
| { taskId: 'hin-1', addressable: true, rejectionReason: undefined }, |
| { taskId: 'hin-2', addressable: false, rejectionReason: 'flaky' }, |
| ], |
| ); |
| assert.deepEqual(result.addressability.heldOut.selectedTaskIds, ['hout-0', 'hout-1']); |
| assert.deepEqual(result.droppedHeldInTaskIds, []); |
| }); |
| }); |
| |
| test('re-banks the held-in reference when a capability-limit task shrinks the decision set', async () => { |
| await withHarness(async (harness) => { |
| const heldInTasks = makeTasks('hin', 20); |
| const heldOutTasks = makeTasks('hout', 4); |
| const proposalInputs: MetaAgentPromptInput[] = []; |
| const roundOneTaskIds: string[] = []; |
| const propose = fakeMetaAgent(); |
| const rewardFor = (roundId: string, taskId: string): number => { |
| if (taskId.startsWith('hout-')) return 1; |
| const index = taskIndex(taskId); |
| if (roundId.startsWith('baseline-')) return index < 10 ? 1 : 0; |
| if (roundId === 'round-0') return index < 19 ? 1 : 0; |
| return 1; |
| }; |
| |
| const first = await runLoop(harness, { |
| heldInTasks, |
| heldOutTasks, |
| rewardFor, |
| rounds: 1, |
| baselineRuns: 2, |
| metaAgent: async (input) => { |
| proposalInputs.push(input); |
| return propose(input); |
| }, |
| }); |
| assert.equal(first.decisions[0]?.decision, 'keep'); |
| assert.equal(proposalInputs.length, 1); |
| assert.match(proposalInputs[0]!.resultsTsv, /hin-19/); |
| assert.deepEqual( |
| first.addressability.heldIn.taskStats.find((stat) => stat.taskId === 'hin-19'), |
| { |
| taskId: 'hin-19', |
| observations: 3, |
| keptPrompts: 2, |
| passes: 0, |
| flips: 0, |
| flipRate: 0, |
| addressable: false, |
| rejectionReason: 'capability_limit', |
| }, |
| ); |
| assert.equal( |
| first.heldInReferencePassEligibleRate, |
| 1 - |
| promptAcceptanceNoiseBand({ |
| sampleSize: 19, |
| passRate: 10 / 19, |
| baselineRunCount: 2, |
| zScore: 1.96, |
| }), |
| ); |
| proposalInputs.length = 0; |
| |
| const replayedFirst = await runLoop(harness, { |
| heldInTasks, |
| heldOutTasks, |
| rewardFor, |
| rounds: 1, |
| baselineRuns: 2, |
| metaAgent: async (input) => { |
| proposalInputs.push(input); |
| return propose(input); |
| }, |
| }); |
| assert.deepEqual(replayedFirst.addressability, first.addressability); |
| assert.equal( |
| replayedFirst.heldInReferencePassEligibleRate, |
| first.heldInReferencePassEligibleRate, |
| ); |
| assert.equal(proposalInputs.length, 0); |
| |
| const result = await runLoop(harness, { |
| heldInTasks, |
| heldOutTasks, |
| rewardFor, |
| rounds: 2, |
| baselineRuns: 2, |
| metaAgent: async (input) => { |
| proposalInputs.push(input); |
| return propose(input); |
| }, |
| onTaskRun: (roundId, taskId) => { |
| if (roundId === 'round-1' && taskId.startsWith('hin-')) roundOneTaskIds.push(taskId); |
| }, |
| }); |
| |
| assert.equal(result.decisions[0]?.decision, 'keep'); |
| assert.equal(result.decisions[1]?.decision, 'discard'); |
| assert.equal(result.decisions[1]?.reason, 'held_in_within_noise'); |
| assert.equal(result.decisions[1]?.metrics.lastKept.heldIn.passEligibleRate, 1); |
| assert.equal( |
| result.decisions[1]?.previousHeldInReferencePassEligibleRate, |
| 1 - result.decisions[1]!.heldInPassRateNoiseBand, |
| ); |
| assert.equal( |
| result.heldInReferencePassEligibleRate, |
| result.decisions[1]?.previousHeldInReferencePassEligibleRate, |
| ); |
| assert.equal(proposalInputs.length, 1); |
| assert.doesNotMatch(proposalInputs[0]!.resultsTsv, /hin-19/); |
| assert.equal( |
| proposalInputs[0]!.heldInDigests.some((digest) => digest.taskId === 'hin-19'), |
| false, |
| ); |
| assert.ok(roundOneTaskIds.includes('hin-19')); |
| const terminalStat = result.addressability.heldIn.taskStats.find( |
| (stat) => stat.taskId === 'hin-19', |
| ); |
| assert.equal(terminalStat?.observations, 3); |
| assert.equal(terminalStat?.keptPrompts, 2); |
| assert.equal(terminalStat?.passes, 0); |
| assert.equal(terminalStat?.rejectionReason, 'capability_limit'); |
| |
| proposalInputs.length = 0; |
| const replayed = await runLoop(harness, { |
| heldInTasks, |
| heldOutTasks, |
| rewardFor, |
| rounds: 2, |
| baselineRuns: 2, |
| metaAgent: async (input) => { |
| proposalInputs.push(input); |
| return propose(input); |
| }, |
| }); |
| assert.equal(proposalInputs.length, 0); |
| assert.deepEqual(replayed.decisions, result.decisions); |
| assert.equal( |
| replayed.heldInReferencePassEligibleRate, |
| result.heldInReferencePassEligibleRate, |
| ); |
| assert.deepEqual(replayed.addressability, result.addressability); |
| }); |
| }); |
| |
| test('reward-hack scanning includes capability-limited tasks outside the decision set', async () => { |
| await withHarness(async (harness) => { |
| const heldInTasks = makeTasks('hin', 20); |
| const heldOutTasks = makeTasks('hout', 4); |
| const roundOneTaskIds: string[] = []; |
| const rewardFor = (roundId: string, taskId: string): number => { |
| if (taskId.startsWith('hout-')) return 1; |
| const index = taskIndex(taskId); |
| if (roundId.startsWith('baseline-')) return index < 10 ? 1 : 0; |
| if (roundId === 'round-0') return index < 19 ? 1 : 0; |
| return 1; |
| }; |
| |
| const result = await runLoop(harness, { |
| heldInTasks, |
| heldOutTasks, |
| rewardFor, |
| rounds: 2, |
| baselineRuns: 2, |
| rewardHackVerifierPatternsByTaskId: { |
| ...Object.fromEntries(heldInTasks.map((task) => [task.id, ['ZZZ_NO_VERIFIER_MATCH']])), |
| 'hin-19': ['EXPECTED_SECRET'], |
| }, |
| runtimeEventCommandFor: (roundId, taskId) => |
| roundId === 'round-1' && taskId === 'hin-19' ? 'echo EXPECTED_SECRET' : undefined, |
| onTaskRun: (roundId, taskId) => { |
| if (roundId === 'round-1' && taskId.startsWith('hin-')) roundOneTaskIds.push(taskId); |
| }, |
| }); |
| |
| assert.equal(result.decisions[0]?.decision, 'keep'); |
| assert.equal(result.decisions[1]?.decision, 'discard'); |
| assert.equal(result.decisions[1]?.reason, 'reward_hack_quarantined'); |
| assert.deepEqual(result.decisions[1]?.rewardHackScan, { |
| decision: 'quarantine', |
| reason: 'verifier_pattern', |
| matchedPatterns: ['EXPECTED_SECRET'], |
| }); |
| assert.ok(roundOneTaskIds.includes('hin-19')); |
| assert.equal(result.decisions[1]?.metrics.candidate.heldIn.taskCount, 19); |
| }); |
| }); |
| |
| test('re-banks again when retained evidence expands the decision set', async () => { |
| await withHarness(async (harness) => { |
| const heldInTasks = makeTasks('hin', 20); |
| const heldOutTasks = makeTasks('hout', 4); |
| const proposalInputs: MetaAgentPromptInput[] = []; |
| const propose = fakeMetaAgent(); |
| const rewardFor = (roundId: string, taskId: string): number => { |
| if (taskId.startsWith('hout-')) return 1; |
| const index = taskIndex(taskId); |
| if (roundId.startsWith('baseline-')) return index < 10 ? 1 : 0; |
| if (roundId === 'round-0') return index > 0 && index < 18 ? 1 : 0; |
| return 1; |
| }; |
| |
| const result = await runLoop(harness, { |
| heldInTasks, |
| heldOutTasks, |
| rewardFor, |
| rounds: 3, |
| baselineRuns: 2, |
| metaAgent: async (input) => { |
| proposalInputs.push(input); |
| return propose(input); |
| }, |
| }); |
| |
| assert.deepEqual( |
| result.decisions.map((decision) => decision.decision), |
| ['keep', 'keep', 'discard'], |
| ); |
| assert.deepEqual( |
| proposalInputs.map((input) => input.heldInDigests.length), |
| [20, 18, 19], |
| ); |
| assert.equal( |
| proposalInputs[1]?.heldInDigests.some((digest) => digest.taskId === 'hin-18'), |
| false, |
| ); |
| assert.equal( |
| proposalInputs[1]?.heldInDigests.some((digest) => digest.taskId === 'hin-19'), |
| false, |
| ); |
| assert.equal( |
| proposalInputs[2]?.heldInDigests.some((digest) => digest.taskId === 'hin-18'), |
| true, |
| ); |
| assert.equal( |
| proposalInputs[2]?.heldInDigests.some((digest) => digest.taskId === 'hin-19'), |
| true, |
| ); |
| assert.equal( |
| proposalInputs[2]?.heldInDigests.some((digest) => digest.taskId === 'hin-0'), |
| false, |
| ); |
| assert.equal(result.decisions[2]?.metrics.lastKept.heldIn.passEligibleRate, 1); |
| assert.equal( |
| result.decisions[2]?.previousHeldInReferencePassEligibleRate, |
| 1 - result.decisions[2]!.heldInPassRateNoiseBand, |
| ); |
| assert.equal(result.decisions[2]?.reason, 'held_in_within_noise'); |
| }); |
| }); |
| |
| test('fails loud when a terminal keep makes the whole held-out partition unaddressable', async () => { |
| await withHarness(async (harness) => { |
| await assert.rejects( |
| runLoop(harness, { |
| heldInTasks: makeTasks('hin', 20), |
| heldOutTasks: makeTasks('hout', 1), |
| rewardFor: (roundId, taskId) => { |
| if (taskId.startsWith('hout-')) return 0; |
| if (roundId.startsWith('baseline-')) return taskIndex(taskId) < 10 ? 1 : 0; |
| return 1; |
| }, |
| rounds: 1, |
| baselineRuns: 2, |
| }), |
| /held-out addressable task count is 0 after kept-prompt history filtering/, |
| ); |
| }); |
| }); |
| |
| test('aborts when no held-in task completes across baseline sweeps', async () => { |
| await withHarness(async (harness) => { |
| await assert.rejects( |
| runLoop(harness, { |
| heldInTasks: makeTasks('hin', 2), |
| heldOutTasks: makeTasks('hout', 1), |
| rewardFor: () => 1, |
| shouldFail: (_roundId, taskId) => taskId.startsWith('hin-'), |
| rounds: 1, |
| baselineRuns: 1, |
| }), |
| /held-in stable task count 0 is below the minimum 1/, |
| ); |
| }); |
| }); |
| |
| test('drops a held-in task slower than the duration cap from calibration and rounds', async () => { |
| await withHarness(async (harness) => { |
| const heldInTasks = makeTasks('hin', 3); |
| const heldOutTasks = makeTasks('hout', 2); |
| // hin-1 is pathologically slow in baseline; the cap drops it. |
| const durationMsFor = (_roundId: string, taskId: string): number => |
| taskId === 'hin-1' ? 9_000 : 10; |
| const rewardFor = (_roundId: string, taskId: string): number => |
| taskId.startsWith('hout-') ? 1 : taskIndex(taskId) === 0 ? 1 : 0; |
| |
| const result = await runLoop(harness, { |
| heldInTasks, |
| heldOutTasks, |
| rewardFor, |
| durationMsFor, |
| maxStableTaskDurationMs: 1_000, |
| rounds: 1, |
| baselineRuns: 2, |
| }); |
| |
| assert.deepEqual(result.droppedHeldInTaskIds, ['hin-1']); |
| assert.equal(result.baseline.heldIn.taskCount, 2); |
| assert.equal(result.stopReason, 'rounds_complete'); |
| assert.equal(result.smoke.status, 'pass'); |
| }); |
| }); |
| |
| test('aborts when too few held-in tasks survive the minimum-stable floor', async () => { |
| await withHarness(async (harness) => { |
| await assert.rejects( |
| runLoop(harness, { |
| heldInTasks: makeTasks('hin', 4), |
| heldOutTasks: makeTasks('hout', 2), |
| rewardFor: () => 1, |
| // Only hin-0 survives; the floor of 3 is not met, so the run fails loud |
| // rather than calibrating on an unrepresentative single task. |
| shouldFail: (_roundId, taskId) => taskId.startsWith('hin-') && taskId !== 'hin-0', |
| minStableHeldInTasks: 3, |
| rounds: 1, |
| baselineRuns: 1, |
| }), |
| /held-in stable task count 1 is below the minimum 3 \(4 configured, 3 dropped/, |
| ); |
| }); |
| }); |
| }); |