#!/bin/bash
# PreToolUse hook — 감사 미보고 시 Edit/Write/MultiEdit/Bash(git commit·push) 차단
# C35-9 Layer 3 개정 (2026-04-20 PD님 직접 지시 — 차단 + 해제 워크플로우)
# 근본 해결: "hook은 proxy" 자인 + LLM 자율 준수 한계 차단 층 추가
# 8회차 변종 재발 방지 (proxy 회피 반사·작업 유연성 명분 기각)

INPUT=$(cat 2>/dev/null)

# 1. tool_name 추출
TOOL_NAME=$(echo "$INPUT" | grep -oE '"tool_name"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*"\([^"]*\)"$/\1/')

# 2. 대상 tool 필터
SHOULD_GATE=0
case "$TOOL_NAME" in
  Edit|Write|MultiEdit) SHOULD_GATE=1 ;;
  Bash)
    CMD=$(echo "$INPUT" | grep -oE '"command"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1)
    if echo "$CMD" | grep -qE 'git[[:space:]]+(commit|push)'; then
      SHOULD_GATE=1
    fi
    ;;
esac
[ "$SHOULD_GATE" -eq 0 ] && exit 0

# 3. 의무 영역 식별 (auditor_guard 동일 로직)
TARGET=""
if echo "$INPUT" | grep -qE '"file_path"[[:space:]]*:[[:space:]]*"[^"]*(SKILL\.md|memory/org/feedback|조직공지|PD_지시_트래킹)[^"]*"'; then
  TARGET="의무 영역 파일"
elif echo "$INPUT" | grep -qE '"command"[[:space:]]*:[[:space:]]*"[^"]*git[[:space:]]+(commit|push)'; then
  TARGET="git commit/push"
fi
[ -z "$TARGET" ] && exit 0

# 4. M-1 수용: BYPASS 플래그 PreToolUse 차단 우회 불가
#    (BYPASS는 기존 PostToolUse 경고 메커니즘 전용, 본 차단은 무조건 체크)

# 5. 활성 매니페스트 존재 확인 (2026-05-06 (나) 채택 — main 워크트리 .claude/manifest/ 일괄 SOT)
# 2026-05-07 결함 1 패치: 다중 매니페스트 union 처리 (단일 매니페스트 의존 폐기)
GCD=$(git rev-parse --git-common-dir 2>/dev/null)
MAIN_ROOT=$(cd "$GCD/.." 2>/dev/null && pwd)
[ -z "$MAIN_ROOT" ] && MAIN_ROOT=$(git rev-parse --show-toplevel 2>/dev/null)
MANIFEST_DIR="$MAIN_ROOT/.claude/manifest/active"
mkdir -p "$MANIFEST_DIR" 2>/dev/null

# 활성 매니페스트 목록 (전수)
MANIFEST_COUNT=$(ls "$MANIFEST_DIR"/*.md 2>/dev/null | wc -l)

if [ "$MANIFEST_COUNT" -eq 0 ]; then
  cat >&2 <<EOF
🔒 [C35-9 차단] $TARGET 수정 전 감사 보고 필요

해결 절차:
  1. pm-auditor Task 호출 (집행 계획 사전 감사)
  2. bash scripts/manifest_register.sh <plan_id> <target_files_csv> <goal>
  3. 본 작업 재시도 → 차단 자동 해제

예시:
  bash scripts/manifest_register.sh "2026-04-20_$(date +%H%M%S)" "scripts/x.sh,SKILL.md" "안건 X 집행"

근거: C35-9 Layer 3 차단 + 해제 워크플로우 (2026-04-20 근본 해결)
BYPASS 플래그로는 우회 불가 (M-1 수용)
EOF
  exit 2
fi

# 6. 범위 체크 — Edit/Write/MultiEdit인 경우
if [ "$TOOL_NAME" != "Bash" ]; then
  FILE_PATH=$(echo "$INPUT" | grep -oE '"file_path"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*"\([^"]*\)"$/\1/')
  # 2026-05-06 (나) 채택 — main 워크트리 기준 상대 경로 (worktree 격리 회피)
  # Windows 경로 → POSIX 정규화 (git bash cygpath)
  FILE_PATH_NORM=$(cygpath -u "$FILE_PATH" 2>/dev/null || echo "$FILE_PATH")
  REF_ROOT="$MAIN_ROOT"
  [ -z "$REF_ROOT" ] && REF_ROOT=$(git rev-parse --show-toplevel 2>/dev/null)
  if [ -n "$REF_ROOT" ] && [ -n "$FILE_PATH_NORM" ]; then
    # 2026-05-07 결함 2 패치: -m (canonicalize-missing) 추가 — 신규 파일도 정상 상대 경로 추출
    REL=$(realpath -m --relative-to="$REF_ROOT" "$FILE_PATH_NORM" 2>/dev/null || echo "$FILE_PATH_NORM")
    # 2026-05-07 결함 3 패치: worktree prefix 자동 제거 — main repo 기준 매니페스트 target_files 정합
    REL="${REL#.claude/worktrees/*/}"
  else
    REL="$FILE_PATH_NORM"
  fi

  # target_files 목록에서 검색 (YAML frontmatter "  - " 형태)
  # 2026-05-07 결함 1 패치: 모든 활성 매니페스트 union 검색
  MATCHED_MANIFEST=""
  for MANIFEST_FILE in "$MANIFEST_DIR"/*.md; do
    [ -f "$MANIFEST_FILE" ] || continue
    if grep -qF "  - $REL" "$MANIFEST_FILE" 2>/dev/null; then
      MATCHED_MANIFEST="$MANIFEST_FILE"
      break
    fi
  done

  if [ -z "$MATCHED_MANIFEST" ]; then
    # 활성 매니페스트 목록 출력 (사용자 진단 보조)
    MANIFEST_LIST=$(ls "$MANIFEST_DIR"/*.md 2>/dev/null | xargs -n1 basename 2>/dev/null | sed 's/^/  - /')
    cat >&2 <<EOF
🔒 [C35-9 차단] 범위 이탈

대상 파일: $REL
활성 매니페스트 ${MANIFEST_COUNT}종 (모두 검색했으나 미매칭):
${MANIFEST_LIST}

해결:
  - 범위 확장 필요: manifest_register.sh 재호출 (신 plan_id 또는 기존 갱신)
  - 또는 해당 파일이 의도 밖이면 수정 취소
EOF
    exit 2
  fi
fi

# 통과
exit 0
