{
  "schema_version": "1.0.0",
  "bot_id": "6.18",
  "bot_name": "ReplaySimulator",
  "slug": "replay_simulator",
  "layer": "Governance",
  "layer_key": "gov",
  "bot_class": "Governance Service",
  "authority": [
    "Simulate"
  ],
  "status": "planned",
  "readiness": "Spec ready",
  "flagship": false,
  "is_reference": false,
  "public_export": false,
  "identity": {
    "layer": "Governance",
    "bot_class": "Governance",
    "authority": "Simulate",
    "runs_before": "\u2014",
    "runs_after": "\u2014",
    "applies_to": "Continuous",
    "default_mode": "shadow",
    "user_visible": "Yes",
    "developer_owner": "Governance pod"
  },
  "purpose": "Re-runs any historical pipeline trace against the current bot revisions to verify that the outcome would be the same (or to surface changes). Used for regression testing, incident post-mortems, and 'what would have happened' reviews. Runs only on recorded ReportEnvelope streams \u2014 never against live state.",
  "why_it_matters": [
    {
      "failure": "Regression detection",
      "consequence": "When a single bot is bumped, the simplest correctness check is to replay yesterday's traffic and diff the outcomes."
    },
    {
      "failure": "Postmortem reproducibility",
      "consequence": "An incident review that cannot reproduce the exact decision is just speculation."
    },
    {
      "failure": "Promotion gate",
      "consequence": "Templates require a passing replay against the canonical fixture set before promoting from shadow to advisory."
    }
  ],
  "polymarket_inputs": [],
  "internal_inputs": [
    {
      "input": "Recorded ReportEnvelope stream",
      "source": "ReportEnvelope archive",
      "required": true,
      "use": "Source of inputs to replay."
    },
    {
      "input": "Current bot revisions",
      "source": "Bot registry",
      "required": true,
      "use": "Target system to replay against."
    }
  ],
  "raw_params": [
    "max_replay_minutes \u00b7 1\u20131440",
    "tolerance_bps \u00b7 0\u2013500"
  ],
  "parameters": [
    {
      "name": "max_replay_minutes",
      "default": 60,
      "warning": "60",
      "hard": "180",
      "controls": "Maximum replay duration in a single run.",
      "why_default_matters": "60 minutes is enough for a single incident window without overwhelming the simulator.",
      "threshold_logic": [
        {
          "condition": "60",
          "action": "Default"
        }
      ],
      "dev_check": "if (replay_window > p.max_replay_minutes) chunk();",
      "user_facing": "(Internal.)"
    },
    {
      "name": "tolerance_bps",
      "default": 5,
      "warning": "\u2014",
      "hard": "\u2014",
      "controls": "Tolerance in basis points for numeric outputs (slippage, cost) before a diff is flagged as REGRESSION.",
      "why_default_matters": "5 bps is below normal noise floor on Polymarket but tight enough to catch real changes.",
      "threshold_logic": [
        {
          "condition": "\u2264 5 bps",
          "action": "MATCH"
        },
        {
          "condition": "> 5 bps",
          "action": "REGRESSION"
        }
      ],
      "dev_check": "if (abs(now - then) > p.tolerance_bps) flag('REGRESSION');",
      "user_facing": "(Internal.)"
    }
  ],
  "default_config": {
    "max_replay_minutes": 60,
    "tolerance_bps": 5
  },
  "flow": "Receive ReplayJob(window) \u2192 load recorded ReportEnvelopes \u2192 for each input, invoke the current bot pipeline in a sandboxed runtime (no network writes) \u2192 diff outputs against the recorded outputs \u2192 emit ReplayDigest with match/diff counts and the first 10 mismatches.",
  "decision_logic": {
    "approve": "Strict input match (same intent_id, same payload). Tolerance comparison on numeric outputs. Exact match on enum/categorical outputs.",
    "reshape_required": "This bot does not reshape orders.",
    "reject": "No reject path defined for this bot \u2014 it is observe-only.",
    "warning_only": "No warn-only path defined."
  },
  "decision_output_example": {
    "kind": "ReplayDigest",
    "window_start_ms": 1715260000000,
    "window_end_ms": 1715263600000,
    "matches": 1042,
    "regressions": 3,
    "first_regressions": [
      {
        "intent_id": "intent_001",
        "field": "cost_estimate.slippage_bps",
        "then": 35,
        "now": 41
      }
    ]
  },
  "developer_log": "Per replay: job_id, window, total_inputs, matches, regressions, runtime_ms.",
  "user_explanations": [
    {
      "situation": "When this bot acts",
      "message": "Replays past activity through the current system to confirm nothing important changed."
    }
  ],
  "failure_modes": {
    "main_failure_mode": "Replay sandbox accidentally calls a live network endpoint.",
    "false_positive_risk": "Time-dependent outputs (anything reading now_ms()) flagged as regressions; mitigation: the replay runtime injects a frozen clock.",
    "false_negative_risk": "Bot uses external state not captured in the recording; mitigation: bots that read external state must declare it in `data_freshness.max_external_feed_age_ms` and recordings include it.",
    "safe_fallback": "If the sandbox cannot guarantee no-network mode, abort the replay and emit ReplayDigest with status=ABORTED."
  },
  "acceptance_tests": {
    "unit": [
      {
        "test": "A replay against an unchanged bot version reports zero regressions on its golden traces.",
        "setup": "Synthetic fixture per template.",
        "expected": "Behaviour matches the rule described in the test name."
      }
    ],
    "integration": [
      {
        "test": "Replay 1 hour of recorded traffic through a deliberately changed bot and assert regressions are surfaced.",
        "expected": "End-to-end behaviour matches the spec without manual intervention."
      }
    ],
    "property": [
      {
        "property": "Match count + regression count equals total input count for any non-aborted run.",
        "required": "Always true across all generated inputs."
      }
    ]
  },
  "reference_implementation": {
    "language": "pseudocode",
    "pseudocode": "for env in archive.window(job.start_ms, job.end_ms):\n  out = sandbox.run(current_bots, env.input)\n  if differs(out, env.recorded_output, p.tolerance_bps):\n    regressions.append(diff_record(env, out))\n  else:\n    matches += 1\nemit('ReplayDigest', job, matches, regressions[:10])"
  },
  "wire_examples": {
    "input": {
      "job_id": "replay_001",
      "window_start_ms": 1715260000000,
      "window_end_ms": 1715263600000
    },
    "output": {
      "kind": "ReplayDigest",
      "matches": 1042,
      "regressions": 3
    }
  },
  "reason_codes": [
    {
      "code": "GOV_REPLAY_MATCH",
      "severity": "P3",
      "meaning": "Gov Replay Match",
      "action": "See decision output and developer log for context.",
      "user_message": "Replays past activity through the current system to confirm nothing important changed."
    },
    {
      "code": "GOV_REPLAY_REGRESSION",
      "severity": "P3",
      "meaning": "Gov Replay Regression",
      "action": "See decision output and developer log for context.",
      "user_message": "Replays past activity through the current system to confirm nothing important changed."
    },
    {
      "code": "GOV_REPLAY_ABORTED",
      "severity": "P3",
      "meaning": "Gov Replay Aborted",
      "action": "See decision output and developer log for context.",
      "user_message": "Replays past activity through the current system to confirm nothing important changed."
    },
    {
      "code": "GOV_REPLAY_NO_NETWORK_VIOLATION",
      "severity": "P3",
      "meaning": "Gov Replay No Network Violation",
      "action": "See decision output and developer log for context.",
      "user_message": "Replays past activity through the current system to confirm nothing important changed."
    }
  ],
  "metrics": {
    "emitted": [
      {
        "name": "replay_jobs_total",
        "type": "counter",
        "unit": "event",
        "labels": [
          "bot_id"
        ],
        "meaning": "Replay jobs total."
      },
      {
        "name": "replay_matches_total",
        "type": "counter",
        "unit": "event",
        "labels": [
          "bot_id"
        ],
        "meaning": "Replay matches total."
      },
      {
        "name": "replay_regressions_total",
        "type": "counter",
        "unit": "event",
        "labels": [
          "bot_id"
        ],
        "meaning": "Replay regressions total."
      },
      {
        "name": "replay_aborts_total",
        "type": "counter",
        "unit": "event",
        "labels": [
          "bot_id"
        ],
        "meaning": "Replay aborts total."
      }
    ],
    "alerts": [],
    "dashboards": [
      "6.18 overview dashboard"
    ]
  },
  "state": {
    "summary": "Replay archive index. Job history. No live state.",
    "stores": [
      {
        "name": "replay_simulator_state",
        "kind": "in-memory + fast KV mirror",
        "key": "bot_id",
        "value": "Replay archive index. Job history. No live state.",
        "ttl": "24h",
        "durability": "crash-safe via KV mirror"
      }
    ],
    "recovery": "Cold-start hydrates from fast KV; missing keys default to safe fallback.",
    "on_restart": "All in-flight decisions are re-evaluated; no bot decision is trusted across restart without re-emit."
  },
  "concurrency": {
    "execution_model": "Runs in a sandbox process pool. Concurrent jobs allowed; each is isolated.",
    "max_in_flight": 32,
    "idempotency_key": "order_intent_id",
    "replay_safe": true,
    "deduplication": "By idempotency_key within a 60s window.",
    "ordering_guarantees": "Per-market_id FIFO; cross-market unordered.",
    "timeout_ms": 250,
    "backpressure": "Bounded queue; oldest-dropped with metric increment when full.",
    "locking": "Per-market_id mutex; no global locks."
  },
  "dependencies": {
    "depends_on": [],
    "emits_to": []
  },
  "graph": {
    "requires": [],
    "required_before": [],
    "consumes": [
      "ReportEnvelopeArchive"
    ],
    "emits": [
      "OperationsReport(kind=ReplayDigest)"
    ],
    "blocks": false
  },
  "mode_support": [
    "off",
    "shadow",
    "advisory",
    "enforced"
  ],
  "latency_budget_ms": 600000,
  "data_freshness": {
    "max_market_data_age_ms": 0,
    "max_orderbook_age_ms": 0,
    "on_stale_data": "Replay reads only recorded data; live freshness does not apply."
  },
  "ownership": {
    "owner": "Governance pod",
    "on_call": "gov-oncall",
    "channel": "#polytraders-gov",
    "escalation": "Head of Governance",
    "severity_class": "P3"
  },
  "human_override": {
    "allowed": true,
    "who": "Governance on-call",
    "log_event": "GOV_REPLAY_OVERRIDE",
    "time_bound": "Single job",
    "scope": "Single replay window",
    "second_approval": false
  },
  "security_surfaces": {
    "summary": "Sandbox network is fully blocked. Only replay archive read access.",
    "signing": "None \u2014 bot does not sign or submit.",
    "secrets": [],
    "contract_calls": [],
    "abuse_vectors": [],
    "mitigations": [
      "Rate-limit per source",
      "Audit-log every override",
      "Require role-based authz on admin paths"
    ]
  },
  "polymarket_v2_compat": {
    "clob_version": "V2",
    "collateral": "pUSD",
    "eip712_domain_version": "2",
    "builder_code_aware": true,
    "negrisk_aware": true,
    "multichain_ready": true,
    "sdk_used": "Polymarket CLOB V2 SDK",
    "settlement_contract": "CTFExchangeV2",
    "notes": "Replays against V2 bot revisions only."
  },
  "version": {
    "current": "0.1.0",
    "contract_version": "1.0.0",
    "last_breaking_change": "none",
    "deprecation_window_days": 30
  },
  "migration_history": [],
  "runbook": {
    "summary": "If replays fail with NO_NETWORK_VIOLATION, the offending bot leaks an external call \u2014 file a P2 issue.",
    "oncall_actions": [
      {
        "alert": "6.18_anomaly",
        "first_step": "Open the bot's reporting page and confirm the alert is real (not a metric hiccup).",
        "diagnosis": "Inspect developer log entries for the affected market_id over the last 30 minutes.",
        "mitigation": "Force-clear via Admin UI if the rule is clearly stale; otherwise leave engaged and notify owner.",
        "escalation": "Governance pod"
      }
    ],
    "manual_overrides": [
      {
        "command": "polytraders bot pause 6.18",
        "effect": "Disables the bot's enforcement layer; downstream consumers fall back to safe defaults."
      }
    ],
    "healthcheck": "GET /healthz/replay_simulator \u2192 200 if last successful evaluation < 60s ago."
  },
  "promotion_gates": {
    "to_shadow": [
      {
        "gate": "Stub",
        "how_measured": "golden replay reports zero regressions.",
        "threshold": "Documented threshold met for the full window."
      }
    ],
    "to_limited_live": [
      {
        "gate": "Shadow",
        "how_measured": "14 days running on a daily window.",
        "threshold": "Documented threshold met for the full window."
      },
      {
        "gate": "Advisory",
        "how_measured": "7 days.",
        "threshold": "Documented threshold met for the full window."
      }
    ],
    "to_general_live": [
      {
        "gate": "Enforced",
        "how_measured": "every promotion through the modes ladder requires a passing replay digest.",
        "threshold": "Documented threshold met for the full window."
      }
    ]
  },
  "failure_injection": [
    {
      "scenario": "Inject a deliberately wrong output and assert the regression is surfaced",
      "how_to_inject": "Inject a deliberately wrong output and assert the regression is surfaced.",
      "expected_behavior": "Bot detects within its latency budget and emits the corresponding reason code.",
      "recovery": "Remove the injected fault; bot returns to healthy state within one debounce window."
    },
    {
      "scenario": "Block the archive read and assert ABORTED status",
      "how_to_inject": "Block the archive read and assert ABORTED status.",
      "expected_behavior": "Bot detects within its latency budget and emits the corresponding reason code.",
      "recovery": "Remove the injected fault; bot returns to healthy state within one debounce window."
    }
  ],
  "capital_impact": "Indirect",
  "v3_status": {
    "phase": 7,
    "phase_name": "Governance & replay",
    "docs": {
      "done": 27,
      "total": 27,
      "state": "done"
    },
    "impl": {
      "done": 0,
      "total": 15,
      "state": "pending"
    },
    "runtime": {
      "done": 0,
      "total": 8,
      "state": "pending"
    },
    "overall": "pending"
  }
}