3.8 KiB
3.8 KiB
Capability: seeded-prng
ADDED Requirements
Package identity
- REQ-PRNG-001: Package name
@suaveplan/pseudo-random,packages/universal/pseudo-random. - REQ-PRNG-002: Runtime deps:
@suaveplan/error,@suaveplan/types,tslib,zod. Zero crypto deps, zero browser deps. - REQ-PRNG-003:
"sideEffects": false.
SeededRng interface
- REQ-PRNG-010: Exports
SeededRnginterface extendingRngfrom@suaveplan/types:{ readonly seed: number; readonly position: number; skip(n: number): this; reset(): this; at(offset: number): SeededRng; fork(id: number | string): SeededRng; checkpoint(): RngCheckpoint; restore(checkpoint: RngCheckpoint): this }. - REQ-PRNG-011: Exports
RngCheckpoint = { seed: number; position: number; state: unknown }— serialisable to JSON.
Seed normalisation
- REQ-PRNG-020: Exports
normalizeSeed(seed: string | number): number. - REQ-PRNG-021: String seeds: splitmix64 mixing over UTF-16 char codes. Produces stable 32-bit integer.
- REQ-PRNG-022: Numeric seeds: single splitmix64 round to avalanche input bias. Rejects NaN, Infinity, non-safe-integers with
PseudoRandomError("PRNG.SEED.INVALID"). - REQ-PRNG-023: Zero input produces a non-zero seed (avoids degenerate PRNG state).
Mulberry32Rng
- REQ-PRNG-030: Exports
Mulberry32RngimplementingSeededRng. 32-bit state. - REQ-PRNG-031:
nextUint32()uses the standard Mulberry32 algorithm:a = (a + 0x6d2b79f5) >>> 0; .... - REQ-PRNG-032: Byte-identical output to the inline implementation in
@suaveplan/testing/context.
Sfc32Rng
- REQ-PRNG-040: Exports
Sfc32RngimplementingSeededRng. 128-bit state (4×uint32). - REQ-PRNG-041: State initialised with 12 warmup rounds from
seedToSFC32State. - REQ-PRNG-042: Byte-identical output to
BulletproofPRNG(SFC32 mode) in the bingo app for same seed.
Xoshiro256Rng
- REQ-PRNG-050: Exports
Xoshiro256RngimplementingSeededRng. 256-bit state (4×uint64 via BigInt or two uint32 pairs). - REQ-PRNG-051: Uses xoshiro256++ algorithm.
- REQ-PRNG-052:
skip(2**128)andskip(2**192)use the algebraic jump polynomials (O(log n)); otherskip(n)uses linear burn.
CounterRng
- REQ-PRNG-060: Exports
CounterRngimplementingSeededRng. Counter-based via splitmix64 hash. - REQ-PRNG-061:
at(offset)is O(1) — directly sets the counter. - REQ-PRNG-062:
nextUint32()=splitmix64(seed XOR counter++)truncated to 32 bits.
Shared SeededRng behaviour
- REQ-PRNG-070:
fork(id)derives child seed vianormalizeSeed(parentSeed XOR hash(id)). Children are statistically independent. - REQ-PRNG-071:
checkpoint()returns a plain object thatJSON.stringifyround-trips without loss. - REQ-PRNG-072:
restore(checkpoint)resets the instance to the checkpointed state and returnsthis. - REQ-PRNG-073:
at(offset)returns a new instance at the given offset (does not mutate the original).
Utilities
- REQ-PRNG-080: Exports
shuffle<T>(array: T[], rng?: Rng): T[]— Fisher-Yates, returns new array. - REQ-PRNG-081: Exports
shuffleInPlace<T>(array: T[], rng?: Rng): T[]— Fisher-Yates, mutates. - REQ-PRNG-082: Exports
sample<T>(array: T[], n: number, rng?: Rng): T[]— n distinct elements without replacement. - REQ-PRNG-083: Exports
weightedChoice<T>(items: T[], weights: number[], rng?: Rng): T.
Error surface
- REQ-PRNG-090: Exports
PseudoRandomError extends SuaveplanError<PseudoRandomCode>. - REQ-PRNG-091: Codes:
PRNG.SEED.INVALID,PRNG.OFFSET.OUT_OF_RANGE,PRNG.SAMPLE.INSUFFICIENT_ITEMS,PRNG.CHECKPOINT.INVALID.
Quality
- REQ-PRNG-100: 100% statement + branch coverage.
- REQ-PRNG-101: fast-check: determinism, fork independence (10k samples, correlation < 0.01), checkpoint round-trip.
- REQ-PRNG-102: mitata benchmarks:
nextUint32throughput for each algorithm. - REQ-PRNG-103:
Sfc32Rngoutput verified against known vectors from bingo test suite.