a11oy / test /gates /halt_eligibility.test.ts
betterwithage's picture
sync(space): complete build context — fix BUILD_ERROR (CTO)
518343a verified
Raw
History Blame
7.24 kB
/**
* halt_eligibility.test.ts
*
* Vitest tests for the Lutar.HUKLLA.HaltEligibility gate.
*
* Tests:
* 1. 1000-input random parity test — verifies the monotonicity inequality holds
* 2. Edge case: exactly at LAMBDA_FLOOR
* 3. Edge case: just below LAMBDA_FLOOR
* 4. Edge case: false receipts/rho flags
* 5. Receipt emission with mock signer
*
* Lean commit: c4d13795689601324fce0236351bfe0ade990a43
*/
import { describe, it, expect } from "vitest";
import {
isHaltEligible,
emitHaltEligibilityReceipt,
haltEligibilityGate,
LAMBDA_FLOOR,
type ExecutionTrace,
type Signer,
} from "../../src/gates/halt_eligibility";
// ---------------------------------------------------------------------------
// Seeded pseudo-random (LCG — deterministic across runs)
// ---------------------------------------------------------------------------
function seedRandom(seed: number) {
let s = seed >>> 0;
return () => {
s = (Math.imul(1664525, s) + 1013904223) >>> 0;
return s / 0x100000000;
};
}
// ---------------------------------------------------------------------------
// Mock signer
// ---------------------------------------------------------------------------
const mockSigner: Signer = (payload: string) =>
`mock-sig::${Buffer.from(payload).slice(0, 16).toString("hex")}`;
// ---------------------------------------------------------------------------
// 1. 1000-input random parity / monotonicity test
// ---------------------------------------------------------------------------
describe("halt_eligibility: 1000-input random monotonicity test", () => {
it("monotonicity holds: t1.lambda ≤ t2.lambda ∧ bools match ∧ t1 eligible → t2 eligible", () => {
const rand = seedRandom(0xdeadbeef);
let violations = 0;
for (let i = 0; i < 1000; i++) {
const score1 = rand();
// t2 always has score ≥ score1 (monotonicity direction)
const score2 = score1 + rand() * (1 - score1);
const rc = rand() > 0.5;
const rho = rand() > 0.5;
const t1: ExecutionTrace = { lambdaScore: score1, receiptsClosed: rc, rhoClosure: rho };
const t2: ExecutionTrace = { lambdaScore: score2, receiptsClosed: rc, rhoClosure: rho };
const e1 = isHaltEligible(t1);
const e2 = isHaltEligible(t2);
// Lean theorem halt_eligibility_monotone: e1 = true → e2 = true
if (e1 && !e2) violations++;
}
expect(violations).toBe(0);
});
it("score below LAMBDA_FLOOR always yields false (not_eligible_of_low_score)", () => {
const rand = seedRandom(0xcafebabe);
let violated = false;
for (let i = 0; i < 1000; i++) {
const score = rand() * (LAMBDA_FLOOR - 1e-10); // strictly below floor
const trace: ExecutionTrace = {
lambdaScore: score,
receiptsClosed: true,
rhoClosure: true,
};
if (isHaltEligible(trace)) violated = true;
}
expect(violated).toBe(false);
});
});
// ---------------------------------------------------------------------------
// 2. Edge cases
// ---------------------------------------------------------------------------
describe("halt_eligibility: edge cases", () => {
it("score exactly at LAMBDA_FLOOR with bools true → eligible", () => {
const trace: ExecutionTrace = {
lambdaScore: LAMBDA_FLOOR,
receiptsClosed: true,
rhoClosure: true,
};
expect(isHaltEligible(trace)).toBe(true);
});
it("score just below LAMBDA_FLOOR → not eligible", () => {
const trace: ExecutionTrace = {
lambdaScore: LAMBDA_FLOOR - Number.EPSILON,
receiptsClosed: true,
rhoClosure: true,
};
expect(isHaltEligible(trace)).toBe(false);
});
it("score above floor but receiptsClosed=false → not eligible", () => {
const trace: ExecutionTrace = {
lambdaScore: 0.95,
receiptsClosed: false,
rhoClosure: true,
};
expect(isHaltEligible(trace)).toBe(false);
});
it("score above floor but rhoClosure=false → not eligible", () => {
const trace: ExecutionTrace = {
lambdaScore: 0.95,
receiptsClosed: true,
rhoClosure: false,
};
expect(isHaltEligible(trace)).toBe(false);
});
it("score=1.0 all true → eligible", () => {
const trace: ExecutionTrace = {
lambdaScore: 1.0,
receiptsClosed: true,
rhoClosure: true,
};
expect(isHaltEligible(trace)).toBe(true);
});
it("score=0.0 → not eligible regardless of bools", () => {
const trace: ExecutionTrace = {
lambdaScore: 0.0,
receiptsClosed: true,
rhoClosure: true,
};
expect(isHaltEligible(trace)).toBe(false);
});
it("all false → not eligible", () => {
const trace: ExecutionTrace = {
lambdaScore: 0.0,
receiptsClosed: false,
rhoClosure: false,
};
expect(isHaltEligible(trace)).toBe(false);
});
});
// ---------------------------------------------------------------------------
// 3. Receipt emission test
// ---------------------------------------------------------------------------
describe("halt_eligibility: DSSE receipt emission", () => {
it("emits receipt with correct theorem and commit SHA", () => {
const trace: ExecutionTrace = { lambdaScore: 0.95, receiptsClosed: true, rhoClosure: true };
const receipt = emitHaltEligibilityReceipt(trace, mockSigner);
expect(receipt.theorem).toBe("Lutar.HUKLLA.HaltEligibility");
expect(receipt.lean_commit_sha).toBe("c4d13795689601324fce0236351bfe0ade990a43");
expect(receipt.output).toBe(true);
expect(receipt.inputs_hash).toMatch(/^[0-9a-f]{64}$/);
expect(receipt.sig).toContain("mock-sig::");
expect(receipt.ts).toMatch(/^\d{4}-\d{2}-\d{2}T/);
});
it("receipt output matches isHaltEligible for random traces", () => {
const rand = seedRandom(0x12345678);
for (let i = 0; i < 50; i++) {
const trace: ExecutionTrace = {
lambdaScore: rand(),
receiptsClosed: rand() > 0.5,
rhoClosure: rand() > 0.5,
};
const receipt = emitHaltEligibilityReceipt(trace, mockSigner);
expect(receipt.output).toBe(isHaltEligible(trace));
}
});
it("gate returns eligible and receipt fields consistently", () => {
const trace: ExecutionTrace = { lambdaScore: 0.91, receiptsClosed: true, rhoClosure: true };
const { eligible, receipt } = haltEligibilityGate(trace, mockSigner);
expect(eligible).toBe(true);
expect(receipt.output).toBe(true);
});
it("two identical traces yield identical inputs_hash", () => {
const trace: ExecutionTrace = { lambdaScore: 0.95, receiptsClosed: true, rhoClosure: true };
const r1 = emitHaltEligibilityReceipt(trace, mockSigner);
const r2 = emitHaltEligibilityReceipt(trace, mockSigner);
expect(r1.inputs_hash).toBe(r2.inputs_hash);
});
it("different traces yield different inputs_hash", () => {
const t1: ExecutionTrace = { lambdaScore: 0.95, receiptsClosed: true, rhoClosure: true };
const t2: ExecutionTrace = { lambdaScore: 0.80, receiptsClosed: true, rhoClosure: true };
const r1 = emitHaltEligibilityReceipt(t1, mockSigner);
const r2 = emitHaltEligibilityReceipt(t2, mockSigner);
expect(r1.inputs_hash).not.toBe(r2.inputs_hash);
});
});