Files
legal-ai/.claude/agents/HEARTBEAT.md
Chaim 8171572cdd feat(digests): קורפוס יומונים כשכבת-גילוי (radar) — X12
מאגר חדש ליומוני "כל יום" (עפר טויסטר) כשכבת-גילוי מעל קורפוסי-הפסיקה:
מקור-משני המצביע על פסק הדין המקורי, נקלט לטבלה נפרדת `digests`, נחפש
סמנטית, ומקושר לפסק המקורי בספריית הפסיקה — אך לעולם אינו מצוטט בהחלטה
ואינו מחלץ הלכות.

Phase 0 (spec):
- docs/spec/X12-digests-radar.md — INV-DIG1 (מצביע לא מצוטט) /
  INV-DIG2 (מסלול-קליטה נפרד, לא מקביל — מקיים G2) / INV-DIG3 (קישור-לפסק
  הוא הגשר; חוסר-קישור = פער גלוי). עדכון אינדקס 00/03/README.

Phase 1 (MVP):
- SCHEMA_V30: טבלת `digests` (HNSW על embedding — לא ivfflat, להימנע מ-recall
  cliff בקורפוס קטן/צומח) + GIN/FTS + UNIQUE חלקי ל-idempotent.
- services/digest_metadata_extractor.py — חילוץ-LLM (claude_session local-only,
  ייבוא lazy): תג-מושג, כותרת-הלכה, מראה-מקום, שני-תאריכים מובחנים, תגיות.
- services/digest_library.py — מסלול קצר עצמאי (INV-DIG2): extract→hash→LLM→
  embedding יחיד→autolink. לא משתמש ב-ingest.ingest_document.
- tools/digests.py + רישום 7 כלים ב-server.py (digest_upload/list/get/link/
  relink/delete + search_digests).
- scripts/ingest_digests_batch.py — קליטה ידנית מ-data/digests/incoming.
- legal-researcher.md: שלב 2ב.0 (סריקת-radar לפני אימות) + סעיף-דוח ט +
  3 כלים ב-frontmatter. HEARTBEAT §8: ניתוב יומון→digest_upload.

אומת end-to-end: 4 יומונים נקלטו (מטא-דאטה מדויק), חיפוש סמנטי מדרג נכון
("היטל השבחה"→5160, "תמא 38"→5158), link/relink/autolink/revert + מעטפת-MCP.

Invariants: מוסיף INV-DIG1/2/3 (X12). מקיים G2 (bounded context נפרד, לא
מסלול מקביל), G3 (idempotent upsert), G4 (אין בליעה שקטה — פער-קישור מוצף),
G9 (עקיבוּת — היומון מצביע על מקור עקיב). נוגע G7 (RRF) — נדחה, חיפוש
סמנטי-בלבד בשלב 1 (FTS index מוכן).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 17:49:00 +00:00

