Add Track Changes architecture for draft revisions (CMP + CMPA)
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 1m29s

Fixes critical bug in 1033-25: user-uploaded עריכה-*.docx files were
orphaned on disk while exports kept rebuilding from stale DB blocks.

New architecture:
- User-uploaded DOCX becomes the source of truth (cases.active_draft_path)
- System edits via XML surgery with real Word <w:ins>/<w:del> revisions
- User can Accept/Reject each change from within Word

Components:
- docx_reviser.py: XML surgery for Track Changes (15 tests)
- docx_retrofit.py: retroactive bookmark injection with Hebrew marker
  detection + heading heuristic (9 tests)
- docx_exporter.py: emits bookmarks around each of the 12 blocks
- 3 new MCP tools: apply_user_edit, list_bookmarks, revise_draft
- 4 new/updated endpoints: upload (auto-registers active draft),
  /exports/revise, /exports/bookmarks, /exports/{filename}/retrofit,
  /active-draft
- DB migration: cases.active_draft_path column
- UI: correct banner using real v-numbers, "מקור האמת" badge,
  detailed upload toast with bookmarks_added/missing_blocks
- agents: legal-exporter (3 export modes), legal-ceo (stage G for
  revision handling), legal-writer (revision mode)

Multi-tenancy:
- Works for both CMP (1xxx cases) and CMPA (8xxx/9xxx cases)
- New revise-draft skill added to both companies
- deploy-track-changes.sh syncs skills CMP ↔ CMPA
- retrofit_case.py: one-off retrofit of existing files

Tests: 34 passing (15 reviser + 9 retrofit + 4 exporter bookmarks + 6 e2e)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-16 18:49:30 +00:00
parent 28daff58be
commit 726498126d
20 changed files with 2419 additions and 23 deletions

View File

@@ -25,6 +25,9 @@ tools:
- mcp__legal-ai__brainstorm_directions
- mcp__legal-ai__validate_decision
- mcp__legal-ai__export_docx
- mcp__legal-ai__apply_user_edit
- mcp__legal-ai__list_bookmarks
- mcp__legal-ai__revise_draft
---
# עוזר משפטי — מנהל תהליך כתיבת החלטות
@@ -363,6 +366,47 @@ python3 /home/chaim/legal-ai/scripts/notify.py \
**מתי לחזור אחורה:** אם דוח QA מצביע על בעיה מתודולוגית (סילוגיזם חסר, כיוון לא תואם chair_directions) — חזור לשלב C/D ולא רק לכותב.
### שלב G: טיפול בעריכה מהמשתמש (אחרי ייצוא)
**מתי:** המשתמש העלה `עריכה-v*.docx` (אחרי שייצאנו `טיוטה-v*.docx` קודמת) וכתב תגובה בקומנט.
**מטרה:** המשתמש ערך את הטיוטה ב-Word ושמר כ-`עריכה-v*.docx`. הוא רוצה שתתייחס לעריכה שלו כבסיס החדש, ואולי לבצע שינויים ממוקדים ע"ג העריכה. כל שינוי שאתה מבצע חייב להיות ב-**Track Changes** כדי שהמשתמש יראה מה שינית ויוכל לאשר/לדחות.
**תהליך:**
1. קרא את הקומנט האחרון של המשתמש — האם הוא רק מעדכן ("העליתי טיוטה ערוכה"), או מבקש שינוי ספציפי ("הוסף פסק הלכה X")?
2. הרץ `apply_user_edit(case_number, "עריכה-v{N}.docx")` — זה:
- מזריק bookmarks אם חסר (`block-alef` עד `block-yod-bet`)
- מגדיר את הקובץ כ-`active_draft_path`
- מחזיר `bookmarks_added` ו-`missing_blocks`
3. אם המשתמש רק עדכן (לא ביקש שינוי):
- דווח בקומנט: "העריכה נקלטה. זיהיתי N בלוקים. אם יש שינויים שתרצה שאבצע — שלח אותם כהוראה."
- **אל תייצר `טיוטה-v{N+1}.docx` חדשה**
4. אם המשתמש ביקש שינוי:
- קרא `list_bookmarks(case_number)` לדעת אילו אנקורים זמינים
- אם הבקשה מצריכה ניסוח חדש (למשל הוספת פסק הלכה, שכתוב בלוק) — הפעל את **legal-writer** עם `revision_mode: true` והוראה מדויקת לניסוח. הכותב יחזיר תוכן מנוסח בסגנון דפנה (לא ישמור ב-DB — ה-revision חי בקובץ)
- בנה רשימת revisions (JSON):
```json
[{
"id": "r1",
"type": "insert_after",
"anchor_bookmark": "block-yod",
"content": "<הטקסט שהכותב ניסח>",
"style": "body",
"reason": "הוספת פסק הלכה X לפי בקשת יו\"ר"
}]
```
- הרץ `revise_draft(case_number, revisions_json)` — ייצור `טיוטה-v{N+1}.docx` עם Track Changes
- פרסם comment: "טיוטה מעודכנת: `טיוטה-v{N+1}.docx`. השינויים מסומנים כ-Track Changes — פתח ב-Word ואשר/דחה."
**חשוב:**
- לעולם אל תקרא ל-`export_docx` כשיש `active_draft_path` שהוא `עריכה-*` — זה ידרוס את העריכה של המשתמש בגרסה ישנה מ-DB.
- השתמש ב-`revise_draft` בלבד במצב ג'.
- אם המשתמש ביקש שינוי מאסיבי (שכתוב מלא של בלוק) — עדיף להציע לו לעבוד על זה בעריכה נוספת מצדו ולא לייצר revisions ארוכים.
## מפת סטטוסים
**סטטוסים של התיק (`cases.status`) — כל סטטוס מתאים לפעולה אחת בדיוק:**

