The /precedents metadata queue was stuck — 24 rows requested, nothing draining them — and the agentic claude CLI hit error_max_turns on what is a single structured text→JSON task (slow + flaky). Metadata extraction is bounded extraction, the wrong fit for an agentic loop. - gemini_session.py: query_json drop-in (gemini-2.5-flash, JSON mode, httpx — no new SDK dep). Reads GEMINI_API_KEY (~/.env; SoT Infisical nautilus:/external-apis/gemini). Host-side only — no LLM from the container. - precedent_metadata_extractor: claude_session.query_json → gemini_session. Validated live: rich, accurate fields (case_name/summary/appeal_subtype/tags). - process_pending_extractions: kind-aware cooldown — metadata 2s (Gemini, fast), halacha keeps 30s (Claude rate limits). - drain_metadata_queue.py + legal-metadata-drain.config.cjs (pm2 cron */15) so the queue never clogs again. SCRIPTS.md. - X8 INV-FP5 updated: per-task engine choice (Gemini=bounded metadata, claude_session=agentic halacha), both host-side, single canonical queue (G2). Agentic/voice-sensitive work (writing, analysis, halacha) stays on claude_session (Daphna's subscription). Gemini cost ≈ $0.10/1M tokens — negligible. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
121 lines
11 KiB
Markdown
121 lines
11 KiB
Markdown
# X8 — כללי-מילוי-שדות וחילוץ (Field-Population & Extraction Rules)
|
||
|
||
קובץ-תחום זה כפוף ל-[חוקת המערכת](00-constitution.md) והוא ה-**SSoT לכללים שכרגע סמויים בקוד**:
|
||
כשמעלים החלטה/פסק-דין/מסמך-תיק — *איזה שדה מתמלא מאיזה מקור*, ומה הכללים על-גבי זה (אי-דריסת
|
||
ערך-יו"ר, שער-אישור, ציטוט-verbatim). הכללים האלה חיים היום מפוזרים על-פני 4 שירותים; כאן הם מאוחדים.
|
||
הוא משלים את [01-ingest.md](01-ingest.md) (הפייפליין) ו-[02-data-model.md](02-data-model.md) (הסכמה),
|
||
ומזין את [X6 INV-UI6](X6-ui-api-contract.md) (שיקוף-מקור ב-UI).
|
||
|
||
> **מודלי-סמכות מעורבים.** FP1 ו-FP4 הם **הנדסיים** (lineage/integrity — ≥3 מקורות). FP2/FP3/FP5 הם
|
||
> **פרויקטלי-תפעוליים** הנקשרים ל-[G10](00-constitution.md#inv-g10-המערכת-מסייעת--שערים-אנושיים-הם-invariant)
|
||
> (שער אנושי) ו-[G2](00-constitution.md#inv-g2-מקור-אמת-יחיד--אין-מסלולים-מקבילים-מתפצלים).
|
||
|
||
---
|
||
|
||
## 1. ארבעת מקורות-המילוי
|
||
|
||
| מקור | הגדרה | דוגמאות |
|
||
|------|-------|---------|
|
||
| **DETERMINISTIC** | parse של שם-קובץ / מטא-PDF / OCR / regex — ללא LLM | `full_text`, `extraction_status`, `source_kind`, chunks, page_number |
|
||
| **OPUS-ANALYSIS** | Claude Opus קורא את כל המסמך, ממלא **רק שדה ריק/placeholder**, אסינכרוני | `headnote`, `summary`, `key_quote`, `subject_tags`, `case_name`, `court`, `date`, `appeal_subtype`, `precedent_level`, `source_type`, `citation_formatted`, halachot |
|
||
| **CHAIR-MANUAL** | היו"ר מזין בטופס; חובה או רשות | `citation`/`case_number` (חובה), והשאר נשאר לעריכה |
|
||
| **DERIVED** | מחושב משדות אחרים | `district` מ-court, `proceeding_type` מ-appeal_subtype, `searchable` |
|
||
|
||
---
|
||
|
||
## 2. טבלת-provenance לפי סוג-מסמך (ה-SSoT)
|
||
|
||
> מאומת מול [precedent_metadata_extractor.py](../../mcp-server/src/legal_mcp/services/precedent_metadata_extractor.py),
|
||
> [halacha_extractor.py](../../mcp-server/src/legal_mcp/services/halacha_extractor.py),
|
||
> [ingest.py](../../mcp-server/src/legal_mcp/services/ingest.py), [db.py](../../mcp-server/src/legal_mcp/services/db.py).
|
||
|
||
### 2א. פסיקה חיצונית (`case_law`, source_kind=`external_upload`)
|
||
| שדה | מקור | הערה |
|
||
|-----|------|------|
|
||
| `case_number` (citation) | CHAIR (חובה) | מפתח idempotency |
|
||
| `full_text`, `extraction_status`, `source_kind` | DETERMINISTIC | — |
|
||
| `case_name`, `court`, `date`, `headnote`, `summary`, `key_quote`, `subject_tags`, `appeal_subtype`, `precedent_level`, `source_type`, `citation_formatted` | CHAIR או OPUS | Opus ממלא רק אם ריק |
|
||
| `is_binding` | CHAIR (default true) | קובע prompt-הלכה |
|
||
| chunks (`content`/`section_type`/`page_number`) | DETERMINISTIC | — |
|
||
| `embedding` (chunks) | Voyage (לא-LLM-reasoning) | ⚠ לא-GENERATED ([gap-audit GAP-09](gap-audit.md)) |
|
||
| כל `halachot` | OPUS | נכנס pending_review |
|
||
|
||
### 2ב. החלטה פנימית (`case_law`, source_kind=`internal_committee`)
|
||
כמו 2א, ובנוסף: `case_number` **חובה**; `chair_name`/`district`/`proceeding_type` — CHAIR או OPUS או DERIVED;
|
||
`source_type` = `appeals_committee` (DETERMINISTIC קבוע). placeholder `"(טרם חולץ)"` מסומן ל-chair_name/district
|
||
ריקים ומטופל כריק ע"י ה-extractor.
|
||
|
||
### 2ג. מסמך-תיק (`documents`)
|
||
| שדה | מקור |
|
||
|-----|------|
|
||
| `case_id`, `title` | CHAIR |
|
||
| `doc_type` | DETERMINISTIC (local_classifier) → fallback Claude אם confidence<0.8 |
|
||
| `extracted_text`, `extraction_status`, `page_count` | DETERMINISTIC |
|
||
| chunks + `embedding` | DETERMINISTIC + Voyage |
|
||
| claims / appraiser_facts | OPUS (כלי-חילוץ נפרדים — ראה [X9](X9-mcp-tool-contract.md)) |
|
||
|
||
---
|
||
|
||
## 3. Invariants של התחום
|
||
|
||
### INV-FP1: לכל שדה מקור-מילוי מוצהר — הטבלה היא ה-SSoT
|
||
**כלל:** לכל שדה-מטא יש **מקור-מילוי מוצהר** (deterministic / opus / chair / derived), ב**מקום יחיד**
|
||
(טבלת §2). אין כללי-מילוי סמויים מפוזרים בין שירותים. מופע של
|
||
[G9](00-constitution.md#inv-g9-עקיבוּת-מקור--audit-trail-ל-ai) (lineage — מאיפה כל ערך). **הנדסי.**
|
||
**מקורות:** ISO 8000-110 (data quality — provenance) · DAMA-DMBOK2 (data lineage) · OpenLineage spec
|
||
(https://openlineage.io/) | סטטוס: verified
|
||
**אכיפה:** טבלת-provenance מוצהרת (§2) + עמודת-מקור-מילוי לכל שדה-נגזר (יעד; ראה [02-data-model.md](02-data-model.md)).
|
||
**הפרה ידועה:** הכללים מפוזרים על precedent_metadata_extractor/halacha_extractor/ingest/recompute_searchable; אין SSoT ([gap-audit GAP-35](gap-audit.md)).
|
||
|
||
### INV-FP2: חילוץ-LLM אינו דורס ערך שהוזן ידנית
|
||
**כלל:** חילוץ-Opus ממלא **רק שדה ריק/placeholder** — ערך שהיו"ר הזין **לעולם אינו נדרס**. סמכות-התוכן
|
||
היא היו"ר. מופע של [G10](00-constitution.md#inv-g10-המערכת-מסייעת--שערים-אנושיים-הם-invariant). **פרויקטלי-תפעולי.**
|
||
**מקור-סמכות:** [precedent_metadata_extractor.py](../../mcp-server/src/legal_mcp/services/precedent_metadata_extractor.py)
|
||
(`apply_to_record` — compare-to-empty); feedback היו"ר. (משרת G10.)
|
||
**אכיפה:** לוגיקת compare-to-empty ב-extractor; convention placeholder מתועד.
|
||
**הפרה ידועה:** placeholder `"(טרם חולץ)"` כמחרוזת-קסם לא-מתועדת/שבירה ([gap-audit GAP-37](gap-audit.md)).
|
||
|
||
### INV-FP3: פלט-LLM נכנס כ-pending — רק אישור-יו"ר הופך אותו לשמיש
|
||
**כלל:** פלט-חילוץ של LLM (הלכות; ובהמשך גם טענות-משפטיות) נכנס במצב **לא-מאושר** (`pending_review`),
|
||
ואינו נחשף לחיפוש/החלטה עד **אישור-יו"ר**. מופע של [G10](00-constitution.md#inv-g10-המערכת-מסייעת--שערים-אנושיים-הם-invariant)
|
||
(שער אנושי) — תואם [05-qa-review.md](05-qa-review.md). **פרויקטלי-תפעולי.**
|
||
**מקור-סמכות:** [halacha_extractor.py](../../mcp-server/src/legal_mcp/services/halacha_extractor.py) (review_status); [01-ingest.md](01-ingest.md).
|
||
**אכיפה:** `review_status` חוסם חיפוש עד `approved`/`published`.
|
||
**הפרה ידועה:** `legal_arguments` **חסר** שער-אישור מקביל ([gap-audit GAP-39](gap-audit.md); [02-data-model.md](02-data-model.md)).
|
||
|
||
### INV-FP4: supporting_quote חייב להיות verbatim
|
||
**כלל:** כל ציטוט-תומך (`supporting_quote` של הלכה, `key_quote`) חייב להופיע **מילה-במילה** בטקסט-המקור;
|
||
אחרת מסומן (`quote_verified=false`). מופע של [G9](00-constitution.md#inv-g9-עקיבוּת-מקור--audit-trail-ל-ai)
|
||
(integrity). **הנדסי.**
|
||
**מקורות:** ISO 15489-1:2016 (records integrity/authenticity) · RAG attribution (Lewis et al., 2020, NeurIPS) ·
|
||
NCSC/JTC — *AI in Courts* (verifiable citation) | סטטוס: verified
|
||
**אכיפה:** `proofreader.verify_quote` בעת חילוץ → `quote_verified`.
|
||
**הפרה ידועה:** — (קיים; ה-flag נכתב, אך אין חיווי ב-UI — ראה [X6 INV-UI6](X6-ui-api-contract.md)).
|
||
|
||
### INV-FP5: חילוץ אסינכרוני, מתור, צד-מארח (לא מהקונטיינר)
|
||
**כלל:** חילוץ-LLM (מטא, הלכות) רץ **אסינכרוני, מתור, מצד-המארח** — לא חוסם את ה-web ולא קורא ל-LLM
|
||
מהקונטיינר. **בחירת-מנוע לפי אופי-המשימה (לא מסלול מקביל):** חילוץ-מטא הוא משימה *תחומה* (טקסט→JSON)
|
||
ולכן רץ על **Gemini Flash** (`gemini_session`, structured JSON) — ה-claude CLI ה-agentic פגע ב-
|
||
`error_max_turns`; חילוץ-הלכות (רגיש-קול/agentic) נשאר על **`claude_session`** (CLI מקומי, מנוי דפנה).
|
||
שני המנועים מתנקזים לתור-החילוץ הקנוני היחיד ([G2](00-constitution.md#inv-g2-מקור-אמת-יחיד--אין-מסלולים-מקבילים-מתפצלים)). **פרויקטלי-תפעולי.**
|
||
**מקור-סמכות:** [ingest.py](../../mcp-server/src/legal_mcp/services/ingest.py) (queue → `process_pending_extractions`); [gemini_session.py](../../mcp-server/src/legal_mcp/services/gemini_session.py) (מטא); [legal-ai/CLAUDE.md](../../CLAUDE.md) (claude_session local-only להלכות). `GEMINI_API_KEY` בצד-המארח בלבד — לא בקונטיינר (תואם `feedback_claude_session_local_only`: אין קריאות-LLM מהקונטיינר).
|
||
**אכיפה:** queue + `precedent_process_pending` + drainers מתוזמנים (`legal-metadata-drain`/CEO); קריאות-LLM רק מצד-המארח.
|
||
**הפרה ידועה:** תור-החילוץ **סמוי** (אין הבחנה pending-initial מול pending-review; אין extraction-job table) ([gap-audit GAP-45](gap-audit.md); [X9](X9-mcp-tool-contract.md)).
|
||
|
||
---
|
||
|
||
## 4. חוזה-searchable (תזכורת — מוגדר ב-02)
|
||
רשומת `case_law` היא `searchable` רק כשמתקיים חוזה-השלמות ([G4](00-constitution.md#inv-g4-חוזה-שלמות-לפני-שמיש--ניתן-לחיפוש),
|
||
[02-data-model.md](02-data-model.md), FU-2a): ≥1 chunk עם embedding · `extraction_status='completed'` ·
|
||
`case_number`/`source_kind` לא-ריקים · practice_area (לפנימי) · ≥1 שדה-מטא ({headnote/summary/subject_tags}).
|
||
ה-UI חייב **לשקף** את ה-flag הזה ([X6 INV-UI6](X6-ui-api-contract.md)).
|
||
|
||
---
|
||
|
||
## 5. הפניות-אחיות
|
||
- [01-ingest.md](01-ingest.md) — הפייפליין הקנוני (12 צעדים) שבו החילוץ יושב.
|
||
- [02-data-model.md](02-data-model.md) — סכמת השדות + חוזה-searchable + ישויות-נגזרות.
|
||
- [X6 INV-UI6](X6-ui-api-contract.md) — שיקוף מקור-המילוי ב-UI.
|
||
- [X9-mcp-tool-contract.md](X9-mcp-tool-contract.md) — כלי-החילוץ (claims/appraiser_facts/halachot/metadata).
|
||
- [00-constitution.md](00-constitution.md) — [G9](00-constitution.md#inv-g9-עקיבוּת-מקור--audit-trail-ל-ai), [G10](00-constitution.md#inv-g10-המערכת-מסייעת--שערים-אנושיים-הם-invariant), [G4](00-constitution.md#inv-g4-חוזה-שלמות-לפני-שמיש--ניתן-לחיפוש), [G2](00-constitution.md#inv-g2-מקור-אמת-יחיד--אין-מסלולים-מקבילים-מתפצלים).
|