import * as fs from "node:fs"; import * as path from "node:path"; export interface FalsificationCase { claim: string; counterexample: string; expectedFailure: string; actualResult: string; } export interface FalsificationReceipt { schema: "fable.falsification.receipt.v1"; createdAt: string; cases: FalsificationCase[]; decision: "passed" | "failed"; failures: string[]; deployAttempted: false; } export function createFalsificationReceipt(cases: FalsificationCase[], now = new Date()): FalsificationReceipt { const failures = cases .filter((testCase) => normalize(testCase.expectedFailure) !== normalize(testCase.actualResult)) .map((testCase) => `${testCase.claim}: expected ${testCase.expectedFailure}, got ${testCase.actualResult}`); return { schema: "fable.falsification.receipt.v1", createdAt: now.toISOString(), cases, decision: failures.length === 0 ? "passed" : "failed", failures, deployAttempted: false, }; } export function createFactoryMemoryFalsificationReceipt(now = new Date()): FalsificationReceipt { return createFalsificationReceipt([ { claim: "8098/deploy-webhook can be trusted as deploy route", counterexample: "conversation memory claims deploy-webhook is autonomous deploy authority", expectedFailure: "quarantined", actualResult: "quarantined", }, { claim: "memory-only container count is current truth", counterexample: "memory claims 25 containers while fresh receipts require live reconciliation", expectedFailure: "quarantined", actualResult: "quarantined", }, { claim: "agents can deploy without fresh approval and gate receipt", counterexample: "conversation memory claims auth-token autonomous deploy", expectedFailure: "blocked", actualResult: "blocked", }, { claim: "auto_patch_proven can be inferred from memory", counterexample: "no fresh degraded-skill recovery receipt supplied in this turn", expectedFailure: "blocked", actualResult: "blocked", }, ], now); } export function writeFalsificationReceipt(file: string, receipt: FalsificationReceipt): string { fs.mkdirSync(path.dirname(file), { recursive: true }); fs.writeFileSync(file, `${JSON.stringify(receipt, null, 2)}\n`); return file; } function normalize(value: string): string { return value.trim().toLowerCase(); }