#!/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

# ── G12 leak-guard (INV-G12 / docs/spec/X15) — warn at write-time ──────────────
# PreToolUse fires BEFORE the edit, so we inspect the CONTENT being written
# (new_string / content), not the file on disk — this catches a Paperclip symbol
# being introduced into the intelligence layer right now. NOT session-deduped:
# every such write should warn. The hard gate is the CI fitness-test
# (mcp-server/tests/test_platform_port_leak_guard.py via scripts/leak_guard.py).
leak_warn=""
case "$file_path" in
  */mcp-server/src/*)
    new_content="$(printf '%s' "$input" | jq -r '.tool_input.new_string // .tool_input.content // empty' 2>/dev/null || true)"
    if printf '%s' "$new_content" | grep -qE 'paperclip|Paperclip|PAPERCLIP|wakeup|heartbeat|HEARTBEAT|pc_request|pc\.sh|X-Paperclip|agent_wakeup|heartbeat_run|ctx\.agents|issueId'; then
      leak_warn="⚠️ G12 (שער-הפלטפורמה) — התוכן שאתה כותב ל-${file_path} (שכבת-האינטליגנציה) מכיל מונח ספציפי-Paperclip. אסור (INV-G12): נתב מגע-פלטפורמה דרך web/agent_platform_port.py. אם זו הערת-מקור בלבד — הוסף רשומה מנומקת ל-allowlist ב-scripts/leak_guard.py, אחרת ה-CI (test_platform_port_leak_guard) ייכשל. ראה docs/spec/X15-agent-platform-port.md.
"
    fi
    ;;
esac

# Dedup לכל session — תזכורת-הספ מופיעה פעם אחת בלבד (אזהרת-leak אינה deduped)
session_id="$(printf '%s' "$input" | jq -r '.session_id // "nosession"' 2>/dev/null || echo nosession)"
marker="${TMPDIR:-/tmp}/.spec-guard-${session_id}"
spec_ctx=""
if [ ! -f "$marker" ]; then
  : > "$marker" 2>/dev/null || true
  spec_ctx="פרוטוקול כתיבת-קוד (CLAUDE.md §פרוטוקול כתיבת-קוד) — נוגעים בקובץ-קוד: ${file_path}
לפני השינוי ודא:
• קראת את docs/spec/00-constitution.md (ייעוד, G1–G12, אינדקס §7) + ספ-התחום הרלוונטי.
• השינוי מקיים את ה-invariants: אין מסלול מקביל ליכולת קיימת (G2), נרמול-במקור ולא תיקון-בקריאה (G1), שער-הפלטפורמה (G12 — Paperclip רק דרך agent_platform_port.py), אין בליעה שקטה של שגיאות (§6).
• בדקת מול docs/spec/gap-audit.md אם נוגעים ב-GAP/FU שכבר ממופה — להתאים, לא לפתור מחדש.
• ה-PR יצהיר אילו invariants (G*/INV-*) נגעת בהם / מקיים (ראה .gitea/PULL_REQUEST_TEMPLATE.md).
(תזכורת זו מופיעה פעם אחת בסשן.)"
fi

ctx="${leak_warn}${spec_ctx}"
[ -z "$ctx" ] && exit 0
jq -n --arg ctx "$ctx" '{hookSpecificOutput:{hookEventName:"PreToolUse",additionalContext:$ctx}}'
exit 0
