From a1969dd90dc7e93412aa4c3b9e5da9d50f1cdf52 Mon Sep 17 00:00:00 2001 From: Chaim Date: Thu, 30 Apr 2026 16:57:49 +0000 Subject: [PATCH] =?UTF-8?q?agents:=20fix=20analyst=20skill=20=E2=80=94=20a?= =?UTF-8?q?ppraiser=5Ffacts=20+=20close=20own=20issue?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two structural bugs surfaced while monitoring the fresh end-to-end run on case 8174-24: 1. **No appraiser_facts extraction.** legal-analyst.md's "what to extract" table didn't mention doc_type='appraisal' at all, and `extract_appraiser_facts` wasn't in its tools frontmatter. The CEO compounded this by writing in CMPA-16's body that all 3 appraisals were "reference materials, do not extract" — which is correct for `extract_claims` but wrong for the appraisal- specific extractor. Result: 0 appraiser_facts in DB after a full run, even though the user had carefully tagged each appraisal's `appraiser_side` (committee/appellant) precisely so detect_conflicts could compare them. 2. **Issue stays in_progress, Paperclip retries forever.** Step 7 ("שמירה ודיווח") instructed the analyst to update the *case* status, post a comment, send email, and wake the CEO — but never to PATCH the issue itself to `done`. Paperclip's "in_progress with no live execution" watchdog then re-woke the analyst, which posted "I'm done" again, which re-triggered another wakeup. We saw three iterations on CMPA-16 before the issue finally transitioned. The PATCH pattern was already documented in HEARTBEAT.md §4ב — the analyst skill just never referenced it. Changes: • legal-analyst.md - Added mcp__legal-ai__extract_appraiser_facts to tools list. - Rewrote the "what to extract" table to use doc_type as the key column and added an `appraisal` row + a callout explaining why it goes through a different extractor. - Added explicit step 5 "חלץ עובדות שמאי" with the call. - Step 7 now PATCHes the issue to `done` (or `blocked` on failure) before waking the CEO. Refers to the actual incident so the rule has a concrete anchor. - Cleaned up the chunking guidance — phase 1 of claude_session already handles big docs automatically; no need to manually split. • legal-ceo.md (analyst issue template section) - Replaced the generic "list of docs not to extract from" with a per-doc_type action table that explicitly says `appraisal → extract_appraiser_facts (NOT extract_claims)`. - Added an explicit guard: "for every appraisal in the case, verify the issue body says to run extract_appraiser_facts — otherwise the writer gets a numbers-free block ז". - Added the close-the-issue-with-PATCH instruction so the CEO knows to write that into every analyst issue. These edits don't affect the run currently in flight (the CEO's prompt was already cached and the analyst already ran). They take effect on the next analyst invocation. Co-Authored-By: Claude Opus 4.7 (1M context) --- .claude/agents/legal-analyst.md | 49 ++++++++++++++++++++++++--------- .claude/agents/legal-ceo.md | 14 ++++++---- 2 files changed, 45 insertions(+), 18 deletions(-) diff --git a/.claude/agents/legal-analyst.md b/.claude/agents/legal-analyst.md index f3de867..794a265 100644 --- a/.claude/agents/legal-analyst.md +++ b/.claude/agents/legal-analyst.md @@ -14,6 +14,7 @@ tools: - mcp__legal-ai__document_list - mcp__legal-ai__document_get_text - mcp__legal-ai__extract_claims + - mcp__legal-ai__extract_appraiser_facts - mcp__legal-ai__get_claims - mcp__legal-ai__search_case_documents - mcp__legal-ai__search_decisions @@ -67,12 +68,15 @@ tools: ## סוגי מסמכים — מה לחלץ ומה לא -| סוג מסמך | מה לחלץ | claim_type | -|-----------|----------|------------| -| כתב ערר | **טענות** — מה העוררים טוענים | claim | -| כתב תשובה | **תשובות** — מה המשיבים/ועדה עונים | response | -| תגובה / השלמת טיעון | **תגובות** — תשובות לתשובות | reply | -| פסיקה / תכנית / פרוטוקול / היתר | **אל תחלץ כלום** — מסמכי רקע בלבד | — | +| סוג מסמך (doc_type) | מה לחלץ | באיזה כלי | +|----------------------|----------|------------| +| `appeal` | **טענות** — מה העוררים טוענים | `extract_claims` (claim_type=claim) | +| `response` | **תשובות** — מה המשיבים/ועדה עונים | `extract_claims` (claim_type=response) | +| `reply` / השלמת טיעון | **תגובות** — תשובות לתשובות | `extract_claims` (claim_type=reply) | +| `appraisal` | **עובדות שמאי** — מספרים, מקדמים, עסקאות השוואה, מסקנות שווי | `extract_appraiser_facts` | +| `reference` / `plan` / `protocol` / `permit` / `decision` / `court_decision` | **אל תחלץ כלום** — מסמכי רקע בלבד | — | + +> **הבחנה קריטית — שומה אינה כתב טענות.** שומה (`appraisal`) היא חוות דעת מקצועית, לא טיעון משפטי. **לא** מריצים עליה `extract_claims` — מריצים `extract_appraiser_facts` שמחלץ נתונים כמותיים מובנים (שווי, מקדמים, עסקאות). זאת קלט מהותי לבלוקים ז ו-י של ההחלטה. **דילוג עליה = פלט חסר**. ## תהליך עבודה — 4 שלבים @@ -85,9 +89,10 @@ tools: - **הצדדים**: מי העורר, מי המשיב, מי צד ג' - **המסגרת הנורמטיבית**: חוקים, תקנות, תכניות רלוונטיות — **קרא את המסמכים הנורמטיביים במלואם** (לא רק הסעיף הנטען; מילה בסעיף אחד מתפרשת לאור סעיפים אחרים באותו מסמך) 4. חלץ טענות/תשובות/תגובות (`extract_claims` עם doc_type ו-party_hint מתאימים) - - **מסמך גדול (>15,000 תווים):** פצל לחלקים לפי פרקים/סעיפים וחלץ מכל חלק בנפרד. אל תשלח מסמך שלם של 20K+ מילים בקריאה אחת — זה יגרום ל-timeout. - - **אם extract_claims נכשל (timeout):** נסה שוב עם חלק מהמסמך. אם עדיין נכשל — חלץ ידנית: קרא את הטקסט (`document_get_text`), זהה את הטענות המרכזיות, והכנס ל-DB. -5. וודא שכל פריט מסווג ל-claim_type הנכון + - **מסמך גדול (>15,000 תווים):** מאז phase 1 של מערכת הניתוח, ה-chunking הסמנטי + מקבילות + retry מטופל אוטומטית. גם מסמך של 100K+ תווים ירוץ עד הסוף. אם בכל זאת נכשל — דווח ב-issue. + - **טיפול בכשל:** אם `extract_claims` החזיר `partial=true` או 0 טענות ממסמך לא ריק — נסה שוב פעם אחת. אם עדיין נכשל — סטטוס issue = `blocked`, פרסם comment עם הפירוט. +5. **חלץ עובדות שמאי** — לכל מסמך `doc_type='appraisal'` בתיק, הרץ `extract_appraiser_facts(case_number)` (פעם אחת לתיק, מטפל בכל השומות). **חובה בכל ערר השבחה (8xxx) ופיצויים (9xxx) — בלי זה ה-writer לא יוכל לכתוב את בלוק ז עם מספרים מדויקים.** +6. וודא שכל פריט מסווג ל-claim_type הנכון ### שלב 2: ניתוח מעמיק הצג במבנה הבא: @@ -203,13 +208,33 @@ FROM documents d WHERE d.case_id = '{case_id}' AND d.doc_type IN ('appeal', 'res 2. **פרסם comment** ב-Paperclip עם סיכום: - כמה טענות חולצו (מפורט: X טענות עוררים, Y תשובות משיבים, Z תגובות) - **האם כל המסמכים חולצו בהצלחה** (כן/לא — אם לא, פרט מה נכשל) + - **כמה עובדות שמאי חולצו** (אם יש מסמכי `appraisal`) - הסוגיות המרכזיות (3-5 כותרות) - כמה שאלות מחקר הופקו - המלצה לשלב הבא -3. **עדכן סטטוס** (`case_update` עם status = `documents_ready`) +3. **עדכן סטטוס התיק** (`case_update` עם status = `documents_ready`) -4. **שלח מייל**: +4. **סגור את ה-issue של עצמך — חובה!** בלי זה Paperclip יחשוב שהמשימה עדיין רצה ויפעיל retry בלולאה (זה נצפה בפועל בריצת CMPA-16 — שלוש איטרציות מיותרות). + + **אם הכל עבר בהצלחה (בדיקות שלב 6 + טענות + עובדות שמאי):** + ```bash + curl -s -X PATCH -H "Authorization: Bearer $PAPERCLIP_API_KEY" \ + -H "Content-Type: application/json" \ + "$PAPERCLIP_API_URL/api/issues/{issue-id}" \ + -d '{"status": "done"}' + ``` + + **אם בדיקות שלב 6 נכשלו או חילוץ נכשל:** + ```bash + curl -s -X PATCH -H "Authorization: Bearer $PAPERCLIP_API_KEY" \ + -H "Content-Type: application/json" \ + "$PAPERCLIP_API_URL/api/issues/{issue-id}" \ + -d '{"status": "blocked"}' + ``` + **אסור** לסיים `done` עם פלט חסר — אם ניסיון חוזר נכשל, סטטוס = `blocked` + comment עם פירוט. + +5. **שלח מייל**: ```bash python3 /home/chaim/legal-ai/scripts/notify.py \ "ניתוח ומחקר הושלמו — ערר {case_number}" \ @@ -226,8 +251,6 @@ curl -s -X POST -H "Authorization: Bearer $PAPERCLIP_API_KEY" \ אם ה-API לא עובד: **⚠️ אסור להשתמש ב-INSERT INTO agent_wakeup_requests ישירות!** הכנסה ישירה ל-DB יוצרת רק את הבקשה בלי heartbeat_run — והסוכן לא יתעורר לעולם. **תמיד להשתמש ב-API בלבד.** -**אם בדיקות שלב 6 נכשלו** — סטטוס issue = "blocked", פרסם comment עם פירוט מה נכשל, שלח מייל לחיים. - ## מבנה הפלט המלא — analysis-and-research.md ```markdown diff --git a/.claude/agents/legal-ceo.md b/.claude/agents/legal-ceo.md index ddca055..3e3581b 100644 --- a/.claude/agents/legal-ceo.md +++ b/.claude/agents/legal-ceo.md @@ -508,11 +508,15 @@ Paperclip חוסם אוטומטית כל issue ב-`in_progress` שאין לו ru --- **תבנית issue למנתח — חובה בכל תיק:** -1. **טבלת מיפוי מסמכים** — לכל מסמך: שם, claim_type, party_role. בנה מ-`document_list`. -2. **רשימת מסמכים שלא לחלץ מהם** (reference, plan, decision, court_decision) -3. **הנחיה לפיצול מסמכים גדולים** — מעל 15,000 תווים → חלץ בחלקים -4. **הנחיה לשלוח wakeup ל-CEO בסיום** -5. **הנחיה לסיים כ-blocked אם מסמך נכשל** +1. **טבלת מיפוי מסמכים** — לכל מסמך: שם, doc_type, פעולה נדרשת: + - `appeal` → `extract_claims` (claim_type=claim, party_role=appellant) + - `response` → `extract_claims` (claim_type=response, party_role=respondent/committee) + - `reply` → `extract_claims` (claim_type=reply, party_role=permit_applicant/appellant) + - **`appraisal` → `extract_appraiser_facts`** (לא extract_claims! שומה אינה כתב טענות. חובה בכל תיק 8xxx/9xxx) + - `reference`/`plan`/`protocol`/`permit`/`decision`/`court_decision` → אל תחלץ — חומר רקע בלבד +2. **בדיקת השלמה** — לכל doc_type='appraisal' בתיק, וודא שה-issue אומר במפורש להריץ `extract_appraiser_facts`. בלי זה ה-writer יקבל בלוק ז ריק ממספרים. +3. **הנחיה לסגור את ה-issue ב-PATCH** — סטטוס `done` בהצלחה, `blocked` בכשל. בלי זה Paperclip יפעיל retry בלולאה (נצפה בפועל ב-CMPA-16 / 30-04-26). +4. **הנחיה לשלוח wakeup ל-CEO בסיום** (כך שאתה תידע להמשיך) ## סינון תיקים לפי חברה — חובה!