mirror of
https://github.com/allaunthefox/SilverSight.git
synced 2026-07-30 17:16:16 +00:00
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
86 lines
2.2 KiB
Python
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."
|
|
)
|