diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 0000000..27322c6 --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1,15 @@ +{ + "hooks": { + "PreToolUse": [ + { + "matcher": "Edit|Write|MultiEdit", + "hooks": [ + { + "type": "command", + "command": "${CLAUDE_PROJECT_DIR}/scripts/spec-guard.sh" + } + ] + } + ] + } +} diff --git a/.gitea/PULL_REQUEST_TEMPLATE.md b/.gitea/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..5daa1a1 --- /dev/null +++ b/.gitea/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,32 @@ +. +--> + +## מה ולמה + + + +## Invariants — הצהרה (חובה) + + + +- **נוגע / מקיים:** + +## צ'קליסט — פרוטוקול כתיבת-קוד + +- [ ] קראתי את `docs/spec/00-constitution.md` + ספ-התחום הרלוונטי לפני הכתיבה +- [ ] השינוי **לא** יוצר מסלול מקביל ליכולת קיימת (G2) ולא מתקן תסמין בקריאה (G1) +- [ ] אין בליעה שקטה של שגיאות — רשומה חסרה/פגומה מסומנת ומדווחת (כלל-הנדסה §6) +- [ ] בדקתי מול `docs/spec/gap-audit.md` — אם נגעתי ב-GAP/FU ממופה, התאמתי ליחידת-התיקון +- [ ] בדיקות עוברות (אם רלוונטי) / לא נדרשות +- [ ] **אם data-migration** — גיבוי + manifest ל-`data/audit/` לפני `--apply` (chair-gated אם נדרש) + +## אימות + + diff --git a/CLAUDE.md b/CLAUDE.md index 103d34c..e8772ca 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -38,6 +38,9 @@ | מסמך | תוכן | מתי לקרוא | |------|-------|-----------| +| [`docs/spec/00-constitution.md`](docs/spec/00-constitution.md) | **חוקת המערכת** — ייעוד, 11 invariants גלובליים (G1–G11), כללי-הנדסה, אינדקס-ספ | **לפני כל כתיבת/שינוי קוד** (ראה §פרוטוקול כתיבת-קוד) | +| [`docs/spec/README.md`](docs/spec/README.md) | **אינדקס ספ-המערכת** — מחזור-חיים (01–07) + חוצי-שלבים (X1–X11). מקור-האמת ל"מהו תקין" | **לפני כל כתיבת/שינוי קוד** | +| [`docs/spec/gap-audit.md`](docs/spec/gap-audit.md) | **מפת-פערים** — 62 ממצאים → 15 יחידות-תיקון (FU); invariant מופר + file:line + תיקון מוצע | לפני נגיעה ב-GAP/FU קיים או תכנון FU חדש | | [`docs/architecture.md`](docs/architecture.md) | ארכיטקטורת המערכת, תרשים רכיבים, זרימת נתונים, 4 שכבות DB | לפני עבודה על תשתית | | [`docs/block-schema.md`](docs/block-schema.md) | הגדרת 12 בלוקים — content model, constraints, processing params | **לפני כל כתיבת החלטה** | | [`docs/migration-plan.md`](docs/migration-plan.md) | תוכנית מעבר vault → DB — טבלאות, עדיפויות, כמויות | לפני ייבוא נתונים | @@ -61,6 +64,29 @@ --- +## פרוטוקול כתיבת-קוד — קודם הספ ⚠️ + +> **כלל-על.** המקור הקנוני ל"מהו תקין הנדסית" הוא ספ-המערכת תחת [`docs/spec/`](docs/spec/) — לא +> הרגלים, לא "הקוד הקיים נראה ככה". כל קוד שנכתב בלי לעבור דרך הספ מסתכן בהחזרת **כשל-השורש** +> שהספ בא לייבש: מסלולים/קורפוסים מקבילים שמתפצלים (drift). זהו המקבילה האינטראקטיבית ל-INV-AG1 +> שכבר אוכף על סוכני Paperclip ([HEARTBEAT.md](.claude/agents/HEARTBEAT.md) §"קריאת-ספ"). + +**לפני יצירה/שינוי של קוד ב-`web/`, `mcp-server/`, `web-ui/`, `scripts/`:** + +1. **קרא** [`docs/spec/00-constitution.md`](docs/spec/00-constitution.md) — ייעוד, ה-invariants הגלובליים G1–G11, וכללי-ההנדסה (§6). אינדקס-הספ ב-§7. +2. **קרא את ספ-התחום הרלוונטי** לפי האינדקס (§7) — לדוגמה: אחזור→[`03-retrieval.md`](docs/spec/03-retrieval.md), קליטה→[`01-ingest.md`](docs/spec/01-ingest.md), נתונים→[`02-data-model.md`](docs/spec/02-data-model.md), כלי-MCP→[`X9-mcp-tool-contract.md`](docs/spec/X9-mcp-tool-contract.md), UI↔API→[`X6-ui-api-contract.md`](docs/spec/X6-ui-api-contract.md), Paperclip→[`X3`](docs/spec/X3-integration-deploy.md)/[`X7`](docs/spec/X7-paperclip-client-params.md), env/secrets→[`X10-deploy-env-secrets.md`](docs/spec/X10-deploy-env-secrets.md). +3. **ודא שהשינוי *מקיים* את ה-invariants** — לא יוצר מסלול מקביל ליכולת קיימת ([G2](docs/spec/00-constitution.md)), לא מתקן תסמין בקריאה במקום נרמול במקור (G1), לא בולע שגיאות בשקט (כלל-הנדסה §6). +4. **בדוק מול** [`gap-audit.md`](docs/spec/gap-audit.md) — אם אתה נוגע ב-GAP/FU שכבר ממופה, התאם את העבודה ליחידת-התיקון; אל תפתור מחדש. +5. **כל PR מצהיר invariants** — אילו G*/INV-* ה-PR נוגע בהם / מקיים (ראה תבנית ה-PR ב-[`.gitea/PULL_REQUEST_TEMPLATE.md`](.gitea/PULL_REQUEST_TEMPLATE.md)). + +> **שתי שכבות-כללים מובחנות, שתיהן חלות:** +> - **הנדסה (G1–G10)** — הסעיף הזה + `docs/spec/`. סמכות: ≥3 מקורות חיצוניים. +> - **תוכן משפטי (G11)** — סעיף "עקרונות כתיבה קריטיים" למטה (12 בלוקים, רקע ניטרלי...). סמכות: היו"ר + מסמכי-הפרויקט. +> +> אכיפה אוטומטית: hook `PreToolUse` ([scripts/spec-guard.sh](scripts/spec-guard.sh)) מזכיר את הפרוטוקול בכל Edit/Write על נתיב-קוד. + +--- + ## שרת Nautilus (158.178.131.193) | שירות | תפקיד | כתובת | diff --git a/scripts/SCRIPTS.md b/scripts/SCRIPTS.md index 0579ce8..cdfb09a 100644 --- a/scripts/SCRIPTS.md +++ b/scripts/SCRIPTS.md @@ -9,6 +9,7 @@ | Script | Type | Purpose | Scheduled | |--------|------|---------|-----------| | `pc.sh` | bash | **wrapper לכל קריאות Paperclip API מסוכנים** — מוסיף Authorization, X-Paperclip-Run-Id (audit trail), Content-Type, base URL. תחביר: `pc.sh [BODY_JSON]`. אסור `curl` ישיר ל-`$PAPERCLIP_API_URL`. ראה `HEARTBEAT.md §0`. counterpart ב-Python: `web/paperclip_api.py`. | נקרא ע"י סוכנים | +| `spec-guard.sh` | bash | **PreToolUse hook לאכיפת "פרוטוקול כתיבת-קוד"** (CLAUDE.md §פרוטוקול כתיבת-קוד) — בכל Edit/Write/MultiEdit על נתיב-קוד (`web/`, `mcp-server/`, `web-ui/src/`, `scripts/`, `adapters/`) מזריק תזכורת ל-Claude לקרוא את `docs/spec/00-constitution.md`+ספ-התחום ולוודא קיום G1–G11 — לפני שכותבים. המקבילה האינטראקטיבית ל-INV-AG1 (שאוכף על סוכני Paperclip ב-HEARTBEAT.md §"קריאת-ספ"). קלט JSON ב-stdin (`.tool_input.file_path`), פלט `hookSpecificOutput.additionalContext` (non-blocking, exit 0). מחריג `.md`/`docs/`/`tests/`/artifacts. Dedup פעם-בסשן (`$TMPDIR/.spec-guard-`). רשום ב-`.claude/settings.json`. | נקרא אוטומטית ע"י Claude Code (hook) | | `sync_missing_agent_skills.py` | python | סקריפט "אל-כשל" להוספת `paperclipSkillSync` ל-`הגהת מסמכים` ו-`מנתח משפטי` שפיספסו את ה-sync ההיסטורי (Gap #28). תומך `--verify`/`--dry-run`/`--apply`. גיבוי אוטומטי ל-`agents-pre-skill-sync-*.sql`. דורש `PAPERCLIP_BOARD_API_KEY` (Infisical /paperclip ב-nautilus env). idempotent. | חד-פעמי (בוצע 2026-05-04). שמור לרפרנס | | `sync_agents_across_companies.py` | python | **סנכרון סוכנים מ-CMP (1xxx, master) ל-CMPA (8xxx, mirror)** — Gap #25. משווה adapter_config (model/timeout/instructions/skills/etc), runtime_config (heartbeat), ושדות top-level (budget/metadata/icon/title/role). מסנן אוטומטית local skills שלא קיימים ב-mirror. לוגיקת subset (mirror יכול להחזיק יותר skills כי ה-API מוסיף required runtime skills). תומך `--verify`/`--dry-run`/`--apply [--only NAME]`. גיבוי אוטומטי. דורש `PAPERCLIP_BOARD_API_KEY`. **להריץ אחרי כל שינוי הגדרות ב-CMP.** **⚠ אם `adapter_type` שונה בין CMP ל-CMPA — `--apply` מדלג על הסוכן; `--verify` מדווח אותו רם כ-DRIFT.** בעת מעבר adapter (למשל ל-`deepseek_local`) חובה לעדכן ידנית בשתי החברות. **`--verify` יוצא exit≠0 על כל drift** (needs-sync / adapter-mismatch / missing-in-mirror) — שמיש כ-gate ל-cron/CI (GAP-21/FU-8a). | ידני אחרי כל שינוי | | `fix_paperclipai_skills_drift.py` | python | סקריפט חד-פעמי (בוצע 2026-05-04) שניקה drift על `paperclipai/*` skills בין CMP ל-CMPA. הסיר `paperclip-dev` מכל 14 הסוכנים, ודאג ש-`paperclip-converting-plans-to-tasks` קיים רק על CEO ו-analyst. תומך `--apply` (ברירת מחדל: dry-run). דורש `PAPERCLIP_BOARD_API_KEY`. נשמר לרפרנס למקרה שhdrift חוזר. | חד-פעמי (בוצע) | diff --git a/scripts/spec-guard.sh b/scripts/spec-guard.sh new file mode 100755 index 0000000..0092ace --- /dev/null +++ b/scripts/spec-guard.sh @@ -0,0 +1,53 @@ +#!/usr/bin/env bash +# spec-guard.sh — PreToolUse hook לאכיפת "פרוטוקול כתיבת-קוד" (CLAUDE.md). +# +# תפקיד: כשעורכים/כותבים קובץ-קוד (web/, mcp-server/, web-ui/src/, scripts/, adapters/), +# מזריק תזכורת ל-Claude לקרוא את docs/spec/ ולוודא קיום ה-invariants G1–G11 — לפני שכותבים. +# זוהי המקבילה האינטראקטיבית ל-INV-AG1 (שכבר אוכף על סוכני Paperclip ב-HEARTBEAT.md §"קריאת-ספ"). +# +# מנגנון: PreToolUse hook. קלט JSON ב-stdin (.tool_input.file_path), פלט JSON ל-stdout +# (hookSpecificOutput.additionalContext) — non-blocking, רק מזכיר. תמיד exit 0. +# Dedup: מזכיר פעם אחת בלבד לכל session (בכניסה הראשונה לכתיבת-קוד) כדי לא להציף. +# +# רישום: legal-ai/.claude/settings.json → hooks.PreToolUse (matcher "Edit|Write|MultiEdit"). +# תיעוד: scripts/SCRIPTS.md. + +set -uo pipefail + +# בלי jq אין מה לעשות — אל תחסום, צא נקי +command -v jq >/dev/null 2>&1 || exit 0 + +input="$(cat)" +file_path="$(printf '%s' "$input" | jq -r '.tool_input.file_path // empty' 2>/dev/null || true)" + +# בלי file_path (למשל Bash) — לא רלוונטי +[ -z "$file_path" ] && exit 0 + +# החרגות: תיעוד, markdown/טקסט/קונפיג-נתונים, בדיקות, artifacts — אלה לא "קוד הנדסי" +case "$file_path" in + *.md|*.markdown|*.txt|*.csv|*.lock) exit 0 ;; + */docs/*|*/tests/*|*/test/*|*/__pycache__/*|*/.venv/*|*/node_modules/*|*/.git/*|*/.next/*) exit 0 ;; +esac + +# כלילה: רק נתיבי-קוד אמיתיים +case "$file_path" in + */web/*|*/mcp-server/*|*/web-ui/src/*|*/scripts/*|*/adapters/*) : ;; + *) exit 0 ;; +esac + +# Dedup לכל session — מזכיר פעם אחת בלבד +session_id="$(printf '%s' "$input" | jq -r '.session_id // "nosession"' 2>/dev/null || echo nosession)" +marker="${TMPDIR:-/tmp}/.spec-guard-${session_id}" +[ -f "$marker" ] && exit 0 +: > "$marker" 2>/dev/null || true + +ctx="פרוטוקול כתיבת-קוד (CLAUDE.md §פרוטוקול כתיבת-קוד) — נוגעים בקובץ-קוד: ${file_path} +לפני השינוי ודא: +• קראת את docs/spec/00-constitution.md (ייעוד, G1–G11, אינדקס §7) + ספ-התחום הרלוונטי. +• השינוי מקיים את ה-invariants: אין מסלול מקביל ליכולת קיימת (G2), נרמול-במקור ולא תיקון-בקריאה (G1), אין בליעה שקטה של שגיאות (§6). +• בדקת מול docs/spec/gap-audit.md אם נוגעים ב-GAP/FU שכבר ממופה — להתאים, לא לפתור מחדש. +• ה-PR יצהיר אילו invariants (G*/INV-*) נגעת בהם / מקיים (ראה .gitea/PULL_REQUEST_TEMPLATE.md). +(תזכורת זו מופיעה פעם אחת בסשן.)" + +jq -n --arg ctx "$ctx" '{hookSpecificOutput:{hookEventName:"PreToolUse",additionalContext:$ctx}}' +exit 0