Quartet / Quintet

2026-09-05  ·  claudecode · 設定 · json · 個人開発 · 運用

設定は書けているのに、何も起きない — .claude/ で黙って無視されるもの

hook を書きました。JSON は正しい。キー名も合っている。エラーも出ません。

何も起きません。

このとき困るのは、間違っている箇所が画面に出ないことです。 起動しても警告が出ず、--debug にも出ず、ただ動きません。

.claude/ の設定には、構文として正しく、意味として無効という状態がいくつかあります。 公式ドキュメントに「無視される」「動かない」と明記されているものを並べます。

1. matcher が黙って無視されるイベントがある

これは公式にそう書いてあります。

If you add a matcher field to an event without matcher support, it is silently ignored. — Hooks

silently ignored。 エラーになりません。

matcher を受け付けないイベントは、ドキュメントの表から拾うとこれだけあります。

CwdChanged, UserPromptSubmit, PostToolBatch, Stop, TeammateIdle,
TaskCreated, TaskCompleted, WorktreeCreate, WorktreeRemove, MessageDisplay

つまり、こう書いた場合。

{
  "hooks": {
    "UserPromptSubmit": [
      { "matcher": "Bash", "hooks": [{ "type": "command", "command": "./guard.sh" }] }
    ]
  }
}

matcher は消えます。 そして guard.shすべてのプロンプト送信で走ります。

書いた本人は「Bash のときだけ動く」と思っています。 実際には毎回動いていて、それに気づく手がかりがありません。

絞ったつもりが絞れていない、という向きの事故です。 動いていないより性質が悪い場合があります。

2. if は、ツール系のイベントでしか評価されない

if はツール名と引数をまとめて見る絞り込みです。

For tool events, you can filter more narrowly by setting the if field on individual hook handlers.

ツール系のイベントというのが条件です。ここに入るのは次の5つです。

PreToolUse, PostToolUse, PostToolUseFailure, PermissionRequest, PermissionDenied

それ以外のイベントで if を書くと、そのハンドラは決して動きません。

{
  "hooks": {
    "SessionStart": [
      { "hooks": [{ "type": "command", "command": "./init.sh", "if": "Bash(git *)" }] }
    ]
  }
}

SessionStart にツールはありません。条件が一致しようがないので、永久に走りません。

1 と 2 は向きが逆です。

書いたつもり 実際
matcher を無視 絞られている 毎回走る
if が評価されない 条件付きで走る 一度も走らない

どちらもエラーは出ません。

3. 非推奨のキーは、書けてしまう

古い記事や古い設定から引き継いだキーが、そのまま残っていることがあります。

書いてあるキー いま有効なもの
ignorePatterns permissions.deny
includeCoAuthoredBy attribution
disableArtifact enableArtifact(真偽が反転)
voiceEnabled voice.enabled

JSON としては正しいので、パースは通ります。

disableArtifact が厄介です。置き換え先で真偽が反転しています。 "disableArtifact": false を機械的に "enableArtifact": false へ書き換えると、 意味が逆になります。

4. ハンドラの必須フィールドは type ごとに違う

{ "type": "command" }

command がありません。何も起きません。

type ごとに要るものはこれだけ違います。

type 必須
command command
http url
mcp_tool server, tool
prompt prompt
agent prompt

type を書き換えたときに、前の type のフィールドが残るのがよくある形です。 command から http に変えて、command を消し忘れ、url を足し忘れる。

5. MCP のツール名は、プラグイン経由だと変わる

matcher を書いたのに一度も当たらない、という形です。

プラグインが同梱する MCP サーバーのツールは、名前にプラグイン名が入ります。

mcp__plugin_<プラグイン名>_<サーバー名>__<ツール名>

サーバー名だけで書いた matcher は、このツールには一生当たりません。

✗ mcp__db__.*                    プラグイン経由のものに当たらない
✓ mcp__plugin_my-plugin_db__.*

この種の失敗が厄介な理由

共通しているのは、失敗が観測できないことです。

書き間違い    → 起動時にエラー。すぐ直る
黙って無視    → 何も起きない。**動いていると思い込んだまま運用される**

そして hook は、動いていないことに気づきにくい種類の仕組みです。 「危険なコマンドを止める hook」を書いて、それが無効だった場合、 止まらなかった日まで気づきません。

設定ファイル自身は、これを教えてくれない

対処は外から検査するしかありません。 .claude/ を読んで、公式が「無視される」と書いているものだけを報告する 小さなツールを作りました。

$ ccheck
error .claude/settings.json  matcher on CwdChanged is silently ignored
      https://code.claude.com/docs/en/hooks
warn  .claude/settings.json  ignorePatterns is deprecated; use permissions.deny
      https://code.claude.com/docs/en/settings-reference

作るときに1つだけ制約を置きました。

公式ドキュメントに「エラーになる」「無視される」「スキップされる」と 明記されているものだけをルールにする。

だから全部の指摘に出典 URL が付いています。 出典を書けないルールは書きません。 それは私の好みであって、壊れてはいないからです。

この制約のせいで検査できないものが大量に残りました。 モデル名の妥当性、パスパターンの正しさ、未知のキー。 どれも「検査できたら便利そう」ですが、根拠が無いまま指摘すると誤検出になります。

そして検査ツールは、誤検出を1件出した時点で読まれなくなります。

MIT で公開しています。

https://github.com/quintetkit/ccheck

まとめ


あわせて読む


Claude Code に設計・実装・レビューを別々の人格として分担させ、GitHub Issue と ブランチを軸に並列開発を回すための設定一式を MIT で公開しています。 コピーして ./setup.sh を叩けば動きます。技術スタックには依存しません。

https://github.com/quintetkit/quartet

このワークフローだけで実際にツールを 1 つ作りました。Issue の分割から PR、 レビュー、マージまで記録が全部残っています。うまくいかなかった箇所も消していません。

https://github.com/quintetkit/mdlinkcheck

UI 設計人格・レビュー基準・Issue 単位の並列実行スクリプト・実践ガイド 10 章を 足したものは製品ページにあります。

実践ガイド全10章は Zenn Book で読めます(¥1,500・2章まで無料)。

https://zenn.dev/quintetkit/books/claude-code-parallel-workflow

設定一式(5人格・スクリプト・ガイド全文)の配布はこちらです。

https://quartet-dev.booth.pm/items/8807156

この運用そのものを配っています

4 人格版 Quartet は MIT で無料公開しています。UI 設計人格・レビュー基準・ Issue 単位の並列実行スクリプト・実践ガイド 10 章を足した Quintet は有料版です。

無料版を見る 製品ページ