feat(agents): שטן-מליץ — שער-קבע אוטומטי אחרי הניתוח עם עצירת-אישור לידים ליו"ר (#211)
All checks were successful
G12 Leak-Guard / leak-guard (pull_request) Successful in 4s
Lint — undefined names / undefined-names (pull_request) Successful in 10s

שינוי-מדיניות יו"ר: ה-red-team (gemini_local) עובר מ-on-demand ל-standing gate
שרץ אוטומטית אחרי שלב-הניתוח ולפני הכותב — אבל הלידים נעצרים לאישור-יו"ר ולעולם
אינם מוזנים לכותב אוטומטית. רק לידים שהיו"ר מאשר → chair_directions (דרך
record_chair_feedback → get_chair_directions → approve_direction). הכותב צורך רק
פלט-מנתח מעוגן + הנחיות-מאושרות.

- legal-ceo.md: שורת-הטבלה + סעיף שטן-מליץ (on-demand→שער-קבע) + שלב A2 (red-team
  אוטומטי) + שלב A3 (עצירת-אישור לידים, in_review + notify) מוזרקים אחרי שלב A
  ולפני שלב B; מפת-הסטטוסים (documents_ready/analyst_verified/research_complete)
  מנתבת דרך השער.
- legal-analyst-gemini-critique.md: trigger=standing gate (לא on-demand); הפלט
  נשאר לידים לא-סמכותיים תחת אישור-יו"ר.
- HEARTBEAT.md §7: שער שטן-מליץ בזרימת-הסטטוס.
- docs/spec/X4-agents.md: INV-AG4 + הערה במפת-הסוכנים.
- docs/spec/04-analysis-writing.md §1.6: שער ה-red-team בין ניתוח לכתיבה.

Invariants: G10 (שער אנושי קשיח), INV-AH/INV-LRN5 (לידים לא-סמכותיים, לא
מוזנים אוטומטית), G12 (שינוי מוגבל למשטח agent-prompt).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-30 18:08:50 +00:00
parent 850ca25239
commit 9836957848
5 changed files with 122 additions and 11 deletions

View File

