mcpField
C
cc-defensive-programming

cc-defensive-programming

github.com/ryanthedev開発38448 回インストール2 週間前に更新
リポジトリ

cc-defensive-programming について

防御的プログラミングの実践状況を確認し、一貫した適用を支援するスキルです。境界での入力検証、アサーションの使い分け、明示的なエラー処理を重視し、レビューと実装の両モードを備えます。

主な機能

  1. 01入力検証と例外処理の確認
  2. 02空の catch ブロックの検出
  3. 03アサーションと実行時処理の区別
  4. 04入力検証境界の設計
  5. 05一貫したエラー処理方針の適用

活用シーン

  1. 01防御的プログラミング違反のレビュー
  2. 02外部インターフェースへの検証追加
  3. 03アサーションとエラー処理規則の策定
  4. 04非同期処理の失敗対応の改善

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/ryanthedev/code-foundations --skill cc-defensive-programming

インストール後、Claude Code で/cc-defensive-programmingを入力して読み込まれたか確認します。

同梱ファイルchecklists.md

詳細

cc-defensive-programming

防御的なコードは、小さな失敗が積み重なって、気づきにくく診断困難な問題になるのを防ぎます。以下の4つのチェックでは、目立つクラッシュを起こすのではなく、データを破損させたりバグを隠したりする違反を検出します。いずれもほぼ常に必要です。例外を認める場合は、明確な正当化が必要です。

チェック理由
アサーション内に実行可能コードを置かないアサーションは本番ビルドではコンパイル時に除外されるため、コードも一緒に消えてしまいます
空の catch ブロックを作らないバグを黙って飲み込み、後続でより深刻な失敗を引き起こします
外部入力を受け取り時に検証する未検証の入力は、セキュリティ上の脆弱性やデータ破損につながります
アサーションはバグにのみ使う想定されるランタイムエラーには、アサーション(本番環境では無効化される)ではなく、エラー処理が必要です

共有のしきい値と情報隠蔽の根拠については、Read(${CLAUDE_PLUGIN_ROOT}/references/cc-foundations.md) を参照してください。

教科書のルールに優先する2つのルール

  • 「チーム内部の API」も外部として扱います。 ネットワークまたはプロセスの境界を越えるデータは、すべて外部入力です。自チームが所有するサービスからのデータであっても、検証してください。
  • バリケードによって冗長な検証を減らせますが、多層防御の代わりにはなりません。 バリケードの内側では、データが検証済みであると想定できます。ただし、セキュリティ上重要な経路(認証、暗号処理、PII)では、再度検証してください。バリケードの検証にもバグはあります。

外部入力とは、現在のコードパスによって制御されていると証明できないすべてのデータです。ユーザー入力、ファイル、ネットワーク/API/DB の応答、環境変数、その他のサービスからのデータが含まれます。

適用しない場合

  • 副作用のない純粋関数(ただし、システム境界では引き続き入力を検証してください)。
  • エラー対応の方針を決める前に、時間を区切って作成するプロトタイプ/スパイクコード。
  • テストコード。本番環境のパターンに意図的に従わないテストダブルを使用します。
  • アサーションのオーバーヘッドがプロファイリングで 5% を超える、パフォーマンスが重要な内部ループ。

上記にかかわらず、セキュリティ上重要なコード(認証、認可、暗号操作、PII の取り扱い)は、決して免除されません。迷った場合は、検証してください。

モード

CHECKER

防御的プログラミング、アサーション、例外処理のチェックリストに照らしてコードを確認します。Read(${CLAUDE_SKILL_DIR}/checklists.md) を参照してください。各項目につき1行を出力します:| Item | Status | Evidence | Location |。status は VIOLATION(検証の欠如、空の catch、副作用のあるアサーション)/WARNING(一貫性のない処理、ドキュメントの不足)/PASS のいずれかです。

APPLIER

アサーションの配置、エラー処理の方針、バリケードのアーキテクチャ、検証の実装を提示します。既存のエラー処理パターン(例外、戻りコード、Result 型、カスタム例外クラス、ログの規約など)をコードベースから探し、それに従ってください。エラー処理の一貫性が、失敗のデバッグを容易にします。完全なゲートについては、Read(${CLAUDE_PLUGIN_ROOT}/references/pattern-reuse-gate.md) を参照してください。

アサーションとエラー処理の使い分け

