a11oy / packages /policy /src /gates /bekensteinBound_gate.ts
betterwithage's picture
sync(space): complete build context — fix BUILD_ERROR (CTO)
518343a verified
Raw
History Blame
5 kB
// SPDX-License-Identifier: Apache-2.0
// © 2026 Lutar, Stephen P. — SZL Holdings
// ORCID: 0009-0001-0110-4173
//
// Layer 6 — a11oy policy gate for BekensteinBound (A7)
//
// *** STAGED — ADVISORY ONLY ***
// Lean status: conjectured (formal proof pending lutar-lean Paper R2)
// This gate issues warnings but does NOT block production by default.
//
// Policy rationale:
// Receipt chain entropy H(R_n) is bounded by the information-theoretic
// limit from registry area: H(R_n) ≤ 8·sizeBytes bits. This is an advisory
// check — chains exceeding the bound indicate anomalous entropy generation
// that may signal state corruption or replay attacks.
//
// Lean axiom cited: `bekensteinBound` (A7)
// Lean file: Lutar/Gate/BekensteinBound.lean (pending — conjectured)
// Lean commit SHA: 1dca00032dfc9aa8559cc6c2e4b63192fcf52371
//
// Policy: advisory (severity: 'warning') — entropy > 8*sizeBytes → warn
//
// References:
// Zenodo: https://doi.org/10.5281/zenodo.19944926
// Thesis §4.5: bekensteinBound axiom; TH6 DPI proof discharges this
export interface BekensteinBoundGateConfig {
/** Bits-per-byte multiplier. Default: 8 (maximum information density). */
bitsPerByte?: number;
/**
* If true, deny on bound violation. Default: false (advisory / warning only).
* STAGED: set to false until TH6 formal proof lands on lutar-lean.
*/
enforced?: boolean;
}
export interface BekensteinBoundGateOpts {
/** Measured chain entropy in bits (Shannon estimator). */
chainEntropyBits: number;
/** Registry size in bytes. */
registrySizeBytes: number;
}
export interface BekensteinBoundDecision {
allow: boolean;
rationale: string;
formula: string;
leanTheorem: string;
leanFile: string;
leanCommitSha: string;
severity: 'warning' | 'error';
staged: boolean;
chainEntropyBits: number;
boundBits: number;
withinBound: boolean;
lambdaScore: number;
}
const LEAN_THEOREM = "bekensteinBound";
const LEAN_FILE = "Lutar/Gate/BekensteinBound.lean";
const LEAN_COMMIT = "1dca00032dfc9aa8559cc6c2e4b63192fcf52371";
const DEFAULT_BPB = 8;
// ── Inline formula ────────────────────────────────────────────────────────────
// A7 (conjectured): H(R_n) ≤ 8·sizeBytes bits (advisory; TH6 DPI discharges formally)
/**
* BekensteinBound (A7) policy gate — STAGED ADVISORY.
*
* Checks receipt chain entropy against the information-theoretic registry bound.
* Issues a warning by default; can be made enforcing once TH6 is formally proved.
*
* Lean axiom: `bekensteinBound` (A7) — conjectured; TH6 provides elementary proof
* Lean file: Lutar/Gate/BekensteinBound.lean (pending; commit 1dca00032dfc9aa8559cc6c2e4b63192fcf52371)
* Zenodo: https://doi.org/10.5281/zenodo.19944926
*/
export function bekensteinBoundGate(
config: BekensteinBoundGateConfig = {}
): (opts: BekensteinBoundGateOpts) => BekensteinBoundDecision {
const bitsPerByte = config.bitsPerByte ?? DEFAULT_BPB;
const enforced = config.enforced ?? false;
if (!Number.isFinite(bitsPerByte) || bitsPerByte <= 0) {
throw new Error(`BekensteinBoundGate: bitsPerByte must be > 0; got ${bitsPerByte}`);
}
return function gate(opts: BekensteinBoundGateOpts): BekensteinBoundDecision {
const { chainEntropyBits, registrySizeBytes } = opts;
if (!Number.isFinite(chainEntropyBits) || chainEntropyBits < 0) {
throw new Error(`BekensteinBoundGate: chainEntropyBits must be ≥ 0; got ${chainEntropyBits}`);
}
if (!Number.isFinite(registrySizeBytes) || registrySizeBytes <= 0) {
throw new Error(`BekensteinBoundGate: registrySizeBytes must be > 0; got ${registrySizeBytes}`);
}
const boundBits = bitsPerByte * registrySizeBytes;
const withinBound = chainEntropyBits <= boundBits;
const severity = enforced ? 'error' as const : 'warning' as const;
const allow = withinBound || !enforced;
const lambdaScore = withinBound ? 1.0 : boundBits / chainEntropyBits;
const stagedNote = enforced ? '' : ' [STAGED-ADVISORY: not blocking]';
const rationale = withinBound
? `BekensteinBound (A7): H(chain)=${chainEntropyBits.toFixed(2)} bits ≤ bound=${boundBits.toFixed(2)} bits (${registrySizeBytes} bytes × ${bitsPerByte}). Within bound.${stagedNote} Lean: ${LEAN_THEOREM} @${LEAN_COMMIT.slice(0, 12)}`
: `BekensteinBound (A7): H(chain)=${chainEntropyBits.toFixed(2)} bits > bound=${boundBits.toFixed(2)} bits — anomalous entropy.${stagedNote} Lean: ${LEAN_THEOREM} @${LEAN_COMMIT.slice(0, 12)}`;
return { allow, rationale, formula: "BekensteinBound", leanTheorem: LEAN_THEOREM, leanFile: LEAN_FILE, leanCommitSha: LEAN_COMMIT, severity, staged: !enforced, chainEntropyBits, boundBits, withinBound, lambdaScore };
};
}