feat(corpus): Stage A — corpus tagging fixes + prevention layer
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 3m8s

מתקן את הבאג של תיוג שגוי לועדות ערר ומונע חזרתו:

**Code changes:**
* New MCP tool `internal_decision_upload` (chair_name+district required)
  — sole supported path for ingesting committee decisions; tags
  source_kind='internal_committee' automatically.
* Citation guard in `precedent_library_upload` rejects citations starting
  with "ערר" or "בל\"מ" with a directive to use internal_decision_upload.
* `practice_area.py` taxonomy unification: PRACTICE_AREAS now accepts
  both multi-tenant (appeals_committee/national_insurance/labor_law)
  and domain (rishuy_uvniya/betterment_levy/compensation_197) values.
  New helper `to_db_practice_area(multi_tenant, subtype) -> domain`.

**Agent docs:**
* legal-researcher (+5K): upload-tool decision flowchart, code samples
  per source_kind, district enum (ירושלים/מרכז/תל אביב/צפון/דרום/חיפה/ארצי)
* legal-ceo, legal-analyst, legal-writer, legal-qa, HEARTBEAT — taxonomy
  awareness + source_kind-aware citation patterns + research_complete
  as valid status.
* Fixed two pre-existing wrong practice_area values in examples
  (histael_hashbacha→betterment_levy, pitsuim_197→compensation_197).

Closes TaskMaster #30(parts), #38(parts), #39 (root cause).
DB-side backfill + CHECK constraints applied directly via psql:
* 11 cases.practice_area corrected (1xxx→rishuy, 8xxx→betterment)
* 6 case_law records reclassified external_upload→internal_committee
  with inferred district
* 6 chair_name backfilled from full_text (5 שרית אריאלי + 1 דפנה תמיר)
* 88 new halachot extracted for newly-uploaded precedents
  (אנטרים + ירושלים שקופה 1112/22 + אגא וכט)
* CHECK constraints: cases.practice_area enum, case_law internal⇒district

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-26 07:40:18 +00:00
parent 8153bc9f03
commit c6e368e4f7
10 changed files with 469 additions and 14 deletions

View File

