42 lines
1.8 KiB
TypeScript
42 lines
1.8 KiB
TypeScript
import * as fs from "node:fs";
|
|
import * as os from "node:os";
|
|
import * as path from "node:path";
|
|
import { describe, expect, it } from "vitest";
|
|
import { createFactoryMemoryFalsificationReceipt, createFalsificationReceipt, writeFalsificationReceipt } from "./falsification-receipt.js";
|
|
|
|
describe("falsification receipts", () => {
|
|
it("records hostile factory memory counterexamples as failed-closed", () => {
|
|
const receipt = createFactoryMemoryFalsificationReceipt(new Date("2026-07-01T00:00:00.000Z"));
|
|
|
|
expect(receipt).toMatchObject({
|
|
schema: "fable.falsification.receipt.v1",
|
|
decision: "passed",
|
|
failures: [],
|
|
deployAttempted: false,
|
|
});
|
|
expect(receipt.cases.map((testCase) => testCase.claim)).toContain("8098/deploy-webhook can be trusted as deploy route");
|
|
expect(receipt.cases.map((testCase) => testCase.actualResult)).toContain("quarantined");
|
|
expect(receipt.cases.map((testCase) => testCase.actualResult)).toContain("blocked");
|
|
});
|
|
|
|
it("fails when a counterexample does not fail closed", () => {
|
|
const receipt = createFalsificationReceipt([
|
|
{ claim: "deploy without gate", counterexample: "missing receipt", expectedFailure: "blocked", actualResult: "allowed" },
|
|
]);
|
|
|
|
expect(receipt.decision).toBe("failed");
|
|
expect(receipt.failures[0]).toContain("deploy without gate");
|
|
expect(receipt.deployAttempted).toBe(false);
|
|
});
|
|
|
|
it("writes falsification receipts", () => {
|
|
const dir = fs.mkdtempSync(path.join(os.tmpdir(), "falsification-receipt-"));
|
|
const file = path.join(dir, "receipt.json");
|
|
|
|
writeFalsificationReceipt(file, createFactoryMemoryFalsificationReceipt());
|
|
|
|
expect(JSON.parse(fs.readFileSync(file, "utf-8"))).toMatchObject({ schema: "fable.falsification.receipt.v1" });
|
|
fs.rmSync(dir, { recursive: true, force: true });
|
|
});
|
|
});
|