feat(p7): FakeInference deterministic provider + golden eval registry

Task 7.2: FakeInference implements the InferencePort with keyword vocabulary
mirroring the P6 RuleEngine; deterministic (no clock/random) so AI artifacts are
replayable. Golden fixtures (AI_GOLDEN) + inference.spec.ts assert byte-identical
replay, abstention, and Scenario-7 (EVENT never exceeds DISCUSSION certainty).
Controls: abstain()/deny()/setCost().

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-01 16:29:51 +05:30
parent 42bb99c09f
commit e03f2f72e4
5 changed files with 252 additions and 0 deletions
@@ -0,0 +1,45 @@
import { describe, it, expect } from 'vitest';
import { makeFakeInference, AI_GOLDEN } from '@insignia/iios-testkit';
import type { AiJobType } from '@insignia/iios-contracts';
const run = (jobType: AiJobType, text: string) =>
makeFakeInference().infer({ jobType, text, purpose: `ai_${jobType.toLowerCase()}`, scopeId: 'scope1', interactionId: 'int1' });
describe('FakeInference — deterministic golden provider (P7)', () => {
it('is replayable: every golden case yields byte-identical output twice', async () => {
for (const c of AI_GOLDEN) {
const a = await run(c.jobType, c.text);
const b = await run(c.jobType, c.text);
expect(JSON.stringify(a)).toEqual(JSON.stringify(b));
}
});
it('matches golden expectations (artifact type, claims, abstention)', async () => {
for (const c of AI_GOLDEN) {
const r = await run(c.jobType, c.text);
expect(r.artifactType).toBe(c.expect.artifactType);
expect(r.claims.map((x) => x.claimType).sort()).toEqual([...c.expect.claimTypes].sort());
expect(!!r.abstentionReason).toBe(c.expect.abstained);
}
});
it('never asserts an event beyond DISCUSSION certainty (Scenario 7)', async () => {
for (const c of AI_GOLDEN.filter((g) => g.expect.maxCertainty)) {
const r = await run(c.jobType, c.text);
const event = r.claims.find((x) => x.claimType === 'EVENT');
expect(event?.claimJson.certainty).toBe('DISCUSSION');
}
});
it('abstain control forces no claims + a reason', async () => {
const r = await makeFakeInference().abstain().infer({ jobType: 'EXTRACT', text: 'party at 9 pm', purpose: 'x', scopeId: 's' });
expect(r.claims).toHaveLength(0);
expect(r.abstentionReason).toBeTruthy();
});
it('emits a positive integer cost (budget governor input)', async () => {
const r = await run('SUMMARIZE', 'hello world this is a message');
expect(Number.isInteger(r.modelRun.costUnits)).toBe(true);
expect(r.modelRun.costUnits).toBeGreaterThan(0);
});
});