@@ -21,6 +21,8 @@ tools:
- mcp__legal-ai__precedent_list
- mcp__legal-ai__precedent_search_library
- mcp__legal-ai__search_precedent_library
- mcp__legal-ai__internal_decision_upload
- mcp__legal-ai__precedent_library_upload
- mcp__legal-ai__precedent_library_get
- mcp__legal-ai__precedent_library_list
- mcp__legal-ai__precedent_extract_halachot
@@ -70,6 +72,84 @@ tools:
כתבי ערר, תשובות, תגובות — אלה בטיפול סוכן "מנתח משפטי".
## ⚠️ חובה לקרוא — איזה כלי upload להשתמש לכל סוג פסיקה
כשאתה מעלה פסיקה לקורפוס הסמכותי, **יש שני זרמים שונים** והם **לא ניתנים להחלפה**. שגיאה כאן פוגעת בכל המערכת.
### Flowchart החלטה — איזה כלי?
```
האם ה-citation מתחיל ב-"ערר" או "בל"מ" (החלטת ועדת ערר)?
├── כן → internal_decision_upload ✅ (חובה chair_name + district)
└── לא →
האם מתחיל ב-עע"מ / בר"מ / עמ"נ / בג"ץ / ע"א / ע"פ / רע"א / רע"פ / ת"א / ת"מ
(פסיקת בית משפט מנהלי/עליון/מחוזי/שלום)?
├── כן → precedent_library_upload ✅ (external_upload)
└── לא → דווח לחיים: citation לא מוכר, אל תעלה
```
### זרם A — `precedent_library_upload` (external)
לפסיקת ערכאות שיפוטיות: עליון (בג"ץ/ע"א/רע"א/ע"פ/רע"פ/דנ"א), מנהלי (עע"מ/בר"מ/עמ"נ), מחוזי (ת"א/ת"מ), שלום.
```python
mcp__legal-ai__precedent_library_upload(
file_path="/path/to/file.pdf",
citation="עע\"מ 3911/19 פלוני נ' הוועדה המקומית רמת גן (פורסם בנבו, 12.07.2023)",
case_name="פלוני נ' הוועדה המקומית רמת גן",
court="בית המשפט העליון",
decision_date="2023-07-12",
practice_area="rishuy_uvniya", # Axis B בלבד
subject_tags=["שימוש חורג", "מגרש מסחרי"],
)
```
**הכלי שומר `source_kind='external_upload'`.** Citation guard: אם תנסה להעלות citation שמתחיל ב-"ערר" או "בל\"מ" — הכלי **ידחה** עם שגיאה ויפנה ל-`internal_decision_upload`.
### זרם B — `internal_decision_upload` (internal_committee) — **חובה לחלק מהפסיקה**
להחלטות **ועדות ערר** מכל המחוזות (ירושלים, מרכז, תל אביב, צפון, דרום, חיפה, ארצי). כולל גם ערר רגיל וגם בל"מ.
```python
mcp__legal-ai__internal_decision_upload(
file_path="/path/to/file.pdf",
case_number="ערר (ועדות ערר - תכנון ובנייה ירושלים) 1110/20",
chair_name="שרית אריאלי", # חובה!
district="ירושלים", # חובה! אחד מ-7
case_name="פלוני נ' הוועדה המקומית מודיעין",
court="ועדת הערר לתכנון ובנייה — מחוז ירושלים",
decision_date="2020-11-15",
practice_area="rishuy_uvniya", # Axis B
appeal_subtype="building_permit",
subject_tags=["שימוש חורג"],
is_binding=False, # תמיד False — שכנוע אופקי, לא חוב
)
```
**שדות חובה (הכלי דוחה בלעדיהם):**
- `file_path`
- `case_number`
- `chair_name` — בלעדיו אי-אפשר לחפש סלקטיבית לפי הרכב
- `district` — ערכים תקפים: **ירושלים / מרכז / תל אביב / צפון / דרום / חיפה / ארצי** (גם "תל-אביב" עם מקף נקלט)
**הכלי שומר `source_kind='internal_committee'`.** DB constraint `case_law_internal_district_check` אוכף ש-`district NOT NULL` כשמדובר ב-internal_committee.
### אם chair_name או district חסר ב-PDF
- חפש בתוך הטקסט: "בפני: עו\"ד X" / "יו\"ר הוועדה: X" / "מחוז ירושלים" / שם המחוז בכותרת
- אם לא מצליח לזהות — **אל תנחש**. דווח לחיים ב-comment: "נמצא PDF של החלטת ערר ללא chair_name/district ברורים — נדרש מילוי ידני". המשך עם שאר העבודה.
### 2 שכבות חיפוש מקבילות
לאחר ההעלאות הנכונות:
| כלי | מטרה | מתי |
|-----|------|-----|
| `search_precedent_library` | חיפוש פסיקה **חיצונית** (עליון/מנהלי/מחוזי) | כל סוגיה מרכזית — חובה |
| `search_internal_decisions` | חיפוש בהחלטות **ועדות ערר** (כל המחוזות) | כשהסוגיה דיונית או כשאין הלכת עליון |
שניהם מקבלים את אותם הפילטרים: `practice_area` (Axis B), `subject_tag`, וכו'. `search_internal_decisions` מקבל בנוסף `district` ו-`chair_name`.
## תהליך עבודה
### שלב 1: התמצאות
@@ -104,8 +184,8 @@ tools:
| סיווג תיק | practice_area |
|------------|---------------|
| 1xxx (רישוי ובניה) | `rishuy_uvniya` |
| 8xxx (היטל השבחה) | `histael_hashbacha` |
| 9xxx (פיצויים ס' 197) | `pitsuim_197` |
| 8xxx (היטל השבחה) | `betterment_levy` |
| 9xxx (פיצויים ס' 197) | `compensation_197` |
אם הסוגיה ב-`appeal_subtype` ידוע (כמו "שימוש חורג", "סטייה ניכרת") — הוסף `appeal_subtype` לפילטר.
@@ -136,7 +216,7 @@ search_precedent_library(
```
search_internal_decisions(
query="...",
practice_area="histael_hashbacha", # rishuy_uvniya / betterment_levy / compensation_197
practice_area="betterment_levy", # rishuy_uvniya / betterment_levy / compensation_197
district="ירושלים", # ריק = כל המחוזות
chair_name="", # ריק = כל היו"רים; "דפנה תמיר" = דפנה בלבד (שווה ל-search_decisions)
limit=5