AIが追加したパッケージ、そのまま入れてない? マージ前に見る3つの場所
金曜16時42分、lockfileを閉じたくなる
金曜の16時42分。管理画面から出力するファイル名の日付が、利用者の地域ではなくサーバーの時刻になる不具合を直していた。
AIコーディングエージェントへ状況を渡すと、数分で修正案が出た。日付を扱うパッケージを一つ追加し、ファイル名を組み立てる処理を書き換え、テストも増やしている。画面上の確認も通った。
差分の中心は十数行だった。ただ、lockfileには数百行の追加がある。lockfileは、実際に入るパッケージ名と版を記録するファイルだ。直接追加した一つだけでなく、そのパッケージが内部で使う別のパッケージも並ぶ。
内容を開いたものの、見慣れない名前が続き、目が滑った。定例報告まであと18分。「ここは自動生成だし、テストも通っている」「AIが選んだ定番なら大丈夫だろう」と考え、ファイルを閉じたくなった。
そこへレビュー担当者から、短いコメントが来た。
このパッケージは、既存の日付処理では足りませんでしたか?
すぐに答えられなかった。依頼したのは不具合修正で、パッケージ選定ではない。エージェントの説明には「タイムゾーンを安全に扱うため」とあったが、既存コードをどこまで調べたのか、自分では確認していなかった。
「一般的なパッケージなので問題ありません」と打ちかけて、消した。一般的かどうかも、最後の更新日も、誰が公開しているかも見ていない。質問に答えられない恥ずかしさから、コメントを閉じて先にマージしたくなる。一方で、知らないコードを本番へ入れる怖さも出てきた。😓
ここで、AIに任せたことまで失敗にしなくていい。AIは候補を速く出せる。人が戻るべき場所は、候補を出す工程ではなく、第三者のコードをこの先も使い続ける理由を引き受ける工程だ。
依存パッケージの追加は、数行の実装を借りるだけではない。更新、脆弱性対応、ライセンス、配布停止への対応も、プロジェクトの仕事に加わる。だから、コードが動いたかに加えて、必要性、増えるもの、配布元の3か所を見る。
1. 必要性: 何のために増やすのか
最初に見るのは、パッケージの評判ではない。今回の完了に本当に必要かだ。
AIへ「直して」とだけ頼むと、目的を達成するための道具も自由に選ぶ。短時間で確実に動かすには、専用パッケージを使う方が合理的なこともある。ただ、すでに同じ用途の道具が入っていたり、標準機能で十分だったりする場合もある。
追加前に、次の3点を一行ずつ置く。
- 目的: どの不具合や要件のために必要か
- 代替: 既存コード、標準機能、すでにあるパッケージではなぜ足りないか
- 外す条件: どの機能をやめたら削除できるか
金曜の修正では、目的は「利用者の地域に合わせた日付をファイル名へ入れる」だった。リポジトリ内を検索すると、別画面ですでに同じ変換を行う共通関数があった。今回の要件は、その関数で満たせる。
「新しいパッケージは危ないから使わない」と決めたわけではない。既存の一つで足りるのに、同じ役割を二つ持つ理由がなかった。目的を短く書くと、採用か見送りかを感覚ではなく説明できる。
2. 増えるもの: manifestとlockfileを分けて見る
必要だと分かったら、次は何がプロジェクトへ入るかを見る。
package.jsonのようなmanifestには、こちらが直接選んだパッケージが書かれる。lockfileには、その正確な版と、内部で使われるパッケージまで記録される。直接の追加が一つでも、実際に入るものは一つとは限らない。
GitHubのDependency reviewは、Pull Requestで追加、更新、削除された依存関係を見やすく表示する。版、公開時期、利用しているプロジェクト数、既知の脆弱性、ライセンスなどを確認できる。設定すれば、既知の脆弱性を含む依存追加を自動チェックで止めることもできる。
大きなlockfileを上から全部読むより、まず次の順で絞る。
- manifestで、直接追加した名前と版を確認する
- Dependency reviewで、内部から増えたものと既知の問題を確認する
- lockfileの元差分で、ツールが読み取れない変更や想定外の配布元がないか見る
ここで「脆弱性の警告がないから安全」とは決めない。警告は、すでに知られている問題を見つける助けだ。公開されたばかりの問題や、保守が止まったこと、名前のよく似た別パッケージを選んだことまでは、別に確かめる必要がある。
確認する量が多い時は、すべてを同じ重さで追わない。直接追加したもの、インストール時に処理を実行するもの、本番コードから使うものを先に見る。テスト用の道具と、本番で動く道具も分ける。🔍
3. 配布元: 誰のどの成果物を受け取るのか
最後は、パッケージ名の先を見る。
配布ページに書かれたリポジトリは実在するか。最近も保守されているか。公開されている版は、どのソースコードから、どの手順で作られたのか。似た名前やダウンロード数だけでは、ここは分からない。
npmのprovenanceは、公開されたパッケージが、どのソースコードとビルド手順から作られたかを確かめるための情報だ。npmの公式説明も、provenanceがあることは悪意のあるコードがない保証ではなく、出所をたどって信頼するか判断する材料だとしている。対応するパッケージでは、配布ページの表示やnpm audit signaturesで署名と出所の情報を確認できる。
OpenSSF Scorecardも、保守状況、コードレビュー、依存更新の仕組み、署名付きリリースなどを自動で確認する材料になる。一方、公式READMEは、点数が安全性の最終判定ではなく、誤検知や見落としもある目安だと明記している。
つまり、緑の印や高い点数を一つ見て終わりではない。
- 公式リポジトリと配布ページがつながっているか
- 直近の公開や保守が、今回の利用条件に合うか
- 出所を示す情報があるか。ない場合、何を根拠に採用するか
- 問題が出た時、更新するか、外すか、代替へ移るか
判断材料が足りない時は、すぐ却下しなくてもよい。「今回のPRでは追加せず調査を分ける」「本番では使わず検証環境に限る」と、影響を狭くできる。
月曜9時12分、レビューコメントへ理由を返せた
金曜は、マージを止めた。止めた直後は、「こんな小さな修正で時間を使っている」と落ち着かなかった。AIで速く進めたはずなのに、自分だけ後ろへ戻っているように感じた。
それでも、PRへ5行だけ残した。
- 目的: 利用者の地域に合わせた日付を出力ファイル名へ入れる
- 代替: 既存の共通関数で同じ変換ができる
- 増えるもの: 新規パッケージ1件と内部依存
- 配布元: 今回は採用しないため詳細調査を省略
- 判断: 依存追加を戻し、既存関数を使う
エージェントへ条件を渡し直すと、パッケージ追加を戻し、既存関数を使った修正へ変わった。テストはそのまま通った。月曜9時12分、レビュー担当者へ「既存関数で足りたため追加を見送りました」と返せた。
確認に使ったのは20分ほどだった。金曜の予定より遅れたことは変わらない。でも、返事を先延ばしにする重さは消えた。AIの提案を否定したのでも、自分の判断の遅さをごまかしたのでもない。目的に合う方を選び直しただけだ。🌱
別の案件なら、新しいパッケージを採用する結論もある。その時も、5行があれば「AIが選んだから」ではなく、必要性と影響を説明できる。採用後の更新担当や、問題が出た時の外し方も引き継ぎやすい。
AIで大きくなった差分をレビュー前に分ける方法では、変更の目的と危なさでPRを小さくする流れを整理している。AIで作ったPRを渡す時の説明も、採用理由を次の人へ渡す時に使える。
まず、今開いているPRのmanifestを見て、新しい名前がないか確認する。あれば「目的」「代替」「増えるもの」「配布元」「判断」を一行ずつ書く。空欄が残ったままなら、マージを急ぐ前に、その一か所だけ調べる。
AI時代のレビューは、生成されたコードを全部人力で書き直す仕事ではない。速く出た候補について、プロジェクトがこれから持ち続ける理由を言葉にする仕事だ。
ValueGateでは、AIが作った差分の確認場所、依存追加の判断記録、顧客やチームへ渡す説明を、実際の開発フローに合わせて一緒に整えている。速さを残しながら、理由を説明できる進め方を作ろう。