This PR refactors ChaosPolicy in src/chaos/chaosPolicy.ts to make the random number generator injectable, enabling deterministic chaos testing and reproducible incident debugging.
ChaosPolicy.decide() directly called Math.random() when chaosMode === 'random', coupling the policy to a global, non-seedable RNG. This made probabilistic chaos testing impossible to reproduce and hard to debug when chaos-induced incidents occurred.
Added an optional random: () => number parameter to the ChaosPolicy constructor:
- Defaults to
Math.randomfor production behavior - Allows tests to supply deterministic RNG sequences
- Enables exact reproduction of chaos decision sequences
- Added
RandomFntype alias for the random function signature - Updated constructor to accept optional
randomparameter withMath.randomdefault - Added explicit boundary handling in random mode:
probability <= 0: always returns'none'(never injects)probability >= 1: always returns'error'(always injects)
- Enhanced JSDoc with security notes about chaos being gated on
chaosMode
Added comprehensive tests for the injectable RNG:
- Tests use injected functions instead of spying on
Math.random - Deterministic sequence tests prove exact decision reproduction
- Boundary tests for probability 0 and 1 (and edge cases like negative/greater-than-1)
- Production behavior test confirms default
Math.randomworks correctly
All 23 tests pass with coverage focused on:
- Mode dispatch (
off,error,timeout,random, unknown) - Target matching (empty, specific, case-insensitive)
- Probability boundaries (0, 1, values in between, edge cases)
- Deterministic RNG injection and sequence reproduction
- Chaos can never be active in production by default (gated on
chaosMode) - The
Math.randomdefault provides the same cryptographic-quality randomness as Node.js - No behavior change for production code paths
closes #465