a11oy / test /gates /delayed_choice_closure.test.ts
betterwithage's picture
sync(space): complete build context — fix BUILD_ERROR (CTO)
518343a verified
Raw
History Blame
7.31 kB
/**
* delayed_choice_closure.test.ts
*
* Vitest tests for the Lutar.Wheeler.DelayedChoiceClosure gate.
*
* Tests:
* 1. 1000-input random admissibility parity test
* 2. Edge cases: exact window, late, early, wrong span
* 3. closeLabel semantics
* 4. Receipt emission with mock signer
*
* Lean commit: c4d13795689601324fce0236351bfe0ade990a43
*/
import { describe, it, expect } from "vitest";
import {
admissible,
closeLabel,
emitDelayedChoiceReceipt,
delayedChoiceClosureGate,
WHEELER_WINDOW,
type Span,
type WheelerReceipt,
type DoctrineLabel,
type Signer,
} from "../../src/gates/delayed_choice_closure";
// ---------------------------------------------------------------------------
// Seeded LCG
// ---------------------------------------------------------------------------
function seedRandom(seed: number) {
let s = seed >>> 0;
return () => {
s = (Math.imul(1664525, s) + 1013904223) >>> 0;
return s / 0x100000000;
};
}
const mockSigner: Signer = (p: string) =>
`mock-sig::${Buffer.from(p).slice(0, 16).toString("hex")}`;
const LABELS: DoctrineLabel[] = ["Bot", "L1", "L2", "Top"];
// ---------------------------------------------------------------------------
// 1. 1000-input random admissibility test
// ---------------------------------------------------------------------------
describe("delayed_choice_closure: 1000-input admissibility parity test", () => {
it("late receipts (closeAt > endAt + W) always inadmissible", () => {
const rand = seedRandom(0xcafe0001);
let violations = 0;
for (let i = 0; i < 1000; i++) {
const endAt = Math.floor(rand() * 10000);
const span: Span = { id: 1, start: 0, endAt };
const closeAt = endAt + WHEELER_WINDOW + Math.floor(rand() * 5000) + 1;
const receipt: WheelerReceipt = { span: 1, closeAt, label: "L1" };
if (admissible(span, receipt)) violations++;
}
expect(violations).toBe(0);
});
it("receipts inside window always admissible (same span)", () => {
const rand = seedRandom(0xcafe0002);
let violations = 0;
for (let i = 0; i < 1000; i++) {
const endAt = Math.floor(rand() * 10000);
const span: Span = { id: 42, start: 0, endAt };
const offset = Math.floor(rand() * WHEELER_WINDOW); // [0, W-1]
const receipt: WheelerReceipt = { span: 42, closeAt: endAt + offset, label: "Top" };
if (!admissible(span, receipt)) violations++;
}
expect(violations).toBe(0);
});
it("wrong-span receipts always inadmissible", () => {
const rand = seedRandom(0xcafe0003);
let violations = 0;
for (let i = 0; i < 1000; i++) {
const endAt = Math.floor(rand() * 10000);
const span: Span = { id: 1, start: 0, endAt };
const wrongId = Math.floor(rand() * 1000) + 2; // never 1
const receipt: WheelerReceipt = { span: wrongId, closeAt: endAt + 1, label: "L2" };
if (admissible(span, receipt)) violations++;
}
expect(violations).toBe(0);
});
});
// ---------------------------------------------------------------------------
// 2. Edge cases
// ---------------------------------------------------------------------------
describe("delayed_choice_closure: edge cases", () => {
const span: Span = { id: 7, start: 100, endAt: 200 };
it("receipt at exact endAt → admissible (wheeler_window_admits_zero_offset)", () => {
const r: WheelerReceipt = { span: 7, closeAt: 200, label: "L1" };
expect(admissible(span, r)).toBe(true);
});
it("receipt at endAt + W → admissible (wheeler_window_admits_max_offset)", () => {
const r: WheelerReceipt = { span: 7, closeAt: 200 + WHEELER_WINDOW, label: "L2" };
expect(admissible(span, r)).toBe(true);
});
it("receipt at endAt + W + 1 → inadmissible (wheeler_window_safety)", () => {
const r: WheelerReceipt = { span: 7, closeAt: 200 + WHEELER_WINDOW + 1, label: "L2" };
expect(admissible(span, r)).toBe(false);
});
it("early receipt (closeAt < endAt) → inadmissible (early_receipt_rejected)", () => {
const r: WheelerReceipt = { span: 7, closeAt: 150, label: "Top" };
expect(admissible(span, r)).toBe(false);
});
it("closeAt = 0, endAt = 200 → inadmissible", () => {
const r: WheelerReceipt = { span: 7, closeAt: 0, label: "Bot" };
expect(admissible(span, r)).toBe(false);
});
});
// ---------------------------------------------------------------------------
// 3. closeLabel semantics
// ---------------------------------------------------------------------------
describe("delayed_choice_closure: closeLabel semantics", () => {
const span: Span = { id: 7, start: 100, endAt: 200 };
it("admissible receipt → closeLabel = receipt.label", () => {
for (const label of LABELS) {
const r: WheelerReceipt = { span: 7, closeAt: 250, label };
expect(closeLabel(span, r)).toBe(label);
}
});
it("inadmissible (late) receipt → closeLabel = Bot (wheeler_window_safety)", () => {
const r: WheelerReceipt = { span: 7, closeAt: 200 + WHEELER_WINDOW + 1, label: "Top" };
expect(closeLabel(span, r)).toBe("Bot");
});
it("wrong span → closeLabel = Bot (wrong_span_rejected)", () => {
const r: WheelerReceipt = { span: 99, closeAt: 250, label: "L2" };
expect(closeLabel(span, r)).toBe("Bot");
});
it("delayed_choice_idempotent: closeLabel is referentially stable", () => {
const r: WheelerReceipt = { span: 7, closeAt: 210, label: "L1" };
expect(closeLabel(span, r)).toBe(closeLabel(span, r));
});
});
// ---------------------------------------------------------------------------
// 4. Receipt emission
// ---------------------------------------------------------------------------
describe("delayed_choice_closure: DSSE receipt emission", () => {
const span: Span = { id: 1, start: 0, endAt: 500 };
it("admissible receipt emits correct DSSE receipt", () => {
const r: WheelerReceipt = { span: 1, closeAt: 700, label: "L2" };
const { label, dsse } = emitDelayedChoiceReceipt(span, r, mockSigner);
expect(label).toBe("L2");
expect(dsse.output).toBe("L2");
expect(dsse.theorem).toBe("Lutar.Wheeler.delayed_choice_idempotent");
expect(dsse.lean_commit_sha).toBe("c4d13795689601324fce0236351bfe0ade990a43");
expect(dsse.inputs_hash).toMatch(/^[0-9a-f]{64}$/);
expect(dsse.sig).toContain("mock-sig::");
});
it("late receipt → output = Bot in DSSE receipt", () => {
const r: WheelerReceipt = { span: 1, closeAt: 500 + WHEELER_WINDOW + 1, label: "Top" };
const { label, dsse } = emitDelayedChoiceReceipt(span, r, mockSigner);
expect(label).toBe("Bot");
expect(dsse.output).toBe("Bot");
});
it("gate returns admissible + label correctly", () => {
const r: WheelerReceipt = { span: 1, closeAt: 600, label: "Top" };
const { label, admissible: adm, dsse } = delayedChoiceClosureGate(span, r, mockSigner);
expect(label).toBe("Top");
expect(adm).toBe(true);
expect(dsse.output).toBe("Top");
});
it("inputs_hash is deterministic", () => {
const r: WheelerReceipt = { span: 1, closeAt: 600, label: "Top" };
const r1 = emitDelayedChoiceReceipt(span, r, mockSigner);
const r2 = emitDelayedChoiceReceipt(span, r, mockSigner);
expect(r1.dsse.inputs_hash).toBe(r2.dsse.inputs_hash);
});
});