Spaces:
Running
Running
| /** | |
| * 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); | |
| }); | |
| }); | |