条件アサーションエラー処理
決して発生しないはずの状態(プログラマーのバグ)はいいいえ
ランタイムに発生する可能性がある/想定される不正な入力いいえはい
外部入力いいえはい — 必ず検証する
内部インターフェース、同一モジュール内はいいいえ
信頼境界を越える内部インターフェースはいはい
公開 API の事前条件違反はいはい
セキュリティ上重要/高い堅牢性が求められるシステム両方両方(多層防御)

条件が本当に曖昧な場合(「これはバグか、想定された動作か」)、推測せずにドメインエキスパートに要件を確認してください。

正確性と堅牢性

  • 正確性 — 不正確な結果は決して返しません。誤った回答を出すくらいなら停止します(安全性が重要なシステム、金融、データパイプライン)。
  • 堅牢性 — 結果がときどき不正確でも、動作を継続します(コンシューマー向けアプリ、社内ツール)。
分野重視するもの重要な問い
安全性が重要な分野(医療、航空)正確性—
エンタープライズ/B2B、金融、データパイプライン正確性誤ったデータが不適切なビジネス上の判断につながりますか? 下流のシステムはデータの完全性を前提としていますか?
SaaS プラットフォームバランス誤った回答の影響範囲と、利用不能による影響のどちらが大きいですか?
コンシューマー向けアプリ、社内ツール堅牢性ユーザーはクラッシュから復旧できますか?
リアルタイムシステム状況による古いデータは、データがない状態より望ましいですか、それとも望ましくないですか?

バリケード設計

  1. 外部インターフェース(ユーザー入力、ファイル、ネットワーク、API、サービス間呼び出し)を特定します。
  2. バリケードの境界に検証を配置し、すべての外部データをここでチェックします。
  3. バリケードの内側では、内部バグにアサーションを使います(データは検証済みであると想定します)。
  4. 方針:外部境界ではエラー処理、内部ではアサーションを使います。

クラスレベルのバリケード:パブリックメソッドは検証とサニタイズを行い、クラス内のプライベートメソッドは安全なデータを前提にできます。

エラー処理の方針

いずれかを選び、一貫して適用します。エラー処理はアーキテクチャ上の決定事項です。

方針用途
中立的な値を返す表示用のデフォルト値、重要度の低い設定
次に有効なデータに置き換える冗長性のあるストリーミングデータ/センサーデータ
前回の回答を返す表示の更新、重要度の低いキャッシュ(金融データでは決して使わない)
最も近い有効な値に置き換える入力値のクランプ、スライダーの範囲
警告をログに記録して続行する重要度の低い機能低下、機能フラグ
エラーコードを返すステータス規約のある API、C スタイルのインターフェース
集中型エラーハンドラー一貫したログ記録、監視との統合
エラーメッセージを表示するユーザー向けアプリ(セキュリティ情報を漏らさない)
正常にシャットダウンする安全性が重要なシステム、データを破損させるエラー

最新のエラー伝播

同期的な例外伝播は同期的なコールスタックを前提としています。次のパターンでは明示的な処理が必要です。

  • async/await — 未処理の拒否は Node をクラッシュさせます。await する呼び出しをラップし、ドメインレベルの例外を再スローします。
  • コールバック — エラーは伝播しません。エラーを先頭に置く callback(error, result) パターンを使うか、Promise でラップします。
  • Promise.all — 最初の拒否が発生すると、ほかの結果は失われます。allSettled を使い、全体を失敗とするか、一部の結果を許容するかを判断します。
  • イベントハンドラー/React — 同期的なスローは黙って握りつぶされます。明示的にログを記録し、レンダーエラーにはエラーバウンダリーを使います。

攻撃的プログラミング(開発ビルド)

開発中はエラーが早期に見つかるよう顕在化させ、本番環境では適切に復旧して目立たないようにします。手法:アサーションでプロセスを中断する、割り当てたメモリや解放済みオブジェクトをジャンクデータで埋める、default/else 節で即座に失敗させる、エラーログを自分宛てにメールする。

根拠

  • 「ゴミを入れればゴミが出る」は時代遅れです。製品版ソフトウェアは検証するか、データを拒否しなければなりません[McConnell p.188]。
  • エラー処理はアーキテクチャ上の決定事項であり、一貫して徹底されます[McConnell p.197]。
  • バグの修正コストは、設計時に比べて本番環境では約100倍になります[IBM Systems Sciences Institute]。
  • Mars Climate Orbiter は単位の不一致により失われました[NASA 1999]。9か月間の成功は、コードが安全であることを意味しません。

次のステップ

現在の状態次
検証完了Skill(code-foundations:cc-control-flow-quality)

コメント