{"version":"oracle-methodology-v1.0","pipeline":{"overview":"Drazill resolves markets through a transparent, multi-stage oracle pipeline. Structured resolution criteria are validated before a market can auto-resolve; external provider results are fetched, cross-verified where a second source exists, and mapped to outcomes with an explicit confidence score. Only high-confidence results auto-resolve — everything else is held for human review. Every resolution writes a public evidence packet and timeline and opens a dispute window.","stages":["Structured criteria definition and lint validation (must PASS before auto-resolution).","Provider selection by external event id / category.","Result fetch with split timeouts, retries, and circuit breakers.","Cross-source verification where a second provider covers the category.","Outcome mapping with an explicit confidence score (explicit id → fuzzy name → binary title analysis → draw detection).","Confidence-gated resolution: HIGH auto-resolves; MEDIUM queues for admin review; LOW flags for manual resolution.","Evidence packet and timeline recording (sources, provider timestamps, normalized result, outcome-mapping explanation).","Dispute window opens; overturns re-settle balance-safely."],"confidence_tiers":[{"tier":"HIGH","threshold":">= 0.85","action":"Auto-resolve."},{"tier":"MEDIUM","threshold":"0.6–0.85","action":"Queue for admin review."},{"tier":"LOW","threshold":"< 0.6","action":"Manual resolution required."}],"auto_resolve_threshold":0.85,"review_threshold":0.6,"default_dispute_window_hours":168,"max_retries":5,"retry_delay_seconds":3600,"notes":["Manual-only markets (no external provider) are resolved by admin review against the published criteria, not by automated polling.","Synthetic price simulation never writes canonical resolution state.","A market's structured resolution criteria can override the default dispute window."]},"providers":[{"provider_id":"espn","display_name":"ESPN","description":"Official North American major-league scoreboards (NHL, NFL, NBA, MLB) via ESPN's public sports API.","categories":["hockey","american-football","basketball","baseball","tennis","mma-boxing","golf","college-basketball","college-football","cfl"],"sources":[{"name":"ESPN API","url":"https://site.api.espn.com/apis/site/v2/sports","type":"primary","description":"Primary result/price feed."}],"requires_api_key":false,"authentication":"None (public scoreboard endpoint).","external_id_format":"espn:<sport>:<league>:<event_id> (e.g. espn:hockey:nhl:401559123)","precision":"Official final scores. Team / binary outcomes are deterministic from the final result; regulation, overtime, and shootout finals (STATUS_FINAL / _OT / _SO) all map to FINISHED.","latency_expectation":"Final results are typically reflected within minutes of the official game end.","update_frequency":"Polled by the auto-resolution worker every 300s while a closed market awaits resolution.","tie_break_rules":["Overtime and shootout finals are treated as completed games.","A draw/tie maps to a 'Draw'/'Tie' outcome when one exists; otherwise the market is held for manual review.","Postponed or cancelled events cancel and refund the market rather than resolving it."],"fallback":["Cross-verified against API-Sports for the leagues where both feeds cover the event before auto-resolution.","Provider disagreement or low mapping confidence routes to manual admin review — never auto-resolved.","Repeated provider failures increment resolution_failure_count and surface as a DEGRADED source state."],"cross_verification_providers":["api-sports"],"rate_limit":"Unofficial public API with no published quota; requests use split connect/read timeouts, retries, and a circuit breaker.","known_limitations":["ESPN's public API is unofficial and may change without notice.","Coverage is limited to major North American leagues (NHL / NFL / NBA / MLB)."]},{"provider_id":"api-sports","display_name":"API-Sports","description":"Global sports results (football/soccer, Formula 1, tennis, cricket, golf, MMA/boxing) via the API-Sports.io feeds.","categories":["football-soccer","formula-1","tennis","cricket","rugby","golf","mma-boxing"],"sources":[{"name":"API-Sports — football-soccer","url":"https://v3.football.api-sports.io","type":"primary","description":null},{"name":"API-Sports — formula-1","url":"https://v1.formula-1.api-sports.io","type":"primary","description":null},{"name":"API-Sports — tennis","url":"https://v1.tennis.api-sports.io","type":"primary","description":null},{"name":"API-Sports — cricket","url":"https://v1.cricket.api-sports.io","type":"primary","description":null},{"name":"API-Sports — rugby","url":"https://v1.rugby.api-sports.io","type":"primary","description":null},{"name":"API-Sports — golf","url":"https://v1.golf.api-sports.io","type":"primary","description":null},{"name":"API-Sports — mma-boxing","url":"https://v1.mma.api-sports.io","type":"primary","description":null}],"requires_api_key":true,"authentication":"Server-side API key sent per request.","external_id_format":"api-sports:<sport>:<fixture_id> (e.g. api-sports:football-soccer:1035123)","precision":"Official fixture results across supported competitions. Final, after-extra-time, after-penalties, awarded, and walkover statuses all map to FINISHED.","latency_expectation":"Results are available shortly after the official competition end; exact timing varies by competition and feed.","update_frequency":"Polled by the auto-resolution worker every 300s while a closed market awaits resolution.","tie_break_rules":["After-extra-time and after-penalties results map to FINISHED.","Draws map to a 'Draw' outcome when present; otherwise manual review.","Abandoned or cancelled fixtures cancel and refund the market."],"fallback":["Cross-verified against ESPN for football/soccer where both feeds cover the fixture.","Low confidence or source disagreement routes to manual admin review.","Circuit breaker and retry handling defer resolution on a feed outage rather than guessing."],"cross_verification_providers":["espn"],"rate_limit":"Free tier is ~100 requests/day; production uses a paid plan. Resilient HTTP with retries and a circuit breaker.","known_limitations":["Requires a valid API key; without it these categories fall back to manual resolution.","Per-competition status vocabularies differ and are normalized internally before mapping."]},{"provider_id":"coingecko","display_name":"CoinGecko","description":"Cryptocurrency spot and historical price data for above/below-threshold, range, and period-high markets.","categories":["crypto","cryptocurrency"],"sources":[{"name":"CoinGecko API","url":"https://api.coingecko.com/api/v3","type":"primary","description":"Primary result/price feed."},{"name":"CoinGecko Pro API","url":"https://pro-api.coingecko.com/api/v3","type":"primary","description":"Used when a Pro API key is configured."}],"requires_api_key":false,"authentication":"None for the public tier; optional Pro API key for higher quota.","external_id_format":"coingecko:<coin>:<market_type>:<params> (e.g. coingecko:bitcoin:above:100000:2026-12-31)","precision":"The price observed at the market's resolution timestamp determines the outcome (above/below threshold, within range, or period high), read to the provider's published precision.","latency_expectation":"Spot price is near-real-time; the closing/observation price is available shortly after the resolution timestamp.","update_frequency":"Polled by the auto-resolution worker every 300s while a closed market awaits resolution.","tie_break_rules":["Threshold markets resolve strictly by the comparison at the observation time (e.g. price >= threshold).","Range markets resolve to the matching price bucket.","Exactly-at-threshold handling follows the market's structured criteria edge-case rules."],"fallback":["No automated cross-provider verification for crypto; low confidence routes to manual review.","Circuit breaker and retries defer resolution on a feed outage."],"cross_verification_providers":[],"rate_limit":"Free tier is ~10,000 calls/month; an optional Pro API key raises the quota.","known_limitations":["Single-source price feed (no automated cross-verification).","Coverage is limited to the supported coins."]}],"methodology":{"formula_version":"oracle-methodology-v1.0","data_window":"Static provider registry plus each market's structured resolution criteria.","sample_size":3,"last_computed_at":null,"confidence_level":"HIGH","limitations":["Methodology describes the resolution process, not a guarantee of any specific outcome.","Provider availability and external feed coverage can change; manual review is the fallback in every case."],"informational_only":true},"source_of_truth":"app/services/oracle_methodology_service.py"}