Extends the system spec beyond the core pipeline to the 8 surfaces outside it: - X6 UI↔API contract + design rules (INV-UI1..6) - X7 Paperclip client & connection params (INV-INT4..8) - X8 field-population & extraction provenance (INV-FP1..5) - X9 MCP tool contract — 71 tools (INV-TOOL1..6) - X10 deploy/env/secrets (INV-ENV1..5) - ui-audit.md — page-by-page UI audit (13 pages) - 02-data-model: derived-entity invariants (INV-DM4..6) - X4-agents: tool-grant map + INV-AG3 - gap-audit: GAP-24..62 → FU-9..15; cycle-1 (FU-1..8b) marked done - constitution §7 + README index (X1..X10) Planning/spec artifacts only — no application code. All engineering invariants backed by ≥3 sources; every finding carries verified file:line. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
9.5 KiB
X10 — Deploy, סביבה וסודות (Deploy, Environment & Secrets)
קובץ-תחום זה כפוף ל-חוקת המערכת והוא ה-deep-dive על קונפיגורציה, משתני-סביבה וסודות — מה שהיה מכוסה כחצי-deploy בלבד ב-X3 §2. הוא מגדיר את חוזה-ה-env (SSoT אחד), מקור-ה-config (Coolify), טיפול-הסודות, ואי-ה-hardcode. X3 נשאר הבעלים של זרימות-האינטגרציה; X10 הבעלים של הקונפיגורציה וה-deploy.
invariant פרויקטלי-תפעולי + הנדסי. ENV1/ENV3/ENV4/ENV5 נשענים על עקרונות-הנדסה מוכרים (12-Factor, ניהול-סודות) — ≥3 מקורות. ENV2 (מקור-config של מערכת זו) הוא תפעולי, נקשר ל-G2.
1. מצב קיים (מאומת מול הקוד)
- מודל-deploy: legal-ai = Coolify Docker (UUID
gyjo0mtw2c42ej3xxvbz8zio, build_packdockerimage); ה-env מוזרק ישירות מ-Coolify, לא מ-Infisical (X3 §2; זיכרוןreference_legal_ai_env_architecture). - 40+ משתני-env נקראים על-פני config.py, web/app.py, paperclip_api.py/paperclip_client.py, gitea_client.py, chat_proxy.py.
- קטלוג-UI (mcp_env_catalog.py) מכסה 13 בלבד מתוך ה-40+ → השאר בלתי-נראים לדף-ההגדרות ולגילוי-drift.
- Infisical: קוד-ה-SDK ב-config.py קורא
INFISICAL_TOKEN, אך בקונטיינר הוא לעולם לא מוגדר → קוד מת; ה-priority בפועל = Coolify-env בלבד.
2. Invariants של התחום
INV-ENV1: env-catalog יחיד = SSoT לכל משתני-הסביבה
כלל: קיים קטלוג-env יחיד המתאר את כל המשתנים (שם, ברירת-מחדל, סוד?, מי-קורא, מה-שולט). אין משתנה
שנקרא-בקוד אך לא-בקטלוג, ואין משתנה-בקטלוג שלא-נקרא. מופע של G2
ו-G4 (שלמות-הקטלוג). הנדסי.
מקורות: The Twelve-Factor App — III. Config (https://12factor.net/config) · OWASP — Configuration / Secrets Management Cheat Sheet
(https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html) · Kleppmann DDIA (config as data) | סטטוס: verified
אכיפה: קטלוג מקיף + בדיקה ש-getenv call-sites ⊆ קטלוג. כיום: 13/40+ בלבד (gap-audit GAP-60).
הפרה ידועה: PAPERCLIP_BOARD_API_KEY/GITEA_*/CHAT_SERVICE_URL/LEGAL_CHAT_SHARED_SECRET לא בקטלוג; GITEA_ACCESS_TOKEN מול GITEA_TOKEN (שני שמות) (gap-audit GAP-58).
INV-ENV2: מקור-config יחיד ומתועד (Coolify) — בלי קוד-מת
כלל: למערכת מקור-config אחד מתועד (Coolify-env לקונטיינר), והקוד אינו מניח מקור-שני שאינו פעיל.
אין "Infisical priority" מדומה כשאין INFISICAL_TOKEN. מופע של G2
(מקור-אמת יחיד) וכלל "אין בליעה שקטה" (§6). פרויקטלי-תפעולי.
מקור-סמכות: זיכרון reference_legal_ai_env_architecture; feedback_infisical_coolify_drift; X3 §2.
אכיפה: לתעד Coolify כ-SSoT; להסיר/לבודד את קוד-ה-Infisical או להפעילו אמיתית.
הפרה ידועה: קוד-Infisical ב-config.py מת בקונטיינר; ה-priority המתועד לא תואם מציאות (gap-audit GAP-55).
INV-ENV3: ללא hardcode — IDs/URLs/נתיבים מ-config
כלל: מזהים (company/agent), כתובות (Paperclip/Coolify/Gitea/chat/frontend), פורטים ונתיבים נגזרים מ-config,
לא קבועים בקוד. אין /home/chaim קשיח ואין UUID קשיח. מופע של G2
(SSoT) — תואם X7 INV-INT5. הנדסי.
מקורות: Twelve-Factor App — III. Config · Twelve-Factor — X. Dev/prod parity (https://12factor.net/dev-prod-parity) ·
Google SRE / configuration as data (https://sre.google/workbook/configuration-design/) | סטטוס: verified
אכיפה: grep-gate נגד literals (UUID/URL/path) בקוד-חדש. כיום אין.
הפרה ידועה: UUIDs קשיחים (paperclip_client.py:36-62, app.py:3976); URLs קשיחים (pc.nautilus..., coolify..., legal-ai-next...); LEGAL_AI_WORKSPACE_CWD="/home/chaim/legal-ai"; chat-URL 10.0.1.1 מול תיעוד host.docker.internal (gap-audit GAP-56/59/61).
INV-ENV4: אין secrets בקוד/בברירות-מחדל — fail-loud
כלל: שום סוד (creds/key/token) אינו בקוד או בברירת-מחדל; היעדר-סוד נכשל בקול (לא נופל לברירת-מחדל
שקטה עם creds). אין סוד מודלף ל-log או ל-git. מופע של G9
(integrity) וכלל "אין בליעה שקטה" (§6). הנדסי. תואם זיכרון feedback_secrets_first.
מקורות: OWASP — Secrets Management Cheat Sheet (https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html) ·
Twelve-Factor — III. Config (no secrets in code) · CWE-798 — Use of Hard-coded Credentials (https://cwe.mitre.org/data/definitions/798.html) | סטטוס: verified
אכיפה: ברירות-מחדל ריקות + כישלון-מפורש; secret-scan ב-CI.
הפרה ידועה: PAPERCLIP_DB_URL ברירת-מחדל postgresql://paperclip:paperclip@... (creds plaintext) ב-3 מקומות (paperclip_client.py:21, app.py:3789,3964) (gap-audit GAP-57).
INV-ENV5: drift-detection מכסה את כל המשתנים הקריטיים
כלל: מנגנון גילוי-ה-drift (Coolify↔container) מכסה את כל המשתנים הקריטיים, לא תת-קבוצה. מופע של G6 ברוח-שלו (freshness של config) ו-G2. הנדסי. מקורות: Twelve-Factor — III. Config · Google SRE — config drift · HashiCorp — config drift / desired state (https://developer.hashicorp.com/well-architected-framework) | סטטוס: verified אכיפה: הרחבת ה-catalog ל-drift-detection מלא בדף-ההגדרות. הפרה ידועה: רק 13/40+ במנגנון; 8+ סודות קריטיים בלתי-מנוטרים (gap-audit GAP-60).
3. Deploy — עמידוּת (מ-X3 §2, מורחב)
- מחזור: commit→push→Gitea Actions→Coolify redeploy (~2-4 דק'); endpoint חדש דורש גם
npm run api:types(X3 §2, INV-INT2). - חולשות-עמידוּת שנמצאו: start.sh אינו נכשל אם uvicorn לא עולה (ה-UI עולה עם בקאנד שבור); ה-curl ל-Coolify ב-.gitea/workflows/deploy.yaml הוא fire-and-forget (אין אימות-הצלחה) (gap-audit GAP-62).
- host.docker.internal: ה-chat-service נדרש דרך gateway; תיעוד מול קוד לא-תואמים (10.0.1.1) — ENV3.
4. הפניות-אחיות
- X3-integration-deploy.md — זרימות-אינטגרציה + INV-INT2 (מחזור-deploy).
- X7-paperclip-client-params.md — IDs/keys של Paperclip (INV-INT5 תואם ENV3).
- 00-constitution.md — G2, G4, G9, כלל "אין בליעה שקטה" (§6).
- זיכרונות:
reference_legal_ai_env_architecture,feedback_infisical_coolify_drift,feedback_secrets_first. - config.py, mcp_env_catalog.py, Dockerfile, start.sh, .env.example.