X15 — Agent Platform Port: Paperclip כמעטפת ניתנת-להחלפה מאחורי Port יחיד. מגדיר INV-PORT1/G12 (Ports&Adapters + Dependency Rule + Anti-Corruption Layer), מצאי-דליפה baseline (mcp-server נקי; דליפה ב-app.py + 10 פרומפטים + web-ui), מפת-תיקון R0–R4, ומנגנון-אכיפה נגד דליפה-עתידית (leak-guard + תבנית-PR). X16 — Durable Pipeline Execution: LangGraph כספרייה בתוך הסקריפט (לא תחליף-פלטפורמה) ל-final_halacha/final_learning. מגדיר INV-DUR1 (checkpointing+replay, מימוש משותף), SqliteSaver תחת data/checkpoints, גרעיניות מדורגת P0–P3, שימור-חוזה-CLI. מיישם/מחזק: G2 (X15), G3 (X16). תכנון בלבד — ללא שינוי-קוד. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
150 lines
12 KiB
Markdown
150 lines
12 KiB
Markdown
# X15 — שער-הפלטפורמה (Agent Platform Port)
|
||
|
||
> כפוף ל-[00-constitution.md](00-constitution.md). מיישם ומחזק את **INV-G2** (מקור-אמת
|
||
> יחיד — אין מסלולים מקבילים) ברובד הקַשירה (coupling) בין שכבת-האינטליגנציה לפלטפורמת-הסוכנים.
|
||
|
||
## 0. למה המסמך הזה קיים
|
||
|
||
פלטפורמת-הסוכנים שלנו היום היא **Paperclip**. היא אינה ליבת-המערכת — היא ה**מעטפת**
|
||
(לוח-issues, סוכנים מתמידים, human-in-the-loop דרך comments, wakeup/heartbeat, תזמון,
|
||
תקציבים per-agent, adapters). ליבת-האינטליגנציה — `mcp-server/src`, ה-skills של
|
||
ההחלטה/הסגנון, ולוגיקת-ההחלטה — היא הנכס שאינו תלוי-פלטפורמה.
|
||
|
||
**כשל-השורש שהמסמך מייבש:** מגע עם Paperclip שדולף לתוך שכבת-האינטליגנציה הופך את
|
||
המעטפת מ"רכיב ניתן-להחלפה מאחורי חוזה" ל"תלות-רוחב ארוגה בכל הקוד". ככל שהדליפה גדלה,
|
||
"החלפת המעטפת" (או אפילו שדרוג גרסה — ראו ההצמדה ל-opus-4-8) הופכת מ**החלפת-רכיב**
|
||
ל**כתיבה-מחדש**. זוהי הופעה נוספת של כשל-השורש שכל הספ בא לייבש: מסלולים מקבילים
|
||
שמתפצלים (drift), הפעם בציר התלות בין שכבות.
|
||
|
||
הבסיס התאורטי: **Ports & Adapters / Hexagonal Architecture** (Alistair Cockburn),
|
||
**The Dependency Rule / Clean Architecture** (Robert C. Martin), **Anti-Corruption
|
||
Layer** (Eric Evans, DDD). כולם אומרים את אותו הדבר: התלות זורמת פנימה בלבד; הליבה
|
||
אינה יודעת על העולם החיצון; כל מגע עם מערכת-חוץ עובר דרך שכבת-תרגום אחת (port/adapter).
|
||
|
||
---
|
||
|
||
## 1. השכבות והתפר
|
||
|
||
```
|
||
┌────────────────────────────────────────────────────────────────────┐
|
||
│ INTELLIGENCE (תלוי-פלטפורמה = אסור) │
|
||
│ mcp-server/src · skills/decision · skills/style · decision logic │
|
||
│ · style-acquisition │
|
||
│ ── חייב להכיל אפס סמלים ספציפיים-Paperclip ── │
|
||
└───────────────────────────────┬────────────────────────────────────┘
|
||
│ ה-PORT (שכבת-התרגום היחידה)
|
||
│ • web/agent_platform_port.py (Python)
|
||
│ • .claude/agents/HEARTBEAT.md (פרומפטים)
|
||
┌───────────────────────────────┴────────────────────────────────────┐
|
||
│ SHELL (Paperclip-specific — מותר ומוצהר) │
|
||
│ web/paperclip_client.py · web/paperclip_api.py · plugin-legal-ai │
|
||
│ · adapters/* · web-ui settings/paperclip-tab · skills/new-company │
|
||
└───────────────────────────────┬────────────────────────────────────┘
|
||
│
|
||
┌─────┴─────┐
|
||
│ Paperclip │ ← הפלטפורמה. ניתנת-להחלפה.
|
||
└───────────┘
|
||
```
|
||
|
||
**הגדרת-ה-Port:** קבוצת-הקבצים היחידה שמורשית לדבר Paperclip:
|
||
|
||
| Port surface | תפקיד | מורשה לייבא/להזכיר Paperclip |
|
||
|--------------|-------|------------------------------|
|
||
| `web/agent_platform_port.py` *(לבנייה — R2)* | תרגום אירועי-דומיין → קריאות-פלטפורמה | כן — המודול היחיד שמייבא `paperclip_client`/`paperclip_api` |
|
||
| `web/paperclip_client.py`, `web/paperclip_api.py` | מימוש-הלקוח (מאחורי ה-Port) | כן (זו המעטפת המתוכננת) |
|
||
| `.claude/agents/HEARTBEAT.md` | מקור-אמת יחיד לפרוטוקול-הריצה של הסוכנים | כן |
|
||
| `plugin-legal-ai/*`, `adapters/*` | הגשר מצד-Paperclip | כן |
|
||
| `web-ui` settings/paperclip-tab, agents-tab | UI לניהול-Paperclip עצמו | כן (מוצהר) |
|
||
| `skills/new-company-setup/SKILL.md` | blueprint-הקמה (חייב לדבר Paperclip) | כן — **חריג מוצהר** |
|
||
|
||
כל קובץ אחר — בפרט תחת `mcp-server/src`, `skills/decision`, `skills/style`,
|
||
ופרומפטי-הסוכנים פרט ל-HEARTBEAT — **אסור** שיכיל סמל ספציפי-Paperclip.
|
||
|
||
---
|
||
|
||
## 2. ה-invariant
|
||
|
||
### INV-PORT1 (גלובלי: G12) — שער-הפלטפורמה
|
||
**כלל:** פלטפורמת-הסוכנים (Paperclip) נגישה אך-ורק דרך ה-Platform Port
|
||
(`web/agent_platform_port.py` + `HEARTBEAT.md` לפרומפטים). שכבת-האינטליגנציה —
|
||
`mcp-server/src`, וה-skills של ההחלטה/הסגנון — מכילה **אפס** סמלים ספציפיים-לפלטפורמה
|
||
(שמות-מוצר, wakeup/heartbeat, pc.sh/pc_request, X-Paperclip-Run-Id, enums של הפלטפורמה).
|
||
פרומפטי-הסוכנים אינם משכפלים את פרוטוקול-הריצה — הם מצביעים ל-HEARTBEAT.md בלבד. כל מגע
|
||
חדש עם הפלטפורמה עובר דרך ה-Port.
|
||
**מקורות:** Alistair Cockburn, *Hexagonal Architecture (Ports & Adapters)* · Robert C.
|
||
Martin, *Clean Architecture* (The Dependency Rule) · Eric Evans, *Domain-Driven Design*
|
||
(Anti-Corruption Layer) | סטטוס: verified
|
||
**אכיפה:** (א) ביקורת-ארכיטקטורה + רשימת-ה-Port (§1); (ב) leak-guard אוטומטי — הרחבת
|
||
[scripts/spec-guard.sh](../../scripts/spec-guard.sh) שמשווה מול baseline-הדליפה (§4) ומזהיר
|
||
על דליפה חדשה ב-Edit/Write; (ג) fitness-test ב-CI שנכשל על מונח-Paperclip קשיח חדש תחת
|
||
`mcp-server/src`; (ד) הצהרת-G12 בתבנית-ה-PR.
|
||
**הפרה ידועה:** ראו מצאי-הדליפה ב-§3 — `web/app.py` קורא ל-`pc_*` inline בלוגיקת
|
||
מחזור-חיים של תיקים; 10 פרומפטי-סוכנים משכפלים את פרוטוקול-הריצה במקום להצביע ל-HEARTBEAT.
|
||
|
||
> **סיווג:** invariant הנדסי (≥3 מקורות חיצוניים, verified). מורחב מ-G1–G10 בתור **G12**.
|
||
> רישומו ברשימת-הגלובליים ובאינדקס של [00-constitution.md](00-constitution.md) מתבצע במשימת
|
||
> R0b (תיקון-תיעוד) — עד אז המסמך הזה הוא מקור-האמת ל-G12.
|
||
|
||
---
|
||
|
||
## 3. מצאי-הדליפה (baseline — נמדד 2026-06-09)
|
||
|
||
מבחן-נטישה: כמה השכבות חוצות את התפר. הספירה היא בסיס-ההשוואה ל-leak-guard.
|
||
|
||
| Layer | Paperclip hits | סיווג | מחיר-ניתוק |
|
||
|-------|----------------|-------|------------|
|
||
| `mcp-server/src` (כלים) | 5 — **הערות בלבד** | ✅ נקי (זה הנכס) | ~0 |
|
||
| `skills/` (decision/style) | 36 — רק `new-company-setup` | ✅ נקי (חריג מוצהר) | נמוך |
|
||
| `web/paperclip_client.py` | 116 | ✅ מעטפת מתוכננת | — |
|
||
| `web/paperclip_api.py` | 33 | ✅ מעטפת מתוכננת | — |
|
||
| `web/app.py` | ~33 קריאות `pc_*` + `PAPERCLIP_COMPANIES`×72 | ⚠️ דליפה מבנית (מחזור-חיים) | בינוני |
|
||
| `.claude/agents/*.md` | 288 — פרוטוקול משוכפל ב-10 פרומפטים | ⚠️⚠️ דליפה מכנית | גבוה (בנפח) |
|
||
| `web-ui` (`types.ts`×41, `cases.ts`, `sse.ts`, ...) | ~60 | ⚠️ מושגי-פלטפורמה בחוזי-פרונט | בינוני |
|
||
|
||
**הממצא המרכזי:** שכבת-האינטליגנציה (`mcp-server/src` + skills של ההחלטה/הסגנון) כבר
|
||
נקייה כמעט-לחלוטין — 5 ההיטים ב-mcp-server הם הערות בלבד (מקור `company_id`). מחיר-הגירושין
|
||
בינוני, מרוכז בשלוש שכבות-נושקות-למעטפת.
|
||
|
||
---
|
||
|
||
## 4. מפת-התיקון (R-tasks)
|
||
|
||
| R | תחום | תיאור | סיכון |
|
||
|---|------|-------|-------|
|
||
| **R0** | ספ | המסמך הזה — מגדיר את ה-Port, ה-invariant, ו-baseline-הדליפה | 0 |
|
||
| **R0b** | ספ | רישום G12 ב-[00-constitution.md](00-constitution.md) (רשימת-גלובליים + אינדקס) + שורת G12 בתבנית-ה-PR + מצביע ב-CLAUDE.md | 0 |
|
||
| **R1** | פרומפטים | כל פרוטוקול-הריצה עובר ל-HEARTBEAT.md (מקור יחיד); 10 הפרומפטים מצביעים אליו בלבד. 288→~20 היטים | נמוך |
|
||
| **R2** | web | יצירת `web/agent_platform_port.py` — המודול היחיד שמייבא `paperclip_client`/`paperclip_api`. `app.py` פולט אירוע-דומיין (`case_archived`/`created`/...) שה-Port מתרגם. `PAPERCLIP_COMPANIES`→`company_map` מאחורי ה-Port | בינוני |
|
||
| **R3** | web-ui | `types.ts` → namespace `paperclip.*` נפרד; חוזי case/api כלליים נשארים נקיים. טאבי-ניהול-Paperclip נשארים (מעטפת מוצהרת) | נמוך-בינוני |
|
||
| **R4** | אכיפה | הרחבת `spec-guard.sh` ל-leak-guard מול ה-baseline + fitness-test ב-CI על `mcp-server/src` | 0 |
|
||
|
||
**עיקרון-מנחה (G2):** R1+R2 הם G2 בלבוש חדש — מאחדים פרוטוקול/מסלול משוכפל למקור אחד.
|
||
הם אינם יוצרים מסלול מקביל; הם מסירים אחד.
|
||
|
||
---
|
||
|
||
## 5. מנגנון נגד דליפה-עתידית
|
||
|
||
תיקון חד-פעמי חסר-ערך אם הדליפה תחזור בפיצ'ר הבא. שלוש שכבות-אכיפה, כולן מתחברות
|
||
למנגנונים קיימים (ולא ממציאות מסלול חדש):
|
||
|
||
1. **invariant (G12)** — מוגדר כאן, נרשם בחוקה (R0b). first-class, לא הערת-שוליים.
|
||
2. **אכיפה-אוטומטית** — `spec-guard.sh` כבר מיירט כל Edit/Write בנתיב-קוד; ה-leak-guard
|
||
(R4) משווה מול baseline §3 ומזהיר על דליפה חדשה **בזמן-אמת**, לפני ה-review.
|
||
3. **חוזה-תיעוד** — תבנית-ה-PR כבר דורשת הצהרת-invariants; נוסיף שורת-G12 לצ'קליסט
|
||
("□ לא הוספתי מגע-Paperclip מחוץ ל-Platform Port"). CLAUDE.md §Paperclip + §פרוטוקול
|
||
כתיבת-קוד מצביעים לכאן.
|
||
|
||
> **כלל-זהב לכל פיתוח עתידי:** פיצ'ר חדש שנוגע בפלטפורמה — מוסיף/משנה **רק** קוד תחת
|
||
> רשימת-ה-Port (§1). אם נדרש מגע-פלטפורמה משכבת-האינטליגנציה — זו אינדיקציה לתכנון
|
||
> שגוי: הוסיפו במקום זאת אירוע-דומיין שה-Port יתרגם.
|
||
|
||
---
|
||
|
||
## 6. ראו גם
|
||
- [00-constitution.md](00-constitution.md) — G2 (שאותו מיישם), G12 (לאחר R0b).
|
||
- [X7-paperclip-client-params.md](X7-paperclip-client-params.md) — פרמטרי לקוח-Paperclip (מתחת ל-Port).
|
||
- [X4-agents.md](X4-agents.md) — מפת-הסוכנים.
|
||
- [X3-integration-deploy.md](X3-integration-deploy.md) — אינטגרציה+deploy.
|
||
- [X16-pipeline-durability.md](X16-pipeline-durability.md) — עמידות-פייפליין (החלטה נפרדת, נושקת).
|