Files
legal-ai/scripts/spec-guard.sh
Chaim 7f4e036211 feat(spec): חיבור ספ-המערכת למסלול-הכתיבה האינטראקטיבי (אכיפה 3-שכבתית)
הספ (docs/spec/, G1–G11) חובר לסוכני Paperclip דרך INV-AG1 אבל לא למסלול
שבו רוב הקוד נכתב בפועל — הסשן האינטראקטיבי של Claude Code. סוגר את הפער
לפני מחזור-2 (FU-9..15), שהוא כולו כתיבת-קוד.

שלוש שכבות אכיפה:
1. תיעוד — CLAUDE.md §"פרוטוקול כתיבת-קוד" + docs/spec בטבלת-הייחוס
2. hook — scripts/spec-guard.sh (PreToolUse על Edit/Write/MultiEdit, רשום
   ב-.claude/settings.json) מזכיר פעם-בסשן בכל נגיעה בקובץ-קוד; non-blocking
3. PR — .gitea/PULL_REQUEST_TEMPLATE.md עם סעיף-חובה "Invariants"

המקבילה האינטראקטיבית ל-INV-AG1 שכבר אוכף על הסוכנים (HEARTBEAT §"קריאת-ספ").

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 13:28:15 +00:00

54 lines
2.9 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
# spec-guard.sh — PreToolUse hook לאכיפת "פרוטוקול כתיבת-קוד" (CLAUDE.md).
#
# תפקיד: כשעורכים/כותבים קובץ-קוד (web/, mcp-server/, web-ui/src/, scripts/, adapters/),
# מזריק תזכורת ל-Claude לקרוא את docs/spec/ ולוודא קיום ה-invariants G1G11 — לפני שכותבים.
# זוהי המקבילה האינטראקטיבית ל-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 (ייעוד, G1G11, אינדקס §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