Merge pull request 'docs(claude-md): לרזות CLAUDE.md מ-11.3k ל-~7k טוקן (TaskMaster #107.1)' (#160) from worktree-claude-md-trim into main
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 10s
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 10s
This commit was merged in pull request #160.
This commit is contained in:
239
CLAUDE.md
239
CLAUDE.md
@@ -1,10 +1,11 @@
|
|||||||
# עוזר משפטי — Legal Decision Assistant
|
# עוזר משפטי — Legal Decision Assistant
|
||||||
|
|
||||||
|
> **אינדקס דק.** הכללים הקריטיים נמצאים כאן; העומק התפעולי (Deploy, Paperclip-ops, adapters, מבנה-תיקיות, Chair-Feedback, TaskMaster מלא) הוצא ל-[`docs/operations-runbook.md`](docs/operations-runbook.md) כדי לרזות את ההקשר הנטען בכל סשן.
|
||||||
|
|
||||||
## רקע הפרויקט
|
## רקע הפרויקט
|
||||||
|
|
||||||
מערכת AI לסיוע בכתיבת החלטות של **ועדת ערר לתכנון ובניה, מחוז ירושלים**, בראשות **עו"ד דפנה תמיר**.
|
מערכת AI לסיוע בכתיבת החלטות של **ועדת ערר לתכנון ובניה, מחוז ירושלים**, בראשות **עו"ד דפנה תמיר**.
|
||||||
|
|
||||||
### מה עושה ועדת ערר?
|
|
||||||
ועדת ערר היא גוף מעין-שיפוטי שדן בעררים על החלטות ועדות מקומיות לתכנון ובניה. הוועדה מקבלת חומרי מקור (כתבי ערר, תגובות, פרוטוקולים, תכניות), דנה בטענות הצדדים, ומוציאה **החלטה כתובה מנומקת** — מסמך משפטי פורמלי שניתן לביקורת שיפוטית בבית משפט לעניינים מנהליים.
|
ועדת ערר היא גוף מעין-שיפוטי שדן בעררים על החלטות ועדות מקומיות לתכנון ובניה. הוועדה מקבלת חומרי מקור (כתבי ערר, תגובות, פרוטוקולים, תכניות), דנה בטענות הצדדים, ומוציאה **החלטה כתובה מנומקת** — מסמך משפטי פורמלי שניתן לביקורת שיפוטית בבית משפט לעניינים מנהליים.
|
||||||
|
|
||||||
### שלושה סוגי עררים
|
### שלושה סוגי עררים
|
||||||
@@ -15,12 +16,7 @@
|
|||||||
| פיצויים (ס' 197) | 9xxx | קר ומקצועי | דומה להיטל השבחה |
|
| פיצויים (ס' 197) | 9xxx | קר ומקצועי | דומה להיטל השבחה |
|
||||||
|
|
||||||
### מטרת המערכת
|
### מטרת המערכת
|
||||||
לבנות כלי עבודה שמסייע ליו"ר הוועדה לנסח החלטות:
|
כלי עבודה שמסייע ליו"ר הוועדה: **ניהול תיקים** (ייבוא, סיווג, מעקב סטטוס) · **בסיס ידע** (פסיקה, ביטויי מעבר, לקחים, חקיקה) · **חיפוש סמנטי (RAG)** · **סיוע בכתיבה** (טיוטות לפי 12 בלוקים בסגנון דפנה) · **ייצוא DOCX**.
|
||||||
1. **ניהול תיקים** — ייבוא חומרי מקור, סיווג מסמכים, מעקב סטטוס
|
|
||||||
2. **בסיס ידע** — פסיקה, ביטויי מעבר, לקחים מהחלטות קודמות, חקיקה
|
|
||||||
3. **חיפוש סמנטי (RAG)** — מציאת תקדימים רלוונטיים ופסקאות דומות
|
|
||||||
4. **סיוע בכתיבה** — ייצור טיוטות לפי ארכיטקטורת 12 בלוקים בסגנון דפנה
|
|
||||||
5. **ייצוא DOCX** — מסמך מעוצב מוכן להגשה
|
|
||||||
|
|
||||||
### ⭐ יעד-העל: רכישת-הסגנון של דפנה (Style Acquisition)
|
### ⭐ יעד-העל: רכישת-הסגנון של דפנה (Style Acquisition)
|
||||||
**היעד הראשי של המערכת הוא שהסוכנים יכתבו וינתחו עררים בדיוק כמו עו"ד דפנה תמיר** — לא רק לייצר טיוטה תקנית, אלא להפנים את **הקול והשיטה** שלה. זה מחייב **הפרדה מובהקת בין שתי תת-מערכות**:
|
**היעד הראשי של המערכת הוא שהסוכנים יכתבו וינתחו עררים בדיוק כמו עו"ד דפנה תמיר** — לא רק לייצר טיוטה תקנית, אלא להפנים את **הקול והשיטה** שלה. זה מחייב **הפרדה מובהקת בין שתי תת-מערכות**:
|
||||||
@@ -30,19 +26,9 @@
|
|||||||
|
|
||||||
**הגישה (state-of-the-art לדאטה-מועט):** Text Style Transfer מבוסס **Authorial Style Profiling** — להכליל את סגנון דפנה ולהתאים לתיק. העתקת פסקאות מותרת לתוכן קבוע/נוסחאי; ניתוח ספציפי → להכליל; **מהות משפטית (הלכה/עובדה) — אסור להעתיק מתיק לתיק**. *לא* fine-tuning של משקולות (Opus סגור; קורפוס קטן מדי).
|
**הגישה (state-of-the-art לדאטה-מועט):** Text Style Transfer מבוסס **Authorial Style Profiling** — להכליל את סגנון דפנה ולהתאים לתיק. העתקת פסקאות מותרת לתוכן קבוע/נוסחאי; ניתוח ספציפי → להכליל; **מהות משפטית (הלכה/עובדה) — אסור להעתיק מתיק לתיק**. *לא* fine-tuning של משקולות (Opus סגור; קורפוס קטן מדי).
|
||||||
|
|
||||||
**כלל-העל — INV-LRN4:** כל החלטה אינה "סגורה" עד שהושוותה מול הגרסה הסופית של דפנה; כל סופי מנותח מול הטיוטה. כך לומדים מכל החלטה. **INV-LRN5:** שכבת-ידע-הקול לא תכיל מהות ספציפית — רק סגנון ושיטה.
|
**כלל-העל — INV-LRN4:** כל החלטה אינה "סגורה" עד שהושוותה מול הגרסה הסופית של דפנה; כל סופי מנותח מול הטיוטה. **INV-LRN5:** שכבת-ידע-הקול לא תכיל מהות ספציפית — רק סגנון ושיטה. ספ מלא: [`docs/spec/07-learning.md`](docs/spec/07-learning.md) §0. ארכיטקטורה ומשימות: תוכנית `style-acquisition-subsystem`.
|
||||||
|
|
||||||
ספ מלא: [`docs/spec/07-learning.md`](docs/spec/07-learning.md) §0. ארכיטקטורה ומשימות: תוכנית `style-acquisition-subsystem`.
|
> **Legacy:** המערכת הקודמת היתה Obsidian vault עם Claude Code skills. הידע שהופק ממנה (ניתוח סגנון, 12 בלוקים מבוססי CREAC/DITA/Akoma-Ntoso/FJC, כללי כתיבה, לקחים, ייצוא DOCX) הוטמע בפרויקט הנוכחי (`docs/`, `data/training/`). ה-vault נמחק; כעת PostgreSQL + pgvector.
|
||||||
|
|
||||||
### מה היה קודם (Legacy)
|
|
||||||
המערכת הקודמת היתה **Obsidian vault** עם Claude Code skills על שרת אחר. פותחו:
|
|
||||||
- ניתוח סגנון של 3 החלטות (הכט — דחייה, בית הכרם — קבלה חלקית, אריאלי — השוואה)
|
|
||||||
- ארכיטקטורת 12 בלוקים מבוססת CREAC / DITA / Akoma Ntoso / Federal Judicial Center
|
|
||||||
- כללי כתיבה (רקע ניטרלי, ללא כפילות, טענות מקוריות בלבד)
|
|
||||||
- לקחים מהשוואת טיוטות לגרסאות סופיות
|
|
||||||
- סקריפט ייצוא DOCX
|
|
||||||
|
|
||||||
הידע שהופק מה-vault הוטמע במערכת הנוכחית — מסמכי ייחוס (`docs/`), קורפוס אימון (`data/training/`), ומבנה 12 בלוקים. ה-vault המקורי נמחק; הפרויקט הנוכחי עובד עם PostgreSQL + pgvector.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -74,6 +60,7 @@
|
|||||||
| [`.claude/agents/HEARTBEAT.md`](.claude/agents/HEARTBEAT.md) | checklist הפעלת סוכן — routing, company filtering, quirks, wakeup עם UUID נכון | **לפני כל עבודה על סוכנים** |
|
| [`.claude/agents/HEARTBEAT.md`](.claude/agents/HEARTBEAT.md) | checklist הפעלת סוכן — routing, company filtering, quirks, wakeup עם UUID נכון | **לפני כל עבודה על סוכנים** |
|
||||||
| [`skills/dafna-decision-template/SKILL.md`](skills/dafna-decision-template/SKILL.md) | export DOCX לפי styles של תבנית Word של דפנה — line classification, dash policy, placeholder handling | לפני export DOCX |
|
| [`skills/dafna-decision-template/SKILL.md`](skills/dafna-decision-template/SKILL.md) | export DOCX לפי styles של תבנית Word של דפנה — line classification, dash policy, placeholder handling | לפני export DOCX |
|
||||||
| [`docs/corpus-graph.md`](docs/corpus-graph.md) | **מפת הקורפוס** (`/graph`) — גרף ציטוטים אינטראקטיבי נייטיב; 6 שכבות (פסיקה/נושא/תחום/הלכות/חוסרי‑מחקר/יומונים), אנליטיקה (PageRank/אשכולות), endpoints, ואיך מוסיפים שכבה | לפני עבודה על דף `/graph` או `web/graph_api.py` |
|
| [`docs/corpus-graph.md`](docs/corpus-graph.md) | **מפת הקורפוס** (`/graph`) — גרף ציטוטים אינטראקטיבי נייטיב; 6 שכבות (פסיקה/נושא/תחום/הלכות/חוסרי‑מחקר/יומונים), אנליטיקה (PageRank/אשכולות), endpoints, ואיך מוסיפים שכבה | לפני עבודה על דף `/graph` או `web/graph_api.py` |
|
||||||
|
| [`docs/operations-runbook.md`](docs/operations-runbook.md) | **עומק תפעולי** — Deploy (Coolify/pm2), Paperclip-ops מלא (wakeup, sync, webhook, scheduled jobs, adapters), מבנה-תיקיות, Chair-Feedback, TaskMaster | לפני עבודה על Deploy / אינטגרציית-Paperclip / adapters |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -106,17 +93,13 @@
|
|||||||
|
|
||||||
**לכן — כל סשן שעומד לכתוב/לשנות קוד או תיעוד חייב לעבוד ב-git worktree מבודד משלו. אסור לערוך/לתייק בעץ-העבודה הראשי `~/legal-ai` כשייתכן שסשן אחר פעיל.**
|
**לכן — כל סשן שעומד לכתוב/לשנות קוד או תיעוד חייב לעבוד ב-git worktree מבודד משלו. אסור לערוך/לתייק בעץ-העבודה הראשי `~/legal-ai` כשייתכן שסשן אחר פעיל.**
|
||||||
|
|
||||||
הבידוד **נתמך-סביבה** — לא רק כלל-משמעת. ההגדרות נשמרות ב-repo (`.claude/settings.json`, `.worktreeinclude`, `.gitignore`) כך שכל worktree שה-harness יוצר מקבל אוטומטית בסיס נקי, את התלויות, ואת ההרשאות. מקורות רשמיים: [Run parallel sessions with worktrees](https://code.claude.com/docs/en/worktrees), [Settings → worktree](https://code.claude.com/docs/en/settings).
|
הבידוד **נתמך-סביבה** — ההגדרות נשמרות ב-repo (`.claude/settings.json`, `.worktreeinclude`, `.gitignore`) כך שכל worktree שה-harness יוצר מקבל אוטומטית בסיס נקי, את התלויות, ואת ההרשאות. מקורות רשמיים: [Run parallel sessions with worktrees](https://code.claude.com/docs/en/worktrees), [Settings → worktree](https://code.claude.com/docs/en/settings).
|
||||||
|
|
||||||
### הדרך המומלצת — worktree של ה-harness
|
### הדרך המומלצת — worktree של ה-harness
|
||||||
```bash
|
```bash
|
||||||
cd ~/legal-ai && claude --worktree <slug> # או, בתוך סשן: "עבוד ב-worktree" (כלי EnterWorktree)
|
cd ~/legal-ai && claude --worktree <slug> # או, בתוך סשן: "עבוד ב-worktree" (כלי EnterWorktree)
|
||||||
```
|
```
|
||||||
נוצר תחת `.claude/worktrees/<slug>/` על ענף `worktree-<slug>`, ומקבל **אוטומטית**:
|
נוצר תחת `.claude/worktrees/<slug>/` על ענף `worktree-<slug>`, ומקבל **אוטומטית**: בסיס נקי מ-`origin/main` (`worktree.baseRef: "fresh"`) · `web-ui/node_modules` כסימלינק (`worktree.symlinkDirectories`; אין צורך ב-`npm ci`) · `.claude/settings.local.json` + קבצי-env מקומיים (דרך `.worktreeinclude`) · ניקוי אוטומטי ביציאה (כולל עקיפת באג סימלינק [#40259](https://github.com/anthropics/claude-code/issues/40259) דרך `WorktreeRemove` hook עם `--force`).
|
||||||
- **בסיס נקי מ-`origin/main`** — דרך `worktree.baseRef: "fresh"` ב-`.claude/settings.json`.
|
|
||||||
- **`web-ui/node_modules` (789MB) כסימלינק** — דרך `worktree.symlinkDirectories`; אין צורך ב-`npm ci`. (אם משנים deps של web-ui — עשו זאת בעץ הראשי או היו מודעים שה-node_modules משותף.)
|
|
||||||
- **`.claude/settings.local.json` + קבצי-env מקומיים** — מועתקים דרך `.worktreeinclude` (מונע הצפת אישורי-הרשאה).
|
|
||||||
- **ניקוי אוטומטי ביציאה** — כולל עקיפת באג סימלינק [#40259](https://github.com/anthropics/claude-code/issues/40259) דרך `WorktreeRemove` hook עם `--force`.
|
|
||||||
|
|
||||||
### הפרוטוקול (חל על שתי הדרכים)
|
### הפרוטוקול (חל על שתי הדרכים)
|
||||||
1. **בתחילת עבודת-כתיבה** — צור worktree (מומלץ: `claude --worktree`; ידני-fallback: `git worktree add -b <branch> .claude/worktrees/<slug> origin/main` — **תחת `.claude/worktrees/`** כדי שההגדרות יחולו).
|
1. **בתחילת עבודת-כתיבה** — צור worktree (מומלץ: `claude --worktree`; ידני-fallback: `git worktree add -b <branch> .claude/worktrees/<slug> origin/main` — **תחת `.claude/worktrees/`** כדי שההגדרות יחולו).
|
||||||
@@ -127,202 +110,41 @@ cd ~/legal-ai && claude --worktree <slug> # או, בתוך סשן: "עבוד
|
|||||||
6. **אל תיגע** בשינויים לא-מתויקים שאינם שלך בעץ הראשי — הם של סשן אחר. אם העץ הראשי על ענף זר — אל תתייק עליו.
|
6. **אל תיגע** בשינויים לא-מתויקים שאינם שלך בעץ הראשי — הם של סשן אחר. אם העץ הראשי על ענף זר — אל תתייק עליו.
|
||||||
|
|
||||||
> **בידוד-DB:** ה-worktree מבודד-קבצים בלבד — לא בידוד-repo ולא בידוד-DB. **אל תריץ migrations מ-2 worktrees במקביל** על Postgres המשותף (`localhost:5433`) — סכמה שאף סשן לא מצפה לה ([Run agents in parallel](https://code.claude.com/docs/en/agents)).
|
> **בידוד-DB:** ה-worktree מבודד-קבצים בלבד — לא בידוד-repo ולא בידוד-DB. **אל תריץ migrations מ-2 worktrees במקביל** על Postgres המשותף (`localhost:5433`) — סכמה שאף סשן לא מצפה לה ([Run agents in parallel](https://code.claude.com/docs/en/agents)).
|
||||||
> **סוכני Paperclip — אינם מבודדים (אומת 2026-06-06):** 14 מתוך 16 הסוכנים רצים על אדפטר `claude_local` הרשמי, שמריץ `claude -p` ב-`adapter_config.cwd=/home/chaim/legal-ai` **המשותף** — אין לו אופציית `worktreeMode`/`-w` (קיימת רק ב-fork ה-deepseek שלנו). כלומר **כל סוכני Paperclip חולקים את עץ-העבודה הראשי**. הסיכון ממותן ע"י כלל הסשנים נתמך-הסביבה למעלה + תזמור סדרתי ע"י ה-CEO — **לא** ע"י בידוד-worktree per-agent. הניתוח המלא והדרכים שנשקלו: TaskMaster `legal-ai` #104 (נסגר כ-cancelled — "לתעד, לא לבדד").
|
> **סוכני Paperclip — אינם מבודדים (אומת 2026-06-06):** 14 מתוך 16 הסוכנים רצים על אדפטר `claude_local` הרשמי, שמריץ `claude -p` ב-`adapter_config.cwd=/home/chaim/legal-ai` **המשותף** — אין לו אופציית `worktreeMode`/`-w`. כלומר **כל סוכני Paperclip חולקים את עץ-העבודה הראשי**. הסיכון ממותן ע"י כלל הסשנים נתמך-הסביבה למעלה + תזמור סדרתי ע"י ה-CEO — **לא** ע"י בידוד-worktree per-agent. ניתוח מלא: TaskMaster `legal-ai` #104 (נסגר cancelled — "לתעד, לא לבדד").
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## שרת Nautilus (158.178.131.193)
|
## Deploy — תמצית קריטית
|
||||||
|
|
||||||
| שירות | תפקיד | כתובת |
|
שלושה מודלי-הרצה דרים יחד; ערבוב = הטעות הנפוצה. **פירוט מלא, UUIDs ופקודות: [`docs/operations-runbook.md`](docs/operations-runbook.md).**
|
||||||
|-------|--------|-------|
|
|
||||||
| Coolify | ניהול containers | `http://158.178.131.193:8000` |
|
|
||||||
| PostgreSQL + pgvector | בסיס נתונים ראשי | `legal-ai-postgres` |
|
|
||||||
| Redis | תור משימות | `legal-ai-redis` |
|
|
||||||
| 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** (`web/`, `web-ui/`) = **Docker דרך Coolify**. שינוי קוד לא נכנס לתוקף עד `git commit` + `git push origin main` → Gitea Actions בונה image → `mcp__coolify__deploy` (~2-4 דק'). **אסור** uvicorn/`next dev` מקומית — אין Python על המכונה. בדיקה: `curl https://legal-ai.nautilus.marcusgroup.org/api/health`.
|
||||||
|
- **Paperclip** = **pm2 מקומי** (`localhost:3100`). שינוי → `pm2 restart paperclip`. **אין** Docker/Coolify.
|
||||||
**עוזר משפטי (Legal-AI)** — רץ כ-**Docker container דרך Coolify**:
|
- **legal-chat-service** = **pm2 מקומי** (`127.0.0.1:8770`), גשר claude CLI לטאב הצ'אט ב-/training. שינוי → `pm2 restart legal-chat-service`.
|
||||||
- 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**
|
|
||||||
|
|
||||||
**legal-chat-service** — רץ **מקומית דרך pm2** (חדש, מאפריל 2026):
|
|
||||||
- פורט: `localhost:8770` (loopback בלבד)
|
|
||||||
- שירות aiohttp קצר שעוטף את `claude` CLI ב-streaming + session continuation, ומשרת את הטאב "שיחה" בדף `/training`. הקונטיינר משדל אליו proxy דרך `host.docker.internal:8770`.
|
|
||||||
- קוד: [mcp-server/src/legal_mcp/chat_service/](mcp-server/src/legal_mcp/chat_service/)
|
|
||||||
- התקנה: `pm2 start /home/chaim/legal-ai/scripts/legal-chat-service.config.cjs && pm2 save`
|
|
||||||
- בריאות: `curl http://127.0.0.1:8770/health` → `{"ok":true,...}`
|
|
||||||
- שינויי קוד: `pm2 restart legal-chat-service`
|
|
||||||
- **אפס עלות API** — claude CLI משתמש ב-claude.ai subscription של chaim. הנחת היסוד של `claude_session.py` (claude CLI מקומי בלבד) נשמרת — השירות הזה הוא הגשר הרשמי בין הקונטיינר לחוץ.
|
|
||||||
- Coolify dependency: ה-Service Definition של legal-ai חייב להכיל `extra_hosts: host.docker.internal:host-gateway` (אחרת ה-proxy יקבל ConnectError).
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## מבנה תיקיות
|
## Paperclip — כללים קריטיים (תמצית)
|
||||||
|
|
||||||
```
|
**פירוט מלא + דוגמאות + פקודות sync: [`docs/operations-runbook.md`](docs/operations-runbook.md).**
|
||||||
/home/chaim/legal-ai/
|
|
||||||
├── CLAUDE.md ← הקובץ הזה
|
- **Wakeup תמיד דרך API**: `POST /api/agents/{agent-id}/wakeup` עם `payload.issueId`. **אסור** `INSERT INTO agent_wakeup_requests` ישיר — הסוכן לא יתעורר לעולם (אין `heartbeat_run`).
|
||||||
├── Dockerfile ← Docker build
|
- **ניתוב comments דרך CEO**: תגובת-משתמש → פלאגין מעיר CEO → CEO מנתב ויוצר issue. סוכנים קוראים comments אחרונים לפני עבודה (HEARTBEAT 2b-2c).
|
||||||
├── docs/ ← תיעוד + לקחים
|
- **קריאות API דרך helper בלבד**: bash → `scripts/pc.sh`; Python → `pc_request()` מ-`web/paperclip_api.py`. **אסור** `curl` ישיר ל-Paperclip או `httpx.AsyncClient` ישיר.
|
||||||
│ ├── architecture.md ארכיטקטורה
|
- **Cross-company sync**: 14 סוכנים = 7 × 2 חברות (CMP=1xxx master, CMPA=8xxx mirror). אחרי כל שינוי הגדרות/skills של סוכן — להריץ `scripts/sync_agents_across_companies.py --apply`. **מדלג** על סוכנים עם `adapter_type` שונה בין החברות (למשל `deepseek_local`) — להחיל ידנית בשתיהן.
|
||||||
│ ├── 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.md`
|
||||||
|
בכל פעם שנוצר, נמחק, או משתנה סקריפט בתיקיית `scripts/` — **חובה לעדכן את `scripts/SCRIPTS.md`** (תפקיד, סטטוס, החלפה).
|
||||||
בכל פעם שנוצר, נמחק, או משתנה סקריפט בתיקיית `scripts/` — **חובה לעדכן את `scripts/SCRIPTS.md`** בהתאם.
|
|
||||||
הקובץ מתעד את התפקיד, הסטטוס, וההחלפה (אם יש) של כל סקריפט.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ניהול משימות — TaskMaster AI
|
## ניהול משימות — TaskMaster AI
|
||||||
|
**תמיד** TaskMaster (לא TASKS.md ידני). קובץ קנוני: `~/legal-ai/.taskmaster/tasks/tasks.json` (tags: `master`, `legal-ai`). פקודות: `get_tasks`, `next_task`, `add_task`, `update_task`, `expand_task`.
|
||||||
הפרויקט משתמש ב-**TaskMaster AI** (MCP server) לניהול משימות מובנה:
|
> **⚠️ מלכוד cwd ב-CLI:** `--tag` בוחר קבוצה *בתוך* הקובץ — לא לאיזה קובץ לכתוב (ה-CLI מאתר לפי cwd). תמיד `cd ~/legal-ai` לפני כל פקודה משנה, ואז אמת ב-MCP `get_tasks`. כשלא בטוחים — לערוך את הקובץ ישירות. פירוט: [`docs/operations-runbook.md`](docs/operations-runbook.md).
|
||||||
- **תמיד** להשתמש ב-TaskMaster לפירוק, מעקב וניהול משימות — לא ב-TASKS.md ידני
|
|
||||||
- קובץ המשימות הקנוני: `~/legal-ai/.taskmaster/tasks/tasks.json` (יחסי ל-project root, **לא** `~/.taskmaster/tasks/tasks.json`). מכיל את כל ה-tags של legal-ai (`master`, `legal-ai`).
|
|
||||||
- פקודות עיקריות: `get_tasks`, `next_task`, `add_task`, `update_task`, `expand_task`
|
|
||||||
- לפני התחלת עבודה → `next_task` כדי לדעת מה הבא לפי תלויות
|
|
||||||
- אחרי סיום משימה → `update_task` עם status=done
|
|
||||||
- משימה מורכבת → `expand_task` לפירוק לתתי-משימות
|
|
||||||
|
|
||||||
> **⚠️ מלכוד cwd ב-CLI:** הדגל `--tag` בוחר קבוצה לוגית *בתוך* הקובץ — הוא **לא** בוחר לאיזה `tasks.json` לכתוב. ה-CLI מאתר את הקובץ לפי ה-cwd (`<cwd>/.taskmaster/tasks/tasks.json`). תמיד `cd ~/legal-ai` לפני `task-master add-task` או כל פקודה משנה, ואז אמת ב-MCP `get_tasks` שהשינוי נחת. הרצה מ-`~/` כותבת לקובץ נטוש והמשימה לא תופיע בשאילתות MCP. כשלא בטוחים — לערוך את `~/legal-ai/.taskmaster/tasks/tasks.json` ישירות.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Paperclip — כללי אינטגרציה קריטיים
|
## עקרונות כתיבה קריטיים (G11)
|
||||||
|
|
||||||
### Wakeup API — תמיד דרך API, לעולם לא דרך DB
|
|
||||||
- **הנתיב הנכון**: `POST /api/agents/{agent-id}/wakeup` (לא `/wake`!)
|
|
||||||
- **⚠️ אסור**: `INSERT INTO agent_wakeup_requests` ישירות — זה יוצר רק רשומה בלי `heartbeat_run`, והסוכן **לא יתעורר לעולם**
|
|
||||||
- **⚠️ חובה לשלוח `payload` עם `issueId`** — בלי זה הסוכן מתעורר בלי הקשר (בלי תיק, בלי issue, בלי cwd נכון)
|
|
||||||
- דוגמה נכונה:
|
|
||||||
```json
|
|
||||||
{"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), **חובה להריץ:**
|
|
||||||
```bash
|
|
||||||
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 לשבוע האחרון
|
|
||||||
|
|
||||||
### Scheduled Jobs (plugin-legal-ai)
|
|
||||||
|
|
||||||
| 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/](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](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 סופי; אינו מעדכן קבצים ישירות
|
|
||||||
- **תהליך אישור הצעות:** הצעות ה-curator מגיעות כ-comment ב-Paperclip → חיים בוחן ומאשר ידנית → commits ל-`SKILL.md` ו-`docs/legal-decision-lessons.md`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## עקרונות כתיבה קריטיים
|
|
||||||
|
|
||||||
1. **"מבחן השופט"** — כל החלטה חייבת להיות קריאה לשופט שלא מכיר את התיק
|
1. **"מבחן השופט"** — כל החלטה חייבת להיות קריאה לשופט שלא מכיר את התיק
|
||||||
2. **"רקע ניטרלי"** — בלוק ו = עובדות בלבד. אין ציטוטים מצדדים, אין מילות שיפוט
|
2. **"רקע ניטרלי"** — בלוק ו = עובדות בלבד. אין ציטוטים מצדדים, אין מילות שיפוט
|
||||||
@@ -331,14 +153,7 @@ CEO שמתעורר מ-`weekly-feedback-job` כותב לקובץ בלבד — **
|
|||||||
5. **ארכיטקטורת 12 בלוקים** — ראה `docs/block-schema.md`
|
5. **ארכיטקטורת 12 בלוקים** — ראה `docs/block-schema.md`
|
||||||
6. **צ'קליסט תוכן** — בלוק י מקבל צ'קליסט תוכן אוטומטי לפי סוג הערר (ראה `lessons.py: CONTENT_CHECKLISTS`)
|
6. **צ'קליסט תוכן** — בלוק י מקבל צ'קליסט תוכן אוטומטי לפי סוג הערר (ראה `lessons.py: CONTENT_CHECKLISTS`)
|
||||||
|
|
||||||
## הערות יו"ר (Chair Feedback)
|
> **הערות יו"ר (Chair Feedback):** מנגנון תיעוד הערות דפנה — טבלת `chair_feedback`, API `/api/feedback`, MCP `record_chair_feedback`/`list_chair_feedback`, UI `/feedback`. פירוט: [`docs/operations-runbook.md`](docs/operations-runbook.md).
|
||||||
|
|
||||||
מנגנון לתיעוד הערות דפנה על טיוטות:
|
|
||||||
- **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`
|
מדריך סגנון מלא: [`skills/decision/SKILL.md`](skills/decision/SKILL.md).
|
||||||
|
|||||||
203
docs/operations-runbook.md
Normal file
203
docs/operations-runbook.md
Normal file
@@ -0,0 +1,203 @@
|
|||||||
|
# Operations Runbook — עוזר משפטי
|
||||||
|
|
||||||
|
> תוכן תפעולי-עומק שהוצא מ-[`CLAUDE.md`](../CLAUDE.md) כדי לרזות את ההקשר הנטען בכל סשן (TaskMaster #107.1).
|
||||||
|
> ה-CLAUDE.md מחזיק את **הכללים הקריטיים בקצרה**; כאן נמצאים הפרטים המלאים, הפקודות, וטבלאות-הייחוס.
|
||||||
|
> כשעובדים על Deploy, Paperplip-ops, או adapters — לקרוא את הסעיף הרלוונטי כאן.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## שרת Nautilus (158.178.131.193)
|
||||||
|
|
||||||
|
| שירות | תפקיד | כתובת |
|
||||||
|
|-------|--------|-------|
|
||||||
|
| Coolify | ניהול containers | `http://158.178.131.193:8000` |
|
||||||
|
| PostgreSQL + pgvector | בסיס נתונים ראשי | `legal-ai-postgres` (`localhost:5433`, user `legal_ai`) |
|
||||||
|
| Redis | תור משימות | `legal-ai-redis` |
|
||||||
|
| 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` |
|
||||||
|
| legal-chat-service | גשר claude CLI לטאב הצ'אט ב-/training (pm2, loopback) | `127.0.0.1:8770` |
|
||||||
|
| Infisical | ניהול סודות | `secret.dev.marcus-law.co.il` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ארכיטקטורת Deploy — חובה לקרוא
|
||||||
|
|
||||||
|
שלושה מודלי-הרצה דרים יחד. ערבוב ביניהם הוא הטעות הנפוצה ביותר.
|
||||||
|
|
||||||
|
### עוזר משפטי (Legal-AI) — Docker container דרך Coolify
|
||||||
|
- UUID: `gyjo0mtw2c42ej3xxvbz8zio` (build_pack: `dockerimage`, **לא** `dockerfile`)
|
||||||
|
- שינוי קוד ב-`web/` או `web-ui/` **לא נכנס לתוקף** עד ש:
|
||||||
|
1. עושים `git commit` + `git push origin main`
|
||||||
|
2. Gitea Actions בונה image → דוחף ל-registry → מפעיל redeploy ב-Coolify (`mcp__coolify__deploy`)
|
||||||
|
3. ממתינים ~2-4 דקות לבנייה
|
||||||
|
- **אסור** לנסות להריץ uvicorn / `next dev` מקומית — אין סביבת Python על המכונה
|
||||||
|
- ה-container מריץ Next.js (`:3000`, חשוף) + FastAPI (`:8000`, פנימי)
|
||||||
|
- בדיקה: `curl https://legal-ai.nautilus.marcusgroup.org/api/health`
|
||||||
|
- runbook מלא של ה-pipeline: `~/CI-CD-MIGRATION-GUIDE.md`
|
||||||
|
|
||||||
|
### Paperclip — מקומית דרך pm2
|
||||||
|
- פורט: `localhost:3100`, DB: `localhost:54329` (Postgres embedded)
|
||||||
|
- שינויי קוד נכנסים לתוקף אחרי `pm2 restart paperclip`
|
||||||
|
- **אין צורך ב-Docker או Coolify** (מיגרציה ל-Coolify נוסתה 2026-04-04 והוחזרה 2026-04-08)
|
||||||
|
- תרגום/RTL: `~/.paperclip/hebrew/` → `bash ~/.paperclip/hebrew/apply-hebrew.sh && pm2 restart paperclip`
|
||||||
|
|
||||||
|
### legal-chat-service — מקומית דרך pm2 (מאפריל 2026)
|
||||||
|
- פורט: `127.0.0.1:8770` (loopback בלבד)
|
||||||
|
- שירות aiohttp קצר שעוטף את `claude` CLI ב-streaming + session continuation, ומשרת את הטאב "שיחה" בדף `/training`. הקונטיינר משדל אליו proxy דרך `host.docker.internal:8770`.
|
||||||
|
- קוד: [`mcp-server/src/legal_mcp/chat_service/`](../mcp-server/src/legal_mcp/chat_service/)
|
||||||
|
- התקנה: `pm2 start /home/chaim/legal-ai/scripts/legal-chat-service.config.cjs && pm2 save`
|
||||||
|
- בריאות: `curl http://127.0.0.1:8770/health` → `{"ok":true,...}`
|
||||||
|
- שינויי קוד: `pm2 restart legal-chat-service`
|
||||||
|
- **אפס עלות API** — claude CLI משתמש ב-claude.ai subscription של chaim. הנחת היסוד של `claude_session.py` (claude CLI מקומי בלבד) נשמרת.
|
||||||
|
- Coolify dependency: ה-Service Definition של legal-ai חייב להכיל `extra_hosts: host.docker.internal:host-gateway` (אחרת ה-proxy יקבל ConnectError).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## מבנה תיקיות
|
||||||
|
|
||||||
|
```
|
||||||
|
/home/chaim/legal-ai/
|
||||||
|
├── CLAUDE.md ← אינדקס דק (כללים קריטיים + מצביעים)
|
||||||
|
├── docs/operations-runbook.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/ ← סקריפטים שהושלמו (לא להריץ)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Paperclip — כללי אינטגרציה (פירוט מלא)
|
||||||
|
|
||||||
|
> הכללים הקריטיים בתמצית נמצאים ב-[`CLAUDE.md`](../CLAUDE.md). כאן הפירוט המלא, הדוגמאות, וה-"למה".
|
||||||
|
|
||||||
|
### Wakeup API — תמיד דרך API, לעולם לא דרך DB
|
||||||
|
- **הנתיב הנכון**: `POST /api/agents/{agent-id}/wakeup` (לא `/wake`!)
|
||||||
|
- **⚠️ אסור**: `INSERT INTO agent_wakeup_requests` ישירות — זה יוצר רק רשומה בלי `heartbeat_run`, והסוכן **לא יתעורר לעולם**
|
||||||
|
- **⚠️ חובה לשלוח `payload` עם `issueId`** — בלי זה הסוכן מתעורר בלי הקשר (בלי תיק, בלי issue, בלי cwd נכון)
|
||||||
|
- דוגמה נכונה:
|
||||||
|
```json
|
||||||
|
{"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), **חובה להריץ:**
|
||||||
|
```bash
|
||||||
|
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 לשבוע האחרון
|
||||||
|
|
||||||
|
### Scheduled Jobs (plugin-legal-ai)
|
||||||
|
| 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/`](../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`](../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 סופי; אינו מעדכן קבצים ישירות
|
||||||
|
- **תהליך אישור הצעות:** הצעות ה-curator מגיעות כ-comment ב-Paperclip → חיים בוחן ומאשר ידנית → commits ל-`SKILL.md` ו-`docs/legal-decision-lessons.md`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## הערות יו"ר (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
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ניהול משימות — TaskMaster AI (פירוט)
|
||||||
|
|
||||||
|
- קובץ המשימות הקנוני: `~/legal-ai/.taskmaster/tasks/tasks.json` (יחסי ל-project root, **לא** `~/.taskmaster/tasks/tasks.json`). מכיל את כל ה-tags של legal-ai (`master`, `legal-ai`).
|
||||||
|
- פקודות עיקריות: `get_tasks`, `next_task`, `add_task`, `update_task`, `expand_task`
|
||||||
|
- לפני התחלת עבודה → `next_task`; אחרי סיום → `update_task` עם status=done; משימה מורכבת → `expand_task`
|
||||||
|
- **⚠️ מלכוד cwd ב-CLI:** הדגל `--tag` בוחר קבוצה לוגית *בתוך* הקובץ — הוא **לא** בוחר לאיזה `tasks.json` לכתוב. ה-CLI מאתר את הקובץ לפי ה-cwd. תמיד `cd ~/legal-ai` לפני `task-master add-task` או כל פקודה משנה, ואז אמת ב-MCP `get_tasks`. כשלא בטוחים — לערוך את `~/legal-ai/.taskmaster/tasks/tasks.json` ישירות.
|
||||||
Reference in New Issue
Block a user