Client State & Temporal Chaos ('Poisoned Well')
Corrupt persisted browser storage (localStorage / sessionStorage), trigger QuotaExceededError, shift the JS clock forward, and test rehydration survival on page.reload().
Usage
bash
loki run http://localhost:8000 --persona novice-chaotic --state-chaosloki run http://localhost:8000 --swarmloki run http://localhost:8000 --no-state-chaos
Active personas
StateChaosEngine (src/loki/engine/state_chaos.py) runs during novice-chaotic, swarm (--swarm), and all sessions when --state-chaos is enabled (on by default).
'Poisoned Well' Fault Types (`--state-chaos`)
| Flag | Type | Default | Description |
|---|---|---|---|
| storage_corrupt_json | localStorage / sessionStorage | truncated JSON | Slices serialized JSON values mid-object (e.g. {"items":[{"id":1) to expose unguarded JSON.parse() calls during state hydration. |
| storage_trap_literal | localStorage / sessionStorage | "undefined", "null", "NaN" | Replaces persisted values with JavaScript string trap literals ("undefined", "null", "NaN", "[object Object]"). |
| storage_type_swap / schema_strip | localStorage / sessionStorage | Zustand / Redux-Persist aware | Swaps expected types (arrays to numbers, objects to strings, positive totals to -999999) or strips required inner keys from {state, version} persistence envelopes. |
| quota_exhausted | Storage.prototype.setItem | QuotaExceededError | Overrides Storage.prototype.setItem in the page context to throw DOMException("QuotaExceededError") on subsequent writes. |
| clock_drift | Date.now / new Date | +1h, +2h, +24h | Fast-forwards the client JavaScript clock mid-session to expose expired JWT refresh loops, broken countdown timers, and cache TTL bugs. |
| poisoned_reload | page.reload() | end of wave | Reloads the page with poisoned storage still in place and inspects the DOM for white-screen hydration crashes ([UI Freeze / Poisoned Reload Collapse]). |