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