251 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 של ההפעלה; קריאת-הספ קודמת לעבודה המהותית).
1. **תמיד ראשון:** [`~/legal-ai/docs/spec/00-constitution.md`](../../docs/spec/00-constitution.md) — ייעוד, עקרונות-עבודה, ה-invariants הגלובליים G1G11, ואינדקס-הספ (§7).
2. **אז ספ-התחום לפי תפקידך** (מ-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/`](../../docs/spec/). המפה המלאה (תפקיד→ספ, frontmatter, שערי-אישור) ב-[`X4-agents.md`](../../docs/spec/X4-agents.md). זהו מופע של **G10** (המערכת מסייעת תחת שערים אנושיים) — הסוכן פועל בגבולות שהחוקה מגדירה. קובץ-הסוכן שלך חוזר על ההפניה הזו בראשו ("קרא לפני פעולה").
---
## §0. כל קריאה ל-Paperclip API — דרך `pc.sh` בלבד
**ה-skill הרשמי משתמש ב-`curl` ישיר. אצלנו אסור.** משתמשים ב-helper שלנו:
```bash
~/legal-ai/scripts/pc.sh <METHOD> <PATH> [BODY_JSON] [extra curl args...]
```
מוסיף אוטומטית: `Authorization`, `X-Paperclip-Run-Id` (audit), `Content-Type`, base URL.
**דוגמאות:**
```bash
~/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ב. תמיד לקרוא `heartbeat-context`** — לא רק מה ש-skill ממליץ ("Prefer"). אצלנו ה-`attachments` המוחזרים חיוניים (חיים מעלה DOCX/PDF דרך comments). ראה §2.
```bash
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), קרא תשובה דרך:
```bash
~/legal-ai/scripts/pc.sh GET "/api/issues/$PAPERCLIP_TASK_ID/interactions/$PAPERCLIP_APPROVAL_ID" | jq '{status, kind, response}'
```
**אסור** לפענח טקסט מ-comment חופשי כשיש APPROVAL_ID — זה הקלט הסטרוקטורלי.
---
## §2. קבצים מצורפים — דרך `heartbeat-context`, **לא psql**
ה-attachments זמינים ב-`$CONTEXT.attachments` (מ-§1.5ב):
```bash
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`).
**לפני שמתחילים עבודה — בדוק שלא בוצעה כבר:**
1. **תוצרים בדיסק**: `Glob` על תיקיות output הצפויות (`{case_dir}/documents/research/*.md` לחוקר, `analysis-and-research.md` למנתח, וכו')
2. **תוצרים ב-DB**: דרך MCP — `precedent_list`, `get_claims`, `extract_appraiser_facts` (status=completed)
3. **comments קודמים** — חפש "הושלם בהצלחה" מסוף-מצב
**אם הכל קיים ותקין:** פרסם comment קצר ("אין שינוי — תוצרים קיימים מהריצה הקודמת"), `PATCH status=done`, צא נקי. **לא לעבוד פעמיים.**
**אם משהו חסר/שונה:** עבוד רק על מה שחסר.
---
## §4. דיווח — חובה!
**כל heartbeat שמסיים משימה:** comment + status + wake CEO. הסעיף הזה מתעד רק workarounds שלנו לא ב-skill.
### §4א. dual-comment workaround ל-`backtick trap`
**ל-body קצר (<500 תווים, בלי backticks/קוד/נתיבים)** — pattern רגיל:
```bash
~/legal-ai/scripts/pc.sh POST "/api/issues/{issue-id}/comments" '{"body": "סיכום..."}'
```
**ל-body ארוך עם markdown/backticks/נתיבים — חובה שתי פעולות נפרדות:**
1. כתוב את ה-JSON לקובץ זמני דרך **Write tool** (לא bash heredoc):
```
Write(file_path="/tmp/comment-{issue-id}.json",
content=json.dumps({"body": markdown_body}, ensure_ascii=False))
```
2. אז `pc.sh` עם `-d @file` שקורא את הקובץ ישירות:
```bash
~/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` — לא ביניים
```bash
~/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 עם פירוט.
### §4ג. wake CEO לפי חברה
**⚠️ CEO שונה לכל חברה** (ראה §1). UUID hardcoded **אסור** — תמיד דרך `$PAPERCLIP_COMPANY_ID`:
```bash
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. התראת מייל — כשנדרשת תשובה אנושית
```bash
python3 /home/chaim/legal-ai/scripts/notify.py \
"נדרשת תשובתך — [תיאור קצר]" \
"תוכן ההודעה עם סיכום מה נדרש"
```
**מתי לשלוח (תמיד):** סיום כל משימה (סיכום קצר), בקשת תוצאה/כיוון, QA fail, החלטה מוכנה לדפנה, מצב שדורש פעולה אנושית, שגיאה לא פתירה.
**מתי לא:** עדכוני סטטוס ביניים, שגיאות טכניות שאפשר לפתור לבד.
---
## §6. Release
```bash
~/legal-ai/scripts/pc.sh POST "/api/issues/{issue-id}/release"
```
---
## §7. סטטוסי תיק תקפים (case status flow)
הסטטוסים שאתה עשוי לראות ב-`case.status` (לפי `legal-ceo.md` "מפת סטטוסים"):
```
new → proofread → documents_ready → analyst_verified → research_complete*
→ outcome_set → direction_approved → analysis_enriched → ready_for_writing
→ drafted → qa_passed / qa_failed → exported
```
`research_complete` — **valid status** (לא legacy מחוסר תוקף). מנותב ע"י `legal-researcher.md` שלב 5 כשמחקר תקדימים רץ בנפרד מהמנתח (תרחיש מתקדם). ה-CEO יודע לטפל בו כאילו זה `analyst_verified` (ראה `legal-ceo.md` "מפת סטטוסים").
---
## §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).