Files
2026-05-27 23:29:53 +01:00

72 lines
3.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 `SeededRng` interface extending `Rng` from `@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 `Mulberry32Rng` implementing `SeededRng`. 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 `Sfc32Rng` implementing `SeededRng`. 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 `Xoshiro256Rng` implementing `SeededRng`. 256-bit state (4×uint64 via BigInt or two uint32 pairs).
- REQ-PRNG-051: Uses xoshiro256++ algorithm.
- REQ-PRNG-052: `skip(2**128)` and `skip(2**192)` use the algebraic jump polynomials (O(log n)); other `skip(n)` uses linear burn.
### CounterRng
- REQ-PRNG-060: Exports `CounterRng` implementing `SeededRng`. 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 via `normalizeSeed(parentSeed XOR hash(id))`. Children are statistically independent.
- REQ-PRNG-071: `checkpoint()` returns a plain object that `JSON.stringify` round-trips without loss.
- REQ-PRNG-072: `restore(checkpoint)` resets the instance to the checkpointed state and returns `this`.
- 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: `nextUint32` throughput for each algorithm.
- REQ-PRNG-103: `Sfc32Rng` output verified against known vectors from bingo test suite.