Quartet / Quintet

2026-09-10  ·  claudecode · security · 設定 · 個人開発 · devops

書いた deny ルールが、一度も参照されていなかった

エージェントを1つのディレクトリの中に留めるつもりで、これを書いていました。

{ "permissions": { "deny": ["Write(src/generated/**)"] } }

構文は正しい。読み込まれる。そして一度も参照されません。

ファイルパスのルールが効くのは Read(...)Edit(...) だけです。 Write / NotebookEdit / Glob / 旧 MultiEdit に書いても、 受け付けられたうえで一度も見られません。

起動時に警告は出ます。私は起動時の出力を読んでいませんでした。 それまで一度も、そこに何か問題が出たことがなかったので。

これは安いほうです。高いほうを書きます。

Bash(git * main) は git の全サブコマンドを許す

Bash ルールの * は、その位置の文字列すべてに当たります。 だから * を前に置くほど、ルールは広くなります。

書き方 実際に許可されるもの
Bash(git log *) git log から始まるコマンド
Bash(git * main) git の全サブコマンド。 git push origin main も含む
Bash(* --version) そのマシンのあらゆるプログラム

Bash(git * main) は「main に対する git コマンド1つ」に読めます。 git push origin main が通ります。 git -c core.pager=… diff main も通り、-c は git に別のプログラムを起動させます。

私は Bash(git * main) を、diff を許したつもりで書いていました。

* がコマンドの途中にある allow ルールには、起動時に警告が出ます。 上と同じで、警告が流れていく間もルールは効いています。

空白1つで、lsof が許可されるかどうかが変わる

Bash(ls *)   当たる: ls -la, ls        当たらない: lsof
Bash(ls*)    当たる: ls -la, lsof

末尾の * の前の空白は、ルールの一部です。

そして Bash(ls *) が引数なしの ls にも当たるのは、 その末尾の * がそのルール唯一のワイルドカードのときだけです。 Bash(* --help *)npm --help x に当たり、npm --help には当たりません。

読み込まれて何もしないものが、あと3つ

アンカーの無い allow グロブはスキップされます。 allow に書いた "*" / "B*" / "mcp__*" は、何も自動承認しません。 allow でグロブが使えるのは mcp__<サーバ名>__ まで書いたあとだけです。 どのサーバかを名指ししている必要があるためです。

本体の入力へのパラメータ指定は無視されます。 Bash(command:rm *) は複合コマンドで抜けられるので、効きません。

Bash, PowerShell  → command        Grep, Glob   → path
Read, Edit, Write → file_path      WebFetch     → url
NotebookEdit      → notebook_path

Bash(rm *) / Read(./.env) / WebFetch(domain:host) と書きます。

括弧つきの mcp__ ルールは読み込み時にスキップされます。 mcp__memory(read) は効きません。 起動時のダイアログと claude doctor に出ますが、CI ではどちらも見えません。

もう1つは構文の罠です。Bash(ls:*)Bash(ls *) と同じですが、 末尾に置いたときだけ。 Bash(git:* push): はただの文字で、 何にも当たりません。

見た目より重い理由

エージェントを並列で走らせているなら、権限を落とすことが安全側の設計そのものです。 私の場合もそうでした。実装するエージェントは、Issue が宣言したファイルだけ触れる。

それを Write(...) のパス指定で表現していました。 頼っていた仕組みが、一度も参照されないほうでした。

実際に scope を守らせていたのは、Read / Edit のパス指定と、 Issue 本文に書いた宣言と、依頼文の書き方です。 どれも、荷重がかかっている部分として扱っていませんでした。

引いた教訓は「ドキュメントを読め」より狭いです。

何もしていない権限ルールは、効いているルールとまったく同じに見える。 どちらも黙っている。

設定を見る

npx @quintetkit/ccheck
warn  .claude/settings.json:14
      `Write(src/generated/**)` is accepted but never consulted. File path rules
      apply only to `Read(...)` and `Edit(...)`.
      why: https://code.claude.com/docs/en/permissions

この検査を作るとき、面白かったのはテストのほうでした。

ドキュメントに載っている文字列そのものを流します。 指摘が出るべき6件と、出てはいけない11件。 Read(./src/**/*.ts)Bash(ls*) を含みます。

11対6は意図的です。権限ルールは正しい書き方が多いので、 正しいものを「壊れている」と言うほうが起こりやすい失敗で、 誤検出を1件出したら出力全体が読まれなくなります。

5通りの全一覧(見た目と、実際に何をするか)はこちらです。

https://quintetkit.github.io/reference/claude-code-permission-rules.html


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

https://github.com/quintetkit/quartet

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

https://github.com/quintetkit/mdlinkcheck

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

実践ガイド全 11 章は 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 単位の並列実行スクリプト・実践ガイド 11 章を足した Quintet は有料版です。

無料版を見る 製品ページ