SilverSight/scripts/seedlock.py
allaun cf6096882f chore: commit all pending work from prior sessions
Includes:
- n-dimensional generic modules (BraidStateN, MatrixN, SpectralN,
  ClassifyN, FisherRigidityN, FixedPointBridge)
- Feasible Set Theorem proofs + QUBO relaxation
- Anti-smuggle protocol (seedlock, mutation testing, cross_validate,
  qc_flag, symbol verification)
- Q16_16 bridge with quad matrix representation
- Infrastructure scripts (entry gate, determinism checks)
- Test suites for Lean modules, scripts, and QUBO pipeline
- FixedPoint migration and HachimojiN8 updates
- Documentation updates (ARCHITECTURE, GLOSSARY, DOCUMENT_SETS)
- QUBO conflict sweep and FSR validation
- GitHub Actions anti-smuggle workflow

Build: 3307 jobs, 0 errors
2026-06-30 04:54:40 -05:00

86 lines
2.2 KiB
Python

"""seedlock.py — Deterministic RNG wrappers for all SilverSight shims.
Usage:
from seedlock import SeededRNG, lock
lock(42) # called once at program start
rng = SeededRNG(42)
rng.random() # reproducible Python random
rng.np_random() # reproducible NumPy random
Enforcement:
After lock(), direct random.seed() and np.random.seed() raise RuntimeError.
"""
from __future__ import annotations
import os
import random
import sys
from typing import Optional
import numpy as np
_LOCKED = False
_GLOBAL_SEED: int = 0
class SeededRNG:
"""Deterministic RNG using Python's random.Random as the canonical source.
Python's random.Random is specified by CPython and stable across platforms.
NumPy's Generator may differ by version — NumPy is only used for array ops.
"""
def __init__(self, seed: int = 0):
self._seed = seed
self._py_rng = random.Random(seed)
self._np_rng = np.random.default_rng(seed)
def random(self) -> float:
return self._py_rng.random()
def randint(self, a: int, b: int) -> int:
return self._py_rng.randint(a, b)
def choice(self, seq):
return self._py_rng.choice(seq)
def shuffle(self, lst: list) -> None:
self._py_rng.shuffle(lst)
def np_random(self) -> np.random.Generator:
return self._np_rng
def seed(self, new_seed: int) -> None:
self._seed = new_seed
self._py_rng = random.Random(new_seed)
self._np_rng = np.random.default_rng(new_seed)
def lock(seed: int = 0):
"""Lock global RNG. After this call, direct unseeded RNG calls raise RuntimeError."""
global _LOCKED, _GLOBAL_SEED
_GLOBAL_SEED = seed
_LOCKED = True
random.seed = _forbidden_seed # type: ignore
# NumPy's random module may not have seed attribute in newer versions
try:
np.random.seed = _forbidden_seed # type: ignore
except AttributeError:
pass
def is_locked() -> bool:
return _LOCKED
def global_seed() -> int:
return _GLOBAL_SEED
def _forbidden_seed(*args, **kwargs):
raise RuntimeError(
"Direct random.seed() call detected. "
"Use seedlock.SeededRNG(seed) for explicit seeding. "
"Layer 0 determinism violation."
)