diff --git a/.claude/agents/legal-ceo.md b/.claude/agents/legal-ceo.md index f6c428f..f3edf24 100644 --- a/.claude/agents/legal-ceo.md +++ b/.claude/agents/legal-ceo.md @@ -225,12 +225,14 @@ Paperclip חוסם אוטומטית כל issue ב-`in_progress` שאין לו ru ### שלב 0: בדוק למה התעוררת **לפני כל דבר אחר** — בדוק את סיבת ההתעוררות (`$PAPERCLIP_WAKE_REASON`): -- אם ה-reason מכיל `user_commented` → **דלג ישירות לסעיף "טיפול בתגובות חדשות מחיים"**. אל תסרוק תיקים אחרים, אל תבדוק issues, אל תעשה heartbeat רגיל. **טפל רק בתגובה.** +- אם ה-reason מכיל `user_commented` **ו**-`$PAPERCLIP_WAKE_PAYLOAD_JSON` כולל `issueId` → **דלג ישירות לסעיף "טיפול בתגובות חדשות מחיים"** עם ה-issue הזה. אל תסרוק תיקים אחרים. **טפל רק בתגובה.** - אם ה-reason מכיל `agent_completion` → דלג לשלב E/F בהתאם לסוכן שסיים - אם ה-reason מכיל `precedent_extraction_` → **דלג לסעיף "חילוץ פסיקה אוטומטי"**. אל תיגע בתיקים — זו עבודת ספרייה. - אם ה-reason מכיל `weekly-feedback-job` → **דלג לסעיף "ניתוח פידבק שבועי"**. אל תיגע בתיקים פעילים. - אם ה-reason מכיל `feedback_fold_` → **דלג לסעיף "קיפול הערת יו\"ר"**. אל תיגע בתיקים — זו משימת תחזוקת ידע. -- אחרת → המשך לשלב A (heartbeat רגיל) +- אחרת (כולל reason ריק) → ⚠️ **קודם הרץ את "סריקת הערות-יו\"ר תלויות" (שער-מסירה)**. רק אם לא נמצאה אף הערה תלויה — המשך לשלב A (heartbeat רגיל). + +> ⚠️ **wake עיוור — חובה לקרוא.** ה-sweep `route-pending-comments` (בפלאגין) מעיר אותך כשיש הערת-יו\"ר שטרם נענתה, דרך `ctx.agents.invoke` — אבל זה **אינו** מאכלס את `$PAPERCLIP_WAKE_REASON` ולא `payload.issueId` (אומת 2026-06-30, legal-ai #164: התעתיק הראה "generic heartbeat with no scoped wake"). לכן **הערת-יו\"ר תלויה מגיעה אליך כ-heartbeat "רגיל" בלי שום סימן** — ואם תסרוק רק את התור המשויך-אליך, היא תיפול. **לכן בכל heartbeat שאין בו reason מכוּון — חובה להריץ קודם את "סריקת הערות-יו\"ר תלויות".** ### חילוץ פסיקה אוטומטי @@ -320,9 +322,9 @@ Paperclip חוסם אוטומטית כל issue ב-`in_progress` שאין לו ru ### שלב A: בדיקת מצב — שלמות, בדיקות שליליות, תאימות מתודולוגיה בכל heartbeat **רגיל** (לא comment routing): -1. בדוק תיקים פעילים (`case_list`) -2. בדוק אם יש issues ב-"blocked" — אם כן, טפל בהם קודם -3. בדוק comments מחיים שממתינים לתגובה +1. **קודם — "סריקת הערות-יו"ר תלויות"** (ראה סעיף ייעודי). ה-wake מה-sweep עיוור; הערת-יו"ר תלויה מגיעה כ-heartbeat רגיל. אם נמצאה הערה תלויה — טפל בה (scoped לתיק שלה) **לפני** כל דבר אחר. +2. בדוק תיקים פעילים (`case_list`) +3. בדוק אם יש issues ב-"blocked" — אם כן, טפל בהם קודם 4. **לפני מעבר לשלב B — בצע את כל הבדיקות למטה. אם בדיקה נכשלת — עצור.** #### A1. בדיקת שלמות חילוץ @@ -844,9 +846,49 @@ case_prefix="${case_number:0:1}" - **ודא עקביות מתודולוגית** — כיוונים סילוגיסטיים (כלל + עובדות + מסקנה), chair_directions שלם (טיפול בטענות + כיוון + סדר סוגיות + תקן ביקורת), התאמה ל-`decision-methodology.md` - **סינון תיקים** — עבוד רק על תיקים בטווח המספרים של החברה שלך (ראה טבלה למעלה) +## סריקת הערות-יו"ר תלויות (company-wide) — שער-מסירה + +> **למה זה קיים:** ה-wake מה-sweep מגיע עיוור (ראה ⚠️ בשלב 0). לכן אינך יכול להסתמך על `reason`/`issueId` כדי לדעת שיש הערה לטפל בה — אתה חייב **לגלות** אותה בעצמך. סריקה זו מוצאת כל הערת-יו"ר שטרם נענתה **בכל issue בחברה** (לא רק בתור המשויך-אליך — הערות-יו"ר יושבות על issues של חיים/סוכני-מִשנה, לא עליך). + +**⚠️ כלל-ברזל: שיוך-לתיק ממקור מובנה, לעולם לא מהכותרת ולא מתוכן-ההערה.** הערה עשויה להזכיר תיק אחר (למשל "ניסיתי ב-CMPA-89") — זה **תוכן לטיפול**, לא יעד. היעד הוא תמיד התיק של ה-**project** שאליו שייך ה-issue. אם אי-אפשר לפתור תיק בוודאות → **אל תפעל**. + +**הסריקה (הרץ בכל heartbeat ללא reason מכוּון):** + +1. **רשום את כל issues החברה הפעילים:** + ```bash + ISSUES=$(~/legal-ai/scripts/pc.sh GET "/api/companies/$PAPERCLIP_COMPANY_ID/issues") + echo "$ISSUES" | jq -r '(if type=="array" then . else .issues end) + | map(select(.status!="done" and .status!="cancelled" and (.hiddenAt|not))) + | .[].id' + ``` + +2. **לכל issue — האם יש הערת-יו"ר תלויה?** הערה תלויה = הערת-`user` האחרונה **חדשה** מהערת-`agent` האחרונה (התעלם מ-`system`). ⚠️ ה-API מחזיר comments ב-**newest-first** — אל תשתמש ב-`.[-1]`; מיין ב-`createdAt`: + ```bash + C=$(~/legal-ai/scripts/pc.sh GET "/api/issues/$ISSUE_ID/comments") + PENDING=$(echo "$C" | jq -r ' + (map(select(.authorType=="user")) | sort_by(.createdAt) | last) as $u | + (map(select(.authorType=="agent")) | sort_by(.createdAt) | last) as $a | + if $u==null then "no" elif ($a==null) or ($u.createdAt>$a.createdAt) then "yes" else "no" end') + ``` + אם `PENDING != "yes"` → דלג ל-issue הבא. + +3. **שיוך-לתיק (שער-בטיחות חובה)** — חלץ את מספר-התיק מ-**`project.name`** (שדה מובנה: `"ערר <מספר> — ..."`), לא מהכותרת ולא מההערה: + ```bash + CTX=$(~/legal-ai/scripts/pc.sh GET "/api/issues/$ISSUE_ID/heartbeat-context") + CASE_NUMBER=$(echo "$CTX" | jq -r '.project.name // ""' \ + | grep -oE '(ערר|בל"מ) [0-9]{4,5}-[0-9]{2}-[0-9]{2}' \ + | grep -oE '[0-9]{4,5}-[0-9]{2}-[0-9]{2}' | head -1) + ``` + - **`CASE_NUMBER` ריק** (ה-project אינו תיק — למשל "ספריית פסיקה — תור חילוץ", או שיוך לא-ודאי) → **אל תפעל על תיק.** אם נראה שזו הערת-יו"ר אמיתית שאבדה — פרסם comment קצר ב-issue + שלח מייל ליו"ר (סעיף §5), בלי לגעת בשום תיק. עבור ל-issue הבא. + - **`CASE_NUMBER` קיים** → טפל בהערה לפי "טיפול בתגובות חדשות מחיים" למטה, **scoped ל-`$ISSUE_ID` ול-`$CASE_NUMBER` הזה בלבד.** + +4. **כמה issues תלויים** (אפשרי — אפילו על אותו תיק) → טפל בכולם, כל אחד ב-scope שלו. אם לא נמצאה אף הערה תלויה → אין פעולת-CEO; המשך לשלב A. + +--- + ## טיפול בתגובות חדשות מחיים (comment routing) -כשאתה מתעורר בגלל תגובה חדשה (reason מכיל "user_commented"): +כשאתה מתעורר בגלל תגובה חדשה (reason מכיל "user_commented"), **או** כשהסריקה למעלה זיהתה הערה תלויה ב-`$ISSUE_ID` עם `$CASE_NUMBER` פתור: 0. **החזר את ה-issue הראשי ל-`status=in_progress`** — אם ה-issue ב-`in_review` (כי המתנת לחיים) או ב-`blocked` (כי Paperclip חסם אוטומטית), הראשון דבר: עדכן ל-`in_progress` כדי לסמן שאתה עובד עליו.