{
  "schema_version": "1.0.0",
  "bot_id": "6.1",
  "bot_name": "BuilderAttribution",
  "slug": "builderattribution",
  "layer": "Governance",
  "layer_key": "gov",
  "bot_class": "Governance Service",
  "authority": [
    "Explain"
  ],
  "status": "live",
  "readiness": "General live",
  "flagship": true,
  "is_reference": true,
  "public_export": false,
  "identity": {
    "layer": "Governance",
    "bot_class": "Governance Service",
    "authority": "Explain",
    "runs_before": "Nothing \u2014 runs post-trade on every fill event",
    "runs_after": "Order submission and fill confirmation",
    "applies_to": "Every filled or partially filled order, and every daily reconciliation window",
    "default_mode": "general_live",
    "user_visible": "Advanced details only",
    "developer_owner": "Polytraders core \u2014 Governance pod"
  },
  "purpose": "BuilderAttribution tags every outgoing order with the Polytraders builder code before submission, logs each fill against the builder code, and reconciles the local fill log against the Polymarket builder-code report every 24 hours. If a discrepancy is detected \u2014 missing attribution, volume drift, or order counts that do not match \u2014 it quarantines the affected records and raises an alert. BuilderAttribution never submits, modifies, or cancels orders. Its authority is to explain and audit only.",
  "why_it_matters": [
    {
      "failure": "Builder code missing from an outgoing order",
      "consequence": "Volume attributed to the builder is undercounted in the Polymarket report, which affects fee rebates, builder-tier status, and audit trails for compliance."
    },
    {
      "failure": "Daily reconciliation not performed",
      "consequence": "Attribution drift compounds silently over time. Without regular reconciliation, discrepancies may only be discovered during a formal audit when they are much harder to investigate."
    },
    {
      "failure": "Quarantine not applied on drift",
      "consequence": "Unreconciled records remain in the live ledger and may be double-counted or misreported in downstream reports if not flagged and isolated."
    },
    {
      "failure": "Attribution log retention not enforced",
      "consequence": "Without a defined retention policy, old attribution records may be purged before they are needed for a historical audit or fee dispute."
    }
  ],
  "polymarket_inputs": [
    {
      "input": "Per-fill attribution data from every submitted order",
      "source": "CLOB",
      "required": true,
      "use": "Capture the builder_code field on each fill confirmation and store it in the attribution log."
    },
    {
      "input": "Polymarket builder-code volume report (rolling 24 hours)",
      "source": "Data API",
      "required": true,
      "use": "Reconcile the local fill log against Polymarket's official attribution report each reconcile window."
    },
    {
      "input": "Order submission acknowledgements",
      "source": "CLOB",
      "required": true,
      "use": "Confirm that the builder_code was accepted and echoed back in each order acknowledgement; flag any order where it is absent."
    }
  ],
  "internal_inputs": [
    {
      "input": "Outgoing order stream before submission",
      "source": "StrategyRegistry",
      "required": true,
      "use": "Intercept each order in-flight to attach the builder_code to the payload before it is signed and submitted."
    },
    {
      "input": "KillSwitch active flag",
      "source": "KillSwitch",
      "required": false,
      "use": "Continue logging and reconciliation even when KillSwitch is active \u2014 attribution must track all events including rejected ones."
    }
  ],
  "raw_params": [
    "builder_code \u00b7 string (locked)",
    "reconcile_window_h \u00b7 int (default 24)",
    "quarantine_on_drift \u00b7 bool (locked true)",
    "alert_on_missing_code \u00b7 bool (locked true)"
  ],
  "parameters": [
    {
      "name": "builder_code",
      "default": "polytraders",
      "warning": "\u2014",
      "hard": "\u2014",
      "controls": "The canonical builder code string that must be present on every outgoing order. This value is locked and can only be changed via a signed admin action.",
      "why_default_matters": "The builder code is the immutable identifier that Polymarket uses to attribute volume and fee rebates. Any change to it must be coordinated with Polymarket and logged formally.",
      "threshold_logic": [
        {
          "condition": "order.builder_code === builder_code",
          "action": "APPROVE \u2014 log and continue"
        },
        {
          "condition": "order.builder_code is absent",
          "action": "Attach builder_code and emit MISSING_CODE alert"
        },
        {
          "condition": "order.builder_code !== builder_code",
          "action": "Reject attachment and raise PARAMETER_CHANGE_REQUIRES_APPROVAL alert"
        }
      ],
      "dev_check": "if (!order.builder_code) { order.builder_code = p.builder_code; alerting.emit('MISSING_CODE'); }",
      "user_facing": "Every order is tagged with an identifier that tracks your trading volume on Polymarket. This supports fee reconciliation and audit."
    },
    {
      "name": "reconcile_window_h",
      "default": 24,
      "warning": 48,
      "hard": 72,
      "controls": "How often in hours the local fill log is reconciled against the Polymarket builder-code report.",
      "why_default_matters": "A 24-hour window aligns with Polymarket's rolling report cadence. Reconciling more frequently is supported but reconciling less often than 72 hours risks missing drift until it compounds.",
      "threshold_logic": [
        {
          "condition": "reconcile_window_h \u2264 24",
          "action": "Reconcile at configured frequency"
        },
        {
          "condition": "24\u201372 h",
          "action": "WARN \u2014 drift detection is delayed"
        },
        {
          "condition": "> 72 h",
          "action": "Reject config change \u2014 PARAMETER_CHANGE_REQUIRES_APPROVAL"
        }
      ],
      "dev_check": "if (p.reconcile_window_h > p.hard) throw new ConfigError('PARAMETER_CHANGE_REQUIRES_APPROVAL');",
      "user_facing": "Your trading activity is checked daily against the exchange's records to make sure everything is correctly attributed."
    },
    {
      "name": "quarantine_on_drift",
      "default": true,
      "warning": null,
      "hard": null,
      "controls": "When true (locked), any fill records that do not match the Polymarket report are moved to a quarantine partition and flagged for manual review before inclusion in any downstream report.",
      "why_default_matters": "Unreconciled records in the live ledger can corrupt downstream reports. Quarantining immediately on detection isolates the problem without data loss.",
      "threshold_logic": [
        {
          "condition": "quarantine_on_drift=true AND drift detected",
          "action": "Move affected records to quarantine partition and emit reconciliation alert"
        },
        {
          "condition": "quarantine_on_drift=false",
          "action": "Not permitted \u2014 parameter is locked to true"
        }
      ],
      "dev_check": "if (p.quarantine_on_drift && reconciliationDrift) quarantine.move(driftedRecords);",
      "user_facing": "If any inconsistency is found during the daily check, the affected records are set aside for review rather than being included in reports."
    },
    {
      "name": "alert_on_missing_code",
      "default": true,
      "warning": null,
      "hard": null,
      "controls": "When true (locked), every order that arrives at the attribution layer without a builder_code field triggers an immediate alert to the monitoring stack.",
      "why_default_matters": "A missing builder code on any order is an anomaly that should never happen in normal operation. Alerting on every occurrence ensures it is investigated immediately rather than discovered in the next reconciliation.",
      "threshold_logic": [
        {
          "condition": "alert_on_missing_code=true AND builder_code absent",
          "action": "Attach code and emit MISSING_CODE alert"
        },
        {
          "condition": "alert_on_missing_code=false",
          "action": "Not permitted \u2014 parameter is locked to true"
        }
      ],
      "dev_check": "if (p.alert_on_missing_code && !order.builder_code) alerting.emit('MISSING_BUILDER_CODE', { order_id: order.id });",
      "user_facing": "An alert is raised any time an order is detected without the required tracking code, so it can be investigated promptly."
    }
  ],
  "default_config": {
    "bot_id": "gov.builder_attribution",
    "version": "1.0.0",
    "mode": "general_live",
    "defaults": {
      "builder_code": "polytraders",
      "reconcile_window_h": 24,
      "quarantine_on_drift": true,
      "alert_on_missing_code": true
    },
    "locked": {
      "builder_code": {
        "change_requires_signed_admin_action": true
      },
      "quarantine_on_drift": {
        "immutable": true
      },
      "alert_on_missing_code": {
        "immutable": true
      },
      "reconcile_window_h": {
        "max": 72
      }
    }
  },
  "implementation_flow": [
    "Intercept every outgoing order from StrategyRegistry before it reaches the signing step; verify builder_code is present and correct.",
    "If builder_code is absent, attach the configured builder_code value and emit an alert to the monitoring stack (alert_on_missing_code).",
    "After each fill confirmation from the CLOB, extract the fill metadata (order_id, market_id, size_usd, price, side, timestamp, builder_code echoed by exchange).",
    "Append the fill record to the local attribution log with all metadata fields and a log_sequence_number for ordering.",
    "Every reconcile_window_h hours, fetch the Polymarket builder-code volume report from Data API for the matching time window.",
    "Compare local fill log totals (volume, order count, unique market count) against the Polymarket report for the same window.",
    "If discrepancy is detected: compute the drift delta, tag affected records with a quarantine flag, and move them to the quarantine partition (quarantine_on_drift).",
    "Emit a reconciliation report to the governance audit trail (GovernanceLog) whether the reconciliation passes or flags drift.",
    "Retain all attribution log records for a minimum of 90 days; quarantined records are retained indefinitely until manually reviewed and resolved.",
    "Produce a PostTradeExplanation entry for each reconciliation cycle summarising: total volume attributed, match status, drift delta if any, and quarantine record count."
  ],
  "decision_logic": {
    "approve": "Not applicable \u2014 BuilderAttribution does not approve or reject orders. It observes, tags, logs, and reconciles.",
    "reshape_required": "Not applicable \u2014 BuilderAttribution does not reshape orders.",
    "reject": "Not applicable as a trading decision. BuilderAttribution emits no RiskVote. The only action that resembles a reject is quarantining drift records.",
    "warning_only": "Missing builder_code on an inbound order triggers an alert but does not block the order \u2014 BuilderAttribution attaches the code and flags the anomaly. Reconciliation drift triggers quarantine and alert but does not halt trading."
  },
  "decision_output_schema": "GovernanceLog",
  "decision_output_example": {
    "attribution_id": "gov.builder_attribution",
    "event_type": "RECONCILIATION_COMPLETE",
    "window_start": "2026-05-08T00:00:00Z",
    "window_end": "2026-05-09T00:00:00Z",
    "local_volume_usd": 48320.5,
    "polymarket_volume_usd": 48320.5,
    "local_order_count": 217,
    "polymarket_order_count": 217,
    "drift_detected": false,
    "quarantine_count": 0,
    "builder_code": "polytraders",
    "retention_days": 90,
    "reconciled_at": "2026-05-09T00:05:12Z"
  },
  "developer_log": {
    "attribution_id": "gov.builder_attribution",
    "event_type": "FILL_LOGGED",
    "order_id": "ord_00123",
    "market_id": "CLOB:0xabc123",
    "side": "BUY",
    "size_usd": 250.0,
    "price": 0.62,
    "builder_code_present": true,
    "builder_code_echoed": "polytraders",
    "log_sequence_number": 4821,
    "fill_confirmed_at": "2026-05-09T11:45:00Z"
  },
  "user_explanations": [
    {
      "situation": "Daily reconciliation completed with no discrepancies",
      "message": "The system checked today's trading records against the exchange's report. All orders, volumes, and attribution codes matched exactly."
    },
    {
      "situation": "Reconciliation flagged a discrepancy",
      "message": "A difference was found between our records and the exchange's report. The affected records have been set aside for review. No trading is interrupted, but the discrepancy needs to be resolved."
    },
    {
      "situation": "Order arrived without attribution code",
      "message": "An order was detected without the required tracking code. The code was added automatically and the anomaly was flagged for investigation."
    },
    {
      "situation": "Historical attribution records requested",
      "message": "Attribution logs are retained for at least 90 days. Older records and any records held in the review queue are retained indefinitely until cleared."
    }
  ],
  "failure_modes": {
    "main_failure_mode": "A fill is processed and attributed but the Polymarket report is unavailable at reconciliation time, causing the local log to be marked as unverified until the next successful fetch.",
    "false_positive_risk": "Quarantining records due to a temporary data format change in the Polymarket report, when the underlying volume is correctly attributed but the comparison field changed.",
    "false_negative_risk": "Missing a genuine drift because the reconciliation time window does not fully overlap with the Polymarket report window, leaving a gap that does not appear in either comparison.",
    "safe_fallback": "If the Polymarket builder-code report is unavailable at reconciliation time, skip the comparison for that cycle, emit an alert, and retry at the next scheduled window. Never clear quarantine records automatically \u2014 require manual review.",
    "required_dependencies": [
      "CLOB fill confirmation stream",
      "Data API Polymarket builder-code report",
      "StrategyRegistry outgoing order stream",
      "Governance audit log storage (90-day retention)"
    ]
  },
  "acceptance_tests": {
    "unit": [
      {
        "test": "Attach builder_code when absent on outgoing order",
        "setup": "order.builder_code=undefined, builder_code='polytraders'",
        "expected": "order.builder_code='polytraders' attached; MISSING_CODE alert emitted"
      },
      {
        "test": "Log fill record with all metadata after fill confirmation",
        "setup": "Fill event: order_id=ord_001, size_usd=300, price=0.55, side=BUY",
        "expected": "Fill record in attribution log with correct fields and log_sequence_number"
      },
      {
        "test": "Reconciliation passes when local and report totals match",
        "setup": "local_volume=5000, polymarket_volume=5000, local_count=20, report_count=20",
        "expected": "GovernanceLog event_type=RECONCILIATION_COMPLETE, drift_detected=false"
      },
      {
        "test": "Quarantine records when drift detected",
        "setup": "local_volume=5100, polymarket_volume=5000 (drift=100)",
        "expected": "Drift records moved to quarantine, quarantine_count > 0, alert emitted"
      },
      {
        "test": "Reject reconcile_window_h above hard maximum",
        "setup": "reconcile_window_h=80, hard=72",
        "expected": "ConfigError PARAMETER_CHANGE_REQUIRES_APPROVAL"
      },
      {
        "test": "Retain quarantine records when auto-clear attempted",
        "setup": "Automated process attempts to clear quarantine without manual review flag",
        "expected": "Quarantine records remain; alert emitted"
      }
    ],
    "integration": [
      {
        "test": "End-to-end: order tagged, filled, logged, and reconciled against Polymarket report",
        "expected": "Full attribution lifecycle completes with matching GovernanceLog entry"
      },
      {
        "test": "Polymarket report unavailability causes skip-and-retry without data loss",
        "expected": "Reconciliation cycle skipped, alert emitted, records retained; next cycle reconciles full backlog"
      },
      {
        "test": "Missing builder_code on 5 consecutive orders triggers escalated alert",
        "expected": "Individual MISSING_CODE alerts plus an escalated pattern alert after 5 consecutive missing codes"
      }
    ],
    "property": [
      {
        "property": "Every fill event is logged before any downstream report uses it",
        "required": "Always true \u2014 fill logging is synchronous with fill confirmation"
      },
      {
        "property": "Quarantine records are never automatically cleared without a manual review flag",
        "required": "Always true"
      },
      {
        "property": "All attribution log records are retained for at least 90 days",
        "required": "Always true \u2014 retention enforcement is mandatory"
      }
    ]
  },
  "checklist_overrides": {},
  "legacy_goal": "Tag every order with Polytraders' builder code, log it, reconcile it daily against Polymarket's report.",
  "legacy_pm_signals": [
    "Every outgoing order's builder_code field",
    "Polymarket Builder-Code report (rolling 24h)",
    "Per-fill attribution logs"
  ],
  "legacy_external_feeds": [],
  "network": [
    "polygon"
  ],
  "api_surface": [
    "data_api",
    "clob_auth"
  ],
  "reference_implementation": {
    "summary": "Intercepts every outgoing order to verify the builderCode bytes32 field is present, logs each fill to the attribution ledger, and runs a 24-hour reconciliation against the Data API builder-code volume report. Quarantines drift records and emits a GovernanceLog on every cycle.",
    "language_note": "Pseudocode is language-agnostic. FETCH = read input. EMIT = produce output. Translate to TS/Python/Go/Rust.",
    "pseudocode": "// ---- PRE-SUBMISSION HOOK: called on every outgoing order ----\nFUNCTION attachAndVerifyBuilderCode(order):\n  // In V2, builderCode is a bytes32 field on the order (not HMAC)\n  IF order.builder IS NULL OR order.builder == ZERO_BYTES32:\n    order.builder = config.builder_code_bytes32\n    alerting.emit('BUILDER_CODE_MISSING', { order_id: order.id })\n  IF order.builder != config.builder_code_bytes32:\n    alerting.emit('BUILDER_CODE_MISMATCH', { order_id: order.id, found: order.builder })\n    raise PARAMETER_CHANGE_REQUIRES_APPROVAL\n  RETURN order\n\n// ---- POST-FILL HOOK: called on every fill confirmation ----\nFUNCTION logFill(fillEvent):\n  // fillEvent.builder is echoed back by CTFExchangeV2 from the on-order builderCode\n  IF fillEvent.builder != config.builder_code_bytes32:\n    alerting.emit('BUILDER_CODE_MISSING', { fill_id: fillEvent.fill_id })\n\n  record = {\n    fill_id:           fillEvent.fill_id,\n    order_id:          fillEvent.order_id,\n    market_id:         fillEvent.market_id,\n    side:              fillEvent.side,\n    size_pusd:         toUsdcUnits(fillEvent.size_usd),\n    price:             fillEvent.price,\n    builder_code:      fillEvent.builder,\n    // V2 fee: builder_fee = notional * bps / 10000\n    builder_fee_pusd:  toUsdcUnits(fillEvent.size_usd * fillEvent.builder_fee_bps / 10000),\n    fill_confirmed_at: fillEvent.timestamp,\n    log_seq:           postgres.nextval('attribution_log_seq')\n  }\n  postgres.INSERT('attribution_log', record)\n  EMIT GovernanceLog(event_type='FILL_LOGGED', fill_id=fillEvent.fill_id)\n\n// ---- RECONCILIATION: runs every reconcile_window_h hours ----\nFUNCTION reconcile(windowStart, windowEnd):\n  localRows = postgres.SELECT('attribution_log',\n                WHERE fill_confirmed_at BETWEEN windowStart AND windowEnd)\n  localVolume = SUM(r.size_pusd FOR r IN localRows)\n  localCount  = COUNT(localRows)\n\n  report = FETCH data_api.GET(\n    '/builder-code-report?code=' + config.builder_code\n    + '&from=' + windowStart + '&to=' + windowEnd\n  )\n  IF report IS NULL:\n    alerting.emit('RECONCILIATION_SKIP', { reason: 'data_api_unavailable' })\n    RETURN\n\n  drift_usd = abs(localVolume - report.volume_pusd)\n  drift_pct = drift_usd / max(localVolume, 1)\n\n  IF drift_pct > 0.01:  // > 1% drift\n    driftRows = identify_drift_rows(localRows, report)\n    postgres.UPDATE('attribution_log', driftRows, { quarantined: true })\n    alerting.emit('RECONCILIATION_DRIFT_OBSERVED', { drift_usd, drift_pct })\n    EMIT GovernanceLog(event_type='RECONCILIATION_DRIFT',\n                       drift_usd=drift_usd, quarantine_count=len(driftRows))\n  ELSE:\n    EMIT GovernanceLog(event_type='RECONCILIATION_COMPLETE',\n                       drift_detected=False, local_volume=localVolume,\n                       polymarket_volume=report.volume_pusd)\n\n  // Retain all records >= 90 days; quarantined records retained indefinitely\n",
    "helpers": [
      {
        "name": "toUsdcUnits",
        "signature": "toUsdcUnits(rawUsd: float) -> int",
        "purpose": "Converts a raw pUSD float to the 6-decimal integer unit used by CTFExchangeV2; ensures fill_log precision matches on-chain values."
      },
      {
        "name": "fetchClobPublic",
        "signature": "fetchClobPublic(path: str) -> JSON",
        "purpose": "Used to verify fill confirmations against CLOB order status for reconciliation."
      },
      {
        "name": "platformFee",
        "signature": "platformFee(notional: float, prob: float, feeRate: float) -> float",
        "purpose": "Estimates the platform fee component; logged alongside builder_fee_pusd for fee breakdown reporting."
      },
      {
        "name": "buildOrderTypedData",
        "signature": "buildOrderTypedData(order, domain) -> TypedData",
        "purpose": "Not called by BuilderAttribution; referenced to confirm that builderCode bytes32 is populated by SmartRouter before this bot sees the order."
      }
    ],
    "sdk_calls": [
      "data_api.GET('/builder-code-report?code=...&from=...&to=...')",
      "clob_auth.GET('/fills?order_id=...&limit=100')",
      "postgres.INSERT('attribution_log', record)",
      "postgres.SELECT('attribution_log', WHERE fill_confirmed_at BETWEEN ... AND ...)",
      "alerting.emit('RECONCILIATION_DRIFT_OBSERVED', metadata)"
    ],
    "complexity": "O(F) per reconciliation window where F = fill count; O(1) per fill log event"
  },
  "wire_examples": {
    "input": [
      {
        "label": "Fill confirmation from CTFExchangeV2",
        "source": "clob_auth",
        "payload": {
          "fill_id": "fill_00a1b2c3d4e5f6a7",
          "order_id": "ord_00123",
          "market_id": "0x9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c",
          "side": "BUY",
          "size_usd": 250.0,
          "price": 0.62,
          "builder": "0x706f6c7974726164657273000000000000000000000000000000000000000000",
          "builder_fee_bps": 25,
          "fill_confirmed_at": "2026-05-09T11:45:00Z"
        }
      },
      {
        "label": "Data API builder-code volume report",
        "source": "data_api",
        "payload": {
          "builder_code": "polytraders",
          "window_start": "2026-05-08T00:00:00Z",
          "window_end": "2026-05-09T00:00:00Z",
          "volume_pusd": 48320.5,
          "order_count": 217,
          "fill_count": 217
        }
      }
    ],
    "output": [
      {
        "label": "GovernanceLog \u2014 RECONCILIATION_COMPLETE (no drift)",
        "payload": {
          "attribution_id": "gov.builder_attribution",
          "event_type": "RECONCILIATION_COMPLETE",
          "window_start": "2026-05-08T00:00:00Z",
          "window_end": "2026-05-09T00:00:00Z",
          "local_volume_pusd": 48320.5,
          "polymarket_volume_pusd": 48320.5,
          "local_order_count": 217,
          "polymarket_order_count": 217,
          "drift_detected": false,
          "quarantine_count": 0,
          "builder_code": "polytraders",
          "retention_days": 90,
          "reconciled_at": "2026-05-09T00:05:12Z"
        }
      },
      {
        "label": "GovernanceLog \u2014 RECONCILIATION_DRIFT (quarantine triggered)",
        "payload": {
          "attribution_id": "gov.builder_attribution",
          "event_type": "RECONCILIATION_DRIFT",
          "window_start": "2026-05-08T00:00:00Z",
          "window_end": "2026-05-09T00:00:00Z",
          "local_volume_pusd": 48420.5,
          "polymarket_volume_pusd": 48320.5,
          "drift_usd": 100.0,
          "drift_pct": 0.00207,
          "drift_detected": true,
          "quarantine_count": 2,
          "reconciled_at": "2026-05-09T00:06:00Z"
        }
      }
    ],
    "curl": "curl 'https://data-api.polymarket.com/builder-code-report?code=polytraders&from=2026-05-08T00:00:00Z&to=2026-05-09T00:00:00Z'"
  },
  "reason_codes": [
    {
      "code": "BUILDER_CODE_MISSING",
      "severity": "WARN",
      "meaning": "An outgoing order arrived at the attribution layer without the builderCode bytes32 field set, or a fill confirmation echoed back a zero builder code.",
      "action": "Attach the configured builderCode and emit WARN alert.",
      "user_message": "An order was detected without the required tracking code. It was added automatically and the anomaly was flagged."
    },
    {
      "code": "BUILDER_FEE_RATE_CAPPED",
      "severity": "WARN",
      "meaning": "The observed builder_fee_bps on a fill exceeds the V2 cap (taker: 100 bps, maker: 50 bps).",
      "action": "Log the anomaly; quarantine the fill record for manual review.",
      "user_message": ""
    },
    {
      "code": "RECONCILIATION_DRIFT_OBSERVED",
      "severity": "WARN",
      "meaning": "Local fill volume or count diverges from the Polymarket builder-code report by > 1%.",
      "action": "Quarantine drift records; emit reconciliation drift alert.",
      "user_message": "A difference was found between our records and the exchange's report. The affected records have been set aside for review."
    },
    {
      "code": "PARAMETER_CHANGE_REQUIRES_APPROVAL",
      "severity": "HARD_REJECT",
      "meaning": "reconcile_window_h exceeds the 72h hard maximum, or builder_code was changed without a signed admin action.",
      "action": "Reject the config change and emit an alert.",
      "user_message": ""
    },
    {
      "code": "BUILDER_ATTRIBUTION_CODE_MISMATCH",
      "severity": "WARN",
      "meaning": "An order's builder bytes32 field does not match the configured builderCode value.",
      "action": "Reject the order from proceeding to signing; emit WARN alert.",
      "user_message": ""
    },
    {
      "code": "BUILDER_ATTRIBUTION_QUARANTINE_BLOCKED",
      "severity": "WARN",
      "meaning": "An automated process attempted to clear quarantine records without a manual review flag.",
      "action": "Reject the clear operation; retain records; emit alert.",
      "user_message": "Affected records are held for review and cannot be cleared automatically."
    },
    {
      "code": "BUILDER_ATTRIBUTION_REPORT_UNAVAILABLE",
      "severity": "WARN",
      "meaning": "Data API builder-code report is unavailable at reconciliation time.",
      "action": "Skip this reconciliation cycle; emit alert; retry on next scheduled window.",
      "user_message": ""
    }
  ],
  "metrics": {
    "emitted": [
      {
        "name": "polytraders_gov_builderattribution_fills_logged_total",
        "type": "counter",
        "unit": "count",
        "labels": [
          "market_id"
        ],
        "meaning": "Total fill events logged to the attribution ledger."
      },
      {
        "name": "polytraders_gov_builderattribution_volume_pusd_total",
        "type": "counter",
        "unit": "usd",
        "labels": [],
        "meaning": "Cumulative pUSD volume attributed to the builder code."
      },
      {
        "name": "polytraders_gov_builderattribution_drift_usd",
        "type": "gauge",
        "unit": "usd",
        "labels": [],
        "meaning": "Absolute drift between local and Polymarket volume at the last reconciliation."
      },
      {
        "name": "polytraders_gov_builderattribution_quarantine_count",
        "type": "gauge",
        "unit": "count",
        "labels": [],
        "meaning": "Number of fill records currently in the quarantine partition."
      },
      {
        "name": "polytraders_gov_builderattribution_missing_code_total",
        "type": "counter",
        "unit": "count",
        "labels": [],
        "meaning": "Total orders seen without a builder code; should be 0 in normal operation."
      },
      {
        "name": "polytraders_gov_builderattribution_reconcile_latency_ms",
        "type": "histogram",
        "unit": "seconds",
        "labels": [],
        "meaning": "Wall-clock latency of a full reconciliation cycle."
      }
    ],
    "alerts": [
      {
        "name": "BuilderAttributionMissingCode",
        "condition": "rate(polytraders_gov_builderattribution_missing_code_total[5m]) > 0",
        "severity": "P1",
        "runbook": "#runbook-builderattribution-missing-code"
      },
      {
        "name": "BuilderAttributionDriftDetected",
        "condition": "polytraders_gov_builderattribution_drift_usd > 0",
        "severity": "P1",
        "runbook": "#runbook-builderattribution-drift"
      },
      {
        "name": "BuilderAttributionQuarantineGrowing",
        "condition": "delta(polytraders_gov_builderattribution_quarantine_count[1h]) > 0",
        "severity": "P2",
        "runbook": "#runbook-builderattribution-quarantine"
      },
      {
        "name": "BuilderAttributionReportUnavailable",
        "condition": "rate(polytraders_gov_builderattribution_fills_logged_total[30m]) == 0",
        "severity": "P2",
        "runbook": "#runbook-builderattribution-report"
      }
    ],
    "dashboards": [
      "Grafana \u2014 Governance / BuilderAttribution reconciliation",
      "Grafana \u2014 Fee accounting / builder code volume and drift"
    ],
    "log_levels": {
      "DEBUG": "Per-fill record details including builder_fee_bps and fill_confirmed_at.",
      "INFO": "Fill logged; reconciliation cycle completed (pass or drift).",
      "WARN": "Missing builder code on order; reconciliation drift detected; quarantine records added.",
      "ERROR": "Data API report unavailable at reconciliation time; Postgres write failure."
    }
  },
  "state": {
    "summary": "Maintains a durable Postgres attribution ledger with all fill records, plus a quarantine partition for drift records. Reconciliation state is persisted per window.",
    "stores": [
      {
        "name": "attribution_log",
        "kind": "postgres",
        "key": "fill_id",
        "value": "{ fill_id, order_id, market_id, side, size_pusd, price, builder_code, builder_fee_pusd, fill_confirmed_at, quarantined: bool, log_seq: int }",
        "ttl": "none",
        "durability": "strong"
      },
      {
        "name": "reconciliation_state",
        "kind": "postgres",
        "key": "window_start + window_end",
        "value": "{ local_volume, polymarket_volume, drift_usd, drift_pct, status, reconciled_at }",
        "ttl": "none",
        "durability": "strong"
      }
    ],
    "recovery": "On cold start, Postgres attribution_log is read immediately. No in-memory state needs rebuilding.",
    "on_restart": "All state is in Postgres and available immediately. The next fill event triggers a fresh log write."
  },
  "concurrency": {
    "execution_model": "single-threaded event loop (fill hook) + scheduled reconciliation goroutine",
    "max_in_flight": 500,
    "idempotency_key": "fill_id",
    "replay_safe": true,
    "deduplication": "by fill_id \u2014 duplicate fill events are ignored",
    "ordering_guarantees": "log_seq is monotonically increasing per postgres.nextval()",
    "timeout_ms": 500,
    "backpressure": "shed",
    "locking": "none (Postgres serializable isolation)"
  },
  "dependencies": {
    "depends_on": [
      {
        "bot_id": "exec.smart_router",
        "why": "SmartRouter populates the builderCode bytes32 field on each order before BuilderAttribution sees it.",
        "contract": "order.builder must equal config.builder_code_bytes32 before signing."
      }
    ],
    "emits_to": [],
    "sibling": [
      {
        "bot_id": "sec.contract_address_guard",
        "why": "ContractAddressGuard logs every security check to BuilderAttribution's governance audit trail.",
        "contract": "GovernanceLog entry emitted for each SecurityCheck decision."
      }
    ],
    "external": [
      {
        "service": "Data API (builder-code report)",
        "endpoint": "https://data-api.polymarket.com",
        "sla": "99.9% / 500ms p99",
        "failure_mode": "Skip reconciliation cycle; emit alert; retry on next window."
      },
      {
        "service": "CLOB Auth API (fills)",
        "endpoint": "https://clob.polymarket.com",
        "sla": "99.95% / 200ms p99",
        "failure_mode": "Fill log entry deferred until fill confirmation is received."
      }
    ]
  },
  "security_surfaces": {
    "summary": "BuilderAttribution reads fill data and writes to the governance ledger. It never signs orders or holds private keys.",
    "signing": "This bot does NOT sign anything.",
    "secrets": [],
    "contract_calls": [],
    "abuse_vectors": [
      "Clearing quarantine records automatically without manual review to hide attribution drift",
      "Substituting a different builder code bytes32 on orders to redirect fee attribution",
      "Modifying builder_code parameter without a signed admin action"
    ],
    "mitigations": [
      "quarantine_on_drift is locked immutable; auto-clear is rejected",
      "builder_code parameter requires signed admin action and is audit-logged",
      "Each fill record is immutable once written; log_seq is monotonically increasing",
      "alert_on_missing_code is locked immutable; every missing code alert is raised regardless"
    ]
  },
  "polymarket_v2_compat": {
    "clob_version": "v2",
    "collateral": "pUSD",
    "eip712_domain_version": "2",
    "builder_code_aware": true,
    "negrisk_aware": false,
    "multichain_ready": false,
    "sdk_used": "@polymarket/clob-client-v2 ^2.x",
    "settlement_contract": "CTFExchangeV2 on Polygon",
    "notes": "V2 builder attribution uses a native builderCode bytes32 field on every order (replaced V1 HMAC-based builder). Both maker and taker orders can carry different builder codes in V2. Builder fee formula: builder_fee = notional * bps / 10000. Taker max 100 bps, maker max 50 bps, 1 bp granularity. Fee is taker-only currently; fill records include builder_fee_pusd for auditability."
  },
  "version": {
    "spec": "2.0.0",
    "implementation": "2.1.3",
    "schema": "2",
    "released": "2026-04-28"
  },
  "migration_history": [
    {
      "date": "2026-04-28",
      "from": "v1 (USDC.e + HMAC builder)",
      "to": "v2 (pUSD + builderCode field)",
      "reason": "Polymarket V2 cutover",
      "action_taken": "Replaced HMAC builder logic with on-order builderCode bytes32 field. Attribution log schema updated to include builder_fee_bps and builder_fee_pusd columns. Reconciliation report format updated to match Data API V2 builder-code report schema. All fill amounts now denominated in pUSD."
    }
  ],
  "failure_injection": [
    {
      "scenario": "MISSING_BUILDER_CODE",
      "how_to_inject": "Submit order with order.builder = ZERO_BYTES32",
      "expected_behavior": "BuilderAttribution attaches configured builderCode; BUILDER_CODE_MISSING alert emitted",
      "recovery": "Automatic; code is attached."
    },
    {
      "scenario": "DATA_API_REPORT_UNAVAILABLE",
      "how_to_inject": "Block TCP to data-api.polymarket.com during reconciliation window",
      "expected_behavior": "Reconciliation cycle skipped; BUILDER_ATTRIBUTION_REPORT_UNAVAILABLE alert; records retained",
      "recovery": "Next cycle reconciles full backlog once Data API is reachable."
    },
    {
      "scenario": "RECONCILIATION_DRIFT",
      "how_to_inject": "Manually insert an extra fill record into attribution_log with size_pusd=10000",
      "expected_behavior": "RECONCILIATION_DRIFT_OBSERVED alert; drift records quarantined",
      "recovery": "Manual review and removal of synthetic record; reconciliation passes on next cycle."
    },
    {
      "scenario": "QUARANTINE_AUTO_CLEAR_BLOCKED",
      "how_to_inject": "Call postgres.DELETE on quarantine records without setting manual_review_flag=true",
      "expected_behavior": "Delete rejected by application guard; BUILDER_ATTRIBUTION_QUARANTINE_BLOCKED alert",
      "recovery": "Manual review must be completed before clearing."
    },
    {
      "scenario": "BUILDER_CODE_MISMATCH",
      "how_to_inject": "Set order.builder to a different bytes32 value",
      "expected_behavior": "BUILDER_CODE_MISMATCH alert; PARAMETER_CHANGE_REQUIRES_APPROVAL raised; order blocked from signing",
      "recovery": "Correct builder code must be set."
    }
  ],
  "runbook": {
    "summary": "BuilderAttribution incidents involve missing builder codes, reconciliation drift, or quarantine growth. Every RECONCILIATION_DRIFT event is a P1 requiring investigation before the next daily report.",
    "oncall_actions": [
      {
        "alert": "BuilderAttributionMissingCode",
        "first_step": "Identify which strategy or SmartRouter instance is emitting orders without builderCode.",
        "diagnosis": "If a single strategy is the source, it may be using an old SDK version that does not set builder bytes32.",
        "mitigation": "Pause the affected strategy and require SDK upgrade. BuilderAttribution will attach the code in the interim, but the root cause must be fixed.",
        "escalation": "Governance pod lead + Exec pod lead immediately."
      },
      {
        "alert": "BuilderAttributionDriftDetected",
        "first_step": "Review reconciliation drift details in the GovernanceLog.",
        "diagnosis": "Check whether the drift corresponds to a Data API report format change or a genuine attribution discrepancy.",
        "mitigation": "Do NOT clear quarantine records until the root cause is confirmed. Engage Polymarket support if drift is large.",
        "escalation": "Governance pod lead immediately."
      },
      {
        "alert": "BuilderAttributionQuarantineGrowing",
        "first_step": "Check how many records are in quarantine and when they were added.",
        "diagnosis": "If quarantine is growing steadily, drift may be systematic (e.g., a fill reporting format change).",
        "mitigation": "Investigate the fill data format. Do not reduce the drift detection threshold.",
        "escalation": "Governance pod lead after 30 minutes."
      }
    ],
    "manual_overrides": [
      {
        "command": "polytraders gov clear-quarantine --fill-ids <ids> --reviewed-by <operator>",
        "effect": "Clears specific quarantine records after manual review. Requires governance pod lead sign-off and is audit-logged."
      },
      {
        "command": "polytraders gov rerun-reconciliation --window-start <ts> --window-end <ts>",
        "effect": "Re-runs a specific reconciliation window without clearing existing records. Used to check if drift resolves after a Data API format fix."
      }
    ],
    "healthcheck": "GET /health \u2192 200 if Postgres attribution_log is reachable, last fill was logged < 300s ago during active trading, and quarantine_count has not increased in the last 24h."
  },
  "promotion_gates": {
    "to_shadow": [
      {
        "gate": "Unit tests pass for fill logging, builder code attach, and reconciliation logic",
        "how_measured": "CI test run",
        "threshold": "100% pass"
      },
      {
        "gate": "Postgres write integration test verified",
        "how_measured": "Integration test",
        "threshold": "Pass"
      }
    ],
    "to_limited_live": [
      {
        "gate": "Reconciliation cycle completes within 30s for a 24h window of 1000 fill records",
        "how_measured": "polytraders_gov_builderattribution_reconcile_latency_ms histogram",
        "threshold": "< 30s"
      },
      {
        "gate": "Missing-code alert fires within 1s of order without builderCode",
        "how_measured": "Unit test + integration test",
        "threshold": "Pass"
      }
    ],
    "to_general_live": [
      {
        "gate": "End-to-end: fill tagged, logged, reconciled, GovernanceLog entry matches Data API report",
        "how_measured": "E2E test in staging",
        "threshold": "Pass"
      },
      {
        "gate": "Quarantine auto-clear rejection verified",
        "how_measured": "Failure injection test",
        "threshold": "Pass"
      }
    ]
  },
  "reporting_groups": [
    "post_trade",
    "governance_audit"
  ],
  "capital_impact": "Indirect",
  "v3_status": {
    "phase": 3,
    "phase_name": "Reporting & event store",
    "docs": {
      "done": 27,
      "total": 27,
      "state": "done"
    },
    "impl": {
      "done": 0,
      "total": 15,
      "state": "pending"
    },
    "runtime": {
      "done": 0,
      "total": 8,
      "state": "pending"
    },
    "overall": "pending"
  }
}