Files
legal-ai/CLAUDE.md
Chaim 011555fb78
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 8s
docs: update CLAUDE.md — webhook pipeline, scheduled jobs, paperclip_api.py
- Document emit_case_status_webhook flow and plugin integration
- Document stale-case-reminder and weekly-feedback-analysis jobs
- Fix paperclip_api.py vs paperclip_client.py (both exist, api.py is current)
- Add warning: weekly-feedback-job CEO has no issueId

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 11:23:47 +00:00

21 KiB
Raw Blame History

עוזר משפטי — Legal Decision Assistant

רקע הפרויקט

מערכת AI לסיוע בכתיבת החלטות של ועדת ערר לתכנון ובניה, מחוז ירושלים, בראשות עו"ד דפנה תמיר.

מה עושה ועדת ערר?

ועדת ערר היא גוף מעין-שיפוטי שדן בעררים על החלטות ועדות מקומיות לתכנון ובניה. הוועדה מקבלת חומרי מקור (כתבי ערר, תגובות, פרוטוקולים, תכניות), דנה בטענות הצדדים, ומוציאה החלטה כתובה מנומקת — מסמך משפטי פורמלי שניתן לביקורת שיפוטית בבית משפט לעניינים מנהליים.

שלושה סוגי עררים

סוג מספרי תיקים טון מאפיין
רישוי ובנייה 1xxx חם יחסית הקשר תכנוני רחב, אלמנטים אנושיים
היטל השבחה 8xxx קר ומקצועי יבש, ללא רגשות
פיצויים (ס' 197) 9xxx קר ומקצועי דומה להיטל השבחה

מטרת המערכת

לבנות כלי עבודה שמסייע ליו"ר הוועדה לנסח החלטות:

  1. ניהול תיקים — ייבוא חומרי מקור, סיווג מסמכים, מעקב סטטוס
  2. בסיס ידע — פסיקה, ביטויי מעבר, לקחים מהחלטות קודמות, חקיקה
  3. חיפוש סמנטי (RAG) — מציאת תקדימים רלוונטיים ופסקאות דומות
  4. סיוע בכתיבה — ייצור טיוטות לפי ארכיטקטורת 12 בלוקים בסגנון דפנה
  5. ייצוא DOCX — מסמך מעוצב מוכן להגשה

מה היה קודם (Legacy)

המערכת הקודמת היתה Obsidian vault עם Claude Code skills על שרת אחר. פותחו:

  • ניתוח סגנון של 3 החלטות (הכט — דחייה, בית הכרם — קבלה חלקית, אריאלי — השוואה)
  • ארכיטקטורת 12 בלוקים מבוססת CREAC / DITA / Akoma Ntoso / Federal Judicial Center
  • כללי כתיבה (רקע ניטרלי, ללא כפילות, טענות מקוריות בלבד)
  • לקחים מהשוואת טיוטות לגרסאות סופיות
  • סקריפט ייצוא DOCX

הידע שהופק מה-vault הוטמע במערכת הנוכחית — מסמכי ייחוס (docs/), קורפוס אימון (data/training/), ומבנה 12 בלוקים. ה-vault המקורי נמחק; הפרויקט הנוכחי עובד עם PostgreSQL + pgvector.


מסמכי ייחוס

מסמך תוכן מתי לקרוא
docs/architecture.md ארכיטקטורת המערכת, תרשים רכיבים, זרימת נתונים, 4 שכבות DB לפני עבודה על תשתית
docs/block-schema.md הגדרת 12 בלוקים — content model, constraints, processing params לפני כל כתיבת החלטה
docs/migration-plan.md תוכנית מעבר vault → DB — טבלאות, עדיפויות, כמויות לפני ייבוא נתונים
docs/legal-decision-lessons.md לקחים מ-3 החלטות — מה עבד, מה השתנה, ביטויי מעבר חדשים לפני כל כתיבת החלטה
docs/decision-methodology.md מתודולוגיה אנליטית — איך לחשוב על החלטה מעין-שיפוטית לפני כל כתיבת החלטה
docs/garner-methodology-extraction.md חומר מקור: מיצוי מספרי Garner על כתיבה משפטית רק לבדיקת מקור
docs/fjc-principles-extraction.md חומר מקור: מיצוי מ-Judicial Writing Manual (FJC) רק לבדיקת מקור
docs/corpus-analysis.md ניתוח שיטתי של 24 החלטות — מפת תוכן, דפוסי דיון תכנוני, פערים לפני כל כתיבת החלטה
docs/product-specification.md איפיון מוצר מלא — personas, תהליכים עסקיים, דרישות להתמצאות עסקית/מוצרית
docs/new-company-setup-guide.md מדריך הקמת חברה חדשה (CMPA) — skills, corpus, style analysis לפני הוספת חברה/סוג ערר חדש
skills/new-company-setup/SKILL.md Blueprint טכני מלא להוספת חברה — 11 שלבים מסודרים (companies, agents, runtime/adapter, skills, instructions, code, mappings) + checklist 10 מלכודות מ-Gap analysis #16-#28 חובה לפני הוספת חברה (יותר actionable מ-doc)
docs/audit-report.md דוח audit של המערכת רקע כללי
docs/case-migration-tracker.md מעקב מיגרציה של תיקים קיימים לצורך מעקב
docs/case-deletion-runbook.md runbook מלא למחיקת תיק — legal-ai DB + disk + Paperclip + Gitea, FK ordering, fallback ל-SQL ישיר לפני reset שלם של תיק (מבחן, מחיקה בטעות)
docs/paperclip-quirks.md מלכודות ידועות ב-Paperclip — issue.released ש-flips done→todo, bash backtick trap, CEO auto-block, wakeup דרך DB לפני שמייחסים באג בסוכן ל-skill — לבדוק קודם אם זה Paperclip-side
docs/decision-block-mapping.md מיפוי בלוקים להחלטות — איך 12 הבלוקים משתקפים ב-DOCX להתמצאות במבנה
docs/memory.md הקשר כללי — skills, פרויקטים שהושלמו, מבנה vault להתמצאות כללית
skills/decision/SKILL.md מדריך סגנון מלא של דפנה — טון, מבנה, ביטויים, מתודולוגיה לפני כל כתיבת החלטה
.claude/agents/HEARTBEAT.md checklist הפעלת סוכן — routing, company filtering, quirks, wakeup עם UUID נכון לפני כל עבודה על סוכנים
skills/dafna-decision-template/SKILL.md export DOCX לפי styles של תבנית Word של דפנה — line classification, dash policy, placeholder handling לפני export DOCX

שרת Nautilus (158.178.131.193)

שירות תפקיד כתובת
Coolify ניהול containers http://158.178.131.193:8000
PostgreSQL + pgvector בסיס נתונים ראשי legal-ai-postgres
Redis תור משימות legal-ai-redis
n8n אוטומציית workflows להגדרה
Gitea מאגר קוד gitea.nautilus.marcusgroup.org/ezer-mishpati
ezer-mishpati-web ממשק העלאת מסמכים (Docker/Coolify) legal-ai.nautilus.marcusgroup.org
Paperclip סוכן AI — מריץ Claude Code agents (pm2, מקומי) localhost:3100
Infisical ניהול סודות secret.dev.marcus-law.co.il

⚠️ ארכיטקטורת Deploy — חובה לקרוא

עוזר משפטי (Legal-AI) — רץ כ-Docker container דרך Coolify:

  • UUID: gyjo0mtw2c42ej3xxvbz8zio
  • שינוי קוד ב-web/ או web-ui/ לא נכנס לתוקף עד ש:
    1. עושים git commit + git push origin main
    2. מריצים deploy דרך Coolify (mcp__coolify__deploy)
    3. ממתינים ~2-4 דקות לבנייה
  • אסור לנסות להריץ uvicorn מקומית — אין סביבת Python על המכונה
  • ה-container מריץ Next.js (:3000, חשוף) + FastAPI (:8000, פנימי)
  • בדיקה: curl https://legal-ai.nautilus.marcusgroup.org/api/...

Paperclip — רץ מקומית דרך pm2:

  • פורט: localhost:3100, DB: localhost:54329
  • שינויי קוד נכנסים לתוקף אחרי pm2 restart paperclip
  • אין צורך ב-Docker או Coolify

מבנה תיקיות

/home/chaim/legal-ai/
├── CLAUDE.md                          ← הקובץ הזה
├── Dockerfile                         ← Docker build
├── docs/                              ← תיעוד + לקחים
│   ├── architecture.md                   ארכיטקטורה
│   ├── block-schema.md                   12 בלוקים (המסמך החשוב ביותר)
│   ├── migration-plan.md                 תוכנית מעבר vault → DB
│   ├── legal-decision-lessons.md         לקחים מ-3 החלטות
│   └── memory.md                         הקשר כללי — skills, פרויקטים
├── skills/                            ← כלי עבודה ומדריכים
│   ├── decision/                         מדריך סגנון + references + 12 בלוקים
│   ├── assistant/                        קטלוג מסמכים
│   ├── docx/                             עיצוב DOCX
│   ├── dafna-decision-template/          export DOCX לפי תבנית Word של דפנה
│   └── new-company-setup/               blueprint הוספת חברה חדשה
├── .claude/
│   └── agents/                        ← הוראות סוכנים + HEARTBEAT.md (symlinks ב-Paperclip)
│       ├── HEARTBEAT.md                  checklist הפעלה משותף לכל הסוכנים
│       ├── legal-ceo.md                  תזמורן + בקרת זרימה
│       ├── legal-writer.md               כתיבת בלוקים בסגנון דפנה
│       ├── legal-analyst.md              ניתוח משפטי + חילוץ טענות
│       ├── legal-researcher.md           חיפוש תקדימים
│       ├── legal-qa.md                   7 שערי איכות
│       ├── legal-proofreader.md          תיקון OCR
│       ├── legal-exporter.md             ייצוא DOCX סופי
│       └── hermes-curator.md            סוכן Hermes לניתוח סגנון post-export
├── data/
│   ├── training/                      ← 4 החלטות לאימון (DOCX)
│   ├── exports/                       ← טיוטות DOCX מיוצאות
│   └── cases/{case-number}/           ← תיקי עררים (מבנה שטוח, סטטוס ב-DB)
├── web/                               ← FastAPI backend (Python): 75+ API endpoints
│   ├── app.py                            ← API ראשי
│   ├── paperclip_api.py                  ← אינטגרציית Paperclip: `pc_request()` + `emit_case_status_webhook()`
│   ├── paperclip_client.py               ← legacy client (ישן — השתמש ב-paperclip_api.py)
│   └── gitea_client.py                   ← אינטגרציית Gitea
├── web-ui/                            ← Next.js frontend (TypeScript/React): ממשק המשתמש
│   └── next.config.ts                    ← proxy: /api/* → FastAPI :8000
├── mcp-server/                        ← MCP server + services + tools
├── adapters/                          ← Paperclip external adapters (ראה למטה)
│   └── deepseek-paperclip-adapter/      ← `deepseek_local` (Hermes-pinned ל-DeepSeek profile)
└── scripts/                           ← סקריפטים וכלי עזר (ראה scripts/SCRIPTS.md)
    └── .archive/                      ← סקריפטים שהושלמו (לא להריץ)

כלל: עדכון scripts/SCRIPTS.md

בכל פעם שנוצר, נמחק, או משתנה סקריפט בתיקיית scripts/חובה לעדכן את scripts/SCRIPTS.md בהתאם. הקובץ מתעד את התפקיד, הסטטוס, וההחלפה (אם יש) של כל סקריפט.


ניהול משימות — TaskMaster AI

הפרויקט משתמש ב-TaskMaster AI (MCP server) לניהול משימות מובנה:

  • תמיד להשתמש ב-TaskMaster לפירוק, מעקב וניהול משימות — לא ב-TASKS.md ידני
  • קובץ המשימות: tasks/tasks.json
  • פקודות עיקריות: get_tasks, next_task, add_task, update_task, expand_task
  • לפני התחלת עבודה → next_task כדי לדעת מה הבא לפי תלויות
  • אחרי סיום משימה → update_task עם status=done
  • משימה מורכבת → expand_task לפירוק לתתי-משימות

Paperclip — כללי אינטגרציה קריטיים

Wakeup API — תמיד דרך API, לעולם לא דרך DB

  • הנתיב הנכון: POST /api/agents/{agent-id}/wakeup (לא /wake!)
  • ⚠️ אסור: INSERT INTO agent_wakeup_requests ישירות — זה יוצר רק רשומה בלי heartbeat_run, והסוכן לא יתעורר לעולם
  • ⚠️ חובה לשלוח payload עם issueId — בלי זה הסוכן מתעורר בלי הקשר (בלי תיק, בלי issue, בלי cwd נכון)
  • דוגמה נכונה:
    {"source": "automation", "triggerDetail": "system", "reason": "...",
     "payload": {"issueId": "...", "mutation": "comment", "commentId": "..."}}
    
  • Board API Key: שמור ב-DB (board_api_keys), auth: Authorization: Bearer pbk_...

ניתוב comments דרך CEO

  • כשמשתמש כותב תגובה על issue ב-Paperclip, הפלאגין (plugin-legal-ai) מעיר את ה-CEO דרך ctx.agents.invoke()
  • ה-CEO קורא את ה-comment, מחליט על ניתוב, ויוצר issue לסוכן המתאים
  • כל הסוכנים חייבים לקרוא comments אחרונים לפני שהם מתחילים לעבוד (HEARTBEAT שלבים 2b-2c)

קריאות API — תמיד דרך helper, לעולם לא curl ישיר

  • bash (סוכנים): ~/legal-ai/scripts/pc.sh <METHOD> <PATH> [BODY_JSON] — מוסיף Authorization, X-Paperclip-Run-Id, Content-Type, base URL. ראה HEARTBEAT.md §0.
  • Python (FastAPI): from web.paperclip_api import pc_request; await pc_request("POST", "/api/...", json={...}) — שימוש ב-board API key.
  • אסור curl ... $PAPERCLIP_API_URL ישיר ב-bash; אסור httpx.AsyncClient ישיר ל-Paperclip ב-Python.
  • למה: ה-skill הרשמי דורש X-Paperclip-Run-Id בכל קריאה משנה issue. אצלנו ה-audit trail עבד ממילא דרך JWT claims (runId: runIdHeader || claims.run_id), אבל ה-helper מבטיח עקביות + תאימות ל-board API keys (long-lived) שלא נושאות JWT claims.

Cross-company agent sync — אחרי כל שינוי הגדרות

  • יש 14 סוכנים = 7 × 2 חברות (CMP=1xxx, CMPA=8xxx). Paperclip מחייב agents.company_id NOT NULL — אין shared agents.
  • Master = CMP (1xxx), Mirror = CMPA (8xxx).
  • אחרי כל שינוי ב-adapter_config, runtime_config, budget_monthly_cents, או skills של סוכן ב-master (UI, SQL, או API), חובה להריץ:
    PAPERCLIP_BOARD_API_KEY=$(...infisical...) \
      python ~/legal-ai/scripts/sync_agents_across_companies.py --verify  # לבדיקה
    PAPERCLIP_BOARD_API_KEY=$(...) \
      python ~/legal-ai/scripts/sync_agents_across_companies.py --apply   # לסנכרן
    
  • הסקריפט מסנן local skills שלא קיימים ב-CMPA (מציג אזהרה), משתמש ב-API (לא DB ישיר), יוצר revisions, idempotent.
  • שאלות ה-skill הרשמי של Paperclip — paperclip skill תחת paperclipai/paperclip.

Webhook יוצא — עדכון סטטוס תיק לפלאגין

כשסטטוס תיק משתנה דרך PUT /api/cases/{case_number}, הבקאנד שולח webhook אסינכרוני לפלאגין:

PUT /api/cases/{case_number}  →  emit_case_status_webhook() [BackgroundTask]
  →  POST /api/plugins/marcusgroup.legal-ai/webhooks/case-status
  →  plugin-legal-ai/onWebhook()
  →  comment בעברית על issue + CEO wakeup (כשסטטוס = qa_failed)
  • הקוד ב-web/paperclip_api.py (emit_case_status_webhook), fire-and-forget, timeout 5s
  • הפלאגין שומר idempotency key ב-state עם TTL 5 דקות למניעת spam על retry
  • GET /api/cases/stale?days=N — תיקים שלא עודכנו N ימים; מוחרגים: new, final, exported
  • GET /api/chair-feedback/weekly-summary — סיכום פידבק YU"R לשבוע האחרון
Job לוח זמנים מה עושה
stale-case-reminder יומי 08:00 שולח comment אזהרה על תיקים תקועים >3 ימים
weekly-feedback-analysis ראשון 19:00 מעיר CEO לניתוח פידבק YU"R ועדכון docs/legal-decision-lessons.md
sync-case-status כל 30 דק' מסנכרן סטטוסי תיקים בין legal-ai ל-Paperclip

CEO שמתעורר מ-weekly-feedback-job כותב לקובץ בלבד — אין לו issueId, אל תנסה לפרסם comment או לסגור issue.

External adapters — deepseek_local

  • מיקום ה-package: adapters/deepseek-paperclip-adapter/ (לא ב-node_modules).
  • רישום ב-Paperclip: רשומה ב-~/.paperclip/adapter-plugins.json (נטען אוטומטית ב-startup דרך buildExternalAdapters). אין צורך בעריכת node_modules.
  • מה ה-adapter עושה: spawnל-hermes chat עם HERMES_HOME=/home/chaim/.hermes/profiles/deepseek כך שה-CLI טוען את config.yaml (base_url=https://api.deepseek.com/v1, provider=custom, key_env=DEEPSEEK_API_KEY) ואת .env (שמכיל את ה-key).
  • מודלים זמינים (lookup ב-DeepSeek /v1/models): deepseek-v4-pro (default), deepseek-v4-flash. יופיעו כדרופ-דאון ב-UI.
  • התקנה מחדש / עדכון: curl -X POST -H "Authorization: Bearer pcapi_legal_install_key_2026" -H "Content-Type: application/json" -d '{"packageName":"/home/chaim/legal-ai/adapters/deepseek-paperclip-adapter","isLocalPath":true}' http://localhost:3100/api/adapters/install. לעדכון hot — POST /api/adapters/deepseek_local/reload.
  • ⚠ Cross-company sync: sync_agents_across_companies.py מדלג על סוכנים עם adapter_type שונה בין CMP ל-CMPA. כשעוברים סוכן ל-deepseek_local חובה להחיל ידנית בשתי החברות לפני sync.
  • תוספת adapters עתידיים (OpenAI ישיר, Anthropic ישיר, וכו'): אותו דפוס. ה-package הראשי חייב לייצא createServerAdapter() שמחזיר { type, label, models, agentConfigurationDoc, execute, testEnvironment, sessionCodec, listSkills, syncSkills, ... }. ראה את adapters/deepseek-paperclip-adapter/dist/index.js כתבנית.

External adapters — Hermes Curator (curator-cmp / curator-cmpa)

  • פרופילי Hermes נפרדים לסוכן hermes-curator — מנתח החלטות סופיות ומציע עדכוני SKILL.md/lessons.md
  • מיקום: ~/.hermes/profiles/curator-cmp/ + ~/.hermes/profiles/curator-cmpa/
  • מופעל אחרי export סופי; אינו מעדכן קבצים ישירות

עקרונות כתיבה קריטיים

  1. "מבחן השופט" — כל החלטה חייבת להיות קריאה לשופט שלא מכיר את התיק
  2. "רקע ניטרלי" — בלוק ו = עובדות בלבד. אין ציטוטים מצדדים, אין מילות שיפוט
  3. "ללא כפילות" — בלוק י (דיון) מפנה לבלוקים קודמים, לא חוזר עליהם
  4. "טענות מקוריות בלבד" — בלוק ז = מכתבי טענות מקוריים בלבד. השלמות → בלוק ח
  5. ארכיטקטורת 12 בלוקים — ראה docs/block-schema.md
  6. צ'קליסט תוכן — בלוק י מקבל צ'קליסט תוכן אוטומטי לפי סוג הערר (ראה lessons.py: CONTENT_CHECKLISTS)

הערות יו"ר (Chair Feedback)

מנגנון לתיעוד הערות דפנה על טיוטות:

  • DB: טבלת chair_feedback (case_id, block_id, feedback_text, category, lesson_extracted)
  • API: GET/POST /api/feedback, PATCH /api/feedback/{id}/resolve
  • MCP tools: record_chair_feedback, list_chair_feedback
  • UI: דף ניהול ב-/feedback (ב-Next.js)
  • קטגוריות: missing_content, wrong_tone, wrong_structure, factual_error, style, other

יו"ר: עו"ד דפנה תמיר

  • מדריך סגנון מלא: skills/decision/SKILL.md