Files
legal-ai/docs/spec/04-analysis-writing.md
Chaim 9ef0547997
All checks were successful
G12 Leak-Guard / leak-guard (pull_request) Successful in 3s
Lint — undefined names / undefined-names (pull_request) Successful in 10s
docs(spec): WS7 — reconcile 01/02/03/04/06 + gap-audit; verify 7 workflow-redesign leaks closed (#207)
WS7 of the workflow-redesign initiative required closing 7 known leaks along
the way. Cross-code audit verified ALL 7 were already closed in prior cycles
(FU-1/4/5/6/7 + IA waves); the spec still carried stale "known violation" text.
This PR aligns the spec to actual code state and verifies each closure with a
test. No new code path created — this is a spec-alignment audit, not a re-solve.

7 leaks → status (all closed/gated, each with a test):
1. cross-corpus halachot (#56, GAP-10/FU-4) — cl.source_kind in halacha_filters
   (db.py:7516,7519); test_precedent_corpus_isolation.py
2. invisible halacha backlog (GAP-14/FU-5) — health halacha_backlog
   (app.py:2352-2364) + extraction_status/halachot_pending
3. no eval harness (GAP-11/FU-5, G8) — scripts/eval_retrieval.py
   (P/R/MRR/nDCG vs gold-set+baseline); --self-test ALL PASS
4. export gate not hard-block (GAP-15/FU-6, INV-EX3) — export_docx checks
   qa_run_exists + get_critical_qa_failures before exporter (drafting.py:462-494);
   test_export_qa_gate.py
5. metadata on internal path (GAP-02/FU-1, INV-ING3) — unified ingest.ingest_document
   queues metadata+halacha together (ingest.py:233-234); test_unified_ingest.py
6. DOCX creep to source-of-truth (GAP-17/FU-7, INV-EX1) — active_draft_path is
   revision-anchor only; drift caught by cases.blocks_stale flag (V22)
7. UI cache-invalidation (GAP-33/FU-10) — qc.invalidateQueries on mutations

Also added forward-pointer notes for the workflow-redesign additions owned by
sibling tasks (02 documents is_primary/doc_category → #200; 04 re-analysis /
summarize_party_claims / analyze_protocol → #200/#202/#203), kept additive to
avoid line conflicts. block-schema.md interim/template edits deferred to #204/#205.

Invariants: maintains G2 (single source of truth, no parallel path — all leak
closures extend the canonical path), G8 (eval harness now exists), G10 (human
gates visible: halacha backlog + hard export gate), INV-ING3 (unified metadata
queue), INV-EX1 (DOCX is derived; blocks_stale drift flag), INV-RET1/G5 (#56
cross-corpus halacha isolation).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 11:22:11 +00:00

16 KiB
Raw Blame History

04 — ניתוח וכתיבה (Analysis & Writing)

קובץ-תחום זה כפוף ל-חוקת המערכת ומפרט את שלב הסיוע-בכתיבה — חילוץ הטענות, ארכיטקטורת 12 הבלוקים, וסגנון דפנה. הוא אוכף את INV-G11 (תוכן החלטה מנומקת).

⚠ מודל-סמכות שונה מ-0103. זהו קובץ תוכן-משפטי, לא קובץ-הנדסה. לפי החוקה (§2 עיקרון 2, §5ב) הסמכות עליו היא היו"ר (עו"ד דפנה תמיר) + מסמכי-הפרויקטblock-schema.md, decision-methodology.md, legal-decision-lessons.md, corpus-analysis.md, skills/decision/SKILL.md. ה-invariants כאן אינם כפופים לפרוטוקול ≥3-המקורות החיצוני, ואינם נושאים סטטוס: verified / ⚠ UNVERIFIED. במקום מקורות: … | סטטוס הם נושאים מקור-סמכות:. מסמכי-הפרויקט הם המקור המוסמך; קובץ זה מצטט אותם בגובה-ספ, לא משכפל את ההגדרות.


1. חילוץ טענות → טיעונים מאוגדים

לפני הכתיבה, חומרי-המקור הופכים למבנה-נתונים שמזין את הבלוקים. שני שלבים:

1.1 חילוץ טענות גולמיות (claims)

extract_claims(case_number, doc_title="", party_hint="") קורא לכתבי-הטענות בתיק, ושומר טענות גולמיות ב-DB. הוא מסנן למסמכים מסוג appeal / response / objection (אלא אם צוין doc_title מפורש), ולכל מסמך קורא ל-claims_extractor.extract_and_store_claims — ראה mcp-server/src/legal_mcp/tools/documents.py:300-347.

כל טענה נשמרת עם party_role מתוך התפקידים המוכרים: appellant (עוררים) · respondent (משיבים) · committee (ועדה מקומית) · permit_applicant (מבקשי היתר) · appraiser (שמאי). get_claims(case_number, party_role="") שולף ומציג אותן בעברית, עם סינון אופציונלי לפי תפקיד (documents.py:350-385; מיפוי-העברית ב-:370-376).

aggregate_claims_to_arguments(case_number, force=False) מכנס את הפרופוזיציות הגולמיות לטיעונים משפטיים מובחנים (de-duplication) דרך argument_aggregator.aggregate_claims_to_arguments; force=True מוחק טיעונים קיימים ומחשב מחדש — ראה mcp-server/src/legal_mcp/tools/legal_arguments.py:11-33. get_legal_arguments(case_number, party="") שולף את הטיעונים המאוגדים, מקובצים לפי צד (appellant/respondent/committee/permit_applicant/unknown); אם אין — הוא מחזיר הנחיה להריץ קודם את הכינוס (legal_arguments.py:36-83).

מדוע זה חשוב לתוכן: הטיעונים המאוגדים הם הקלט ל-INV-WR3 (מענה לכל טענה עיקרית) ול-INV-WR4 (הפרדת טענות מקוריות מהשלמות). הסינון לפי party_role מאפשר לזהות את הצד המפסיד ולוודא שכל טיעון שלו מקבל מענה בבלוק י.

עיצוב-מחדש זרימת-העבודה (WS2WS4) — מסלול-החילוץ אינו מתפצל (G2): ניתוח-ערר-לבד כבר עובד (extract_claims רץ על appeal בנפרד). ההרחבות נשענות על אותו צינור- חילוץ, לא על מסלול-ניתוח שני: (א) ניתוח-מחדש מאחד (WS2, #200/#201) — מחלץ מ-מסמכים חדשים/מעודכנים בלבד ומאחד עם הקיים (לא מוחק-ומחשב-מחדש), על-בסיס דגל-הניתוח per-מסמך (02-data-model §2ב); (ב) סיכום-מנהלים (WS3, #202, summarize_party_claims) — נגזר מ-claims/legal_arguments, מסמך-פרוזה נפרד מטיוטת-הביניים (G2: תצוגה-נגזרת, לא מקור-אמת שני); (ג) ניתוח-פרוטוקול (WS4, #203, analyze_protocol) — protocol נכנס לחילוץ ההשוואתי (ירד/חוזק/חדש) ומזין ידע-תיק, ונשאר פוסט-דיון (INV-WR4: טענות-פוסט-דיון → בלוק ח, לא ז). חוזי-הכלים המלאים בבעלות המשימות הנ"ל; כאן רק עיגון-הספ שהם מקיימים G2.


2. ארכיטקטורת 12 הבלוקים (סיכום)

המבנה הפורמלי המלא — content model, constraints, משקלות, ופרמטרי-עיבוד לכל בלוק — מוגדר ב-block-schema.md (המקור המוסמך). כאן רק מפת-גובה:

בלוק תפקיד CREAC תוכן מהותי?
א–ד כותרת מוסדית · הרכב · צדדים · "החלטה" לא (template-fill)
ה פתיחה ("לפנינו…") C ראשוני קל
ו רקע עובדתי ("פתח דבר") כן — עובדות בלבד
ז טענות הצדדים כן — טענות מקוריות בלבד
ח הליכים בפני הוועדה כן (תיעוד, ללא הערכה)
ט תכניות חלות (אופציונלי) R כן (כשיש מורכבות תכנונית)
י דיון והכרעה full-CREAC כן — ה-ratio decidendi
יא סיכום / סוף דבר C אחרון קל
יב חתימות לא

יסודות תיאורטיים (CREAC · FJC Judicial Writing Manual · DITA · Akoma Ntoso), תלויות-בין-בלוקים, וכללי-ולידציה — ב-block-schema.md §§1, 5, 6. מתודולוגיית-המשקלות (Communicative / Reader-attention / Judicial-review / Empirical) — שם §4. טיוטת-ביניים (Pre-Ruling Draft) בוחרת תת-קבוצת בלוקים (ו, ט, ז, ח) — block-schema.md §7; שלב-החילוץ השמאי שלה (extract_appraiser_facts) מזין את בלוק ט.

ציטוט-תכנית קנוני (בלוק ט): הזהות והתוקף של תכנית (תאריך פרסום למתן תוקף ברשומות + מס' ילקוט-הפרסומים) נכתבים בנוסח אחיד דטרמיניסטי ממרשם-התכניות (plans, 02-data-model) דרך db.format_plan_citation — לא מנוסחים מחדש ע"י ה-LLM, ובכך לא מהוזים (anti-hallucination-gate, INV-AH). הנוסח עצמו הוא תוכן-משפטי באחריות היו"ר (block-schema.md בלוק ט); המרשם נכנס לשימוש רק אחרי אישור-יו"ר (review_status, G10).

התמקדות לפי feedback היו"ר: הסיוע מתמקד בבלוקים המהותיים (ו–יב); בלוקים א–ד ממולאים מ-template ואינם דורשים ניתוח. ראה MEMORY.md → "התעלם מכותרות".


3. סגנון דפנה (סיכום)

מדריך-הסגנון המלא הוא skills/decision/SKILL.md; המתודולוגיה האנליטית ("איך לחשוב לפני איך לכתוב") היא decision-methodology.md. נקודות-מפתח:

  • טון לפי סוג-ערר — רישוי (1xxx) חם יחסית; היטל-השבחה (8xxx) ופיצויים ס'197 (9xxx) קרים ויבשים (SKILL.md §1; methodology §א.2).
  • מבנה הדיון (בלוק י) — נפתח במסקנה (CREAC: C→R→E→A→C), סילוגיזם לכל סוגיה, steel-manning של הצד המפסיד, ציטוט-פסיקה ב"סנדוויץ'" (methodology §§ד, ו, ז).
  • מסלול-דיון לפי תוצאה — דחייה (עיגולים קונצנטריים) · קבלה (נימוק-נימוק) · קבלה חלקית (מיפוי-מתחים) · היטל-השבחה (פתיחה ישירה) — SKILL.md §7.3; block-schema.md בלוק י.
  • 3 מקורות-פסיקה נפרדים — אסור לבלבל ביניהם (SKILL.md §7.5; ראה גם 03-retrieval.md לשכבת-האחזור שמזינה אותם).
  • לקחים מצטבריםlegal-decision-lessons.md + ביטויי-מעבר; מתעדכנים מפידבק-היו"ר ומ-Hermes (ראה forward-ref 07-learning.md).

4. Invariants של התחום — תוכן החלטה מנומקת

חמשת ה-invariants הבאים הם פאֶטים של INV-G11. כולם נושאים מקור-סמכות (היו"ר + מסמכי-הפרויקט), ללא שדה-מקורות-חיצוני וללא סטטוס-אימות — כמתחייב מהבחנת שתי-הסמכויות בחוקה (§5).

INV-WR1: רקע ניטרלי (בלוק ו) — עובדות בלבד

כלל: בלוק ו מציג עובדות בלבד ואינו טוען. אסורות מילות-ערך/שיפוט ("חריג", "בעייתי", "למרבה הפליאה") ואסורים ציטוטים ישירים מצדדים (אלה שייכים לבלוק ז). החלטות קודמות מובאות כעובדה יבשה ("ביום X נדחתה תכנית Y"), ללא נימוקים. ניטרליות אינה הסתרה: עובדה מהותית התומכת בצד המפסיד חייבת להופיע. מקור-סמכות: היו"ר (עו"ד דפנה תמיר) + block-schema.md (בלוק ו, §5.2 "רקע ניטרלי") + decision-methodology.md §ח.2. אכיפה: ולידציית-תוכן בבלוק ו (סעיף עם ציטוט-צד או מילת-שיפוט → לא שייך כאן) + שערי QA; מפורט ב-05-qa-review.md. הפרה ידועה:

INV-WR2: ללא כפילות (בלוק י מפנה, לא חוזר)

כלל: בלוק י (דיון) מפנה לעובדות ולטענות שכבר הוצגו בבלוקים הקודמים ("כאמור בסעיף X לעיל", "כפי שפורט") — ואינו חוזר עליהן. חריג יחיד: חזרה מכוונת עם שכבת-ניתוח חדשה ("נשוב על כך כי…"). אין עובדות חדשות בדיון שלא הופיעו ברקע. מקור-סמכות: היו"ר + block-schema.md (בלוק י, §5.2 "ללא כפילות") + skills/decision/SKILL.md §9.1. אכיפה: ולידציית-מבנה (עובדה בדיון ללא עוגן ברקע = flag) + שערי QA; מפורט ב-05-qa-review.md. הפרה ידועה:

INV-WR3: מענה לכל טענה של הצד המפסיד

כלל: כל טענה עיקרית שהוצגה בבלוק ז — ובמיוחד של הצד המפסיד — מקבלת מענה מנומק בבלוק י (ישיר, "למעלה מן הצורך", או מקובץ עם דומותיה). מותר לא להכריע בטענה נחוצה-פחות ("נוכח מסקנתנו לעיל, אין צורך…"), אך אסור להתעלם מטענה מרכזית — הצד המפסיד חייב לראות שהוועדה שקלה את יסודות עמדתו (steel-manning). מקור-סמכות: היו"ר + decision-methodology.md §§ג.2, ו.2 + block-schema.md (בלוק י MUST: "מענה לכל טענה" §5.4) + skills/decision/SKILL.md §6.2. אכיפה: מיפוי טענות-בלוק-ז → מענה-בלוק-י (נשען על §1.2, הטיעונים המאוגדים) + שערי QA; מפורט ב-05-qa-review.md. הפרה ידועה:

INV-WR4: בלוק ז — טענות מקוריות בלבד

כלל: בלוק ז מכיל אך ורק טענות מכתבי-הטענות המקוריים (כתב-ערר, כתב-תשובה). תוכן מהשלמות-טיעון, החלטות-ביניים, ותגובות-מאוחרות → בלוק ח (הליכים), לא בלוק ז. הצגת-הטענות היא בנאמנות וללא הערכה ("טענה זו חלשה") — ההערכה שייכת לבלוק י. מקור-סמכות: היו"ר + block-schema.md (בלוק ז Sources + §5.2 "טענות מקוריות בלבד") + skills/decision/SKILL.md §4. אכיפה: סיווג-מקור של טענה בעת החילוץ (extract_claims מסנן appeal/response/ objection; מסמכי פוסט-דיון מתויגים is_post_hearing ומופנים לבלוק ח — block-schema.md §7)

INV-WR5: "מבחן-השופט" — החלטה עצמאית וקריאה

כלל: ההחלטה חייבת להיות עצמאית וקריאה לשופט שלא מכיר את התיק — תשתית עובדתית מלאה (בלוק ו), תיעוד procedural-fairness (בלוק ח), והנמקה שעומדת בבדיקת סבירות ומידתיות (בלוק י). הקורא לא נדרש לחומרי-המקור כדי להבין את ההחלטה ואת הצדקתה. מקור-סמכות: היו"ר + block-schema.md §4.3 ("מבחן השופט" / Judicial-Review weight) + decision-methodology.md §יב (רשימת-ביקורת) + corpus-analysis.md. אכיפה: שער QA סופי ("מבחן-השופט") על ההחלטה כיחידה שלמה; מפורט ב-05-qa-review.md. הפרה ידועה:


5. צ'קליסט-תוכן לפי סוג-ערר

בלוק י מקבל צ'קליסט-תוכן המוזרק אוטומטית ל-prompt לפי סוג-הערר, מתוך CONTENT_CHECKLISTS ב-mcp-server/src/legal_mcp/services/lessons.py:355. הבורר (lessons.py:532-555) ממפה לסוג: tama38 (תמ"א 38) · betterment_levy (היטל-השבחה) · licensing_property · licensing_threshold (שאלת-סף) · licensing_substantive (ברירת-מחדל לרישוי). הצ'קליסט מבטיח שהדיון מכסה את הנושאים התכנוניים/המשפטיים שדפנה מכסה בפועל בקורפוס — ראה corpus-analysis.md §§3, 6 לדפוסי-התוכן ולפער שנסגר (§5.3). זהו מנגנון-תוכן באחריות היו"ר, לא חוק-הנדסה.


6. הפניות-אחיות