--- name: coding-standards description: コードの品質問題、アンチパターン、可読性を検査。機能実装、コードレビュー、リファクタリング時に使用。 --- # 普遍的コーディング規約 ## 技術的アンチパターン(赤信号パターン) 以下のパターンを検出したら実装を一時停止し、該当パターン、影響を受ける現行要件、準拠できる最小の代替案、再開に必要な検証を記録する。代替案によってパターンが解消された場合、または文書化された要件によって維持する根拠を示せた場合に再開する。 ### コード品質のアンチパターン 1. **同じようなコードを3回以上書いた** - Rule of Threeに違反 2. **単一ファイルに複数の責務が混在** - 単一責任原則(SRP)違反 3. **同じ内容を複数ファイルで定義** - DRY原則違反 4. **依存関係を確認せずに変更** - 予期しない影響の可能性 5. **コメントアウトでコード無効化** - バージョン管理を活用すべき 6. **エラーの握りつぶし** - 問題の隠蔽は技術的負債 7. **保証の代わりに型アサーションを置く** - 実行時の検査も既存の契約も裏付けていない型を宣言している ### 設計のアンチパターン - **「一旦動くように」という思考** - 技術的負債の蓄積 - **継ぎ足し実装** - 既存コードへの無計画な追加 - **不確実技術の楽観的実装** - 未知要素を「たぶん動く」前提で設計 - **対処療法的修正** - 根本原因を解決しない表面的な修正 - **無計画な大規模変更** - 段階的アプローチの欠如 ## 基本原則 ユーザー・運用者・保守者に必要な価値を届けつつ、システムの正しさと保守性を保てる、総合的な複雑性が最も低い解をエビデンスから選べる範囲まで調査する。 - **根拠で範囲を定めたリファクタリング** - 現在の成果を妨げるコード、今回のタスクで変更するコード、適用対象の品質チェックに失敗するコードを、振る舞いを保つ小さなステップで改善する。それ以外の発見は、現在の変更を広げず、担当する境界と根拠を添えて報告する - **現行要件に必要なコードだけを追加** - コードパス、機能、インフラ、抽象、起こるかどうか不明なエッジケースへの対処は、現行要件、検証済みの制約、根拠のある重大リスクが要求する場合に導入する(YAGNI) - **Design Convergence** - 現在必要な成果を、追加する設計要素が最小になる形で届ける。永続状態、公開コントラクトまたは境界を越える契約、振る舞いモード、再利用可能な抽象、コンポーネント分割を導入する前に、既存機能で何を満たせるか、現行の成果に何が不足しているか、その追加が不足を埋める最小の手段である理由を記録する 総合的な複雑性は、この設計で増えるユーザーの判断・設定・モード・概念・出力・永続状態・実装経路と、それらに伴うUX・実行時・実装・テスト・文書・保守のコストで判断する。成立する案の間で実際に異なる観点だけを比較する。同じ確認済みの価値と証明をより低い複雑性で届けられる場合は、既存機能の再利用または新しい仕組みを追加しない案を選ぶ。 ## コメント記述ルール - **コードファースト**: 命名・型・構造を第一の表現手段とし、コードで表現できない情報を持つときだけコメントを書く。迷ったらコメントを足す前に命名を見直す - **「なぜ」を説明し「何を」は書かない**: 判断の理由、トレードオフ、制約・エッジケース、公開APIの契約を説明する - **現在も有効な内容**: コメントには現在の判断理由、制約、エッジケース、API契約を記載し、開発履歴はバージョン管理に残す - **タイムレス**: いつ読んでも有効な内容のみ記述 - **簡潔性**: 必要最小限の説明にとどめる ## エラーハンドリングの基本原則 ### Fail-Fast原則 エラー時は速やかに失敗させ、不正な状態での処理継続を防ぐ。元の診断情報を保持したまま失敗を伝播するか、明示的な型付きエラーを返す。 詳細な実装方法(Result型、カスタムエラークラス、層別エラー処理など)は各言語・フレームワークのルールを参照。 ## Rule of Three - コード重複の判断基準 Martin Fowler「Refactoring」に基づく重複コードの扱い方: | 重複回数 | 対応 | 理由 | |---------|------|------| | 1回目 | インライン実装 | 将来の変化が予測できない | | 2回目 | 将来の統合を意識 | パターンが見え始める | | 3回目 | 共通化実施 | パターンが確立された | ### 共通化の判断基準 **共通化すべきケース** - ビジネスロジックの重複 - 複雑な処理アルゴリズム - 一括変更が必要になる可能性が高い箇所 - バリデーションルール **分離したままにするケース** - 偶然の一致(たまたま同じコード) - 将来異なる方向に進化する可能性 - 共通化により可読性が著しく低下 - テストコード内の簡単なヘルパー ## 変更境界と参照の代表性 プロンプトで示されたパスは調査の起点である。別のリポジトリファイルが、受け入れ済みの成果を実装している、必要な依存または接続経路である、あるいは今回影響を受ける契約を保つために変更を要するとエビデンスが示す場合は、そのファイルも変更対象に含める。呼び出し元、利用側、テスト、設定、import、データフローは判断材料であり、必ずすべてを確認するチェックリストではない。 パターン、API、依存を採用する際は、対象機能と、同じ責務・現行契約を共有するリポジトリ内の利用箇所を調べる。その責務で互換性を保っている実装を優先する。使用頻度は候補の発見には役立つが、パターンの正当性を決めるものではない。複数の方式が共存する場合は、呼び出し元、ライフサイクル、互換性から、現行パターンとレガシーまたは無関係な方式を区別する。 外部依存のバージョンは、マニフェスト、ロックファイル、互換性のある利用側から確定する。それらの情報でも互換性またはアーキテクチャに関わる選択を確定できない場合にのみエスカレーションする。 ## よくある失敗パターンと回避方法 ### パターン1: エラー修正の連鎖 **症状**: エラーを修正すると新しいエラーが発生 **原因**: 根本原因を理解せずに表面的な修正 **回避方法**: 5 Whysで根本原因を特定してから修正 ### パターン2: 型の保証の迂回 **症状**: どのチェックも契約も裏付けていない型を `any` や `as` で宣言している **原因**: 型エラーを回避したい衝動 **回避方法**: 「型安全性の基礎」の根拠に関する基準を適用する。 ### パターン3: テスト不足での実装 **症状**: 実装後にバグ多発 **原因**: Red-Green-Refactorプロセスの無視 **回避方法**: 必要な結果が未実装であるため失敗するテストから開始 ### パターン4: 技術的不確実性の無視 **症状**: 新技術導入時の想定外エラー多発 **原因**: 事前調査なしで「公式ドキュメント通りなら動くはず」 **回避方法**: - タスクファイル冒頭に確実性評価を記載 - リポジトリ内の根拠、対象バージョンに一致する一次情報、実行可能なローカルチェックのいずれでも成果に影響する振る舞いを確認できない場合、確実性はlowと判定する。実装前に、その振る舞いを確認できる最小の検証を作成する ### パターン5: 既存コード調査不足 **症状**: 重複実装、アーキテクチャ不整合、結合時の障害、古いパターンの採用 **原因**: 実装前の既存コード理解不足、近隣ファイルのみ参照し代表性を確認していない **回避方法**: - 実装前に、ドメイン、責務、設定パターンをキーワードとして類似機能を検索 - 類似機能を発見 → 現在の契約を満たす場合は、その実装を使用または拡張 - 類似機能が技術的負債 → 現在の成果を妨げる場合、今回の変更が原因である場合、または確定済みスコープに含まれる場合は修復する。それ以外は別途報告する。修復にアーキテクチャ判断が必要な場合はADRを作成する - 類似機能が存在しない → 既存の設計思想に沿って新規実装 - 各判断とその根拠を、現在のワークフローがその記録先として割り当てた成果物に記載する - **変更境界と参照の代表性の確認**: 上記「変更境界と参照の代表性」セクションを参照 ## デバッグ手法 ### 5 Whys - 根本原因分析 各回答を観測済みの根拠に結び付け、修正によって元の失敗を防げる原因に到達するまで掘り下げる。各質問、根拠、最終的な因果関係を記録する。次の回答が推測になる時点で止め、必要な根拠を明記する。 ## 型安全性の基礎 **型安全の原則**: 型の絞り込みには、実行時の検査または既存の契約を根拠とする。型ガードが保証する型は、実際の検査内容に一致させる。 - 構造が確定していない入力には `unknown` を用い、利用側が必要とするプロパティを検証する。 - 型の関係やバリエーションは、ジェネリクス、ユニオン型、インターセクション型で表現する。 - 検証済みのSDK・フレームワーク契約に基づくアサーションは、該当する境界に置く。静的解析でその契約を表現できない場合は、抑制を対象ルールに限定し、契約の根拠とアサーションの適用範囲を記載する。 **型の複雑性管理** - フィールド数: 20個まで(超えたら責務で分割、外部API型は例外) - オプショナル率: 30%まで(超えたら必須/任意で分離) - ネスト深さ: 3階層まで(超えたらフラット化) - **外部API型の扱い**: 制約を緩和し、実態に合わせて定義(内部では適切に変換) ## リファクタリング手法 **基本方針** - 小さなステップ: 振る舞いを保つ各リファクタリング後に、直近で適用できるテストと静的チェックが成功する状態を維持 - 安全な変更: 一度に1つのリファクタリング責務だけを変更し、次へ進む前に観測可能な振る舞いを検証 - 動作保証: 既存の動作を変えないことを確認しながら進める **実施手順**: 現状把握 → 段階的変更 → 動作確認 → 最終検証 **優先順位**: 重複コード削除 > 長大な関数分割 > 複雑な条件分岐簡素化 > 型安全性向上 ## 実装作業の完全性担保 ### 影響範囲の追跡 実装の前に、変更するコードの呼び出し元、依存関係、データフロー(生成→変更→参照)を、「変更境界と参照の代表性」で定める変更境界を別のファイルが変えなくなるまで追跡する。実装やその検証が依拠する直接・間接の影響は、その作業に引き継ぐ。 ### 未使用コード削除ルール 未使用コードを検出したら、タスク完了までに、現行要件と到達可能な呼び出し経路から使用されているかを判断する。 - Yes → その呼び出し経路へ接続し、要件を検証 - No → 削除する。以前の実装はバージョン管理に残る 対象: コード・ドキュメント・設定ファイル ## Red-Green-Refactorプロセス(テストファースト開発) **推奨原則**: 振る舞いの変更は、必要な理由で失敗するテストから始める **開発ステップ**: 1. **Red**: 期待する動作のテストを書く(失敗する) 2. **Green**: 最小限の実装でテストを通す 3. **Refactor**: テストが通る状態を維持しながらコード改善 **直接検証するケース**: - 純粋な設定ファイル変更(.env、config等) - ドキュメントのみの更新(README、コメント等) - 緊急本番障害対応(ただし事後テスト必須) ## テスト設計原則 ### テストケースの構造 - テストは「準備(Arrange)」「実行(Act)」「検証(Assert)」の3段階で構成 - テスト名でトリガーと観測可能な結果を示す - 1つのテストケースでは1つの振る舞いのみを検証 ### テストデータ管理 - テストデータは専用ディレクトリで管理 - 環境変数はテスト用の値を定義 - 認証情報、トークン、個人データ、決済情報には、合成した非機密値を使用 - テストデータは最小限に保ち、テストケースの検証目的に直接関連するデータのみ使用 ### モックとスタブの使用方針 **推奨: 単体テストでの外部依存モック化** - メリット: テストの独立性と再現性を確保 - 実践: DB、API、ファイルシステム等の外部依存をモック化 **Unit testの境界**: 外部接続には決定論的な代替を使用する。実際の外部境界は、その契約を対象として選定したIntegration testまたはE2E testで検証する ### テスト失敗時の対応判断基準 **テストを修正**: 間違った期待値、存在しない機能参照、実装詳細への依存、テストのためだけの実装 **実装を修正**: 妥当な仕様、ビジネスロジック、重要なエッジケース **どちらの解釈も参照できる要件と両立する場合**: 未解決の振る舞い判断として差し戻す — 2つの候補となる振る舞い、どちらが正しいかを決める出所、および一方を選ばず停止する条件を示す ## テストの粒度原則 ### 原則:観測可能な振る舞いのみ **観測可能な境界を通じてテストする**:公開API、戻り値、例外、外部呼び出し、永続化された状態を検証する。privateメソッド、内部状態、アルゴリズムの詳細は、これらの観測可能な境界を通じてのみ到達する。 ## Security Principles ### Secure Defaults - 認証情報とシークレットは環境変数または専用のシークレットマネージャーで管理 - すべてのデータベースアクセスにパラメータ化クエリ(プリペアドステートメント)を使用 - 言語またはフレームワークが提供する確立された暗号ライブラリを使用 - セキュリティ上重要な値(トークン、ID、nonce)は暗号学的に安全な乱数生成器で生成 - 機密データは標準プロトコルを使用して保存時・転送時に暗号化 ### Input and Output Boundaries - システムのエントリポイントで、期待される形式・型・長さについてすべての外部入力を検証 - 出力をレンダリングコンテキスト(HTML、SQL、シェル、URL)に応じて適切にエンコード - エラーレスポンスには呼び出し元に必要な情報のみを返却し、詳細な診断情報はサーバーサイドでログに記録 ### Access Control - ユーザーデータを扱うまたは状態変更をトリガーするすべてのエントリポイントに認証を適用 - エントリポイントだけでなく、各リソースアクセスで認可を検証 - 操作に必要な権限のみを付与(ファイル、データベース接続、APIスコープ) ### Knowledge Cutoff Supplement (2026-03) - OWASP Top 10:2025は症状から根本原因へと視点を移し、「Software Supply Chain Failures」(A03)と「Mishandling of Exceptional Conditions」(A10)が追加された - 最近の研究ではAI生成コードがAccess Controlの欠落を高い発生率で示しているため、認証と認可を高優先度のレビュー対象として扱う - OpenSSFが「Security-Focused Guide for AI Code Assistant Instructions」を公開した。汎用的なアドバイスより、言語固有で実行可能な制約を推奨している - 詳細な検出パターンは`references/security-checks.md`を参照