69 lines
3.0 KiB
Plaintext
69 lines
3.0 KiB
Plaintext
|
|
#!/bin/bash
|
||
|
|
# PostToolUse hook (matcher: Edit|Write|MultiEdit|Bash) — 의무 영역 tool_use 시 호출 기록 검사
|
||
|
|
# C35-9 Layer 3: 의무 호출 누락 즉시 경고 + 무시 사례 UNRESOLVED 로그
|
||
|
|
# 2026-04-19 신설 — PD님 직접 지시 옵션 A (경고 모드)
|
||
|
|
# 관련: C35 의무 참여 체계 · C35-10 무시 사례 PD 보고 · C34-11 Agent 경계 보호
|
||
|
|
|
||
|
|
# 우회 검사 (2026-04-19 옵션 A: 파일 기반 BYPASS 우선, 환경변수 fallback)
|
||
|
|
# 근거: Claude Code tool_use hook 실행 환경에서 PM이 명령 prefix로 설정한 환경변수가
|
||
|
|
# 전달되지 않는 것이 실증됨 (2026-04-19 본 세션 11차 commit 실패 사례)
|
||
|
|
BYPASS_FLAG_FILE="$HOME/.claude/.nerdnavis_bypass_active"
|
||
|
|
BYPASS_REASON_FILE="$HOME/.claude/.nerdnavis_bypass_reason"
|
||
|
|
|
||
|
|
# 1. 파일 기반 BYPASS (권장)
|
||
|
|
if [ -f "$BYPASS_FLAG_FILE" ]; then
|
||
|
|
BYPASS_DIR="$HOME/.claude/.nerdnavis_bypass_log"
|
||
|
|
mkdir -p "$BYPASS_DIR" 2>/dev/null
|
||
|
|
BYPASS_LOG="$BYPASS_DIR/$(date +%Y-%m-%d).log"
|
||
|
|
REASON="(사유 미기록)"
|
||
|
|
[ -f "$BYPASS_REASON_FILE" ] && REASON=$(cat "$BYPASS_REASON_FILE" 2>/dev/null | head -c 500 | tr -d '\n')
|
||
|
|
echo "$(date +%Y-%m-%d_%H:%M:%S) BYPASS (file) reason=$REASON" >> "$BYPASS_LOG"
|
||
|
|
exit 0
|
||
|
|
fi
|
||
|
|
|
||
|
|
# 2. 환경변수 기반 BYPASS (fallback, Claude Code hook에 전달되는 경우만 작동)
|
||
|
|
if [ "${NERDNAVIS_AUDITOR_BYPASS:-0}" = "1" ]; then
|
||
|
|
BYPASS_DIR="$HOME/.claude/.nerdnavis_bypass_log"
|
||
|
|
mkdir -p "$BYPASS_DIR" 2>/dev/null
|
||
|
|
BYPASS_LOG="$BYPASS_DIR/$(date +%Y-%m-%d).log"
|
||
|
|
REASON="${NERDNAVIS_AUDITOR_BYPASS_REASON:-(사유 미기록)}"
|
||
|
|
echo "$(date +%Y-%m-%d_%H:%M:%S) BYPASS (env, may not trigger) reason=$REASON" >> "$BYPASS_LOG"
|
||
|
|
exit 0
|
||
|
|
fi
|
||
|
|
|
||
|
|
INPUT=$(cat 2>/dev/null)
|
||
|
|
|
||
|
|
# 의무 영역 식별
|
||
|
|
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
|
||
|
|
|
||
|
|
# 최근 30분 내 pm-auditor 호출 기록 검사
|
||
|
|
LOG_DIR="$HOME/.claude/.nerdnavis_auditor_calls"
|
||
|
|
RECENT_CALL=0
|
||
|
|
if [ -d "$LOG_DIR" ]; then
|
||
|
|
if find "$LOG_DIR" -type f -mmin -30 2>/dev/null | head -1 | grep -q .; then
|
||
|
|
RECENT_CALL=1
|
||
|
|
fi
|
||
|
|
fi
|
||
|
|
|
||
|
|
[ "$RECENT_CALL" -eq 1 ] && exit 0
|
||
|
|
|
||
|
|
# 경고 출력 (stderr)
|
||
|
|
echo "⚠️ [C35 경고] $TARGET — 최근 30분 내 pm-auditor 호출 기록 없음" >&2
|
||
|
|
echo " C35-1 의무 호출 대상일 수 있음. 응답 발신 전 pm-auditor Task 호출 권장" >&2
|
||
|
|
echo " 긴급 단발 지시면 export NERDNAVIS_AUDITOR_BYPASS=1 + NERDNAVIS_AUDITOR_BYPASS_REASON='사유' (C35-3·C35-10)" >&2
|
||
|
|
|
||
|
|
# UNRESOLVED 로그 기록 (이후 pm-auditor 호출되면 auditor_call_log.sh가 RESOLVED 마커 append)
|
||
|
|
WARNING_DIR="$HOME/.claude/.nerdnavis_warning_ignored"
|
||
|
|
mkdir -p "$WARNING_DIR" 2>/dev/null
|
||
|
|
WARNING_LOG="$WARNING_DIR/$(date +%Y-%m-%d).log"
|
||
|
|
echo "$(date +%Y-%m-%d_%H:%M:%S) UNRESOLVED target=$TARGET" >> "$WARNING_LOG"
|
||
|
|
|
||
|
|
exit 0
|