feat(X13): auto-trigger court fetch from digests + drain tool
סוגר את הלולאה — יומון שמצביע על פס"ד בית-משפט שלא בקורפוס מזניק אחזור אוטומטי, וקושר את היומון חזרה אחרי הקליטה (INV-DIG3 + INV-CF2). - digest_library.try_autolink: בכשל-קישור, אם הציטוט מסווג כפס"ד-בימ"ש (supreme/admin) → _enqueue_court_fetch יוצר court_fetch_jobs(pending); ועדת-ערר (skip) לא מוזנק. never-raises (לא שובר קליטת-יומון). - orchestrator.drain_pending(limit): מנקז pending/failed סדרתי (cooldown, INV-CF4), fetch+ingest לכל אחד; בהצלחה מקשר את היומון ל-case_law שנקלט. - כלי-MCP court_fetch_drain + רישום ב-server.py. - X13 spec: עודכן (הפער ב-INV-CF2 סומן כמתוקן). נבדק מול ה-DB: עת"מ 46111-12-22 → job tier=admin pending digest-linked; ערר 1110/20 → לא מוזנק. כלי מקומי בלבד (ingest = claude CLI). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -83,11 +83,40 @@ async def try_autolink(digest_id: UUID | str, underlying_citation: str) -> str |
|
||||
logger.warning("digest try_autolink lookup failed for %r: %s", citation, e)
|
||||
return None
|
||||
if not match:
|
||||
# Gap (INV-DIG3): the underlying ruling isn't in the corpus. If it's a
|
||||
# court verdict (not ועדת-ערר), enqueue an X13 auto-fetch job so the gap
|
||||
# is actionable instead of silently dropped (INV-CF2). Never raises.
|
||||
await _enqueue_court_fetch(digest_id, citation)
|
||||
return None
|
||||
await db.link_digest_to_case_law(digest_id, match["id"])
|
||||
return str(match["id"])
|
||||
|
||||
|
||||
async def _enqueue_court_fetch(digest_id: UUID | str, citation: str) -> None:
|
||||
"""Queue an X13 court-verdict fetch for an unlinked digest citation.
|
||||
|
||||
Court rulings (supreme/admin) → a ``court_fetch_jobs`` row drained later by
|
||||
``court_fetch_drain``. ועדת-ערר (skip) is left alone — it needs Nevo and is
|
||||
surfaced through the normal missing-precedent path, not auto-fetch.
|
||||
"""
|
||||
try:
|
||||
from legal_mcp.services import court_citation
|
||||
cit = court_citation.classify(citation)
|
||||
if cit.tier not in ("supreme", "admin"):
|
||||
return
|
||||
await db.court_fetch_job_upsert(
|
||||
case_number_norm=cit.case_number_norm,
|
||||
citation_raw=citation,
|
||||
tier=cit.tier,
|
||||
court=cit.court_prefix,
|
||||
digest_id=UUID(str(digest_id)),
|
||||
)
|
||||
logger.info("digest %s: enqueued court-fetch for %r (tier=%s)",
|
||||
digest_id, citation, cit.tier)
|
||||
except Exception as e: # never break digest ingest
|
||||
logger.warning("digest court-fetch enqueue failed for %r: %s", citation, e)
|
||||
|
||||
|
||||
# ── Container-safe creation (web upload) — no LLM, no embedding ──────
|
||||
|
||||
async def create_pending_digest(
|
||||
|
||||
Reference in New Issue
Block a user