feat(manifold): add persistent cooldowns to reduce redundant evaluations
CI/CD / build-and-push (push) Successful in 8s

The trading loop re-evaluated the same ~22 politics/tech markets every ~60s,
flooding manifold_match_audit with ~76k rows (~3,500 attempts/market) of which
none carried new information, making the metrics uninterpretable.

Add per-market persistent cooldowns:
- New table manifold_eval_cooldown (poly_market_id PK, last_evaluated_at,
  last_status, retry_after, cooldown_reason) created via run_migrations.
- bayesian.evaluate() consults the cooldown BEFORE calling the matcher and skips
  the call entirely while now() < retry_after — no matcher call, no audit row,
  no signal (equivalent to no_results). After a real evaluation it upserts the
  cooldown with a verdict-dependent backoff: no_results/low_score/outcome_mismatch/
  ambiguous_inversion -> 24h, conditional_market -> 7d, accepted -> 1h.
- manifold.py stays a pure client/matcher with no DB access.
- New db methods get_manifold_cooldown / upsert_manifold_cooldown.
- /api/metrics/manifold-matches summary gains unique_markets
  {evaluated, accepted, coverage_rate} for per-market (not per-attempt) coverage.

Matching logic, MANIFOLD_MATCHER_VERSION, MANIFOLD_LOGODDS_WEIGHT, edge/exposure
thresholds and existing audit rows are unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
chemavx
2026-06-08 12:19:31 +00:00
co-authored by Claude Opus 4.8
parent df988a36b6
commit 98abd96fd2
4 changed files with 212 additions and 59 deletions
+4
View File
@@ -226,6 +226,10 @@ async def get_manifold_matches():
summary.trades_dominated_by_mfld — non-excluded accepted-match trades where
feat_mfld_lo is the largest signal (consistent with attribution/features,
which also exclude excluded_from_metrics trades).
summary.unique_markets — distinct-market coverage (per-market, not per-attempt):
evaluated — DISTINCT poly_market_id in manifold_match_audit (all versions)
accepted — DISTINCT poly_market_id accepted by the current matcher
coverage_rate — accepted / evaluated (null when evaluated=0)
recent_matches: last 50 rows from manifold_match_audit, newest first, each
tagged with matcher_version.