#!/usr/bin/env python # -*- coding: utf-8 -*- """auditor_gate.sh 보조 — 셸 도구(Bash·PowerShell) 명령에 git commit/push 가 있는지 판정 (C35-9 Layer 3) grep 추출은 JSON 문자열의 이스케이프 따옴표에서 잘리고, `git` 바로 뒤에 commit|push 가 올 때만 잡아 `git -C <레포> commit` · `cd "x" && git commit` · PowerShell 경유 commit/push 를 놓쳤다 (2026-09-16 pm-auditor Critical — ImmortalSword 세션 대화로그 §3). stdin : PreToolUse hook JSON stdout: "1" = 게이트 대상 / "0" = 아님 exit 3: JSON 파싱 실패 (호출부가 grep 폴백으로 판정) """ import io import json import re import sys GIT_COMMIT_PUSH = re.compile( r"""(?:^|[\s;&|(`{])git(?:\.exe)? # git 실행 토큰 (연쇄·파이프·서브셸 뒤 포함) (?:\s+(?:-C\s+(?:"[^"]*"|'[^']*'|\S+) # -C <경로> (대소문자 무시라 -c key=value 도 여기서 소비) |--[\w-]+(?:=(?:"[^"]*"|'[^']*'|\S+))? # --git-dir=... · --no-pager 등 |-\w+))* # 기타 전역 플래그 \s+(?:commit|push)\b""", re.IGNORECASE | re.VERBOSE, ) def main(): raw = sys.stdin.buffer.read().decode("utf-8", errors="replace") try: data = json.loads(raw) except Exception: sys.exit(3) tool = data.get("tool_name", "") cmd = (data.get("tool_input") or {}).get("command") or "" hit = tool in ("Bash", "PowerShell") and bool(GIT_COMMIT_PUSH.search(cmd)) sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8") sys.stdout.write("1" if hit else "0") if __name__ == "__main__": main()