# Policy Simulation Gaps (PS1–PS10) — Lockfile, Quotas, and Shadow Safety This note closes POLICY-GAPS-185-006 by defining a signed inputs lock, offline verifier, and shadow isolation guardrails for policy simulations. ## Lockfile - Schema: `docs/replay/policy-sim/lock.schema.json` - Sample: `docs/replay/policy-sim/inputs.lock.sample.json` - Fields cover policy bundle, graph, SBOM, time anchor, dataset digests; shadowIsolation flag; requiredScopes. - Recommended signing: DSSE over the lockfile with Ed25519; record envelope digest alongside artefacts. ## Validation - Library helper: `PolicySimulationInputLockValidator` in `StellaOps.Replay.Core` compares materialized digests and enforces shadow mode + scope `policy:simulate:shadow`. - Staleness: pass `maxAge` (suggested 24h) to reject outdated locks. ## CLI / CI contract - Script: `scripts/replay/verify-policy-sim-lock.sh` (offline). Exit codes: 0 OK, 2 missing tools/args, 3 schema/hash mismatch, 4 stale, 5 shadow/scope failure. - CI should run verifier before simulations and fail fast on non-zero exit. ## Quotas & backpressure - Default limits: max 10 concurrent shadow runs per tenant; queue depth 100; reject when `policy:simulate:shadow` scope missing. - Simulators must be read-only: no writes to policy stores; only emit shadow metrics. ## Offline policy-sim kit - Lockfile + DSSE, digests of policy/graph/sbom/time-anchor/dataset. - Bundle alongside replay packs; verifier uses local SHA256 only (no network). ## Shadow isolation & redaction - Always run in `shadow` mode; block if requested runMode != `shadow`. - Redact PII fields (`user`, `ip`, `headers`, `secrets`) before storing fixtures; keep only hashes. - Require DSSE evidence when storing fixtures or responding to API clients.