ClaudeMods
☰
KO
● 0 명 접속 중 · 조회 0 회
후원프로젝트 제출
GitHub 저장소 · 작성자 myaji35

harness-guard

기존 Harness PreToolUse 가드를 함수 훅으로 섀도 실행하거나 강제 실행합니다

번역 완료

이 mod 소개

harness-guard mod

기존 PreToolUse 셸 훅 5개를 함수 훅으로 옮긴 Claude Code 2.1.289 버전입니다. tool.call 핸들러 하나를 등록합니다. 기본 shadow 모드는 각 호출을 평가하고 판정, 이유, 경과 밀리초를 ~/.claude/harness-core/logs/mod-guard-shadow.jsonl에 기록한 다음 next(e)를 호출합니다. enforce는 거부 판정에 { deny: message }를 반환하고, 그 외에는 next(e)를 호출합니다. 이 모드에서는 RTK 재작성 결과가 next로 전달됩니다.

| 기존 훅 | 옮겨진 규칙 | | --- | --- | | freeze-guard.sh | Write/Edit에서 동결 파일이 존재하는 동안 FREEZE_DIR 바깥 경로를 차단합니다. 레지스트리에 issue가 있는 동결은 IN_PROGRESS 또는 BACKGROUND_RUNNING일 때만 활성 상태입니다. | | sandbox-enforce.sh | 위험한 삭제, 파괴적인 장치 쓰기, 안전하지 않은 chmod, 셸로 파이프하기, sudo rm을 Bash에서 차단합니다. 강제 push, hard reset, 정리, SQL 삭제, 배포 삭제, 게시에는 경고/T2 패턴을 사용합니다. HARNESS_SANDBOX_BYPASS=1/2는 셸 의미를 유지합니다. | | secret-guard.sh | git commit 또는 git push가 포함된 Bash 명령에서 먼저 스테이징된 파일 이름을 검사한 뒤 추가된 diff 줄을 검사하며, 테스트/spec 경로와 자리 표시자 값은 제외합니다. Write/Edit가 끝난 후 편집한 파일에 secret이 있으면 경고합니다. | | rtk-guard.sh | 지원될 가능성이 있는 명령의 재작성을 rtk hook claude에 요청합니다. RTK가 없거나 실패하면 그대로 통과시킵니다. | | health-gate.sh | 레지스트리가 있는 commit에서 사용 가능한 typecheck, tsc, lint, Rubocop, TODO 검사를 실행하고 점수 이력을 기록합니다. 점수가 최소 5점 떨어질 때만 경고합니다. |

설정

claude --plugin-dir mods/harness-guard로 불러옵니다. 기본값은 shadow입니다. 강제 실행하려면 사용자 설정(~/.claude/settings.json)에 설정을 넣거나 /config에서 Guard mode → enforce를 선택합니다.

{"pluginConfigs":{"harness-guard":{"options":{"mode":"enforce"}}}}

섀도 로그를 비교하는 동안 기존 셸 훅을 설치한 상태로 유지합니다. 섀도 상태 점수와 회귀 비교에는 .claude/knowledge-db/health-history.mod-shadow.jsonl을 사용하고, 셸 health-gate는 계속 .claude/knowledge-db/health-history.jsonl을 사용합니다. enforce로 전환할 때는 enforce 모드가 공유 기록 파일을 사용하므로 셸의 health-gate.sh 훅도 동시에 비활성화합니다. 되돌리려면 이 mod를 비활성화하거나 --plugin-dir를 제거하고, 비활성화했던 셸 health-gate를 다시 활성화합니다.

검증

test/capture-expected.sh는 임시 git 저장소를 만들고 stdin JSON으로 각 실제 셸 훅을 실행하여 test/fixtures.json(source: shell)에 fixture 판정 38개를 기록합니다. test/fixtures.ts는 같은 캡처에서 생성되며 JSON 모듈을 가져올 수 없는 Claude Code 테스트 러너에서 사용합니다. 테스트는 각 fixture를 mod의 해당 판정 함수와 비교합니다. CLI가 ._* AppleDouble 파일을 테스트로 잘못 인식하므로 테스트 명령 전에 이를 무시하고 삭제합니다.

알려진 차이

  • 기존 sandbox 훅은 최상위 command 필드를 요구하지만 다른 훅은 tool_input 봉투를 읽습니다. Sandbox fixture는 스크립트의 최상위 형식을 사용합니다. mod는 e.command를 직접 보기 때문에 위험한 명령을 일관되게 감지하지만, 봉투가 있는 기존 호출은 놓칠 수 있습니다.
  • 전체 판정을 10초 안에 끝내기 위해 mod는 상태 점검에 5초 하위 예산을 사용하고 프로세스마다 1.2초 제한을 둡니다. 셸 worker는 전체 45초와 검사별 20초를 허용합니다. 따라서 느린 검사는 건너뛰거나 시간 초과되어 다른 점수가 나올 수 있습니다.
  • 제공된 Claude Code API 타입은 $.fs.read와 $.fs.write를 노출하지만 append 메서드는 없습니다. 섀도 로그와 상태 기록은 $.fs.write로 읽고 다시 쓰므로 Claude 세션이 동시에 실행되면 추가된 줄이 사라질 수 있습니다. 셸 append는 파일 디스크립터 수준에서 원자적입니다. 섀도 상태 기록은 셸 파일과 별개이며, 셸 파일을 읽고 쓰는 것은 enforce 모드뿐입니다.
  • enforce 모드에서 mod는 거부하기 전에 WARN+T2에 대해 request-user-confirm.sh를 호출합니다. 셸 sandbox도 block/warn 이벤트에 decision-trace.sh를 호출하지만 mod는 대신 자체 JSONL 판정 기록을 사용하므로 기존 trace 줄을 추가하지 않습니다. 셸과 mod가 모두 활성화되어 있으면 T2 도우미가 두 번 호출될 수 있습니다.
  • 셸 source는 동결 파일의 임의 코드를 허용합니다. mod는 리터럴 FREEZE_DIR 및 FREEZE_ISSUE 할당을 읽으므로 생성된 동결 파일을 처리하면서 임의 셸 코드를 실행하지 않습니다.
  • Write/Edit의 tool.call이 끝난 뒤 도구 후 secret 경고를 재현합니다. 기존 PostToolUse 셸 훅이 계속 활성화되어 있으면 경고가 두 번 나타날 수 있습니다.