View File

@@ -14,6 +14,9 @@ tools:
- mcp__legal-ai__get_block_context
- mcp__legal-ai__workflow_status
- mcp__legal-ai__export_docx
- mcp__legal-ai__apply_user_edit
- mcp__legal-ai__list_bookmarks
- mcp__legal-ai__revise_draft
- mcp__legal-ai__get_style_guide
- mcp__legal-ai__validate_decision
---
@@ -26,6 +29,14 @@ tools:
עבוד תמיד בעברית.
## סינון תיקים לפי חברה
⚠️ **אתה אחראי רק על תיקים ששייכים לחברה שלך** (`$PAPERCLIP_COMPANY_ID`):
- CMP (`42a7acd0-...`) → רק תיקים **1xxx** (רישוי ובניה)
- CMPA (`8639e837-...`) → רק תיקים **8xxx, 9xxx** (היטל השבחה / פיצויים)
אם issue מכוון לתיק שלא בטווח שלך — סרב ודווח ב-comment.
## סקייל ייצוא
**חובה לקרוא לפני כל ייצוא:**
@@ -45,6 +56,16 @@ tools:
2. קרא פרטי תיק (`case_get`)
3. בדוק סטטוס workflow (`workflow_status`) — ודא שהכתיבה הושלמה **ושבדיקת QA עברה בהצלחה**
### שלב 1.5: זיהוי active_draft ועריכות ממתינות
1. בדוק אם ב-`data/cases/{case_number}/exports/` יש קבצי `עריכה-v*.docx` (עלו ע"י המשתמש)
2. אם כן — הפעל `apply_user_edit` עם שם הקובץ האחרון; הכלי יזריק bookmarks ויגדיר את הקובץ כמקור האמת
3. אם במצב הזה המשתמש לא ביקש revisions מפורשים — **אל תייצא מחדש** (הקובץ שהועלה *הוא* הטיוטה העדכנית). דווח למשתמש ששמרת את העריכה כמקור האמת, והצע revisions אם נדרש
4. אם המשתמש ביקש שינויים (למשל "הוסף פסק הלכה X" / "תקן את הבלוק"):
- הרץ `list_bookmarks` כדי לראות אילו אנקורים זמינים
- בנה רשימת revisions (ראה פורמט למטה)
- הרץ `revise_draft` — זה ייצור `טיוטה-v{N+1}.docx` חדשה עם Track Changes
### שלב 2: בדיקה סופית מהירה
1. הרץ `validate_decision` — בדוק שאין כשלים קריטיים
2. בדוק שכל 12 הבלוקים (א-יב) קיימים ומלאים
@@ -54,9 +75,30 @@ tools:
6. בדוק שסטטוס ה-QA הוא "passed" — אם ה-QA לא רץ או נכשל, **אל תייצא**
### שלב 3: ייצוא DOCX
**מצב א' — ייצוא ראשוני (אין active_draft):**
1. קרא את סקייל legal-docx (SKILL.md) כדי להבין את דרישות העיצוב
2. השתמש ב-`export_docx` לייצוא ראשוני לקובץ זמני
3. אם הסקריפט `create-legal-doc.js` מתאים יותר (למשל לעיצוב מותאם) — השתמש בו
2. השתמש ב-`export_docx` לייצוא ראשוני
3. ה-tool יוסיף bookmarks ב-12 הבלוקים ויסמן את הקובץ כ-active_draft_path
**מצב ב' — יש active_draft + המשתמש ביקש שינויים:**
1. בנה רשימת revisions ב-JSON. פורמט כל revision:
```json
{
"id": "r1",
"type": "insert_after", // או insert_before, replace, delete
"anchor_bookmark": "block-yod", // מ-list_bookmarks
"content": "וכך נפסק בעניין פלוני. בבג\"ץ 1234/21 קבע השופט...",
"style": "body", // או heading, quote
"reason": "הוספת פסק הלכה שחסר לפי בקשת יו\"ר"
}
```
2. הפעל `revise_draft` — ייצור `טיוטה-v{N+1}.docx` עם `<w:ins>` / `<w:del>` — המשתמש יקבל/ידחה ב-Word
3. דווח למשתמש על הגרסה החדשה ו-applied/failed count
**מצב ג' — יש active_draft אך המשתמש לא ביקש שינוי ספציפי:**
הטיוטה כבר עדכנית (המשתמש ערך ב-Word). אל תייצא מחדש. דווח: "הקובץ העדכני הוא `<active_draft>`. רוצה שאבצע שינויים ממוקדים?"
### שלב 4: שמירה מגורסת
1. צור תיקייה `~/legal-ai/data/cases/{מספר-ערר}/exports/` (אם לא קיימת)

View File

@@ -78,6 +78,28 @@ tools:
## תהליך עבודה
### מצב revision — תוספת נקודתית לטיוטה קיימת
כש-CEO מבקש **תוספת נקודתית** (לא כתיבה מאפס) — למשל "הוסף פסק הלכה X בבלוק י" — המצב הוא:
- המשתמש העלה `עריכה-v*.docx` והוא ה-`active_draft_path`
- נדרש ניסוח של פסקה/פסקאות בסגנון דפנה להכנסה ב-Track Changes
- **אסור להשתמש ב-`save_block_content`** — ה-revision חי בקובץ, לא ב-DB
**זרימה:**
1. קרא `get_block_context(case_number, block_id)` להקשר
2. קרא `get_style_guide()` לוודא סגנון דפנה
3. נסח את התוספת — טקסט עברי נקי, בלי placeholders (`X`, `...`, `[לציטוט]`), מוכן להכנסה ישירה ל-DOCX
4. החזר את הטקסט ל-CEO (בקומנט או כ-return value) — **לא** שומר ב-DB
5. CEO יקרא ל-`revise_draft` עם הטקסט שלך
**דוגמה לפלט מצופה:**
> בבג"ץ 1234/21 [פלוני נ' הוועדה המחוזית] קבע בית המשפט העליון כי הוועדה המקומית מחויבת לשקול שיקולי Y גם בהיעדר התנגדות מפורשת. הלכה זו חלה ישירות על ענייננו: הוועדה המקומית לא בחנה את Y, ודי בכך כדי להחזיר את הדיון לוועדה.
---
### שלב 0: בדיקת הוראות וטיוטות
לפני שתתחיל לכתוב, בדוק אם יש הנחיות ספציפיות: