quick-code-review
scripts/・.claude/hooks/・eslint-rules/・.claude/skills/ 配下のスクリプトを編集した直後の軽量レビュー。バグ・セキュリティ・ESLint で落とせない決まりの3観点だけをメインの会話で見て、その場で直す。「quick-code-review」「軽くコードチェックして」と指示されたとき。app/・infra/ は /code-review・/cdk-
Files1
View on GitHubSKILL.md.claude/skills/quick-code-review/SKILL.md
GitHubQuick Code Review
/code-review はレンズごとに subagent を並列に起動するので重い。本スキルは下の「対象」に挙げたスクリプトを、バグ・セキュリティ・ESLint で落とせない決まりの3観点だけ、メインの会話で見て、その場で直す。
[!NOTE] (AI・必須) 対象のコードはコアドメインのアプリケーションコードではなく、保守性はあまり要らない。だから保守性の観点(設計の形・テスト)は削る。一方で正しさの観点は落とせない。
.claude/hooks/の危険コマンドを止めるガードでは、誤検知(#396)と、コマンドの語頭を読み違えるバグ(#399)が出ており、どちらも ESLint にも単体テストにも掛からなかった。バグとセキュリティの項目は、
code-reviewer-agentのバグ探し・セキュリティレンズと、/code-reviewの観点一覧(.claude/skills/code-review/references/review-criteria.md)が正(SSOT)だが、速度のため判定基準を書き下して自己完結させている(DRY より速度を優先した意図的な例外)。どちらかが改訂されたら、このチェック項目も追従して見直すこと。決まりの項目は Rule を書き写さず、照合先を名指しして読む。
対象
- 対象ファイル:引数にファイルパスがあればそれを対象にする。無ければ、直前のターンで自分が Edit/Write したファイルを対象にする。
- 対象:
scripts/の.mjs・.sh、.claude/hooks/とeslint-rules/の.mjs、.claude/skills/配下の.py・.sh・.js - 対象外:
app/・samples/app/のコードは/code-review、infra/・samples/infra/は/cdk-review、Markdown は/quick-doc-reviewを使うよう伝えて、そのファイルは見ない。上のどれにも当たらないファイル(.github/workflows/*.ymlなど)は、見ないことを伝える
- 対象:
- チェック範囲:
git diff HEAD -- <対象ファイル>で差分を取る。差分があれば差分が生んだ欠陥だけを判定する。差分が無ければ(コミット済みで変更が無い、未追跡の新規ファイル等)、ファイル全文を判定する。- 読むのは差分を含む関数の全体と、変えた関数の呼び出し側。差分の外の行で壊れる欠陥も、原因が差分なら NG にする(例:戻り値を変えた結果、変えていない呼び出し側が壊れる/削除した null チェックのせいで後続の行が落ちる)
- 書き換えた行は、変更前の行(
-)に同じ欠陥が無いときだけ NG にする
- 決まりの照合先:拡張子で決まる。
.mjs・.js:.claude/rules/typescript.mdの「命名規則」と、.claude/rules/code-comment.md(コメントの中身は、同ファイルが冒頭で思想の正として指すdocs/policy/code-comment-policy.mdで見る).sh・.py:当たる Rule が無いので、決まりの項目は N/A
チェック項目・判定基準
バグの項目(1〜6)は、「正しく動くことの確認」ではなく「どんな入力・順番で壊れるかの反証」を、1関数・1分岐ずつ問う。ただし欠陥が必ず潜んでいると仮定しない。探して見つからなければ OK でよい。
NG にしてよいのは、該当箇所のコードを引用できるときだけ。 記述が無いことが問題なら(エラー処理の欠落など)、欠落を確かめた範囲(関数全体など)を引用する。
| # | 観点 | 項目 | 判定基準 |
|---|---|---|---|
| 1 | バグ | 名前と実装の一致 | 関数・変数が名前どおりに動くか。名前から読める振る舞いと、実装の振る舞いが食い違えば NG(getUser が裏で更新している、isValid が値を書き換える、など)。名前の分かりやすさそのものは項目8で見る |
| 2 | バグ | 境界と異常値 | 実際に届きうる値——null/undefined/空配列/空文字/0/最大最小値/型境界——で、誤った結果を返す、または落ちる値を具体的に示せれば NG(off-by-one、0 を偽として扱う、空配列の集計など)。内部の関数どうしの引数への防御的チェックは求めない |
| 3 | バグ | 例外の経路 | throw されうる箇所から呼び出し元までの経路を追う。例外を握り潰す catch、失敗時に状態が半端に更新される経路、リソースが解放されない経路があれば NG。外部コマンドの失敗(終了コード)を見ずに先へ進む経路も含む(例:.sh で set -e を付けずに失敗の後も処理が続く、spawnSync の status を見ずに stdout を使う。execFileSync は終了コードが0以外なら throw するので、catch で握り潰さない限り当たらない)。エラーメッセージの中身は項目6で見る |
| 4 | バグ | 非同期の実害 | 非同期処理の順序・並列の扱いが原因で、結果が誤る、または処理が重複する経路を示せれば NG(実行順序の逆転・競合・二重実行・Promise.all の誤用=1つの失敗で残りの結果を捨てる、順序に依存する処理を並列にする) |
| 5 | バグ | 副作用と不変条件 | 引数・共有状態・イミュータブルであるべき値を想定外に書き換える、または呼び出し側が前提にしている不変条件(整列済み・重複なし・合計が一致する、など)を壊せば NG。副作用を名前が隠していることは項目1で見る |
| 6 | バグ | エラーハンドリング | 信頼境界から入る値(コマンドライン引数・環境変数・標準入力・gh などの外部コマンドの出力・読み込むファイル)の欠損・極値・型の逸脱について、扱いが決まっていない値・区分があれば NG(process.argv[2] が無いときに undefined のままパスを組み立てる、gh ... --json の出力が空配列のときの扱いが無い、など)。あわせて、エラーメッセージが原因を伝えなければ NG。境界を越えた後のロジックの誤りは項目2、例外の伝わり方は項目3で見る |
| 7 | セキュリティ | セキュリティ | 攻撃者の目で見て破れるか。機密の実値の埋め込み、インジェクションの余地(外から来た文字列をシェルやコマンドへ組み立てて渡す、.sh でクォートしない変数展開、など)があれば NG。危険な操作を止めるガードなら、判定をすり抜ける入力を示せれば NG(例:git の直後のオプションを読み飛ばさない判定が、git -C /tmp checkout -b new-feature を通す) |
| 8 | 決まり | 名前が中身を表すか | 照合先の「命名規則」に照らし、用途が名前から読み取れない、同じものを指す名前が揺れている、または規約に反する名前があれば NG |
| 9 | 決まり | コメントの中身 | 照合先に照らし、追加・変更したコメントごとに削除テストを問う(消したとき、読者は何を失うか。失うものが無ければ NG)。ポリシーに反するコメント(コードを読めば分かる WHAT を書いた実装コメント、名前を直せば消せるコメント、同じことを別の場所(同じファイルの別の行・README・別ファイルの冒頭コメント)でも書いているコメント、どの項目にも言えることを1項目にだけ書いたコメント、など)があれば NG。別の場所にあるかは、コメントの要点で Grep して確かめる。既にある書き方をまねたことは OK の理由にしない。ポリシーが求めるコメント(doc comment の契約など)が無ければ NG |
項目8・9では、ESLint が対象ファイルに掛けているルールで落ちる規約(禁止語の名前・コメントの記法など。どのルールがどのファイルに掛かるかは eslint.config.mjs)は照合しない。
チェック項目外の所見の扱い
上の項目に当たらない問題に気づいたら、直さずに報告の表の下へ書く。
出力と修正
- 全項目を判定する。
- NG があれば、確認を挟まずその場で Edit/Write を実行して直す。
- 全項目を次の表で報告する(OK・N/A の項目も含め全項目を出し、見落としを隠さない)。対象ファイルが複数あるときは、ファイルごとに表を出し、表の直前にファイルパスを書く。NG の行には、引用したコードと直した内容を書く。項目ごとに OK / NG / N/A を付けるが、重大度と、レビュー全体の合否(このレビューを通ったか)は付けない。
| # | 判定 | 該当箇所・コメント |
|---|---|---|
| 1 | OK / NG / N/A | ... |