# 06 — ייצוא DOCX (Export Contract) קובץ-תחום זה כפוף ל-[חוקת המערכת](00-constitution.md) ומגדיר את **חוזה-הייצוא** של עוזר משפטי: הרינדור של החלטה ל-DOCX מעוצב (גופן David, RTL, סגנונות-טמפלט). העיקרון המכונן — **ה-DB הוא מקור-האמת היחיד, וה-DOCX הוא נתון נגזר (derived) הניתן לשחזור**. הקובץ אוכף את [INV-G2](00-constitution.md#inv-g2-מקור-אמת-יחיד--אין-מסלולים-מקבילים-מתפצלים) (מקור-אמת יחיד / נתון-נגזר משוחזר) ואת [INV-G9](00-constitution.md#inv-g9-עקיבוּת-מקור--audit-trail-ל-ai) (עקיבוּת-מקור), והוא השלב שאחרי שער-הייצוא הקריטי של [05-qa-review.md / INV-QA3](05-qa-review.md#inv-qa3-החלטה-לא-מיוצאת-עם-כשל-קריטי-governance--g10). > **כללי-סגנון — סמכות אחת.** מכניקת העיצוב (line classification, dash policy, placeholder, > מיפוי-סגנונות, RTL-runs) מתועדת במלואה בסקיל > [`dafna-decision-template/SKILL.md`](../../skills/dafna-decision-template/SKILL.md) — **הוא > המקור הסמכותי**. הקובץ הזה **מסכם ומפנה**, לא משכפל. כללי-הסגנון עצמם הם תוכן-משפטי-דומייני > (סמכות היו"ר + הסקיל), בעוד שחוזה-ה-derived-data (INV-EX1) ועקיבוּת-המקור (INV-EX2) הם > invariants הנדסיים הנושאים `מקורות` + `סטטוס`. --- ## 1. חוזה-הייצוא — DB הוא המקור, DOCX הוא הנגזר החלטה מאוחסנת כ-**בלוקים מובְנים ב-DB** — `decision_blocks` (12 בלוקים, מפתח קנוני `UNIQUE(decision_id, block_id)`) תחת `decisions` (`UNIQUE(case_id, version)`); ראה [02-data-model.md §1](02-data-model.md). ה-DOCX **נגזר** מהבלוקים האלה ואינו מקור-אמת עצמאי: מחיקתו אינה מאבדת תוכן, וייצוא חוזר מאותם בלוקים מפיק מסמך שקול. **מסלול-הייצוא הקנוני (הסופי):** 1. `export_docx(case_number)` (`tools/drafting.py:384`, נחשף `server.py:557`) שולף את התיק, ואז קורא ל-`docx_exporter.export_decision(case_id, …, mode="final")` (`services/docx_exporter.py:306`). 2. `export_decision` שולף את הבלוקים **ישירות מ-`decision_blocks`** (`SELECT block_id, block_index, title, content, word_count … ORDER BY block_index`, `docx_exporter.py:336-342`) — אין מקור-תוכן אחר. 3. טוען את טמפלט-דפנה (`skills/docx/decision_template.docx`, `docx_exporter.py:27-29,364`), מנקה את גוף-המסמך (`_clear_body`), וכותב כל בלוק עם **bookmark עוטף** (אנקור ל-revisions עתידיים, `_wrap_block_with_bookmarks`, `docx_exporter.py:367-382`). 4. שומר לקובץ מגורסן `data/cases/{case_number}/exports/טיוטה-v{N}.docx` (גרסה אוטומטית עולה, `docx_exporter.py:384-400`). > **שני מסלולי-ייצוא לפי מקור-התוכן (לא מסלולים-מקבילים מתפצלים):** > - `docx_exporter.py` — **ההחלטה הסופית** מ-12 הבלוקים ב-`decision_blocks` (`mode="final"`), > וגם **טיוטת-ביניים** (`mode="interim"` — תת-קבוצת בלוקים בסדר חדש: רקע→תכניות→טענות→הליכים, > `export_interim_draft`, `drafting.py:511`). שני המצבים שולפים מאותה טבלה — וריאציית-תצוגה > של אותו מקור-אמת, לא מסלול שני. > - `analysis_docx_exporter.py` (`build_analysis_docx`, `:401`) — מייצא את מסמך **הניתוח > המשפטי** (`analysis-and-research.md`) שכתב `legal-analyst`, לא את בלוקי-ההחלטה. זהו תוצר-עזר > שונה (שלב ניתוח, לא החלטה) — והוא המסלול שהסקיל מתעד בעיקר. שניהם חולקים את **אותו טמפלט > ואותם כללי-סגנון**, כנדרש מ-[INV-G2](00-constitution.md#inv-g2-מקור-אמת-יחיד--אין-מסלולים-מקבילים-מתפצלים) > (סימטריה — לא שתי שכבות-סגנון מתפצלות). ## 2. כללי-הסגנון — סיכום (הסמכות: הסקיל) ה-service מחיל את סגנונות-הטמפלט בלבד (`paragraph.style = "Heading 2"`) — בלי font/size/indent ידני; העיצוב (David, RTL, גדלים) מגיע מ-`styles.xml`. הפירוט המלא + ה-XML של כל סגנון: [`SKILL.md`](../../skills/dafna-decision-template/SKILL.md) + `references/`. - **סיווג-שורות (`_classify_line`):** כל שורה מסווגת לאחת מ-6 קטגוריות — `label_heading`, `inline_label`, `numbered`, `bullet`, `heb_letter`, `plain` — שקובעות את הסגנון המוחל (Heading 2 / Normal / List Paragraph). ראה [`references/line-classification.md`](../../skills/dafna-decision-template/references/line-classification.md). - **מדיניות-מקפים (`_no_dash`):** דפנה ביקשה "בלי מקפים בכלל" — `—` (U+2014) ו-`–` (U+2013) מוסרים מכל טקסט נכתב; מקף רגיל (`-`) נשמר. - **שדות-placeholder:** `chair_position` עם סימן-ריק (`[ימולא ע"י יו"ר הוועדה]` וכד') מוחלף ב-`[טרם מולאה עמדת ועדת הוועדה]` ב-italic — סימן ויזואלי שנותר להשלים (תואם [INV-G10](00-constitution.md#inv-g10-המערכת-מסייעת--שערים-אנושיים-הם-invariant) — היו"ר משלימה, לא המערכת). - **RTL-runs:** כל run מסומן `` (`_mark_run_rtl`) — אחרת Word נופל ל-Times New Roman במקום David. ראה [`references/rtl-runs.md`](../../skills/dafna-decision-template/references/rtl-runs.md). - **מספור:** מספור אוטומטי רק ב-`List Paragraph` (decimal); שורות `(א)(ב)` מקבלות `List Paragraph` עם `_strip_numpr()` (המספור העברי בטקסט). ## 3. רישום הגרסה — `active_draft_path` + git לאחר כתיבת ה-DOCX, `export_docx` (`drafting.py:404-408`): 1. **`set_active_draft_path(case_id, path)`** (`db.py:1177`) — רושם את ה-DOCX שיוצא כ- active-draft הנוכחי (`cases.active_draft_path`, `db.py:189`). שדה זה הוא **האנקור לעריכות עוקבות** (`revise_draft`/`apply_user_edit`/`list_bookmarks`), לא מקור-אמת-תוכן מתחרה ל-DB. 2. **`git_sync.commit_and_push(case_dir, "ייצוא DOCX: …")`** (`drafting.py:408`) — מקבע את הקובץ ב-git של תיקיית-התיק (audit-trail של פלט, [INV-G9](00-constitution.md#inv-g9-עקיבוּת-מקור--audit-trail-ל-ai); ראה [X5-audit-provenance.md](X5-audit-provenance.md)). אותו דפוס (`set_active_draft_path` + commit) חוזר ב-`export_interim_draft` (`drafting.py:533,536`), `revise_draft` (`drafting.py:692,695`) ו-`apply_user_edit` (`drafting.py:579,582`). --- ## 4. Invariants של התחום ### INV-EX1: ייצוא דטרמיניסטי ומשוחזר מהבלוקים — DOCX הוא נתון-נגזר (→G2) **כלל:** הייצוא **דטרמיניסטי וניתן-לשחזור** מבלוקי-ההחלטה המאוחסנים ב-`decision_blocks`: אותם בלוקים + אותו טמפלט מפיקים מסמך שקול. ה-DOCX הוא **נתון-נגזר (derived)** — **לעולם לא מקור-אמת עצמאי**. אסור מסלול-תוכן שני שכותב DOCX ממקור שאינו ה-DB; וריאציות (final/interim) הן תצוגות של אותו מקור. **מקורות:** Martin Kleppmann — *Designing Data-Intensive Applications* (O'Reilly, 2017, system-of-record מול derived data, ושחזור derived מהמקור) · Martin Fowler (Canonical Data Model / Single Source of Truth) · SSOT (Single Source of Truth principle) | סטטוס: verified **אכיפה:** `export_decision` שולף אך-ורק מ-`decision_blocks` (`docx_exporter.py:336-342`); פלט מגורסן + idempotent מבחינת-תוכן; אוכף את [INV-G2](00-constitution.md#inv-g2-מקור-אמת-יחיד--אין-מסלולים-מקבילים-מתפצלים) וכלל-ההנדסה "סימטריה" (חוקה §6). **הפרה ידועה:** אחרי `revise_draft`/`apply_user_edit`, ה-DOCX המסומן `active_draft_path` הופך ל"מקור-האמת" לעריכות-Track-Changes העוקבות (`db.py:185-188`), ו**בלוקי-ה-DB אינם מתעדכנים חזרה** — הנתון-הנגזר זוחל למקור-אמת בפועל בלי סנכרון לאחור. **יעד:** או re-sync מהבלוקים, או חוזה מפורש ש-`active_draft_path` הוא רק אנקור-revision ולא מקור-תוכן → ראה [§5](#5-current-vs-target). ### INV-EX2: עקיבוּת-מקור נשמרת בהחלטה המיוצאת (→G9) **כלל:** ההחלטה המיוצאת **שומרת על עקיבוּת-מקור** היכן שנדרש — סמכויות-משפטיות מצוטטות ניתנות-לאיתור (citation resolvable), והפלט מקובע ב-audit-trail (commit git). הפניות-פסיקה בבלוקים אינן מאבדות את מקורן בעת הרינדור. **מקורות:** Council of Europe / CEPEJ — *European Ethical Charter on AI in judicial systems* (2018, traceability/transparency) · ISO 15489-1:2016 (records authenticity/integrity) · Lewis et al. (2020, NeurIPS — RAG attribution) | סטטוס: verified **אכיפה:** `export_docx` מקבע כל פלט ב-git (`git_sync.commit_and_push`, `drafting.py:408`) + רושם `active_draft_path` (`db.py:1177`); עקיבוּת-המקור של הציטוטים עצמם נאכפת במעלה-הזרם (חילוץ-טענות/הלכות + provenance, [04-analysis-writing.md](04-analysis-writing.md), [X5-audit-provenance.md](X5-audit-provenance.md)). אוכף את [INV-G9](00-constitution.md#inv-g9-עקיבוּת-מקור--audit-trail-ל-ai). **הפרה ידועה:** — ### INV-EX3: אין ייצוא בכשל-QA קריטי (restate של INV-QA3 →G10) **כלל:** הייצוא **חסום** כל עוד שער-QA קריטי נכשל (`claims_coverage` / `structural_integrity`); `export_blocked` חייב להיבדק לפני ייצוא. זהו אותו invariant של [INV-QA3](05-qa-review.md#inv-qa3-החלטה-לא-מיוצאת-עם-כשל-קריטי-governance--g10), בצד-הייצוא. **מקורות:** NCSC/JTC — *Principles & Practices for AI Use in Courts* (controlled, auditable output) · Council of Europe / CEPEJ (2018, under user control) · Federal Judicial Center — *Judicial Writing Manual* (2d ed.) | סטטוס: verified **אכיפה:** `export_blocked = critical_failures > 0` (`qa_validator.py:362`); **נאכף ברמת- הזרימה/agent בלבד** — הסוכן `legal-exporter` מחויב להריץ `validate_decision` ולבדוק כשלים-קריטיים לפני ייצוא (`.claude/agents/legal-exporter.md:71,149`). **הפרה ידועה:** `export_docx` (`drafting.py:384`) **אינו** קורא ל-`validate_decision` בעצמו — הוא ניגש ישירות ל-`docx_exporter.export_decision` בלי לבדוק `export_blocked`. החסימה תלויה במשמעת-הסוכן ואינה hard-block בקוד-הייצוא → ראה [§5](#5-current-vs-target) (תואם [05-qa-review §4](05-qa-review.md#4-current-vs-target--ממצאי-audit)). --- ## 5. Current vs Target - **שער-ייצוא אכוף-זרימה ולא אכוף-קוד (INV-EX3 / INV-QA3).** אומת בקוד: `export_docx` (`drafting.py:384-419`) קורא ישירות ל-`docx_exporter.export_decision` (`:403`) ללא קריאה ל-`qa_validator.validate_decision` ובלי בדיקת `export_blocked`. החסימה מתקיימת רק כי הסוכן `legal-exporter` מחויב להריץ QA קודם (`legal-exporter.md:71,149`) — אדם/סוכן שיקרא ל-`export_docx` ישירות **יעקוף** את השער. **יעד:** hard-block בתוך `export_docx` — שליפת `qa_results`/`export_blocked` ודחייה לפני כתיבת ה-DOCX, כך שאי-אפשר לעקוף. - **`active_draft_path` כ-derived-שזוחל-למקור (INV-EX1).** ה-DOCX נגזר מהבלוקים בייצוא הראשון, אך אחרי עריכה (`revise_draft`/`apply_user_edit`) ה-DOCX הופך ל"מקור-האמת" לעריכות הבאות (`db.py:185-188`) בלי לעדכן את `decision_blocks` חזרה — סטייה אפשרית בין הבלוקים למסמך-החי. **יעד:** חוזה מפורש — או re-sync מהבלוקים, או הגדרת `active_draft_path` כאנקור-revision בלבד (לא מקור-תוכן), עם בדיקת-בריאות לגילוי drift בין הבלוקים ל-DOCX הפעיל. --- ## 6. הפניות-אחיות - [00-constitution.md](00-constitution.md) — [INV-G2](00-constitution.md#inv-g2-מקור-אמת-יחיד--אין-מסלולים-מקבילים-מתפצלים) (derived-data / מקור-יחיד) · [INV-G9](00-constitution.md#inv-g9-עקיבוּת-מקור--audit-trail-ל-ai) (עקיבוּת) · [INV-G10](00-constitution.md#inv-g10-המערכת-מסייעת--שערים-אנושיים-הם-invariant) (שערים). - [02-data-model.md](02-data-model.md) — `decisions`/`decision_blocks` (המקור שממנו מייצאים). - [04-analysis-writing.md](04-analysis-writing.md) — כתיבת הבלוקים שמהם נגזר ה-DOCX. - [05-qa-review.md](05-qa-review.md#inv-qa3-החלטה-לא-מיוצאת-עם-כשל-קריטי-governance--g10) — INV-QA3 (שער-הייצוא הקריטי שקודם לשלב זה). - [07-learning.md](07-learning.md) — `ingest_final_version` + Hermes על ההחלטה הסופית. - [X5-audit-provenance.md](X5-audit-provenance.md) — audit-trail (commit git) ועקיבוּת-מקור. - [`skills/dafna-decision-template/SKILL.md`](../../skills/dafna-decision-template/SKILL.md) — **המקור הסמכותי** לכללי-הסגנון (line classification · dash policy · placeholder · RTL-runs).