{"builder":"scripts/build-alert-precision-fix.py","consumed_by":"build-alert-precision-fix.py also rewrites forecast_per_country_thresholds.json — sentinel-daily-eval.py reads its `suppressed` list and skips alert rows for those countries","description":"The Sentinel alert false-alarm fix, before and after. Backtests every candidate fix over a 90-day window and shows which one shipped, the before/after false-alarm and true-positive rates, the suppressed-country list, and the per-country alert thresholds. The shipped fix downgrades chronically-false countries from 'alert' to 'watch'.","endpoint":"/v1/sentinel/alert-quality","honest_caveats":["Cutting the false-alarm rate TRADES recall. Each candidate's true_positive_rate_pct is reported next to its false_alarm_rate_pct — read them together.","Per-country thresholds are picked IN-SAMPLE on the same 90-day window they are scored on. The live forward false-alarm rate will be somewhat worse than this backtest; treat the backtest FP rate as an optimistic lower bound.","Thresholds are floored at the global 0.05 — the fix only ever RAISES an alert bar, never lowers one, so it can never fire MORE alerts than the baseline.","Countries with zero incidents in the window get recall=1 by convention when they also fire zero alerts; a country that fires alerts but had no incident is correctly scored as all-false-alarm.","The persistence gate fires one alert per sustained episode (on the day the run reaches PERSIST_DAYS length), not one per day — so it genuinely de-duplicates 1-day spikes rather than just delaying them.","Chronic-FP suppression downgrades a country to 'watch', it does not delete its forecast. The risk number is still published at /v1/sentinel/current_risk/{cc}; only the webhook alert is withheld.","DBSCAN / contagion multi-signal confirmation was considered but NOT backtested: those sidecars are point-in-time snapshots, not historical time series, so there is no honest 90-day backtest for them. They remain a candidate for a future fix once their history is retained."],"per_country_endpoint":"/v1/sentinel/alert-quality/{cc}","query_params":{"country":"Optional. ISO 3166-1 alpha-2 — narrow the per-country sections to one country."},"refresh":"daily at 05:10 UTC via cron","sidecar_path":"/opt/voidly-ai/ml-deploy/alert_quality_v1.json","_voidly_pay":{"claim_did":"https://voidly.ai/pay/claim","for_builders":"https://voidly.ai/pay/for-builders","marketplace":"https://api.voidly.ai/v1/pay/marketplace","live_demo":"https://huggingface.co/spaces/emperor-mew/voidly-pay","universal_proxy":{"url":"https://api.voidly.ai/v1/pay/proxy","example":"https://api.voidly.ai/v1/pay/proxy?u=<https-url>&to=did:voidly:<your-did>&price=0.01","page":"https://voidly.ai/pay/proxy","note":"Paywall any public HTTPS URL with one query param. No SDK install required."},"install":{"typescript":"npm install @voidly/pay","python":"pip install voidly-pay","langchain":"pip install voidly-pay-langchain","vercel_ai":"npm install @voidly/pay-vercel-ai","mcp":"npx @voidly/pay-mcp","cli":"npm install -g @voidly/pay-cli"},"note":"Voidly Pay is the open agent-to-agent payment rail. Claim a DID + 10 starter credits in 60s, or paywall any URL via the universal proxy with one query param."}}