내부 오류는 경고로 기록하고 통과시킵니다. 원래 freeze, secret, health 훅도 파싱/검사 실패 시 통과시키며, sandbox의 set -e는 일부 호스트 명령 실패에서 0이 아닌 상태로 종료될 수 있습니다. mod의 제한된 파일 시스템/프로세스 호출은 예상되는 파일 없음 또는 명령 없음 오류를 포착하며, 이런 실패 때문에 차단하지 않습니다.

설치

먼저 작성자의 README에서 marketplace와 플러그인 이름을 확인하세요. 저장소 구조에 따라 명령어가 달라질 수 있습니다.

claude plugin marketplace add myaji35/GH_Harness
claude plugin install harness-guard
원문 / README

harness-guard mod

Claude Code 2.1.289 function-hook version of five existing PreToolUse shell hooks. It registers one tool.call handler. The default shadow mode evaluates each call, writes its verdict, reasons, and elapsed milliseconds to ~/.claude/harness-core/logs/mod-guard-shadow.jsonl, then calls next(e). enforce returns { deny: message } for deny decisions and otherwise calls next(e); RTK rewrites are passed to next in that mode.

| Existing hook | Ported rule | | --- | --- | | freeze-guard.sh | On Write/Edit, block a path outside FREEZE_DIR while the freeze file exists. A freeze with an issue in the registry is active only for IN_PROGRESS or BACKGROUND_RUNNING. | | sandbox-enforce.sh | Bash block patterns for dangerous deletion, destructive device writes, unsafe chmod, pipe-to-shell, and sudo rm; warning/T2 patterns for force push, hard reset, cleanup, SQL deletion, deployment deletion, and publishing. HARNESS_SANDBOX_BYPASS=1/2 keeps the shell semantics. | | secret-guard.sh | On Bash commands containing git commit or git push, inspect staged filenames first, then added diff lines, excluding test/spec paths and placeholder values. After Write/Edit completes, warn about a secret in the edited file. | | rtk-guard.sh | Ask rtk hook claude for a rewrite of likely supported commands; pass through if RTK is absent or fails. | | health-gate.sh | On commit with a registry, run available typecheck, tsc, lint, Rubocop, and TODO checks, record score history, and warn only if the score drops at least five points. |

Configuration

Load with claude --plugin-dir mods/harness-guard. The default is shadow. To enforce, put this in user settings (~/.claude/settings.json), or choose Guard mode → enforce in /config:

{"pluginConfigs":{"harness-guard":{"options":{"mode":"enforce"}}}}

Keep the existing shell hooks installed while comparing shadow logs. Shadow health scores and regression comparisons use .claude/knowledge-db/health-history.mod-shadow.jsonl; the shell health-gate continues using .claude/knowledge-db/health-history.jsonl. When switching to enforce, disable the shell health-gate.sh hook at the same time, since enforce mode uses the shared history file. To roll back, disable this mod or remove its --plugin-dir, then re-enable the shell health-gate if it was disabled.

Verification

test/capture-expected.sh creates a temporary git repository, executes each real shell hook with stdin JSON, and records 38 fixture verdicts in test/fixtures.json (source: shell). test/fixtures.ts is generated from the same capture for the Claude Code test runner, which cannot import JSON modules. The test compares every fixture with the mod's corresponding decision function. ._* AppleDouble files are ignored and removed before test commands because the CLI otherwise mistakes them for tests.

Known differences

  • The classic sandbox hook expects a top-level command field while the other hooks read a tool_input envelope. Sandbox fixtures use the script's top-level shape. The mod sees e.command directly, so it detects dangerous commands consistently; a classic call with an envelope can miss them.
  • The mod uses a 5-second sub-budget for health checks and 1.2-second per-process caps to keep the complete decision below 10 seconds. The shell worker allows 45 seconds overall and 20 seconds per check. A slow check can therefore be skipped or timed out and yield a different score.
  • The supplied Claude Code API type exposes $.fs.read and $.fs.write, but no append method. Shadow logs and health history are read and rewritten with $.fs.write; simultaneous Claude sessions can lose an appended line. Shell append is atomic at the file descriptor level. Shadow health history is separate from the shell file; only enforce mode reads and writes the shell file.
  • In enforce mode the mod calls request-user-confirm.sh for WARN+T2 before denying. The shell sandbox also calls decision-trace.sh for block/warn events; the mod uses its JSONL decision record instead, so it does not add a legacy trace line. While both shell and mod are enabled, the T2 helper can be called twice.
  • Shell source accepts arbitrary code in freeze files. The mod reads literal FREEZE_DIR and FREEZE_ISSUE assignments, which covers generated freeze files without executing arbitrary shell code.
  • The post-tool secret warning is reproduced after a Write/Edit tool.call completes. While the existing PostToolUse shell hook remains enabled, the warning can appear twice.

An internal error is recorded as a warning and passed through. The original freeze, secret, and health hooks also pass on parse/check failures; sandbox's set -e can exit nonzero for some host command failures. The mod's narrow filesystem/process calls catch expected missing-file or missing-command errors and do not block on those failures.

비슷한 프로젝트