quick-code-review

scripts/・.claude/hooks/・eslint-rules/・.claude/skills/ 配下のスクリプトを編集した直後の軽量レビュー。バグ・セキュリティ・ESLint で落とせない決まりの3観点だけをメインの会話で見て、その場で直す。「quick-code-review」「軽くコードチェックして」と指示されたとき。app/・infra/ は /code-review・/cdk-

SKILL.md

GitHub

Quick 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 を書き写さず、照合先を名指しして読む。

対象

  1. 対象ファイル:引数にファイルパスがあればそれを対象にする。無ければ、直前のターンで自分が 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 など)は、見ないことを伝える
  2. チェック範囲:git diff HEAD -- <対象ファイル> で差分を取る。差分があれば差分が生んだ欠陥だけを判定する。差分が無ければ(コミット済みで変更が無い、未追跡の新規ファイル等)、ファイル全文を判定する。
    • 読むのは差分を含む関数の全体と、変えた関数の呼び出し側。差分の外の行で壊れる欠陥も、原因が差分なら NG にする(例:戻り値を変えた結果、変えていない呼び出し側が壊れる/削除した null チェックのせいで後続の行が落ちる)
    • 書き換えた行は、変更前の行(-)に同じ欠陥が無いときだけ NG にする
  3. 決まりの照合先:拡張子で決まる。
    • .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)は照合しない。

チェック項目外の所見の扱い

上の項目に当たらない問題に気づいたら、直さずに報告の表の下へ書く。

出力と修正

  1. 全項目を判定する。
  2. NG があれば、確認を挟まずその場で Edit/Write を実行して直す。
  3. 全項目を次の表で報告する(OK・N/A の項目も含め全項目を出し、見落としを隠さない)。対象ファイルが複数あるときは、ファイルごとに表を出し、表の直前にファイルパスを書く。NG の行には、引用したコードと直した内容を書く。項目ごとに OK / NG / N/A を付けるが、重大度と、レビュー全体の合否(このレビューを通ったか)は付けない。
# 判定 該当箇所・コメント
1 OK / NG / N/A ...