"""Drain the X13 court-verdict fetch queue (jobs the digest trigger fills). When a digest points at a court ruling not yet in the corpus, the digest trigger enqueues a ``court_fetch_jobs`` row (status=pending). This script drains those: for each pending/failed job it runs the full Tier-0/Tier-1 fetch (via the host browser service) + the canonical ingest, then links the verdict back to its source digest. Serial with a cooldown (INV-CF4); failures are recorded and retried until they escalate to ``manual`` (INV-CF3). Host-only: ingest drives halacha extraction via the local ``claude`` CLI (same constraint as ``drain_halacha_queue.py``). A no-op (fast) when the queue is empty. Scheduled hourly by ``legal-court-fetch-drain`` (pm2 cron); also runnable by hand: mcp-server/.venv/bin/python scripts/drain_court_fetch.py [limit] """ import asyncio import os import sys sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "mcp-server", "src")) from legal_mcp.services import court_fetch_orchestrator as orch async def main() -> int: limit = int(sys.argv[1]) if len(sys.argv) > 1 else 5 res = await orch.drain_pending(limit=limit) print(f"===court-fetch drain=== processed={res.get('processed', 0)} " f"ingested={res.get('done', 0)}", flush=True) for r in res.get("results", []): line = f" [{r.get('status')}] {r.get('citation', '')}" if r.get("error"): line += f" — {r['error'][:120]}" if r.get("case_law_id"): line += f" → case_law {r['case_law_id']}" print(line, flush=True) return 0 if __name__ == "__main__": sys.exit(asyncio.run(main()))