Sprint 3: Anti-bot retrieval layer + metrics module

Anti-bot changes (all 6 adapters):
- Browser-grade User-Agent rotation (Chrome/Firefox on Linux/Windows)
- Shared browser_headers() with Accept, Accept-Language, DNT
- Session-consistent UA fingerprint (picked once, not per-request)
- jitter_sleep() replaces fixed time.sleep() on all adapters
- Exponential backoff on 429/503 already on reddit, now consistent

New shared module:
- adapters/__init__.py: browser_user_agent(), browser_headers(), jitter_sleep()
- adapters/_http.py: HTTPClient class for future browser-mode adapters

Metrics module (from Sprint 2 carry):
- oracle/metrics.py: MetricsRun for log_adapter/log_verdicts/log_scores
- oracle/weekly.py: SYSTEM HEALTH section wired to adapter_health
- oracle/cli.py: metrics subparser with --adapters/--publish/--scores/--alerts

Before: bot signatures like 'ai-oracle/0.1', 'python:athena:v0.1'
After: 'Mozilla/5.0 (X11; Linux x86_64; rv:139.0) Gecko/20100101 Firefox/139.0'
This commit is contained in:
Epictetus
2026-07-22 14:26:42 +00:00
parent 3ec955e143
commit 641d531d88
11 changed files with 694 additions and 21 deletions
+10 -1
View File
@@ -526,7 +526,16 @@ def main():
p_weekly.add_argument("--output", "-o", help="Output path for markdown review")
p_weekly.add_argument("--json", action="store_true", help="Output as JSON")
# health
# metrics
p_metrics = subparsers.add_parser("metrics", help="Pipeline metrics and adapter health")
p_metrics.add_argument("--db", default="oracle.db")
p_metrics.add_argument("--days", type=int, default=7)
p_metrics.add_argument("--adapters", action="store_true", help="Show adapter health table")
p_metrics.add_argument("--publish", action="store_true", help="Show PUBLISH rate trend")
p_metrics.add_argument("--scores", action="store_true", help="Show score distribution")
p_metrics.add_argument("--alerts", action="store_true", help="Show current alerts")
p_metrics.add_argument("--all", action="store_true", help="Show everything")
p_metrics.add_argument("--json", action="store_true", help="Output as JSON")
sub.add_parser("health", help="System health check")
args = parser.parse_args()