משלים את follow-up #1: מנחה סוכן שמתעורר-מחדש על תיק לקרוא את כלי-ה-plugin legal_predecessor_context(case_number) לפני שיגלה-מחדש הקשר מאפס — כך ממשיך מנקודת-העצירה ומונע blind heartbeat. הכלי חי ב-plugin (plugin-legal-ai #5+#6, toolCount=9); ה-endpoint by-case חי (legal-ai #410). תוקף: HEARTBEAT נקרא ע"י claude_local מ-~/legal-ai — דורש host git pull. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
19 KiB
HEARTBEAT.md — רשימת ביצוע לכל ריצה (Project-Specific)
🎯 קובץ זה — Project-specific only. ה-skill הרשמי
paperclipai/paperclip/paperclip(טעון אוטומטית בכל heartbeat דרךpaperclipSkillSync) מכיל את כל ה-API patterns הגנריים: identity (/api/agents/me),PAPERCLIP_WAKE_PAYLOAD_JSON,APPROVAL_ID, inbox, comments, checkout, status updates, וכו'. קובץ זה מתעד רק התאמות שלנו — סינון חברה, helpers, workarounds, ו-quirks.בקונפליקט: קובץ זה גובר על ה-skill (project-specific מנצח default).
שפה — כלל עליון
כל הפלט שלך חייב להיות בעברית בלבד. כולל: comments, סטטוס, שגיאות, סיכומים, ו-thinking פנימי. אין יוצאים מן הכלל. גם שמות tools, פקודות, ונתיבי קבצים — ההסבר סביבם בעברית. ה-skill הרשמי באנגלית — תרגם אם נדרש.
קריאת-ספ — קודם החוקה (00), אז ספ-התחום — לפני פעולה מהותית (INV-AG1) ⚠️
לפני העבודה המהותית בכל ריצה — קרא תחילה את חוקת המערכת, ואז את ספ-התחום הרלוונטי לתפקידך. הסוכן אינו פועל "מהזיכרון": המקור הקנוני להתנהגות הוא החוקה + ספ-התחום, לא הרגלים מריצות קודמות. שלב זה קודם ל-§0–§8 התפעוליים שמתחתיו (הם ה-checklist של ההפעלה; קריאת-הספ קודמת לעבודה המהותית).
- תמיד ראשון:
~/legal-ai/docs/spec/00-constitution.md— ייעוד, עקרונות-עבודה, ה-invariants הגלובליים G1–G11, ואינדקס-הספ (§7). - אז ספ-התחום לפי תפקידך (מ-frontmatter
name):
סוכן (name) |
ספ-תחום לקרוא לפני פעולה |
|---|---|
legal-ceo |
00 + כל הספ (מתזמר → צריך תמונה מלאה); ניתוב comments → X3-integration-deploy.md §1ב |
legal-proofreader |
01-ingest.md (קליטה / טקסט-מחולץ) |
legal-researcher |
03-retrieval.md (3 קורפוסים, hybrid/RRF, attribution); קליטת-פסיקה → 01-ingest.md |
legal-analyst |
02-data-model.md + 03-retrieval.md + 04-analysis-writing.md |
legal-writer |
04-analysis-writing.md + 05-qa-review.md (כותב מול שערי-QA) |
legal-qa |
05-qa-review.md (שערי QA + שערים אנושיים) |
legal-exporter |
06-export.md (ייצוא DOCX לפי תבנית דפנה) |
hermes-curator |
07-learning.md (Hermes · לקחים · לולאת פידבק) |
כל הקבצים תחת
~/legal-ai/docs/spec/. המפה המלאה (תפקיד→ספ, frontmatter, שערי-אישור) ב-X4-agents.md. זהו מופע של G10 (המערכת מסייעת תחת שערים אנושיים) — הסוכן פועל בגבולות שהחוקה מגדירה. קובץ-הסוכן שלך חוזר על ההפניה הזו בראשו ("קרא לפני פעולה").
שער anti-hallucination — קודם המקור, אז הציטוט (INV-AH) ⚠️
חל על כל סוכן נוגע-מהות. כמו שאינך פועל "מהזיכרון" לגבי התנהגות-המערכת (INV-AG1) — אינך מצטט פסיקה / סעיף-חוק / הלכה / מספר-תיק / מקדם / נתון כמותי "מהזיכרון". כל אזכור כזה חייב לבוא ממקור מאומת (תוצאת כלי-אחזור או מסמך בתיק), עם ציטוט מדויק.
קרא וקיים את חמש הטכניקות ב-~/legal-ai/docs/anti-hallucination-gate.md:
AH-1 עיגון-מקור (אפס ציטוט מהזיכרון) · AH-2 quote-or-retract · AH-3 abstention ("לא נמצא — דורש אימות") · AH-4 תיוג-ודאות [מאומת]/[טעון-אימות]/[ספקולציה] · AH-5 Chain-of-Verification לפני סיום.
מעוגן במקורות מקצועיים (Stanford RegLab/Magesh JELS 2025 — כלי-RAG משפטיים הוזים 17–33%; Anthropic; CoVe arXiv:2309.11495; RAGAS; NIST AI RMF). "פער" מותר ("אזכרתי X, לא נמצא בקורפוס — לאמת"); "המצאה" אסורה ("הנה תקדים Y" ללא מקור).
§0. כל קריאה ל-Paperclip API — דרך pc.sh בלבד
ה-skill הרשמי משתמש ב-curl ישיר. אצלנו אסור. משתמשים ב-helper שלנו:
~/legal-ai/scripts/pc.sh <METHOD> <PATH> [BODY_JSON] [extra curl args...]
מוסיף אוטומטית: Authorization, X-Paperclip-Run-Id (audit), Content-Type, base URL.
דוגמאות:
~/legal-ai/scripts/pc.sh GET "/api/agents/me/inbox-lite"
~/legal-ai/scripts/pc.sh POST "/api/issues/$ISSUE_ID/checkout"
~/legal-ai/scripts/pc.sh PATCH "/api/issues/$ISSUE_ID" '{"status":"done"}'
ל-body גדול עם backticks — Write ל-temp file, אז pc.sh ... "" -H "Content-Type: application/json" -d @/tmp/comment.json. ראה §דיווח למה.
§1. זיהוי וסינון חברה — כלל ברזל ⚠️
| חברה | COMPANY_ID | סוגי תיקים | טווח מספרים | CEO Agent ID |
|---|---|---|---|---|
| ועדת ערר רישוי ובניה (CMP) | 42a7acd0-30c5-4cbd-ac97-7424f65df294 |
רישוי ובניה | 1xxx | 752cebdd-6748-4a04-aacd-c7ab0294ef33 |
| ועדת ערר היטלי השבחה (CMPA) | 8639e837-4c9d-47fa-a76b-95788d651896 |
היטל השבחה + פיצויים ס' 197 | 8xxx, 9xxx | cdbfa8bc-3d61-41a4-a2e7-677ec7d34562 |
- אם
$PAPERCLIP_COMPANY_ID=42a7acd0...→ רק תיקים ש-1xxx - אם
$PAPERCLIP_COMPANY_ID=8639e837...→ רק תיקים ש-8xxx/9xxx - אסור ליצור פרויקט/issue/תוכן לתיק שלא בטווח שלך
- אם issue שהוקצה לך מכוון לתיק שלא בטווח — סרב בנימוס ב-comment, והעֵר את ה-CEO של החברה הנכונה
§1.5. טיפול ב-wake (skill הרשמי + תוספות שלנו)
ה-skill מסביר PAPERCLIP_WAKE_PAYLOAD_JSON, APPROVAL_ID, ו-heartbeat-context (Step 6). הוסף עליו:
1.5א. אם $PAPERCLIP_WAKE_PAYLOAD_JSON מכיל comment חדש מחיים — התייחס אליו ב-comment הראשון שלך ("ראיתי שביקשת X — מבצע Y") לפני עבודה רחבה. זה מבטיח שחיים יודע שקלטת.
1.5א2. פעולות סטרוקטורליות (כפתורי-UI עתידיים, CEO בלבד). אם $PAPERCLIP_WAKE_PAYLOAD_JSON מכיל שדה action — נתב דטרמיניסטית בלי פענוח-טקסט: action == "interim_draft" → טיוטת ביניים, action == "party_claims_summary" → סיכום מנהלים של טענות הצדדים. פירוט: legal-ceo.md שלב 0 + שלבים H/H2.
1.5ב. תמיד לקרוא heartbeat-context — לא רק מה ש-skill ממליץ ("Prefer"). אצלנו ה-attachments המוחזרים חיוניים (חיים מעלה DOCX/PDF דרך comments). ראה §2.
CONTEXT=$(~/legal-ai/scripts/pc.sh GET "/api/issues/$ISSUE_ID/heartbeat-context?wakeCommentId=$LATEST_COMMENT_ID")
ATTACHMENTS=$(echo "$CONTEXT" | jq '.attachments')
1.5ג. APPROVAL_ID flow — אם חיים ענה על interaction (ראה legal-ceo.md §B/§C/§D), קרא תשובה דרך:
~/legal-ai/scripts/pc.sh GET "/api/issues/$PAPERCLIP_TASK_ID/interactions/$PAPERCLIP_APPROVAL_ID" | jq '{status, kind, response}'
אסור לפענח טקסט מ-comment חופשי כשיש APPROVAL_ID — זה הקלט הסטרוקטורלי.
1.5ד. המשך-עבודה על תיק — קרא predecessor תחילה (seance, #220). אם אתה מתעורר-מחדש על תיק שכבר עבדת עליו (continuation — issue פתוח עם היסטוריית-ריצות), לפני שתגלה-מחדש את ההקשר מאפס, קרא את הכלי legal_predecessor_context(case_number=<מספר-התיק>). הוא מחזיר את מסקנות הריצות-הקודמות על התיק (ה-summary שכל heartbeat השאיר, newest-first) — כך תמשיך מנקודת-העצירה במקום לחזור על עבודה שכבר בוצעה (מונע את ה-blind heartbeat). אם אין ריצות-קודמות עם מסקנות — המשך רגיל.
§2. קבצים מצורפים — דרך heartbeat-context, לא psql
ה-attachments זמינים ב-$CONTEXT.attachments (מ-§1.5ב):
echo "$CONTEXT" | jq '.attachments[] | {filename, contentPath, contentType, byteSize}'
# נתיב מלא לקובץ:
CONTENT_PATH=$(echo "$CONTEXT" | jq -r '.attachments[0].contentPath')
FULL_PATH="/home/chaim/.paperclip/instances/default/data/storage/$CONTENT_PATH"
קבצי DOCX/PDF — קרא עם Read tool ב-$FULL_PATH.
⚠️ psql ישיר ל-issue_attachments — אסור. ה-API הוא ה-source of truth (Gap #21).
§3. self-recovery — issue.released bug
⚠️ Paperclip quirk ידוע: לאחר ש-issue מסומן done, מנגנון issue.released עלול להחזיר אותו ל-todo תוך ~30s, וגורם ל-wakeup חוזר על משימה שכבר בוצעה (תועד ב-docs/paperclip-quirks.md §1).
לפני שמתחילים עבודה — בדוק שלא בוצעה כבר:
- תוצרים בדיסק:
Globעל תיקיות output הצפויות ({case_dir}/documents/research/*.mdלחוקר,analysis-and-research.mdלמנתח, וכו') - תוצרים ב-DB: דרך MCP —
precedent_list,get_claims,extract_appraiser_facts(status=completed) - comments קודמים — חפש "הושלם בהצלחה" מסוף-מצב
אם הכל קיים ותקין: פרסם comment קצר ("אין שינוי — תוצרים קיימים מהריצה הקודמת"), PATCH status=done, צא נקי. לא לעבוד פעמיים.
אם משהו חסר/שונה: עבוד רק על מה שחסר.
§4. דיווח — חובה!
כל heartbeat שמסיים משימה: comment + status + wake CEO. הסעיף הזה מתעד רק workarounds שלנו לא ב-skill.
§4א. dual-comment workaround ל-backtick trap
ל-body קצר (<500 תווים, בלי backticks/קוד/נתיבים) — pattern רגיל:
~/legal-ai/scripts/pc.sh POST "/api/issues/{issue-id}/comments" '{"body": "סיכום..."}'
ל-body ארוך עם markdown/backticks/נתיבים — חובה שתי פעולות נפרדות:
-
כתוב את ה-JSON לקובץ זמני דרך Write tool (לא bash heredoc):
Write(file_path="/tmp/comment-{issue-id}.json", content=json.dumps({"body": markdown_body}, ensure_ascii=False)) -
אז
pc.shעם-d @fileשקורא את הקובץ ישירות:~/legal-ai/scripts/pc.sh POST "/api/issues/{issue-id}/comments" "" \ -H "Content-Type: application/json" -d @/tmp/comment-{issue-id}.json
⚠️ למה לא bash heredoc / python3 -c: backticks ב-markdown (`path/to/file`) ייפרשו על-ידי bash כ-command substitution גם בתוך מחרוזת Python. תקבל Permission denied מטעה. תועד ב-docs/paperclip-quirks.md §2.
§4ב. סטטוס: done או blocked — לא ביניים
~/legal-ai/scripts/pc.sh PATCH "/api/issues/{issue-id}" '{"status": "done"}' # הצליח
~/legal-ai/scripts/pc.sh PATCH "/api/issues/{issue-id}" '{"status": "blocked"}' # נכשל / חסום
אסור done עם כשל שלא טופל. אם משהו נכשל → blocked + comment עם פירוט.
⚠️ שער קריאת-הערות לפני סגירה (חובה). הערות שנכנסות תוך-כדי ריצה אינן נקראות אוטומטית — קראת comments פעם אחת בתחילת הריצה (§2). לפני
PATCH status=done, קרא שוב את ה-comments והשווה לרשימה שראית בתחילת הריצה:~/legal-ai/scripts/pc.sh GET "/api/issues/{issue-id}/comments"אם נכנסה הערת-משתמש חדשה (היו"ר) שעדיין לא טיפלת בה — אל תסגור. או שתטפל בה עכשיו (אם בתחום-המשימה שלך) ותתעד ב-comment, או — אם היא מרחיבה/משנה את ההיקף — השאר את ה-issue פתוח והעבר ל-CEO (§4ג) עם reason שמציין את ההערה החדשה, כדי שינתב. לעולם אל תסמן
doneבעוד הערת-יו"ר ממתינה ללא-מענה — כך הערה "נופלת". (גיבוי-מערכת: sweeproute-pending-commentsבפלאגין תופס הערות-יתום תוך ~2 דק', אך השער הזה מונע את הנפילה במקור. רקע: legal-ai #164.)
§4ג. wake CEO לפי חברה
⚠️ CEO שונה לכל חברה (ראה §1). UUID hardcoded אסור — תמיד דרך $PAPERCLIP_COMPANY_ID:
if [ "$PAPERCLIP_COMPANY_ID" = "8639e837-4c9d-47fa-a76b-95788d651896" ]; then
CEO_ID="cdbfa8bc-3d61-41a4-a2e7-677ec7d34562" # CMPA
else
CEO_ID="752cebdd-6748-4a04-aacd-c7ab0294ef33" # CMP
fi
~/legal-ai/scripts/pc.sh POST "/api/agents/$CEO_ID/wakeup" \
'{"source":"automation","triggerDetail":"system","reason":"סוכן [שם] סיים [issue-id] בסטטוס [done/blocked]","payload":{"issueId":"[issue-id]","mutation":"agent_completion"}}'
⚠️ חובה payload.issueId — בלי זה הסוכן מתעורר בלי הקשר (בלי תיק, בלי cwd).
⚠️ wakeup לחברה אחרת נדחה — Agent key cannot access another company.
⚠️ אסור INSERT INTO agent_wakeup_requests ישיר — לא יוצר heartbeat_run, הסוכן לא מתעורר.
§5. התראת מייל — כשנדרשת תשובה אנושית
python3 /home/chaim/legal-ai/scripts/notify.py \
"נדרשת תשובתך — [תיאור קצר]" \
"תוכן ההודעה עם סיכום מה נדרש"
מתי לשלוח (תמיד): סיום כל משימה (סיכום קצר), בקשת תוצאה/כיוון, QA fail, החלטה מוכנה לדפנה, מצב שדורש פעולה אנושית, שגיאה לא פתירה.
מתי לא: עדכוני סטטוס ביניים, שגיאות טכניות שאפשר לפתור לבד.
§6. Release
~/legal-ai/scripts/pc.sh POST "/api/issues/{issue-id}/release"
§7. סטטוסי תיק (case status flow)
מקור-האמת היחיד למודל-הסטטוסים: mcp-server/src/legal_mcp/case_status_model.py (חשוף ב-GET /api/status-model; ה-enum, ה-STATUS_ORDER וה-frontend נגזרים ממנו). 12 הסטטוסים הקנוניים, לפי 5 השלבים:
קליטה : new · processing
הכנה : documents_ready
ניתוח וכיוון : analyst_verified · research_complete · outcome_set · direction_approved
→ [שער שטן-מליץ: red-team אוטומטי → עצירת-אישור לידים ע"י היו"ר]
כתיבת טיוטה : qa_review · drafted
סגירה : exported · reviewed · final
analyst_verified ו-research_complete הם סטטוסים קנוניים מהמעלה הראשונה (לא legacy) — המנתח/חוקר מציבים אותם, ומקומם בשלב "ניתוח וכיוון". research_complete מנותב ע"י legal-researcher.md שלב 5 כשמחקר תקדימים רץ בנפרד מהמנתח; ה-CEO מטפל בו כמו analyst_verified.
מצבי-ביניים ישנים שעדיין עשויים להופיע מסוכנים מסוימים (
proofread,analysis_enriched,ready_for_writing,qa_passed/qa_failed) אינם בקבוצה הקנונית — הם נמפים-לשלב לתצוגה בלבד (fallback ב-case-status.ts) ואינם ניתנים-לבחירה ידנית. אם נדרש לקבע אחד מהם — להוסיף ל-case_status_model.py(המקור-היחיד).
שער שטן-מליץ (red-team) — שער-קבע אחרי הניתוח (ל-CEO). ברגע שהניתוח עבר (
analyst_verified/research_complete,analysis-and-research.mdתקין), ה-CEO חייב להפעיל אוטומטית את שטן-מליץ (Gemini,gemini_local) לפני הכותב, ואז לעצור לאישור-יו"ר של הלידים (issue ראשי ל-in_review). רק לידים שהיו"ר אישר מומרים ל-chair_directions(record_chair_feedback→get_chair_directions→approve_direction); הלידים הגולמיים לעולם לא מוזנים לכותב או להחלטה — קלט-יו"ר בלבד (G10 / INV-AH / INV-LRN5). זרימה מלאה:legal-ceo.md"שלב A2"/"שלב A3". זה שער-קבע, לא on-demand.
§8. ניתוב upload פסיקה לקורפוס — flowchart מהיר
חיים העלה PDF פסיקה לתיק → ה-citation הוא:
├── "ערר NNNN/YY" או "בל"מ NNNN/YY"
│ → internal_decision_upload (חובה chair_name + district)
├── "עע"מ / בר"מ / עמ"נ / בג"ץ / ע"א / ע"פ / רע"א / רע"פ / ת"א / ת"מ"
│ → precedent_library_upload (external_upload)
└── PDF יומון "כל יום" (סיכום-משני של עפר טויסטר, עמוד אחד)
→ digest_upload (קורפוס-גילוי; לא קורפוס-ציטוט — X12)
internal_decision_uploadדורש:file_path,case_number,chair_name,district. district מתוך הרשימה: ירושלים / מרכז / תל אביב / צפון / דרום / חיפה / ארצי.precedent_library_uploadלא מקבל chair_name/district. אם תנסה להעלות "ערר ..." דרכו — citation guard ידחה.digest_upload— ליומון "כל יום" בלבד (מקור-משני שמצביע על פסק; INV-DIG1/2). אינו מצוטט בהחלטה ואינו מחלץ הלכות. אל תעלה יומון דרך precedent/internal — ואל תעלה פסק-דין דרך digest.- פירוט מלא:
legal-researcher.mdסעיף "איזה כלי upload להשתמש".
נתיבי API — הפניה ל-skill הרשמי
| פעולה | איפה ב-skill |
|---|---|
| Identity, inbox, pick work | Step 1, 3, 4 |
| Wake payload + APPROVAL handling | Authentication + Step 2 |
| Heartbeat-context, comments, attachments | Step 6 |
Checkout (with the checkedOutByHarness skip) |
Step 5 |
| Comment, status update, exit | Step 7-8 |
| Routines, workflows, references | references/ ב-skill |
שינויים project-specific מה-skill: תועדו בקובץ זה (§0 pc.sh, §1 חברה, §2 attachments, §3 quirk, §4 dual-comment + CEO wakeup, §5 notify).