Files
Dragan Spiridonov af4140efb9 feat(quality): oracle evals, durable-first tests, conservation guard + provider fixes
Apply Phoenix Architecture principles to AQE — regenerate internals, conserve the interface.

ADR-113 (evals are oracles, durable-first tests, mutation-score gate):
- src/validation/oracle-eval.ts grades a generated test by running it against a
  reference impl + operator mutants (reuses qe-arena, ADR-104); rejects assertion-less output
- oracle mode wired into scripts/run-skill-eval.ts (skips under the simulating runner; runs live)
- qe-test-generation rewritten durable-first; its eval flipped to oracle
- src/feedback/regenerability-gate.ts: mutation-score + regenerability gate (warn-default, opt-in block)
- live-validated: Claude sonnet-4-6 clears the oracle 5/5; weak local-model output correctly fails

ADR-114 (conservation layer, Phoenix essay 14):
- src/validation/conservation-guard.ts + scripts/conservation-guard.ts guard CLI commands,
  output schemas, and dashboard API against breaking removals (deprecation registry exempts)
- policy doc + baselines in verification/conservation/; wired into invariant-check.yml non-blocking

LLM provider fixes:
- OpenRouterProvider.type was 'openai' but registered under 'openrouter' -> ProviderManager
  failover never found it; fixed to 'openrouter' end-to-end
- Gemini default model gemini-1.5-pro was retired -> gemini-2.5-flash; models/pricing refreshed
  from the live Gemini ListModels API
- scripts/provider-health.ts (npm run providers:health)

Cheaper-model eval lanes:
- scripts/oracle-model-bench.ts + openrouter-models.ts; openai/gpt-oss-120b clears the oracle
  ~50-70x cheaper than Claude Sonnet; guide in docs/guides/cheaper-model-eval-lanes.md

Verification: npm run build ok; 115 new+touched tests pass; 724 LLM tests pass; lint + parity clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27 15:37:46 +00:00

99 lines
3.4 KiB
TypeScript

/**
* P0 proof for the Oracle-Evals plan: the oracle evaluator must distinguish
* a thorough test (kills mutants) from a no-op / weak test (survives) and a
* broken test (fails the reference). Real `node --test` runs via qe-arena.
*
* Reference under test: `inRange(x, lo, hi)` → `x >= lo && x <= hi`, which the
* operator mutator turns into exactly 3 first-order mutants (>=→>, <=→<, &&→||).
*/
import { describe, it, expect } from 'vitest';
import { evaluateOracle } from '../../../src/validation/oracle-eval';
const REFERENCE_IMPL = `export function inRange(x, lo, hi) {
return x >= lo && x <= hi;
}
`;
const TEST_HEADER = `import test from 'node:test';
import assert from 'node:assert/strict';
import { inRange } from '../src/inRange.mjs';
`;
// Asserts every boundary — kills all three mutants.
const THOROUGH_TEST = `${TEST_HEADER}
test('in range', () => { assert.equal(inRange(5, 1, 10), true); });
test('low boundary included', () => { assert.equal(inRange(1, 1, 10), true); }); // kills >= -> >
test('high boundary included', () => { assert.equal(inRange(10, 1, 10), true); }); // kills <= -> <
test('below range excluded', () => { assert.equal(inRange(0, 1, 10), false); }); // kills && -> ||
`;
// Passes against the reference but asserts nothing — should be rejected.
const NOOP_TEST = `${TEST_HEADER}
test('noop', () => { /* no assertions */ });
`;
// One happy-path assertion that no mutant can break — has "coverage", catches nothing.
const WEAK_TEST = `${TEST_HEADER}
test('happy path only', () => { assert.equal(inRange(5, 1, 10), true); });
`;
// Wrong expectation — does not even pass against the correct implementation.
const BROKEN_TEST = `${TEST_HEADER}
test('wrong', () => { assert.equal(inRange(5, 1, 10), false); });
`;
const TIMEOUT = 120_000;
describe('evaluateOracle (P0 spike — real node --test + arena mutants)', () => {
it('enumerates exactly 3 mutants and a thorough test kills all of them', () => {
const result = evaluateOracle({
moduleName: 'inRange',
referenceImpl: REFERENCE_IMPL,
generatedTest: THOROUGH_TEST,
});
expect(result.baselinePassed).toBe(true);
expect(result.mutantsTotal).toBe(3);
expect(result.mutantsKilled).toBe(3);
expect(result.mutationScore).toBe(1);
expect(result.passed).toBe(true);
}, TIMEOUT);
it('rejects an assertion-less test at the sanity guard (the must_contain failure mode)', () => {
const result = evaluateOracle({
moduleName: 'inRange',
referenceImpl: REFERENCE_IMPL,
generatedTest: NOOP_TEST,
});
// No assertion calls (only the `import assert` line) → rejected before running.
expect(result.baselinePassed).toBe(false);
expect(result.passed).toBe(false);
expect(result.reason).toMatch(/no assertions/);
}, TIMEOUT);
it('rejects a happy-path-only test with coverage but no fault detection', () => {
const result = evaluateOracle({
moduleName: 'inRange',
referenceImpl: REFERENCE_IMPL,
generatedTest: WEAK_TEST,
});
expect(result.baselinePassed).toBe(true);
expect(result.mutantsKilled).toBe(0);
expect(result.passed).toBe(false);
}, TIMEOUT);
it('rejects a test that fails against the reference implementation', () => {
const result = evaluateOracle({
moduleName: 'inRange',
referenceImpl: REFERENCE_IMPL,
generatedTest: BROKEN_TEST,
});
expect(result.baselinePassed).toBe(false);
expect(result.passed).toBe(false);
}, TIMEOUT);
});