{
  "schema_version": "1.0.0",
  "bot_id": "1.14",
  "bot_name": "FeeAndGasGuard",
  "slug": "feeandgasguard",
  "layer": "Risk",
  "layer_key": "risk",
  "bot_class": "Guardrail",
  "authority": [
    "Veto",
    "Reshape"
  ],
  "status": "planned",
  "readiness": "Planned",
  "flagship": false,
  "is_reference": false,
  "public_export": false,
  "identity": {
    "layer": "Risk",
    "bot_class": "Guardrail",
    "authority": "Veto, Reshape",
    "runs_before": "ExecutionPlan emit",
    "runs_after": "Strategy OrderIntent",
    "applies_to": "Every OrderIntent \u2014 refuses trades whose realistic fee and Polygon gas burden consumes more than the configured fraction of expected edge",
    "default_mode": "planned",
    "user_visible": "summary-only",
    "developer_owner": "Polytraders core \u2014 Risk pod"
  },
  "purpose": "FeeAndGasGuard estimates the total transaction cost (CLOB maker/taker fee plus Polygon gas) for a proposed order and rejects or downsizes it when the cost-to-edge ratio exceeds the configured ceiling. It prevents strategies from placing orders where fee drag exceeds the expected edge, turning a positive-expected-value intent into a negative-EV execution.",
  "why_it_matters": [
    {
      "failure": "Fee drag exceeds edge",
      "consequence": "Placing an order where fees exceed the expected edge results in a systematically negative-EV trade that erodes capital over many repetitions."
    },
    {
      "failure": "Gas spike not accounted for",
      "consequence": "Polygon gas spikes during congestion can materially increase transaction cost; ignoring gas makes fee estimates unreliable during high-traffic periods."
    }
  ],
  "polymarket_inputs": [
    {
      "input": "CLOB fee rate for the target market (operator-set, bps)",
      "source": "clob_public",
      "required": true,
      "use": "Compute taker or maker fee for the proposed order size and probability."
    },
    {
      "input": "Current Polygon gas price estimate",
      "source": "onchain",
      "required": true,
      "use": "Estimate the Polygon gas cost for the CTFExchangeV2.matchOrders() settlement transaction."
    },
    {
      "input": "Current market probability (best bid/ask midpoint)",
      "source": "clob_public",
      "required": true,
      "use": "Compute the fee using the V2 formula: C * feeRate * p * (1-p), which peaks at p=0.5."
    }
  ],
  "internal_inputs": [
    {
      "input": "Strategy expected edge (bps) per order",
      "source": "internal",
      "required": true,
      "use": "Compare against the estimated fee-to-notional ratio to enforce the max_fee_to_edge_ratio limit."
    },
    {
      "input": "KillSwitch active flag",
      "source": "KillSwitch",
      "required": true,
      "use": "If active, reject immediately."
    }
  ],
  "raw_params": [
    "max_fee_to_edge_ratio \u00b7 float",
    "max_fee_bps \u00b7 int",
    "min_order_usd \u00b7 int"
  ],
  "parameters": [
    {
      "name": "max_fee_to_edge_ratio",
      "default": 0.5,
      "warning": 0.35,
      "hard": 0.5,
      "controls": "Maximum ratio of total transaction cost (fee + gas) to expected edge. Orders where cost/edge > this threshold are blocked or downsized.",
      "why_default_matters": "At 0.5, at least 50% of the expected edge survives after costs; below this threshold execution becomes net-negative in expectation.",
      "threshold_logic": [
        {
          "condition": "cost_to_edge <= 0.35",
          "action": "APPROVE"
        },
        {
          "condition": "0.35 < cost_to_edge <= 0.5",
          "action": "WARN \u2014 FEE_GUARD_COST_APPROACHING"
        },
        {
          "condition": "cost_to_edge > 0.5",
          "action": "HARD_REJECT \u2014 FEE_GUARD_COST_EXCEEDS_EDGE"
        }
      ],
      "dev_check": "if (totalCost / expectedEdge > params.max_fee_to_edge_ratio) return reject('FEE_GUARD_COST_EXCEEDS_EDGE');",
      "user_facing": "This trade's fees would consume too much of the expected gain."
    },
    {
      "name": "max_fee_bps",
      "default": 100,
      "warning": 75,
      "hard": 100,
      "controls": "Absolute maximum fee rate in basis points regardless of the edge ratio. Protects against operator-set fee spikes on specific markets.",
      "why_default_matters": "100 bps is the taker fee ceiling defined in the V2 protocol; orders on markets above this rate indicate a misconfiguration or anomalous market.",
      "threshold_logic": [
        {
          "condition": "effective_fee_bps <= 75",
          "action": "APPROVE"
        },
        {
          "condition": "75 < effective_fee_bps <= 100",
          "action": "WARN"
        },
        {
          "condition": "effective_fee_bps > 100",
          "action": "HARD_REJECT \u2014 FEE_GUARD_RATE_ANOMALY"
        }
      ],
      "dev_check": "if (effectiveFeeBps > params.max_fee_bps) return reject('FEE_GUARD_RATE_ANOMALY');",
      "user_facing": "The fee rate for this market is unusually high. The order was blocked to protect against unexpected costs."
    },
    {
      "name": "min_order_usd",
      "default": 10,
      "warning": null,
      "hard": null,
      "controls": "Minimum order size in pUSD. Below this threshold, fixed gas costs dominate the fee structure and the cost-to-edge ratio is always unfavourable.",
      "why_default_matters": "Gas costs are fixed per transaction; below 10 pUSD the gas component alone can exceed the expected edge on a typical order.",
      "threshold_logic": [
        {
          "condition": "intent.size_usd >= 10",
          "action": "Proceed with fee check"
        },
        {
          "condition": "intent.size_usd < 10",
          "action": "HARD_REJECT \u2014 FEE_GUARD_ORDER_TOO_SMALL"
        }
      ],
      "dev_check": "if (intent.size_usd < params.min_order_usd) return reject('FEE_GUARD_ORDER_TOO_SMALL');",
      "user_facing": "The order size is too small to trade economically after fees. Please use a larger order size."
    }
  ],
  "default_config": {
    "bot_id": "risk.fee_and_gas_guard",
    "version": "0.1.0",
    "mode": "hard_guard",
    "defaults": {
      "max_fee_to_edge_ratio": 0.5,
      "max_fee_bps": 100,
      "min_order_usd": 10
    },
    "locked": {
      "max_fee_bps": {
        "max": 100
      },
      "min_order_usd": {
        "min": 1
      }
    }
  },
  "implementation_flow": [
    "Receive OrderIntent with market_id, side, size_usd, price, and expected_edge_bps from strategy.",
    "Check KillSwitch; if active, HARD_REJECT(KILL_SWITCH_ACTIVE).",
    "Fetch current market probability p = (best_ask + best_bid) / 2 from CLOB.",
    "Fetch operator-set fee rate for the market from CLOB (taker: max 100 bps; maker: max 50 bps).",
    "Compute CLOB fee: fee_usd = size_usd * fee_rate_bps / 10000 * p * (1-p).",
    "Fetch current Polygon gas price; estimate gas cost for CTFExchangeV2.matchOrders().",
    "Compute total_cost_usd = fee_usd + gas_cost_usd.",
    "If intent.size_usd < min_order_usd, HARD_REJECT(FEE_GUARD_ORDER_TOO_SMALL).",
    "If effective_fee_bps > max_fee_bps, HARD_REJECT(FEE_GUARD_RATE_ANOMALY).",
    "Compute edge_usd = size_usd * expected_edge_bps / 10000.",
    "If total_cost_usd / edge_usd > max_fee_to_edge_ratio, HARD_REJECT(FEE_GUARD_COST_EXCEEDS_EDGE).",
    "APPROVE with fee_estimate_usd and cost_to_edge_ratio attached."
  ],
  "decision_logic": {
    "approve": "Total transaction cost is within the max_fee_to_edge_ratio and both fee_bps and order size are within limits.",
    "reshape_required": "Not currently implemented; fee-to-edge ratio cannot be improved by resizing (it is largely size-independent for the CLOB fee formula). Future version may restrict to maker-only to reduce fee.",
    "reject": "Fee-to-edge ratio exceeds the hard ceiling, fee rate is anomalously high, order size is below min_order_usd, or KillSwitch is active."
  },
  "decision_output_schema": "RiskVote",
  "decision_output_example": {
    "guard_id": "risk.fee_and_gas_guard",
    "decision": "HARD_REJECT",
    "severity": "HARD",
    "reason_code": "FEE_GUARD_COST_EXCEEDS_EDGE",
    "message": "Estimated cost 4.20 pUSD (ratio 0.70) exceeds max_fee_to_edge_ratio 0.50 for edge 6.00 pUSD.",
    "constraints": {},
    "inputs_used": [
      "clob_public.fee_rate",
      "clob_public.prices",
      "onchain.gas_price",
      "internal.expected_edge"
    ],
    "checked_at": "2026-05-10T13:00:00Z"
  },
  "developer_log": {
    "bot_id": "risk.fee_and_gas_guard",
    "decision": "HARD_REJECT",
    "reason_code": "FEE_GUARD_COST_EXCEEDS_EDGE",
    "inputs_used": [
      "clob_public.fee_rate",
      "clob_public.prices",
      "onchain.gas_price"
    ],
    "metrics": {
      "fee_usd": 3.8,
      "gas_usd": 0.4,
      "total_cost_usd": 4.2,
      "edge_usd": 6.0,
      "cost_to_edge_ratio": 0.7,
      "fee_rate_bps": 60,
      "prob": 0.5
    },
    "checked_at": "2026-05-10T13:00:00Z"
  },
  "user_explanations": [
    {
      "situation": "Order blocked \u2014 fees exceed edge",
      "message": "The estimated fees for this trade would consume more than half of the expected gain. The order was blocked to protect your returns."
    },
    {
      "situation": "Order blocked \u2014 fee rate anomaly",
      "message": "The fee rate for this market is unusually high. The order was blocked to protect against unexpected costs."
    },
    {
      "situation": "Order blocked \u2014 order too small",
      "message": "Orders below the minimum size are not economical after fees. Please increase the order size."
    }
  ],
  "failure_modes": {
    "main_failure_mode": "Approving an order because the expected_edge estimate from the strategy is overstated, making the cost-to-edge ratio appear acceptable when it is not.",
    "false_positive_risk": "Rejecting a valid order because the Polygon gas price estimate is temporarily inflated during congestion.",
    "false_negative_risk": "Approving an order because the fee rate cache is stale and does not reflect a recent operator fee increase.",
    "safe_fallback": "If fee rate or gas price data is unavailable, HARD_REJECT with FEE_GUARD_DATA_UNAVAILABLE. Never approve on missing fee data.",
    "required_dependencies": [
      "CLOB fee rate endpoint",
      "Polygon gas price oracle",
      "CLOB market prices",
      "Strategy expected_edge",
      "KillSwitch active flag"
    ]
  },
  "acceptance_tests": {
    "unit": [
      {
        "test": "Approve when cost-to-edge within threshold",
        "setup": "total_cost=2.0, edge=6.0, ratio=0.33",
        "expected": "APPROVE"
      },
      {
        "test": "Reject when cost-to-edge exceeds ceiling",
        "setup": "total_cost=4.2, edge=6.0, ratio=0.70",
        "expected": "HARD_REJECT(FEE_GUARD_COST_EXCEEDS_EDGE)"
      },
      {
        "test": "Reject when fee_bps > max_fee_bps",
        "setup": "effective_fee_bps=120, max=100",
        "expected": "HARD_REJECT(FEE_GUARD_RATE_ANOMALY)"
      },
      {
        "test": "Reject when order below min_order_usd",
        "setup": "size_usd=5, min=10",
        "expected": "HARD_REJECT(FEE_GUARD_ORDER_TOO_SMALL)"
      }
    ],
    "integration": [
      {
        "test": "Gas spike causes rejection in live environment",
        "expected": "HARD_REJECT(FEE_GUARD_COST_EXCEEDS_EDGE) when Polygon gas price increases significantly during congestion"
      },
      {
        "test": "KillSwitch bypasses fee check",
        "expected": "HARD_REJECT(KILL_SWITCH_ACTIVE) without fetching fee or gas data"
      }
    ],
    "property": [
      {
        "property": "Approved order always has cost-to-edge ratio <= max_fee_to_edge_ratio",
        "required": "Always true"
      },
      {
        "property": "Missing fee data never results in APPROVE",
        "required": "Always true \u2014 fail-closed on data unavailability"
      }
    ]
  },
  "checklist_overrides": {},
  "legacy_goal": "Refuse trades whose realistic fee and gas burden eats more than the configured edge fraction.",
  "legacy_pm_signals": [
    "Per-route taker / maker fee, expected fill size and price",
    "Predicted edge from strategy (in bps)",
    "Builder-attribution rebate offset"
  ],
  "legacy_external_feeds": [
    "L2 / Polygon gas oracle (live)"
  ],
  "reporting_groups": [
    "risk_compliance"
  ],
  "reason_codes": [
    {
      "code": "KILL_SWITCH_ACTIVE",
      "severity": "HARD_REJECT",
      "meaning": "Global kill switch active.",
      "action": "Immediate HARD_REJECT.",
      "user_message": "Trading is paused. Please try again later."
    },
    {
      "code": "FEE_GUARD_COST_EXCEEDS_EDGE",
      "severity": "HARD_REJECT",
      "meaning": "Total cost-to-edge ratio exceeds the hard ceiling.",
      "action": "HARD_REJECT; log total_cost_usd, edge_usd, and ratio.",
      "user_message": "This trade's fees would consume too much of the expected gain."
    },
    {
      "code": "FEE_GUARD_RATE_ANOMALY",
      "severity": "HARD_REJECT",
      "meaning": "Effective fee rate exceeds max_fee_bps (V2 protocol ceiling).",
      "action": "HARD_REJECT; alert on-call \u2014 anomalous fee rate detected.",
      "user_message": "The fee rate for this market is unusually high."
    },
    {
      "code": "FEE_GUARD_ORDER_TOO_SMALL",
      "severity": "HARD_REJECT",
      "meaning": "Order size is below min_order_usd; gas costs dominate.",
      "action": "HARD_REJECT.",
      "user_message": "The order size is too small to be economical after fees."
    },
    {
      "code": "FEE_GUARD_COST_APPROACHING",
      "severity": "WARN",
      "meaning": "Cost-to-edge ratio between warning and hard threshold.",
      "action": "Attach WARN annotation; APPROVE.",
      "user_message": ""
    }
  ],
  "metrics": {
    "emitted": [
      {
        "name": "polytraders_risk_feeandgasguard_decisions_total",
        "type": "counter",
        "unit": "count",
        "labels": [
          "decision",
          "reason_code"
        ],
        "meaning": "Total decisions by type and reason."
      },
      {
        "name": "polytraders_risk_feeandgasguard_cost_to_edge_ratio",
        "type": "gauge",
        "unit": "ratio",
        "labels": [
          "market_id"
        ],
        "meaning": "Current cost-to-edge ratio at last evaluation per market."
      },
      {
        "name": "polytraders_risk_feeandgasguard_gas_cost_usd",
        "type": "gauge",
        "unit": "usd",
        "labels": [],
        "meaning": "Estimated Polygon gas cost in pUSD at last evaluation."
      },
      {
        "name": "polytraders_risk_feeandgasguard_eval_latency_ms",
        "type": "histogram",
        "unit": "milliseconds",
        "labels": [],
        "meaning": "Latency from intent to RiskVote emit."
      }
    ],
    "alerts": [
      {
        "name": "FeeAndGasGuardGasSpike",
        "condition": "polytraders_risk_feeandgasguard_gas_cost_usd > 2.0",
        "severity": "P2",
        "runbook": "#runbook-feeandgas-gas"
      },
      {
        "name": "FeeAndGasGuardRateAnomaly",
        "condition": "rate(polytraders_risk_feeandgasguard_decisions_total{reason_code='FEE_GUARD_RATE_ANOMALY'}[5m]) > 0",
        "severity": "P1",
        "runbook": "#runbook-feeandgas-anomaly"
      }
    ]
  },
  "state": {
    "store": "in-memory",
    "shape": "Fee rate cache per market_id; gas price cached globally; both refreshed on TTL.",
    "ttl": "Fee rate: 60s; gas price: 15s.",
    "recovery": "On cold start, both caches populated from CLOB and onchain oracle before first evaluation.",
    "size_estimate": "~200 B per market fee entry; ~100 B for gas price entry"
  },
  "concurrency": {
    "execution_model": "single-threaded event loop",
    "max_in_flight": 300,
    "idempotency_key": "intent_id",
    "timeout_ms": 100,
    "backpressure": "drop newest",
    "locking": "fee and gas caches are read-only at evaluation; writes use TTL-based replacement"
  },
  "dependencies": {
    "depends_on": [
      {
        "bot_id": "risk.kill_switch",
        "why": "Global brake checked first.",
        "contract": "HARD_REJECT(KILL_SWITCH_ACTIVE) short-circuits all fee evaluation."
      }
    ],
    "emits_to": [
      {
        "bot_id": "exec.smart_router",
        "why": "Approved RiskVote passes to SmartRouter.",
        "contract": "APPROVE passes; HARD_REJECT discards intent."
      }
    ],
    "sibling": [],
    "external": [
      {
        "service": "CLOB API (fee rates + prices)",
        "endpoint": "https://clob.polymarket.com",
        "sla": "99.95% / 200ms p99",
        "failure_mode": "HARD_REJECT(FEE_GUARD_DATA_UNAVAILABLE) if fee data unavailable."
      },
      {
        "service": "Polygon gas oracle",
        "endpoint": "onchain gas price feed",
        "sla": "best-effort",
        "failure_mode": "HARD_REJECT(FEE_GUARD_DATA_UNAVAILABLE) if gas price unavailable."
      }
    ]
  },
  "security_surfaces": {
    "signs_orders": false,
    "private_key_access": "none",
    "abuse_vectors": [
      "Inflating expected_edge_bps in the intent to make the cost-to-edge ratio appear acceptable",
      "Submitting during low-gas windows to bypass gas-inclusive cost checks, then executing during high-gas periods"
    ],
    "mitigations": [
      "expected_edge_bps is validated against a per-strategy cap from the internal config; values above the cap are clipped",
      "Gas price is fetched at evaluation time, not at intent generation time"
    ]
  },
  "polymarket_v2_compat": {
    "clob_version": "v2",
    "collateral": "pUSD",
    "eip712_domain_version": "2",
    "builder_code_aware": true,
    "negrisk_aware": false,
    "multichain_ready": false,
    "sdk_used": "py-clob-client-v2",
    "settlement_contract": "CTFExchangeV2",
    "notes": "Fee computation uses V2 formula: C * feeRate * p * (1-p). Fees are operator-set at match time (not on signed order). Taker max 100 bps; maker max 50 bps; 1 bp granularity."
  },
  "version": {
    "spec": "2.0.0",
    "implementation": "0.1.0",
    "schema": "2",
    "released": null,
    "planned_release": "Q3-2026"
  },
  "migration_history": [
    {
      "date": "2026-04-28",
      "from": "n/a",
      "to": "v2-spec",
      "reason": "Spec drafted post-CLOB-V2 cutover; bot not yet implemented",
      "action_taken": "Designed against V2 schema (pUSD, builder codes, V2 EIP-712 domain)"
    }
  ],
  "reference_implementation": {
    "pseudocode": "FUNCTION evaluateFeeAndGas(intent):\n  ks = FETCH internal.killswitch.status\n  IF ks.active: EMIT RiskVote(HARD_REJECT, KILL_SWITCH_ACTIVE); RETURN\n\n  IF intent.size_usd < params.min_order_usd:\n    EMIT RiskVote(HARD_REJECT, FEE_GUARD_ORDER_TOO_SMALL); RETURN\n\n  feeRate = FETCH clob_public.fee_rate(intent.market_id)\n  prices = FETCH clob_public.prices(intent.market_id)\n  gasPrice = FETCH onchain.gas_price()\n  IF feeRate IS NULL OR prices IS NULL OR gasPrice IS NULL:\n    EMIT RiskVote(HARD_REJECT, FEE_GUARD_DATA_UNAVAILABLE); RETURN\n\n  IF feeRate.bps > params.max_fee_bps:\n    EMIT RiskVote(HARD_REJECT, FEE_GUARD_RATE_ANOMALY); RETURN\n\n  p = (prices.ask + prices.bid) / 2\n  feeUsd = intent.size_usd * (feeRate.bps / 10000) * p * (1 - p)\n  gasUsd = estimateGasCost(gasPrice, 'matchOrders')\n  totalCost = feeUsd + gasUsd\n\n  edgeUsd = intent.size_usd * (intent.expected_edge_bps / 10000)\n  ratio = totalCost / edgeUsd\n\n  IF ratio > params.max_fee_to_edge_ratio:\n    EMIT RiskVote(HARD_REJECT, FEE_GUARD_COST_EXCEEDS_EDGE,\n                  total_cost=totalCost, ratio=ratio); RETURN\n  IF ratio > params.max_fee_to_edge_ratio * 0.7:\n    annotations.append(WARN(FEE_GUARD_COST_APPROACHING, ratio=ratio))\n\n  EMIT RiskVote(APPROVE, fee_estimate_usd=totalCost, cost_to_edge=ratio)",
    "sdk_calls": [
      "clob_public.fee_rate(market_id)",
      "clob_public.prices(market_id)",
      "onchain.gas_price()",
      "internal.killswitch.status()"
    ],
    "complexity": "O(1)"
  },
  "wire_examples": {
    "input": [
      {
        "label": "OrderIntent \u2014 fee check",
        "source": "internal",
        "payload": {
          "intent_id": "int_f6a7b8c9d0e10006",
          "market_id": "0x4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e",
          "size_usd": 150,
          "price": 0.5,
          "expected_edge_bps": 40,
          "generated_at_ms": 1746800000000
        }
      }
    ],
    "output": [
      {
        "label": "RiskVote \u2014 HARD_REJECT cost exceeds edge",
        "payload": {
          "guard_id": "risk.fee_and_gas_guard",
          "decision": "HARD_REJECT",
          "severity": "HARD",
          "reason_code": "FEE_GUARD_COST_EXCEEDS_EDGE",
          "message": "Cost 4.20 pUSD / edge 6.00 pUSD = ratio 0.70 exceeds ceiling 0.50.",
          "constraints": {},
          "checked_at": "2026-05-10T13:00:00Z"
        }
      }
    ]
  },
  "failure_injection": [
    {
      "scenario": "GAS_PRICE_UNAVAILABLE",
      "how_to_inject": "Block onchain gas oracle",
      "expected_behaviour": "HARD_REJECT(FEE_GUARD_DATA_UNAVAILABLE)",
      "recovery": "Returns to normal once gas oracle is reachable."
    },
    {
      "scenario": "FEE_RATE_ANOMALY",
      "how_to_inject": "Set mock fee_rate.bps=150 in CLOB mock",
      "expected_behaviour": "HARD_REJECT(FEE_GUARD_RATE_ANOMALY) with alert fired",
      "recovery": "Returns to normal once fee rate is corrected."
    },
    {
      "scenario": "HIGH_GAS_COST",
      "how_to_inject": "Set gas price 10x normal in mock",
      "expected_behaviour": "HARD_REJECT(FEE_GUARD_COST_EXCEEDS_EDGE) for small-to-medium orders",
      "recovery": "Returns to APPROVE once gas price normalises."
    }
  ],
  "runbook": {
    "summary": "FeeAndGasGuard incidents typically involve a gas spike or an anomalous fee rate on a newly listed market. Verify gas price normality before adjusting parameters.",
    "oncall_actions": [
      {
        "alert": "FeeAndGasGuardGasSpike",
        "first_step": "Check Polygon gas price on external tracker; confirm spike is network-wide, not a data feed error.",
        "escalation": "Infra on-call if gas oracle is misbehaving.",
        "diagnosis": "",
        "mitigation": ""
      },
      {
        "alert": "FeeAndGasGuardRateAnomaly",
        "first_step": "Identify market_id from reason_code log; check CLOB fee rate endpoint for that market directly.",
        "escalation": "Risk pod lead if fee rate is genuinely anomalous.",
        "diagnosis": "",
        "mitigation": ""
      }
    ],
    "manual_overrides": [
      {
        "command": "polytraders risk set-gas-override --gas-usd <value> --duration 300s",
        "effect": "During a gas oracle outage; sets a conservative fixed gas estimate to unblock orders."
      }
    ],
    "healthcheck": "GET /internal/health/feeandgasguard \u2192 green: CLOB fee rate cache age < 60s, gas price cache age < 15s, no FEE_GUARD_RATE_ANOMALY in last 5m; red: Fee or gas data cache expired or unavailable"
  },
  "promotion_gates": {
    "to_shadow": [
      {
        "gate": "Unit tests pass for fee calculation and anomaly detection",
        "how_measured": "CI test run",
        "threshold": "100% pass"
      }
    ],
    "to_limited_live": [
      {
        "gate": "Shadow cost-to-edge ratios match expected distribution over 48h",
        "how_measured": "Grafana cost_to_edge_ratio gauge histogram",
        "threshold": "No spurious rejections in shadow"
      }
    ],
    "to_general_live": [
      {
        "gate": "Fee formula verified against V2 protocol spec for 5 reference markets",
        "how_measured": "Manual verification against CLOB API docs",
        "threshold": "100% match"
      }
    ]
  },
  "reporting": {
    "emits_kinds": [
      "RiskVote"
    ],
    "topics": [
      "polytraders.reports.risk"
    ],
    "partition_by": "trace_id",
    "cadence": "every-event",
    "retention_class": "2y",
    "sampling_rule": "emit-every",
    "bus_failure_action": "fail-closed",
    "user_visible": "summary-only",
    "consumes_kinds": [
      "ObservationReport"
    ]
  },
  "capital_impact": "Direct",
  "mode_support": [
    "quarantine"
  ],
  "v3_status": {
    "phase": 4,
    "phase_name": "Core risk",
    "docs": {
      "done": 27,
      "total": 27,
      "state": "done"
    },
    "impl": {
      "done": 0,
      "total": 15,
      "state": "pending"
    },
    "runtime": {
      "done": 0,
      "total": 8,
      "state": "pending"
    },
    "overall": "pending"
  }
}