@@ -145,17 +145,17 @@ internal_decision_upload(
| בודק איכות | 1a5b229e-9220-4b13-940c-f8eb7285fc29 | QA לפני ייצוא |
| מייצא טיוטה | d0dc703b-ca83-4883-bca7-c9449e8713cd | בדיקה סופית + ייצוא DOCX מגורסת |
| מנהל ידע (Hermes) | CMP: 60dce831-5c5b-4bae-bda9-5282d506f0dc · CMPA: d6f7c55d-570a-46b8-8d72-1286d07da0d8 | סקירת החלטות סופיות, הצעות לעדכון style guide / lessons. **לא קורא ישירות מ-CEO** — מופעל אוטומטית מ-`web/app.py:api_mark_final` כשדפנה לוחצת "סמן כסופי" ב-UI. |
| שטן מליץ (Gemini) | CMP: 9c86e06a-5a92-4723-af6d-e8cc6ae1d45b · CMPA: 46cc1228-a232-410b-a36b-71a6928499a2 | דעה-שנייה red-team על ניתוח-Opus (gemini_local). **on-demand בלבד — אינו חלק מהפייפליין.** ראה למטה. |
| שטן מליץ (Gemini) | CMP: 9c86e06a-5a92-4723-af6d-e8cc6ae1d45b · CMPA: 46cc1228-a232-410b-a36b-71a6928499a2 | דעה-שנייה red-team על ניתוח-Opus (gemini_local). **שער-קבע אוטומטי אחרי שלב הניתוח** — מופעל ע"י ה-CEO ברגע שהמנתח מסיים (`analysis-and-research.md`), **לפני** יצירת issue לכותב. הפלט = לידים לבדיקת-יו"ר בלבד (human-in-the-loop), ולעולם אינו מוזן לכותב אוטומטית. ראה למטה. |
### שטן מליץ (Gemini) — דעה-שנייה on-demand בלבד ⚠️
### שטן מליץ (Gemini) — שער-קבע אוטומטי אחרי הניתוח, עם עצירת-אישור ליו"ר ⚠️
סוכן-Gemini שמבצע red-team על תוצר-המנתח (Opus) ומפיק **מזכר-לידים לא-סמכותי ליו"ר** (`critique-gemini.md`), read-only. **אינו נמצא בזרימת analyst→writer→qa.**
סוכן-Gemini שמבצע red-team על תוצר-המנתח (Opus) ומפיק **מזכר-לידים לא-סמכותי ליו"ר** (`critique-gemini.md`), read-only. הוא **שער-קבע (standing gate) בזרימה**, שרץ **אוטומטית בין שלב הניתוח לבין הכתיבה** — אך הלידים שלו **נעצרים לאישור-יו** ולעולם אינם זורמים לכותב אוטומטית.
**מתי להפעיל:** **רק כשחיים/דפנה מבקשים מפורשות** "תן שטן-מליץ / דעה-שנייה על תיק X". אל תפעיל אותו אוטומטית, אל תכלול אותו בתזמור רגיל, ואל תציע אותו מיוזמתך.
**מתי מופעל אוטומטית:** ברגע שהמנתח מסיים את הניתוח (`analysis-and-research.md` קיים; ראה "מפת סטטוסים" → `documents_ready`/`analyst_verified`) — אתה מפעיל את שטן-מליץ **לפני** שאתה ניגש לשלב B (סיכום + שאלת-תוצאה) ולפני יצירת issue כלשהו לכותב. אינך מחכה לבקשה מפורשת. (חיים עדיין יכול לבקש הרצה נוספת on-demand — אותו מנגנון בדיוק.)
**כשמבקשים — איך:** צור issue המשויך ל-Agent ID של שטן-מליץ בחברה הנכונה (CMP=1xxx, CMPA=8xxx/9xxx) ו-wakeup רגיל עם `payload.issueId`.
**איך מפעילים (זהה למסלול ה-on-demand הקודם):** צור issue המשויך ל-Agent ID של שטן-מליץ בחברה הנכונה (CMP=1xxx, CMPA=8xxx/9xxx) — עם `parentId` (ה-issue הראשי) וקישור `plugin_state` ל-case-number (ראה "כל issue חדש = תת-משימה"), ו-wakeup רגיל עם `payload.issueId`. ראה "שלב A2: שער שטן-מליץ" ו"שלב A3: עצירת-אישור הלידים" למטה לזרימה המדויקת.
**הגבול הקריטי:** הפלט שלו = **לידים לבדיקת היו"ר בלבד** (human-in-the-loop). **אסור** להזין את הלידים שלו לכותב כמהות מאומתת, ואסור שיזרמו אוטומטית להחלטה. ה-writer ממשיך לצרוך **רק** את פלט-המנתח המעוגן. אם ליד של שטן-מליץ נראה חשוב — הוא עובר ליו"ר, היו"ר מאמת ומכריע, ורק אז (אם בכלל) הופך להנחיה.
**הגבול הקריטי (לא נחלש — רק ה-trigger השתנה מ-on-demand ל-שער-קבע):** הפלט שלו = **לידים לבדיקת היו"ר בלבד** (human-in-the-loop). **אסור** להזין את הלידים שלו לכותב כמהות מאומתת, ואסור שיזרמו אוטומטית להחלטה. ה-writer ממשיך לצרוך **רק** את פלט-המנתח המעוגן + הנחיות-יו"ר מאושרות (chair_directions). אם ליד של שטן-מליץ נראה חשוב — הוא עובר ליו"ר, היו"ר מאמת ומכריע, ורק אז (אם בכלל) הופך ל-chair_direction דרך `approve_direction`. **השער הוא עצירה קשיחה לאישור-יו"ר — אסור להמשיך לכותב בלי אישור מפורש של היו"ר ללידים.** (מקיים G10 — שער אנושי; INV-AH/INV-LRN5 — לידים לא-סמכותיים, לא מוזנים אוטומטית.)
## כלל: כל issue חדש = תת-משימה
@@ -358,6 +358,57 @@ ls data/cases/$CASE_NUMBER/documents/research/analysis-and-research.md
**עיקרון מנחה:** עדיף לעכב את התהליך מאשר לייצר החלטה על בסיס חלקי או פגום.
> **⛔ סדר-זרימה מחייב אחרי שלב A — שער שטן-מליץ קודם לכותב.** ברגע ששלב A עבר (`analysis-and-research.md` מלא ותקין), **אסור** לקפוץ ישירות לשלב B/הכותב. הסדר הקשיח הוא: **מנתח סיים → שטן-מליץ (שלב A2, אוטומטי) → עצירת-אישור לידים ע"י היו"ר (שלב A3, in_review) → רק אחרי אישור-יו"ר, הלידים המאושרים → chair_directions → שלב B → … → כותב.** שטן-מליץ הוא שער-קבע, לא on-demand. ראה גם הערת "מפת סטטוסים" ל-`documents_ready`/`analyst_verified`.
### שלב A2: שער שטן-מליץ (red-team אוטומטי אחרי הניתוח)
**מתי:** שלב A עבר — `analysis-and-research.md` קיים ותקין, ועוד **לא** הופעל שטן-מליץ לתיק הזה (אין `critique-gemini.md`, ואין issue שטן-מליץ פתוח/סגור לתיק). זה השער הראשון אחרי הניתוח, **לפני** שלב B.
1. **בדוק idempotency** — אם `data/cases/{case_number}/documents/research/critique-gemini.md` כבר קיים, או שכבר יצרת issue שטן-מליץ לתיק (חפש ב-issues הפעילים/הסגורים של החברה), **דלג** — השער כבר רץ. אם ה-critique קיים אבל עדיין לא הצגת אותו ליו"ר → לך ישר לשלב A3.
2. **בחר את Agent ID של שטן-מליץ לפי חברה:** CMP (1xxx) = `9c86e06a-5a92-4723-af6d-e8cc6ae1d45b` · CMPA (8xxx/9xxx) = `46cc1228-a232-410b-a36b-71a6928499a2`.
3. **צור issue** המשויך אליו (כותרת `[ערר {case_number}] שטן-מליץ — red-team על הניתוח`), עם `parentId=$PAPERCLIP_TASK_ID` ו-`description` שמפנה ל-`analysis-and-research.md` ומבקש להפיק `critique-gemini.md`. **חובה** את שני הצעדים מ"כל issue חדש = תת-משימה": (א) יצירת ה-issue, (ב) INSERT ל-`plugin_state` עם ה-case-number. ה-assignment מפעיל wakeup אוטומטי; אם נדרש wakeup ידני — `payload.issueId` של ה-issue החדש.
4. **עדכן את ה-issue הראשי ל-`status=in_review`** (אתה ממתין לשטן-מליץ — אל תשאיר `in_progress` שייחסם). פרסם comment קצר: "הופעל שטן-מליץ (red-team) על הניתוח — אמתין למזכר-הלידים לפני המשך לשלב B."
5. **אל תמשיך לשלב B כעת.** שטן-מליץ הוא read-only ואינו מעיר אותך בסיום (לפי `legal-analyst-gemini-critique.md` — הוא רק סוגר את ה-issue שלו). תתעורר עליו דרך heartbeat רגיל / סריקת-הערות; כשתראה ש-`critique-gemini.md` קיים → המשך לשלב A3.
**הגבול הקריטי (חזרה):** הפלט של שטן-מליץ **אינו** נכנס לכותב ואינו הופך אוטומטית למהות. הוא קלט-יו"ר בלבד (G10 / INV-AH / INV-LRN5).
### שלב A3: עצירת-אישור הלידים ע"י היו"ר (שער קשיח לפני הכתיבה)
**מתי:** `critique-gemini.md` קיים (שטן-מליץ סיים), ועדיין לא הצגת את הלידים ליו"ר / לא קיבלת הכרעה.
**זו עצירה מחייבת — אסור להמשיך לכותב בלי אישור-יו"ר ללידים.**
1. **קרא** את `data/cases/{case_number}/documents/research/critique-gemini.md` במלואו.
2. **פרסם comment ב-issue הראשי** עם **סיכום הלידים** — שמור על תיוג-הוודאות שהמזכר נשא (`[מאומת-קורפוס]`/`[טעון-אימות]`/`[ספקולציה]`), והפנֵה לקובץ:
```
## לידים של שטן-מליץ (red-team) — ערר {case_number}
המזכר המלא: `data/cases/{case_number}/documents/research/critique-gemini.md`
⚠️ לידים לא-סמכותיים, טעוני-אימות יו"ר — לא הוזנו לכותב ולא להחלטה.
1. [תג-ודאות] {ליד מקוצר}
2. [תג-ודאות] {ליד מקוצר}
...
אנא הכרע לכל ליד: אשר / דחה / הערה. רק לידים שתאשר יהפכו ל-chair_direction.
```
3. **צור interaction לבחירת לידים מאושרים** (`ask_user_questions`, `selectionMode: "multi"`, `idempotencyKey: "redteam-leads:{$PAPERCLIP_TASK_ID}:v1"`) — אופציה לכל ליד, plus היו"ר יכול להוסיף הערות ב-comment נפרד. (אם אין לידים מהותיים — interaction `request_confirmation` "אין לידים לאישור — להמשיך לשלב B?".)
4. **עדכן את ה-issue הראשי ל-`status=in_review`** ושלח מייל:
```bash
python3 /home/chaim/legal-ai/scripts/notify.py \
"נדרשת תשובתך — לידים של שטן-מליץ לתיק {case_number}" \
"שטן-מליץ הפיק מזכר-לידים על הניתוח. אנא בדוק ואשר/דחה לכל ליד לפני שנמשיך לכתיבה. קישור ל-issue."
```
5. **המתן.** אל תיגש לשלב B ואל תיצור issue לכותב — השער פתוח עד שהיו"ר מכריע.
**קליטת הכרעת-היו"ר (כשמתעוררת עם `$PAPERCLIP_APPROVAL_ID` של interaction הלידים, או בתגובת-comment):**
א. החזר את ה-issue הראשי ל-`status=in_progress`.
ב. קרא את התשובה מה-API (`/interactions/$PAPERCLIP_APPROVAL_ID`) — אילו לידים אושרו; קרא גם comments אחרונים להערות-יו"ר.
ג. **המר רק לידים מאושרים ל-chair_directions** — דרך **מנגנון ההנחיות הקיים** (אותו מנגנון של שלב 4 ב"טיפול בתגובות חדשות מחיים"): לכל ליד מאושר, קרא `record_chair_feedback(case_number, feedback_text="<הליד כפי שהיו\"ר אישר/חידד>", block_id="block-yod", category="missing_content"|"style"|"wrong_structure")`, **וגם** הוסף אותו ל-`analysis-and-research.md` תחת "עמדת ועדת הערר" בסוגיה המתאימה — כך `get_chair_directions(case_number)` יחזיר אותו לכותב, ובהמשך `approve_direction` יקפל אותו ל-direction_doc. **לידים שנדחו — מושלכים, לא נרשמים.**
ד. פרסם comment: "הכרעת-יו"ר נקלטה. {N} לידים אושרו והומרו ל-chair_directions; {M} נדחו ונמחקו. ממשיך לשלב B." סגור את issue שטן-מליץ אם עוד פתוח.
ה. **רק עכשיו** עבור לשלב B — עם הניתוח המעוגן + ההנחיות המאושרות בלבד. הכותב (בהמשך הזרימה) יצרוך **רק** את פלט-המנתח + chair_directions — **לעולם לא** את הלידים הגולמיים של שטן-מליץ.
### שלב B: הכנת סיכום, סיווג, ושאלת תוצאה
**מתי:** כשיש `analysis-and-research.md` מלא (מנתח סיים שלבים 1-7) וסטטוס `analyst_verified`, אבל אין תוצאה עדיין
@@ -706,9 +757,9 @@ ls data/cases/$CASE_NUMBER/documents/research/analysis-and-research.md
| `processing` | start-workflow (ממשק) | → בדוק אם כבר קיים issue פעיל לסוכן משנה. אם לא → המשך ל-§A כרגיל (בדוק documents + claims) |
| `new` | (יצירת תיק) | → בדוק extraction_status של מסמכים. אם יש `pending` → צור issue למגיה (410c0167). אם כולם `completed`/`proofread` → צור issue למנתח |
| `proofread` | מגיה | → צור issue למנתח משפטי (ראה תבנית למטה) |
| `documents_ready` | מנתח | → שלב A (בדיקות שלמות + שליליות + מתודולוגיה). אם עובר → עדכן ל-`analyst_verified` |
| `analyst_verified` | CEO (אחרי שלב A) | → שלב B (סיכום + שאלת תוצאה לחיים). המנתח כבר ביצע את המחקר כחלק מהניתוח — אין ליצור issue לחוקר. |
| `research_complete` | מנתח / חוקר תקדימים (valid status — legacy + תרחישים מתקדמים) | → שלב B (סיכום + שאלת תוצאה לחיים). **זה סטטוס תקף**, לא שגיאה. בזרימה הרגילה המנתח מגדיר `documents_ready`, אבל אם החוקר רץ בנפרד (`legal-researcher.md` שלב 5) הוא מעדכן ל-`research_complete`. אם תראה סטטוס זה, בדוק שגם `analysis-and-research.md` וגם `precedent-research.md` קיימים, ואז המשך ל-§B כרגיל. |
| `documents_ready` | מנתח | → שלב A (בדיקות שלמות + שליליות + מתודולוגיה). אם עובר → עדכן ל-`analyst_verified`, ואז **שלב A2 (שער שטן-מליץ, אוטומטי)** — אל תקפוץ לשלב B לפני שהשער רץ והיו"ר אישר לידים (A3) |
| `analyst_verified` | CEO (אחרי שלב A) | → **קודם שער שטן-מליץ:** אם אין `critique-gemini.md` → שלב A2 (הפעל שטן-מליץ אוטומטית). אם יש `critique-gemini.md` שטרם הוצג ליו"ר → שלב A3 (עצירת-אישור לידים). **רק אחרי שהיו"ר אישר/דחה לידים** → שלב B (סיכום + שאלת תוצאה לחיים). המנתח כבר ביצע את המחקר כחלק מהניתוח — אין ליצור issue לחוקר. |
| `research_complete` | מנתח / חוקר תקדימים (valid status — legacy + תרחישים מתקדמים) | → **קודם שער שטן-מליץ (A2/A3)** כמו ב-`analyst_verified`, ורק אחרי אישור-יו"ר ללידים → שלב B. **זה סטטוס תקף**, לא שגיאה. בזרימה הרגילה המנתח מגדיר `documents_ready`, אבל אם החוקר רץ בנפרד (`legal-researcher.md` שלב 5) הוא מעדכן ל-`research_complete`. אם תראה סטטוס זה, בדוק שגם `analysis-and-research.md` וגם `precedent-research.md` קיימים, ואז המשך לשער שטן-מליץ ואז §B. |
| `outcome_set` | CEO (אחרי שחיים בחר) | → האם יש claim_handling? אם לא → שלב B המשך (טבלת bundle/skip). אם כן → שלב C |
| `direction_approved` | CEO (אחרי שחיים אישר) | → צור issue למנתח (c26e9439) ל-pass 2: העמקת ניתוח ואימות פסיקה |
| `analysis_enriched` | מנתח (pass 2) | → שלב D2: צור issue לכותב (7ed8686f) |