maintainable-code について
maintainable-code は、ソースコードを扱うコーディングエージェント向けのスキルです。保守性、本番環境での耐障害性、テスト容易性をまとめ、作業別の判断指針と小さな変更、適切な検証を重視します。
主な機能
- 01明確なコード構成と命名の指針
- 02ジョブや分散ワークフローの耐障害性を扱う
- 03置き換え可能な依存境界とテストダブルを提案
- 04実装、リファクタリング、レビューの判断経路
- 05適切な検証と復旧を重視
活用シーン
- 01実装や修正で既存アーキテクチャに沿う
- 02小さな段階で動作を保ちながらリファクタリング
- 03キューや外部 API の障害対応を設計
- 04コードのテスト容易性と保守リスクをレビュー
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ jpcaparas/ skills --skill maintainable-codeインストール後、Claude Code で/maintainable-codeを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
AGENTS.mdmetadata.jsonREADME.mdskill-card.prompt.mdagents/.gitkeepassets/.gitkeepevals/evals.jsonevals/files/runtime-defaults.tsreferences/commenting.mddecomposition.mddependency-boundaries.mddistributed-systems.mdgotchas.mdguardrails-and-quality-gates.mdimplementation-plans.mdjobs-and-queues.mdobservability.mdprinciples.mdresilience.mdreview-rubric.mdsource-notes.mdtest-doubles.mdscripts/analyze_app_resilience.pyanalyze_maintainability.pyanalyze_mockability.pytest_skill.pyvalidate.pytemplates/maintainability-review.mdmockability-review.mdresilience-review.md詳細
保守しやすいコード
人間の保守担当者が、巧妙なコードを解読しなくても理解、テスト、変更でき、本番環境の障害をデバッガーを接続せずにデバッグでき、テストでは本番設計を歪めずに依存関係を置き換えられるように、コードを記述、編集、レビューします。
このスキルは、これまで別々のスキルだった3つの関心事、すなわち一般的な保守性、本番アプリケーションのレジリエンス(ジョブ、キュー、再試行、可観測性)、モックのしやすさ(依存関係の境界とテストダブル)を統合します。
パッシブトリガー
ユーザーが保守性について言及していなくても、タスクにソースコードが関係する場合は常に、このスキルをバックグラウンドで読み込みます。これには、バックグラウンドワーカー、スケジュールタスク、Webhook、決済フロー、インポート/エクスポート、通知、API 連携、データベースの状態遷移、キャッシュ、ファイルアップロード、キュー、cron、認証/セッションフロー、ログ記録、トレース、アラート、信頼性に関する動作など、本番環境に関わる実行時の動作も含まれます。また、協調オブジェクト、I/O、時刻、乱数、永続化、設定、ネットワーク呼び出し、SDK、プロセス状態、フレームワークのコンテキストに依存する動作も含まれます。
小規模な編集では、軽量に適用します。基本ルールを黙って適用し、最終的な実装に影響する判断だけを説明します。テストを追加または変更する場合は、利用可能であれば {{ skill:maintainable-tests }} も読み込みます。
判断ツリー
基本ルールやローカルの根拠だけでは、明白でない設計上の判断を下せない場合は、以下のルートを使用します。トピックが一致するだけで、参考資料一式を読む必要はありません。
-
新機能の実装またはバグ修正: まずローカルのアーキテクチャに合わせます。変更は小さく保ち、型を付け、分かりやすく命名し、意味のある最小限の範囲で検証します。基礎知識は十分にあるものの、このシステムについての背景知識が不十分な将来の保守担当者に向けて記述します。
-
既存コードのリファクタリング: 十分な既存のテストカバレッジを活用し、小さなステップで動作を維持します。境界が不明確な場合は
references/decomposition.mdを参照し、絡み合った副作用によって安全な検証が妨げられている場合はreferences/dependency-boundaries.mdを参照します。特性テストや置き換えポイントは、必要な場合にのみ追加します。 -
コードレビュー: 指摘では、具体的なコードを示し、保守担当者への影響を説明します。重大度や範囲の判断が難しい場合は
references/review-rubric.mdを、明白でない運用上の背景を説明する場合はreferences/commenting.mdを参照します。 -
別のエージェントやチームメイト向けの計画の作成: セッションのコンテキストに頼らず、成果、範囲、検証方法が明確になるようにします。引き継ぎが複雑な場合は
references/implementation-plans.mdを、明白でない根拠を残す必要がある場合はreferences/commenting.mdを参照します。固定のセクション数にこだわらず、作業に影響する失敗時の処理や依存関係に関する判断を含めます。 -
運用コード、CI ワークフロー、マイグレーション、生成されたグルーコード、複雑なコマンドパイプラインの作成: 明白でない意図、不変条件、外部の制約にコメントを付けます。コメントの位置や説明が不明確な場合は
references/commenting.mdを参照します。明白なコードの内容を逐一説明しないでください。 -
バックグラウンドジョブ、キュー、cron、Webhook、インポート/エクスポート、メール、決済処理、通知の追加: 該当する失敗モードに対して、安全な重複処理、処理量の上限、復旧方法を確立します。検証済みのフレームワークや既存の保証を再利用します。未解決のリスクがある場合は
references/resilience.mdまたはreferences/jobs-and-queues.mdを参照します。必要がない限り、仕組みをむやみに追加しないでください。 -
複数のサービス、外部 API、イベント発行、分散データの変更、非同期ワークフロー: 待機時間と再試行回数に上限を設け、有害な重複を防ぎ、部分的な完了を考慮します。責任の所在や保証が不明確な場合は
references/distributed-systems.mdを参照します。アウトボックス/インボックス、リコンシリエーション、補償処理は選択肢であり、常に必要な仕組みではありません。 -
ログ、メトリクス、トレース、アラート、ダッシュボード、インシデント診断を追加する場合: ユーザーへの影響と復旧状況を説明できる既存のシグナルを利用します。診断上の不足を補うために計測が必要な場合は、
references/observability.mdを参照してください。すべての編集にテレメトリを追加するためのものではありません。 -
厳格なランタイムのデフォルト、環境ごとの安全策、互換性ポリシー、リポジトリの品質ゲートを選定する場合: 設定済み、適用可能、選択済み、適用成功の各状態を区別し、危険な作用はオプトインにし、動作を変えるデフォルトは段階的に導入し、明示した互換性範囲を検証します。ポリシーのさらなる設計が必要な場合は、
references/guardrails-and-quality-gates.mdを参照してください。 -
依存関係を呼び出すコードを追加する場合、またはテストしにくいコードを置き換え可能にする場合: 外部連携は、狭いポート/アダプターまたは同等のローカル境界の内側に置き、ドメインポリシーを構築、設定、トランスポートから分離します。時間、乱数、環境の読み取りは境界で制御します。既存の分離点が不十分な場合は、
references/dependency-boundaries.mdを参照してください。 -
テストで依存関係を置き換える方法を選ぶ場合: 挙動を検証できる範囲で、最も機能の少ないテストダブルを優先します。決まった応答にはスタブ、現実的なインメモリの挙動にはフェイク、インタラクションの契約にはモックまたはスパイを使います。置き換え時のリスクやアダプターの乖離が明白でない場合は、
references/test-doubles.mdを参照してください。 -
保守しやすい設計かどうか判断できない場合: 重要なドメインの挙動を隠さず、将来の読者の負担を減らす選択肢を選びます。
references/principles.md、または未解決のリスクに関するリファレンスを参照してください。 -
ユーザーが巧妙さ、圧縮、または広範な抽象化を求めている場合: 要望されたトレードオフを尊重し、改めて説明を求めません。正確性、型、安全性を保ち、可能な範囲で巧妙な実装を局所化し、保守コストのうち重要なものだけを説明します。
クイックリファレンス
| 状況 | デフォルトの対応 |
|---|---|
| 新しいコード | 既存のローカルパターン、正確な名前、強い型、直接的な制御フローを使います |
| 繰り返しのロジック | 重複箇所が同じ理由で変更される場合にのみ抽出します |
| 複雑な分岐 | 入力を早い段階で正規化し、無効なケースをガードしてから、正常系を見通しよく保ちます |
| 運用スクリプトまたは CI YAML | 各フェーズに名前を付け、分かりにくいコマンド群、外部 API の癖、アーティファクトの契約、障害処理にコメントを付けます |
| 大きな関数 | 任意の行数ではなく、安定した責務ごとに分割します |
| 新しい抽象化 | 実際の呼び出し箇所が少なくとも 2 つあるか、明確に保護すべき境界があることを条件とします |
| フレームワークの暗黙の挙動 | 互換性を示す根拠がある場合は、エラーを明示するデフォルトまたは不変のデフォルトを優先し、切り替えを動作移行として扱います |
| 危険な操作または上書きを伴う操作 | デフォルトでは無効にします。対話型ツールでは確認を使い、プログラムによる契約では、意図、範囲、前提条件、冪等性、復旧方法を明示します |
| 品質ポリシー | 設定済みレイヤー(フォーマット/リント、解析、動作テスト、安全なリファクタリングのドライラン。ただし対応ツールが存在する場合のみ)を組み合わせる、チェックモードのコマンドを 1 つ用意します |
| バージョン互換性 | スタックがサポートする分離手段(ランタイムの機能チェック、バージョン付きアダプター、ビルドフラグ、条件付きコンパイル)を使い、サポート対象の最小構成と現行バージョンの両方をテストします |
| コメント | 重要な理由や制約のうち分かりにくいものを、必要な範囲に絞って説明します。フローを明確にできる場合にのみ、ASCII 図を使います |
| 計画 | 求められた成果に必要な範囲、ローカルな文脈、検証の根拠を十分に示します |
レジリエンス:
リスクがある場合にのみ、これらを適用します。既存のデータベース、プロバイダー、フレームワーク、プラットフォームの保証が対象の操作をカバーしており、その範囲と設定も十分な場合は、その保証を活用します。仕組みを追加するのは、不足がある場合に限ります。
| 状況 | デフォルトの対応 |
|---|---|
| ブラウザーからの重複送信、Webhook の再送、リトライ、ワーカーの再起動 | 自然な冪等性、一意性、または永続的なインテントキーによって、有害な重複処理を防ぎます |
| 10 人のユーザーが同じ高コストのジョブを起動する | 認可された同一のインテントをアトミックに集約し、並行実行数を制限します。既存のジョブステータスを再利用します |
ジョブが pending または running のまま長時間経過する | 古い処理を検出して安全に復旧するか、終端状態にできるようにします。既存のキュー復旧機能で十分な場合は、それを使用します |
| リモート API 呼び出し | 接続およびリクエストの待ち時間に上限を設けます。リトライする場合は、エラーを分類し、安全で上限のあるバックオフポリシーを使用します |
| キューの負荷が急増する | 既存の容量制御またはバックプレッシャーを使ってリソース使用量を制限し、共有依存先を保護します |
| データベース書き込み後の副作用 | 必要な引き継ぎが失われないようにします。トランザクション機能、アウトボックス、または実績のある別の復旧経路を使用します |
| 複数ステップの分散ワークフロー | 状態と部分完了時の結果を明確にします。必要に応じて調整または補償を行います |
| 部分的な障害 | 優先度の低い機能から縮退させ、ユーザーの主要なタスクを維持します |
| リクエスト/ジョブの進捗のログ記録 | 処理、結果、復旧判断を特定するために必要な安全なコンテキストを含めます |
| メトリクス | ユーザーの健全性と容量に関するリスクを測定します。カウンターを追加する前に、既存のメトリクスを再利用します |
| トレース | 理由が分からない境界をまたぐレイテンシや障害に対してスパンを追加し、細かなローカルヘルパーには追加しません |
| アラート | ユーザーへの影響がある場合、または自動化で対処できなくなった場合にのみページングします。ページングしないシグナルは、診断や対応に役立つ場合に限って使用します |
テスト容易性:
| 状況 | デフォルトの対応 |
|---|---|
| ネットワーク、データベース、ファイル、時計、乱数、環境変数、またはキューへの直接アクセス | 外側の境界にとどめるか、小さな契約の背後に渡します |
| ビジネスルールと SDK 呼び出しが混在している | ルールを決定論的な関数に切り出し、SDK に接続するアダプターを注入します |
| コンストラクターがクライアントを内部で作成する | ローカルのパターンで別の方法が定められていない限り、呼び出し元からクライアント、ファクトリー、または設定を受け取ります |
| 静的/グローバルなシングルトン依存 | 境界で明示的な協力オブジェクト、コンテキストオブジェクト、または限定的なラッパーを優先します |
| フレームワークのハンドラー | ハンドラーには解析とレスポンスのフォーマット処理を残し、ポリシーは呼び出し可能なサービス/関数に移します |
| テストで実際の外部サービスが必要 | 共有インフラに接続する前に、フェイク、スタブ、コントラクトテスト、またはローカルのテストコンテナーを使用します |
| インターフェースが有用に思える | 実際に置き換えが必要な場合、保護すべき境界がある場合、または言語の慣例で必要な場合にのみ追加します |
| レビューでモックできないコードが見つかった | 一律の書き換えではなく、隠れた依存を示し、最小限の修正方法を提示します |
| テスト | 十分なカバレッジを再利用し、リスクの高い変更の前に動作や回帰の抜けを補います |
| レビュー | 欠陥、分かりにくい境界、テストの欠落、将来の変更で問題になり得る箇所を優先します |
基本ルール
明瞭さと構造:
- 洗練さを誇示するのではなく、次に担当する有能なメンテナーにとって最適な形にしてください。基本的な知識は十分にあるものの、あなたの頭の中にあるシステムの経緯までは知らないものとして考えてください。
- 名前を付けたり、切り出したり、パターンを導入したりする前に、周辺のコードを読んでください。
- 振る舞いは、それを説明するデータやポリシーの近くに配置してください。
- 文字列や、何でも入るオプションの集まり、隠れた慣習よりも、平易で型付けされたデータ構造を優先してください。
- 関数の抽象化レベルを一貫させてください。オーケストレーション、ポリシー、変換、I/O のいずれかに統一します。
- 言語やコードベースが対応している場合は、不正な状態を表現しにくくしてください。
- コメントは、名前や構造では表せない、わかりにくい理由、不変条件、制約についてのみ記述してください。説明は該当するクラス、メソッド、プロパティ、分岐、ブロックに記載し、ユーザーが削除する必要のある解説は追加しないでください。
- 不確かな点、バージョンに依存する点、影響の大きい言語やフレームワークに関する主張は、プロジェクトで実際に使われているスタックの公式情報で確認してください。主張の確認に役立つ場合やユーザーから求められた場合は情報源へのリンクを付けてください。既知の基本事項をデフォルトで調査したり、ドキュメントに記載された動作を誇張したりしないでください。
- わかりにくいデータフロー、状態遷移、キュー、再試行、所有権、境界の越え方を明確にできる場合は、コメントや docblock に簡潔な ASCII 図を追加してください。図と説明文の内容を一致させてください。コード変更によって古くなった場合は、両方をすぐに更新してください。
- 重要な振る舞いをリファクタリングする場合は、十分に検証してください。既存のテストを再利用し、不足している箇所に限って特性化テストを追加してください。
- 複雑さを意図的に残す場合は、その重要なトレードオフを最終回答で説明してください。
- ローカルの互換性が許す範囲で、型、解析、フレームワークの振る舞い、境界の検証に段階的な厳格さを適用してください。振る舞いが変わる厳格モードを有効にする前に、移行をカバーするテストを追加してください。
- 各エントリーポイントで、キャンセル、オプション機能の不在、運用上の失敗、予期しない不具合をそれぞれ分類してください。すべての結果を
false、null、または汎用エラーひとつにまとめず、原因を特定できる情報を保持してください。 - 危険な機能はデフォルトで無効にしてください。強制フラグで操作確認を省略することはできますが、認可、検証、不変条件、復旧確認を省略してはいけません。
本番環境の振る舞いと復旧:
- 再試行、重複配信、並行処理、レイテンシー、部分的な失敗、デプロイによる再起動、古い状態は、まれな事故ではなく通常の入力として扱ってください。
- 重複によって正確性やリソース使用量が損なわれる可能性がある場合は、新しい処理意図と再実行を区別してください。自然な冪等性や既存の ID で十分な場合があります。必要がないのに新しい作業記録を永続化しないでください。
- 重要な永続処理には、許可される状態遷移、所有権、終端状態、行き詰まった状態から抜け出すための上限付きの経路を明示してください。ワークフローに必要な状態とフィールドだけを使用してください。
- 該当する失敗には、安全な復旧方法か、明確な終端状態を用意してください。既存の自動復旧を優先し、まだ対処されていないリスクがある場合に限って、再試行、スイーパー、調整、デッドレター処理を追加してください。
- ひとつのワークフローが共有リソースを使い果たさないよう、リソース使用量に上限を設けてください。既存の同時実行数制限、リース、レート制限、バックプレッシャーで十分な場合があります。キューやバルクヘッドを必ず追加する必要はありません。
- 有害な副作用の重複は、それを防止できる境界で防いでください。重複排除の仕組みを追加する前に、自然な冪等性、データベース制約、プロバイダーのキー、その他の既存の保証がどこまで有効かを確認してください。
- プロセス、ネットワーク、キュー、データベース、プロバイダーの境界をまたぐ待機には上限を設けてください。既存の有効な期限を尊重し、競合するタイムアウト層を追加しないでください。結果が不確かな場合でも、安全に復旧できるようにしてください。
- ユーザーの健全性や容量に関する問題を診断できるだけの可観測性を確保してください。レイテンシー、トラフィック、エラー、飽和度は有用な確認項目の出発点であり、テレメトリーのノルマではありません。シークレット、トークン、生の決済情報、個人を特定できる情報の全量、セッションクッキー、プロバイダーの認証情報は、絶対にログに記録しないでください。
テスト容易性: 23. 意思決定と副作用を分離します。ドメインポリシーは、実際のネットワーク、時計、ファイル、データベース、キュー、乱数に依存せずにテストできるようにします。 24. 共同作業者は、モジュール、コンストラクター、関数、ハンドラー、コンテキストの境界で明示し、依存先ができることをすべて記述するのではなく、呼び出し元が必要とする内容を表す狭い契約を優先します。 25. 状態を持つ振る舞いにはフェイク、固定レスポンスにはスタブ、重要なやり取りにはモック/スパイ、アダプターにはコントラクトテストを使用します。モック可能なコードと、モックだらけのテストは同じではありません。 26. 想像上の代替物しかない抽象化を追加したり、テストからアクセスできるようにするだけの目的で非公開の内部実装を公開したりしないでください。明確な置き換え箇所が1つあるシンプルなコードは、使われないインターフェースを重ねるより優れています。
保守性ゲート
コード変更を完了する前に、このゲートを頭の中で確認し、利用可能な場合はローカルツールでも確認してください。
| ゲート | 合格条件 |
|---|---|
| 意図 | 読者がすべての行を読む前に、名前と構造からコードの動作を把握できます |
| 範囲 | 変更箇所が責任を持つ最小限の範囲にとどまり、無関係なクリーンアップを避けています |
| 境界 | 理由なく I/O、オーケストレーション、ドメインポリシー、プレゼンテーションが絡み合っていません |
| 型 | エディター、コンパイラー、テストで誤用を検出できる程度にデータ契約が明示されています |
| コメント | 複雑または予想外のコードには、適切なレベル(クラス/モジュール、メソッド/関数、プロパティ/フィールド、必要に応じてローカルブロック)で理解しやすいコメント/docstringがあります。ASCII 図がある場合、説明文およびコードと一致しています |
| テスト | 最も起こりやすいリグレッションに焦点を絞ったテストがあるか、検証できていない点が明確に記載されています |
| エラー | 有用なコンテキストを追加できる境界で障害モードが処理されています |
| デフォルト | 厳密性、不変性、環境によるゲートが明示され、適切な場合は設定可能であり、互換性を示す根拠に基づいて採用されています |
| 自動化 | ローカルと CI のチェックモードで同じバージョン管理された品質ポリシーを適用し、サポート対象の依存関係の範囲を網羅しています |
| 引き継ぎ | 最終回答に主要なファイル、実行した検証、残っているリスクが記載されています |
自己修復ゲート
本番環境のランタイム変更では、該当する保証を以下で確認してください。既存の仕組みで十分な場合はそれを受け入れてください。この表は、すべての状態、シグナル、復旧コンポーネントを追加することを求めるものではありません。
| ゲート | 合格条件 |
|---|---|
| 識別 | 自然な冪等性、永続的な処理意図の識別情報、一意性、または実証済みの別の境界保証によって、有害な重複処理が防止されています |
| 状態 | 実際に使用する状態について、単純でない処理に明示的な遷移と終端/復旧時の振る舞いがあります |
| 並行性 | 共有リソースに一意性、ロック、リース、レート制限、またはワーカー数の上限があります |
| 時間 | リモート呼び出し、ジョブ、ロック、保留状態にタイムアウトまたは有効期限があります |
| 再試行 | 再試行可能なエラーが分類され、回数が制限され、ジッターが適用され、重複した副作用が起きないよう安全に処理されています |
| 復旧 | 開発者が手作業でデータを編集しなくても、停滞、一部完了、失敗の各状態を再試行、照合、再実行、または終端状態にできます |
| 劣化時の動作 | オプションの依存先が失敗しても、アプリはユーザーにとって最も重要なタスクを維持します |
| 可観測性 | 利用可能なシグナルから、関連するユーザーへの影響、処理の識別情報、失敗、復旧の結果を把握できます |
| アラート | 予想される一時的な失敗ごとではなく、自動処理の再試行を使い果たした場合やユーザーに影響が出た場合にアラートが発報されます |
| テスト | 本番環境で最も起こりやすい障害に焦点を絞ったテストまたはシミュレーションがあるか、検証できていない点が明記されています |
モック化可能性の確認
依存関係や副作用に関わる変更を完了する前に、以下も確認してください。
| 確認項目 | 合格条件 |
|---|---|
| 依存関係の所有者 | 各外部依存関係を誰が作成し、誰が利用するのかが読み手に分かる |
| 置き換え可能性 | テストで、本番コードを変更せずに、遅い、不安定、コストがかかる、または取り消せないコラボレーターを置き換えられる |
| 決定性 | 時刻、乱数、プロセスや環境からの読み取りが境界で制御されている |
| 契約の範囲 | インターフェースやプロトコルに含まれる操作が、呼び出し側が実際に必要とするものだけである |
| 本番環境での配線 | 通常の実行経路が分かりやすく、追跡しやすい |
| テストの意図 | テストが、偶発的な呼び出し順序ではなく、振る舞いと重要な契約を検証している |
| 障害モード | 依存関係のエラー経路を、実際の副作用を発生させずにシミュレートできる |
| 範囲 | 関係のない書き換えやフレームワークの変更を伴わず、変更によってテスト容易性が向上する |
作業ワークフロー
変更の規模に応じて、このプロセスを調整してください。小さな編集では、要点を絞った調査と検証が必要ですが、経緯の記述、障害マップ、複数セクションから成るレポートは必要ありません。
-
まず調査します。 適切に作業するために必要なローカルガイダンス、影響を受けるコード、関連する契約、テストを確認します。変更に必要な場合に限り、より広範な配線や設定を調査します。
-
保守担当者の視点を把握します。 追加または変更する責務を理解します。範囲や引き継ぎに曖昧さがある場合に限り、内容を書き留めます。
-
障害マップを作成します。 実行時に重大なリスクがある場合は、重複入力、並行処理、タイムアウト、クラッシュ、古い状態、不完全な処理のうち、関連するものを検討します。既存の担当箇所、または不足している保証を特定し、実装やレビューに必要な判断だけを記録します。
-
重要な依存関係を特定します。 影響を受ける I/O、時刻、乱数、設定、SDK、グローバル状態の境界を調査します。安全な置き換え箇所を再利用し、関係のない依存関係の一覧は作成しません。
-
コードベースに適した、最も単純な境界を選びます。 既存のモジュールやヘルパーを優先します。新しい抽象化を追加するのは、変更の実際の軸を保護できる場合に限ります。局所的な制約や既存のフレームワークのプリミティブを優先し、キュー、ロック、アウトボックステーブル、サーキットブレーカー、ウォッチドッグは、その障害モードが導入を正当化するほど現実的な場合に限り追加します。
-
小さな段階に分けて実装します。 差分をレビューしやすい状態に保ちます。ついでのフォーマット変更、無関係な移行、スタイルの変更、テストのためだけに追加するパブリックセッターや広範なサービスロケーターなど、テストだけを目的とする無理な変更は避けます。
-
振る舞い、障害時の振る舞い、読みやすさを検証します。 関連するテストと、リポジトリで必須のチェックを実行します。十分なカバレッジは活用し、重大なギャップを補います。初めて見る人のコードをレビューするつもりで差分を読み直し、明白でない理由が失われてしまう場合に限ってコメントを付けます。
-
簡潔に報告します。 結果、検証内容、残るリスクを報告します。設計上の判断は重要なものに限って記載し、該当しないセクションや定型的な作業経過の説明は省略します。
オプションのヘルパー
ヘルパーは、判定ではなく、素早く問題の兆候を見つけるためのスキャナーとして使ってください。
python3 scripts/analyze_maintainability.py /path/to/project
python3 scripts/analyze_maintainability.py /path/to/project --json
python3 scripts/analyze_app_resilience.py /path/to/project
python3 scripts/analyze_app_resilience.py /path/to/project --json
python3 scripts/analyze_mockability.py /path/to/project
python3 scripts/analyze_mockability.py /path/to/project --json
analyze_maintainability.pyは、大きな関数、曖昧な名前、弱い型、コメントの負債、TODO の放置を検出します。関数の範囲と関数名のチェックには Python の AST のみを使用します。その他の対応言語で宣言されている呼び出しや関数形式は推測せず、意図的に対象外としています。また、弱い型に関するシグナルは、Python の型注釈と保守的に判定した TypeScript の型位置に限定されています。analyze_app_resilience.pyは、冪等性の欠如、リトライやバックオフの不足、明らかなタイムアウト設定のない外部呼び出し、コンテキスト情報の乏しいログ、握りつぶされたエラー、復旧手段のない保留状態を検出します。analyze_mockability.pyは、ハードコードされた副作用やグローバル変数の可能性を検出し、人間やエージェントが確認できるようにします。
出力は、人間がレビューするための手掛かりとして扱ってください。スキャン結果に何も表示されなくても、コードの品質、回復性、モック可能性が保証されるわけではありません。また、スキャンで多くの項目が検出されても、コードに問題があるとは限りません。より詳細なレビューを行う場合は、必要に応じて templates/maintainability-review.md、templates/resilience-review.md、または templates/mockability-review.md を調整してください。形式やセクションに従う必要はありません。
ガイダンスが役に立たなくなったとき
まとめられたパターンよりも、実証済みのローカルな不変条件や、フレームワークにおける慣用的な動作を優先してください。これらが矛盾する場合や、ガイダンスに従ってもうまくいかない場合は、インストール済みのバージョンと、関連する公式ドキュメントまたは信頼できる一次情報を確認してください。未解決の制約は明記してください。矛盾するルール、情報源とバージョン、具体的な回帰例または反例を添えて、正規のスキルの修正または削除を提案してください。インストール済みのコピーを黙って編集したり、調査結果を無関係なリファクタリングに置き換えたりしないでください。
読み方ガイド
| 知りたいこと | 参照先 |
|---|---|
| デフォルト設定の背景にある原則 | references/principles.md |
| 関数、モジュール、責務の分割 | references/decomposition.md |
| 役立つ開発者コメントと言語別の例 | references/commenting.md |
| 保守性、回復性、テスト容易性に関するレビュー結果と重大度の順序 | references/review-rubric.md |
| 他のエージェントやチームメイト向けの計画 | references/implementation-plans.md |
| 厳格なデフォルト設定、危険な副作用、互換性、実行可能な品質ゲート | references/guardrails-and-quality-gates.md |
| 自己修復型アプリの原則、障害マップ、作業の識別、状態マシン | references/resilience.md |
| ジョブ、キュー、Webhook、cron、停滞した作業、重複した作業 | references/jobs-and-queues.md |
| リトライ、タイムアウト、冪等な API、outbox/inbox、サガ、再調整 | references/distributed-systems.md |
| ログ、メトリクス、トレース、アラート、ダッシュボード | references/observability.md |
| 依存関係、副作用、時間、乱数、設定の分離 | references/dependency-boundaries.md |
| モック、スタブ、フェイク、スパイ、コントラクトテストの選択 | references/test-doubles.md |
| 3 つの観点すべてに共通する落とし穴とアンチパターン | references/gotchas.md |
| 参照した情報源とその応用に関する注記 | references/source-notes.md |
注意点
- 関数を小さくすれば、自動的に保守しやすくなるわけではありません。分割しすぎると、長い関数と同じように全体像が見えにくくなることがあります。
- DRY は、たまたま似ているコードを統合する指示ではありません。共有コードは、変更する理由も共有しているべきです。
- 「クリーン」なコードでも、間違っていることがあります。動作を維持し、構造を磨く前に検証してください。
- 汎用的な抽象化は、明示的な重複よりも劣化しやすいことがよくあります。実際に違いが生じるまで待ちましょう。
- コメントを追加しても、誤解を招く名前や複雑に絡み合った境界は解消できません。まず名前を変更するか、構造を見直してください。
- エージェントが生成したコードは、テストに合格しても、ローカルの慣習に反していることがよくあります。全体に適用できる一般論を当てはめる前に、リポジトリの慣習に合わせてください。
- 厳格なデフォルト設定は、単なる設定変更に見えても、動作を破壊的に変更することがあります。影響を受ける経路を洗い出し、段階的に展開してください。
- ユニットテスト一式がすべて成功しても、リポジトリで設定されたフォーマッターやリンターのチェック、解析、互換性テスト、利用可能な場合の安全な codemod のドライランの代わりにはなりません。それぞれ異なる保守上の問題を検出します。
- 安全でない処理を再試行すると、解消しようとしていた障害を引き起こすことがあります。再試行を追加する前に、処理を冪等にしてください。
- ワーカーが処理を終える前にロックの有効期限が切れるなら、ジョブを一意にしても不十分です。ロック TTL、ジョブのタイムアウト、可視性タイムアウト、再試行期間を揃えてください。
pendingは復旧策ではありません。終端状態でないすべての状態に、担当者と、古い状態への対処経路を設定してください。- デッドレターキューはゴミ箱ではありません。アラーム、調査用フィールド、再投入ルール、ポイズンメッセージへの対処方針が必要です。
- オブザーバビリティを高めれば、必ず良くなるわけではありません。カーディナリティが高い、秘密情報を含む、またはクエリされないテレメトリは、復旧の改善につながらず、コストとリスクを生みます。
- すべてのクラスにインターフェースを用意すると、コードの見通しが悪くなります。代替可能性や所有権の境界が実際にある場合に、コントラクトを追加してください。
- クロック、乱数生成器、環境変数、グローバルコンテキストからの隠れた読み取りは、ネットワーク呼び出しと同じくらいテストを壊すことがあります。
- モンキーパッチは役に立つこともありますが、コアとなる本番コードで協調要素を置き換える唯一の方法にしてはいけません。