ClaudeMods
☰
JA
● 0 人がオンライン ・閲覧 0 回
スポンサー作品を投稿
GitHub リポジトリ · 投稿者 myaji35

harness-guard

既存の Harness PreToolUse ガードを関数フックとしてシャドー実行または強制実行する

myaji35@myaji35

myaji35/GH_Harness/tree/main/mods/harness-guard

翻訳済み

この mod について

harness-guard mod

5 つの既存 PreToolUse shell フックを関数フックに置き換える Claude Code 2.1.289 版です。tool.call ハンドラーを 1 つ登録します。デフォルトの 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、shell へのパイプ、sudo rm を Bash でブロックします。強制 push、hard reset、クリーンアップ、SQL 削除、デプロイ削除、公開には警告/T2 パターンを使います。HARNESS_SANDBOX_BYPASS=1/2 では shell の意味を保ちます。 | | 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"}}}}

シャドーログを比較している間は既存の shell フックをインストールしたままにします。シャドーのヘルススコアと回帰比較には .claude/knowledge-db/health-history.mod-shadow.jsonl を使い、shell health-gate は .claude/knowledge-db/health-history.jsonl を使い続けます。enforce に切り替えるときは、enforce モードが共有履歴ファイルを使うため、shell の health-gate.sh フックも同時に無効にします。戻すにはこの mod を無効にするか --plugin-dir を削除し、無効にしていた shell health-gate を再び有効にします。

検証

test/capture-expected.sh は一時 git リポジトリを作成し、stdin JSON で各実際の shell フックを実行して、test/fixtures.json(source: shell)に 38 件の fixture 判定を記録します。test/fixtures.ts は同じキャプチャーから生成されます。JSON モジュールを import できない Claude Code テストランナー向けです。テストは各 fixture と mod 対応の判定関数を比較します。CLI が ._* AppleDouble ファイルをテストと誤認するため、テストコマンドの前にそれらを無視して削除します。

既知の相違点

  • 従来の sandbox フックはトップレベルの command フィールドを想定しますが、他のフックは tool_input エンベロープを読みます。Sandbox fixture はスクリプトのトップレベル形式を使います。mod は e.command を直接見るため危険なコマンドを一貫して検出しますが、エンベロープ付きの従来の呼び出しでは見逃す可能性があります。
  • 完全な判定を 10 秒未満に収めるため、mod はヘルスチェックに 5 秒のサブ予算を使い、プロセスごとに 1.2 秒の上限を設けます。shell worker は全体で 45 秒、各チェックで 20 秒を許可します。そのため、遅いチェックはスキップまたはタイムアウトになり、異なるスコアになることがあります。
  • 提供されている Claude Code API 型は $.fs.read と $.fs.write を公開していますが、append メソッドはありません。シャドーログとヘルス履歴は $.fs.write で読み書きし直すため、同時に動く Claude セッションでは追加した行が失われる可能性があります。Shell append はファイルディスクリプター単位でアトミックです。シャドーのヘルス履歴は shell ファイルとは別で、shell ファイルを読み書きするのは enforce モードだけです。
  • enforce モードでは拒否する前に request-user-confirm.sh を WARN+T2 に対して呼び出します。Shell sandbox も block/warn イベントで decision-trace.sh を呼びますが、mod は代わりに JSONL の判定記録を使うため、従来の trace 行は追加しません。shell と mod の両方が有効だと、T2 ヘルパーが 2 回呼ばれることがあります。
  • Shell の source は凍結ファイル内の任意コードを受け付けます。mod はリテラルの FREEZE_DIR と FREEZE_ISSUE の代入を読むため、生成された凍結ファイルをカバーしつつ任意の shell コードは実行しません。
  • Write/Edit の tool.call 完了後に、ツール後の secret 警告を再現します。既存の PostToolUse shell フックも有効なままだと、警告が 2 回表示されることがあります。

内部エラーは警告として記録され、そのまま通ります。元の freeze、secret、health フックも解析/チェック失敗時には通します。sandbox の set -e は一部のホストコマンド失敗で非ゼロ終了することがあります。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.

関連作品