Files
legal-ai/scripts/legal-court-fetch-service.config.cjs
Chaim 0990db7a3c feat(X13): auto-fetch court verdicts from נט המשפט → corpus (Tier 0 + scaffold)
תת-מערכת אחזור-פסיקה אוטומטי: כשיומון מצביע על פס"ד בית-משפט, מסווגים את
הערכאה, מורידים מהמקור הציבורי המתאים, וקולטים דרך צינור-הקליטה הקנוני.

- spec-first: docs/spec/X13-court-fetch.md (INV-CF1..CF7) + אינדקס
- מסווג court_citation.py (supreme/admin/skip) + 10 בדיקות (עת"מ 46111-12-22 → admin)
- Tier 0: court_fetch_supreme.py — supremedecisions API (reverse-engineered), httpx
  + browser-headers (אומת 200) + politeness
- תור court_fetch_jobs (SCHEMA_V30) + DB helpers + court_fetch_orchestrator.py
- Tier 1 scaffold: legal-court-fetch-service (aiohttp+Bearer, מראת legal-chat-service)
  + camofox_client (Camoufox open-source) + recaptcha_audio (Whisper מקומי) + pm2
- Tier 2 fallback חינני: manual + missing_precedent (INV-CF2/CF3 — אין drop שקט)
- כלי-MCP court_verdict_fetch / court_fetch_status; SCRIPTS.md

Invariants: מקיים G2 (מסלול-קליטה יחיד, INV-CF1) · G3/G1 (idempotent+נרמול, INV-CF5)
· G4/§6 (אין בליעה שקטה, INV-CF2) · G10 (שער-אנושי, INV-CF3) · G5 (source_type,
INV-CF6) · G9 (provenance+audit, INV-CF7). מקורות INV-CF4: RFC 9309 · Google
crawler · OWASP OAT.

Follow-ups (טרם אומתו חי): live Tier-0 validation · התקנת camofox-browser+whisper
· כיול selectors Tier-1 · COURT_FETCH_SHARED_SECRET (Infisical+Coolify) · טריגר
מ-digest try_autolink (worktree-digests-radar). V30 עלול להתנגש עם digests-radar.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 18:12:13 +00:00

66 lines
2.6 KiB
JavaScript

/**
* pm2 ecosystem entry for legal-court-fetch-service — the host-side Tier-1
* verdict fetcher (X13). It drives a Camoufox stealth browser against
* נט המשפט to download administrative/district-court verdicts the Supreme
* portal (Tier 0) doesn't carry. Lives on the host because the legal-ai
* container can't run a browser. See docs/spec/X13-court-fetch.md.
*
* Mirrors legal-chat-service.config.cjs (same security model):
* 1. Bind to 10.0.1.1 (docker0 bridge gateway) — host + docker-bridge
* containers only; nothing from outside the host.
* 2. Bearer token auth — COURT_FETCH_SHARED_SECRET loaded from
* /home/chaim/.legal-court-fetch-service.env (chmod 600) and mirrored in
* Coolify so the FastAPI proxy sends a matching Authorization header.
* The service refuses to start without the secret.
*
* Prereqs for Tier-1 to actually fetch (otherwise it returns ok:false and the
* orchestrator escalates to the human fallback — INV-CF3):
* - camofox-browser running, CAMOFOX_URL set (e.g. http://127.0.0.1:9377).
* git clone https://github.com/jo-inc/camofox-browser && npm i && npm start
* - faster-whisper installed in the venv for the reCAPTCHA audio solver.
*
* Install (once):
* pm2 start /home/chaim/legal-ai/scripts/legal-court-fetch-service.config.cjs
* pm2 save
* Smoke test:
* curl http://10.0.1.1:8771/health
* Update:
* pm2 restart legal-court-fetch-service --update-env
*/
const fs = require("fs");
const ENV_FILE = "/home/chaim/.legal-court-fetch-service.env";
const env = {
HOME: "/home/chaim",
PATH: "/home/chaim/.local/bin:/usr/local/bin:/usr/bin:/bin",
PYTHONUNBUFFERED: "1",
// CAMOFOX_URL: "http://127.0.0.1:9377", // set when camofox-browser is up
};
try {
const text = fs.readFileSync(ENV_FILE, "utf8");
for (const line of text.split("\n")) {
if (!line || line.trim().startsWith("#")) continue;
const m = line.match(/^\s*([A-Z_][A-Z0-9_]*)\s*=\s*(.*?)\s*$/);
if (m) env[m[1]] = m[2];
}
} catch (e) {
console.error(`legal-court-fetch-service: failed to load ${ENV_FILE}: ${e.message}`);
console.error("Service will refuse to start without COURT_FETCH_SHARED_SECRET.");
}
module.exports = {
apps: [
{
name: "legal-court-fetch-service",
cwd: "/home/chaim/legal-ai/mcp-server",
script: "/home/chaim/legal-ai/mcp-server/.venv/bin/python",
args: "-m legal_mcp.court_fetch_service.server --port 8771 --host 10.0.1.1",
env,
restart_delay: 5000,
max_restarts: 10,
autorestart: true,
max_memory_restart: "1G",
},
],
};