code-standards について
Code Standardsは、コードや関連成果物の規約を適用・レビューするスキルです。読みやすさ、保守しやすい修正、テスト品質を重視し、言語別の指針も示します。
主な機能
- 01読みやすいコード構造の指針
- 02保守しやすい設計原則
- 03テストの最低基準
- 04コメントと成果物の規則
- 05実装とレビューのワークフロー
活用シーン
- 01実装時の規約適用
- 02明確な基準に基づく変更レビュー
- 03不正な入力の扱いの判断
- 04規約とプロジェクト判断の競合への対応
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ vivswan/ skills --skill code-standardsインストール後、Claude Code で/code-standardsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
LICENSE.mdREADME.md.codex-plugin/plugin.jsonagents/openai.yamlreferences/artifacts.mdcomments.mddesign.mdshape.mdstructure.mdtests.mdreferences/languages/go.mdpython.mdrust.mdtypescript.mdscripts/python-order.mts詳細
コード標準
コードとその周辺の成果物に関する標準です。作成時に適用し、レビュー時に確認してください。
可読性と美しさを最優先します。ここに示すすべての標準はそのためのものであり、従うとかえって読みづらくなる場合は譲ります。その場合は、逸脱したことを一行で記し、無理に標準を守ることはしません。
これはシルバー標準であり、ゴールド標準ではありません。言語やツールはこのページより速く変化します。新しいバージョンでより美しく、より読みやすい書き方が登場した場合、ページが追いついていなくてもそちらを優先し、後からページを更新します。
以下の各標準では、ルールを数行で示し、該当する場合はその基準となった実例を載せています。その下に記載されたreferences/のページには、理由、適用方法の一覧、適用範囲が記されています。標準の適用範囲が曖昧な場合は、判断する前にそのページを読んでください。
標準
個別の事例ではなく、クラスを修正する
システム上の問題には、再発を不可能にする根本的な修正を行い、その場の事例だけを修正することはしません。判断と対応の段階は/never-twiceスキルが担います。詳細はreferences/design.mdを参照してください。
基準を通過するものを保護する
/never-twiceの基準による判断を通過した問題には、到達可能な限り最上位の対応を適用します。状態を不可能にする型や構造、それが無理ならテスト、トリップワイヤー、パイプラインの修正(またはパイプラインに手が届かない場合はユーザーへの提案)、それも無理なら負債として記録するルールを文書化します。詳細はreferences/design.mdを参照してください。
特殊ケースより汎用性を優先する
変化し続ける軸は、今日の事例をハードコードするのではなくパラメーター化し、一つの概念には一つのパイプラインを与えます。実例:ルールブックが頻繁に変わる安全性分類器を、評価基準を入力として受け取る分類器ファクトリーとして構築しました。DRYの適用範囲も含む詳細はreferences/design.mdを参照してください。
労力より保守性を優先する
コード品質は差分の大きさや費やす労力よりも重要です。誤った方法での修正より大規模なリファクタリングを優先し、不変条件は型で表現し(/no-invalid-statesスキル)、型で保証できないことは境界でアサーションを行います。実例:文書化された回避策のハイブリッド構成を維持せず、全面的に作り直しました。詳細はreferences/design.mdを参照してください。
自作するよりライブラリを優先する
優れたライブラリがすでに行えることは、決して自作しません。リポジトリにあるツールも対象です。宣言済みの直接依存関係か、そのツール自身のコードは該当しますが、推移的依存関係、ライブラリのプライベートモジュール、スキルのスクリプトは該当しません。最初の一行を書く前に検索し、その結果をブリーフ、続いてPR本文または着地レポートに記録します。ライブラリが大規模な場合や適合するか不明な場合は、まずオーナーに確認してください。
実例:公開済みパッケージやgit diff --exit-codeだけですでに代替できていた、CIスクリプト5本。詳細はreferences/design.mdを参照してください。
テストの最低基準
すべてのテストが満たすべき最低基準です。テストは一連の結果全体を検証し、名前または最初の行で「これがなければ何が気づかれないまま変化するか」に答えます。対象は外部の事実、ファイル間の整合性、または名前が付いたインシデントです。定数やリリース済みファイルを情報源とし、それ自身を基準として固定してはいけません。
ガードテストは、対象のバグがある状態で失敗することを確認します。それ自体に動作がないコードの削除は、作り物のテストではなく全数調査で妥当性を示します。フィクスチャは手作業で作成し、実データから記録してはいけません。
実例:辞書のキーを一つずつ検証していた15個のテストを、辞書全体を固定するパラメーター化テスト1つにまとめました。テスト関数は81個から44個に減り、ガード対象のバグはすべて引き続き検出されます。詳細とその他の実例はreferences/tests.mdを参照してください。
コメントに書くのは、コードからは分からないことだけです
なぜその選択をしたのか、別のファイルが依存する不変条件、外部システムの癖、ここからは見えない結果、ガードを設けるきっかけとなった入力を書きます。コードの動作、型、制御フロー、履歴、代替案は書きません。
最初に一、二文で伝え、ブロックのほうが速く読める場合に限り、整列した行や矢印のフローを示します。上限に収めるために文章を詰め込まず、正直に削ります。書く前、または残す前に、次の点を考えます。コードからは分からないことを何と伝えているか、疲れた人が一度読めば理解できるか。具体例と TODO 禁止事項については、references/comments.md を参照してください。
境界で修復するか、そこで拒否します
破損した状態に明確な修復方法が一つある場合は境界で修復し、そのことを報告します。修復方法がない、または複数ある場合は境界で拒否します。ツールが読み取るだけのものは拒否し、出力するものはユーザーが宣言した内容に沿って修復します。破損したものを通過させて、後で失敗させることはありません。詳細は references/design.md を参照してください。
コードは上から下まで美しく読めるようにします
コードは常に美しく、一度読めば理解できるものにします。モジュールはスクロールして戻る必要がなく、上から下へ読めるようにし、関数は手順のリストとして読めるようにします。この見出し以下はすべてデフォルトであり、絶対的な規則ではありません。判断は状況に委ね、逸脱したほうが読みやすければそれを優先し、逸脱を指摘するレビュー担当者は、どうすればより読みやすくなるかを示します。
- モジュール: インポート、定数(キャッシュを含む)を一つのブロックにまとめ、型、関数の順にします。関数は呼び出し元より上に置き、エントリーポイントは最後の定義にします。この順序にできない場合や、かえって読みにくくなる場合は、読みやすさを優先して逸脱の理由を述べます。セクション区切りは、小さく範囲の限られたグループにのみ使います。セクション分けが必要なモジュールは、二つのモジュールに分けます。
- 関数: それぞれ一つの概念を扱い、数語で名前を付けられるものにします。概念が長ければ関数も長くします。ガードを最初に置き、それぞれを独立した段落にして、二つ目の概念として数えないようにします。早期リターンの後に本体をラップせずに続けます。ループではネストせず、
continueを使います。 - 分割するか、呼び出し元に戻す: 名前を付けられる二つの処理は、名前付きの手順に分けます。独自の概念ではなく、一か所からしか呼び出されない手順は、呼び出し元に戻します。複雑度リンターは最後の砦として使います。理由を示して警告を上げるか、処理を分割します。インラインで警告を抑制せず、言語ページに定められた最低値より厳しく設定しません。
- 行: 見苦しい一行コード(ネストした条件分岐、条件付きの挿入、最初に一致したものの検索、条件式内の代入、制御フローとしての
and/or)は避けます。単純な名詞の名前を付け、一行に一つの計算を書きます。三つの値が同じ型なら、名前付き引数を使います。後処理はリソースの取得と結び付けます(with、defer、Drop、using)。 - 本体: セットアップの後、判断や分岐の間、リターンの前に空行を入れます。
ifとその単一の処理の間には空行を入れません。 - 公開インターフェース: すべてのシグネチャに型を付けます。すべての公開項目に、戻り値と引数の意味を説明するドキュメントコメントを付けます。動作の説明は書きません。言語本来の可視性を超えて、モジュールレベルまたは属性にアンダースコア始まりの名前を付けません。ただし、そのモジュールの利用者が決して触れてはならないもの(プロパティの背後にある値とそのセッター、フレームワークによって固定されたフック)は例外です。
段落の規則のきっかけとなった本体の具体例:
key = (video_key(video), audio_sig(video), model)
if key not in SEGMENTS:
cache = cache_file(video, model)
segments = read_cache(cache)
if segments is None and window is not None:
return with_min_words(transcribe_window(video, model, window), min_words)
if segments is None:
segments = run_asr(full_audio_wav(video), model, offset=audio_start(video))
write_cache(cache, segments)
SEGMENTS[key] = segments
segments = SEGMENTS[key]
if window is not None:
segments = within_window(segments, window)
return with_min_words(segments, min_words)
規則と具体例については references/shape.md を参照してください。リンターの最低基準、各言語のイディオム、Python の順序チェッカーについては references/languages/ を参照してください。
バレルファイルや単なる中継関数を作らない
インポートだけを行う index、古いインポート元のコンパイルを維持するための再エクスポート、処理全体を別の関数に渡すだけの関数は削除します。インポート元や呼び出し元を、定義元のモジュールを参照するように変更します。ラッパーを設ける意味があるのは、デフォルト値、変換、エラーマッピング、依存関係の注入、型の絞り込みなど、実質的な機能を追加する場合に限ります。
分かりにくいレイアウトは、ひとつ上の階層で同じ問題を抱えています。予測しやすいレイアウトでは、各ファイルに主な公開要素の名前を付けてヘルパーをそのそばに置き、フォルダー内の兄弟ファイルすべてで同じ内部テンプレートを使い、隣り合うステージ間でファイル名を繰り返します。これにより、読者はファイルを開く前から目的のものがどこにあるか分かります。配置先が分からない場合は、選択肢を示してユーザーに尋ねます。
ステージのレコード、定数、小さな関数は、それぞれ records、constants、util モジュールにまとめます。ひとつのモジュールに収まるパッケージは、ひとつのモジュールにします。主な要素の名前を付けたモジュールに、その要素だけを置くのは問題ありません。問題なのは、特定のひとつの呼び出し元だけが使うヘルパーや定数を、これら3つ以外の独立したモジュールに置くことです。
事例:ある一括整理でツリーが269個のモジュールに分割され、その中には書式変換ヘルパーひとつだけを含むファイルや、デフォルトのレイヤーリストだけを含むファイルもありました。
関数ごとにファイルを分けるのも、反対側から見た同じ問題です。ファイルはヘルパーを含めてひとつの概念を扱い、関数は手順を含めてひとつの概念を扱います。
どのファイルも移動できます。単なる移動だけを行う場合は、エクスポートの全件調査とテスト数を変えないことを含む、独立したPRにします。リポジトリ全体の再編成は、まず目標とするレイアウトを提案します。詳細は references/structure.md、各言語のバレルについては references/languages/ を参照してください。
コード内で計画資料に言及しない
コードやコメントから、作業パッケージ名、スパイクやフェーズのラベル、計画のコードネーム、監査指摘番号を参照してはいけません。事例:「WP-B spike, part 2:」で始まるコメントは、計画の外では意味をなしません。詳細は references/comments.md を参照してください。
簡潔な AGENTS.md
AGENTS.md(および CLAUDE.md)には、プロジェクトの基本原則と、エージェントがほかでは把握できない情報だけを記載します。プロジェクトの概要、維持すべきオーナーの規約、安全上の制約、ツールチェーンの入口、参照先などです。特定のファイルを見れば分かる情報は、1行の参照に置き換えます。また、テストで本文を固定しません。事例:末尾の66行が15行になりました。詳細は references/artifacts.md を参照してください。
コミットメッセージには内容だけを書く
リポジトリの件名に関する規約に従い、変更内容とその理由を書きます。AIやツールのクレジット、本文の強制的な折り返し、PIIは含めません(/pr-and-issue-discipline スキルの規則)。唯一認められているクレジット表記は、コミュニティに貢献した人への謝辞です。詳細は references/artifacts.md を参照してください。
フックはチェックするだけで、コミットしない
pre-commit フックは開発者がステージした内容をチェックして結果を報告します。チェックして失敗するか、チェックして修正を作業ツリーに書き込み、それでも失敗します。ステージング、コミット、整形後の再ステージ、書き込みを伴う git コマンドの実行、ネットワークへの接続、何かのインストールは行いません。詳細と事例は references/artifacts.md を参照してください。
テキストの塊を作らない
人がざっと読むものは、内容を把握しやすい構造にします。段落は1〜3文とし、列挙できる内容はリストにします。構成規則と段落チェック方法は /working-text スキルに記載されています。PR本文は /pr-and-issue-discipline スキルに従います。アクションの説明や CLI ヘルプなど、コード成果物内の文章には、/working-text のページ規則を適用します。
ワークフロー
- コードを書く: 作業しながら標準を適用してください。レビュー時よりも、執筆時に適用するほうが低コストです。読みやすさと美しさを最優先してください。標準を適用するとかえって読みにくくなる場合は、適用せず、その旨を一行で説明してください。
- テストを書く: テストファイルを作成したり、テストケースを追加したりする前に、そのドリフトの答え(外部の事実、ファイル間の整合性、名前のあるインシデント)をテストの名前または最初の行に記載してください。答えがなければ、テストも作成しません。
- レビューする: レビュー基準を確認し、指摘ごとに該当する標準を明示してください。また、個別箇所の修正より、クラス全体の修正を提案してください。
- 適用範囲: 標準の適用範囲(何が該当するか、何が除外されるか、どこまで適用するか)を確認する必要がある場合は、その標準に対応する
references/ページを参照してから対応してください。 - 型レベルの修正: 型システムで不変条件を強制する必要がある場合は、リファクタリング自体に
/no-invalid-statesスキルを適用してください。 - 競合: 標準が、ユーザーまたはプロジェクトの明示的な決定と競合する場合は、その決定に従い、意図的に適用しなかった標準を記録してください。
レビュー基準
- 問題が
/never-twiceの判定基準を通過した後の、該当箇所だけを直す修正。変更によって再発を防げるのか(テスト、型、ツール)、それとも目の前のケースにパッチを当てるだけなのか。 /never-twiceの判定基準を通過した問題を、到達可能な最高段階に達することなく再度修正すること。型や構造、テスト、トリップワイヤー、パイプラインの修正、パイプラインに手が届かない場合はユーザーへの提案、いずれも不可能な場合は負債として記録したルールのいずれかを実施してください。- 形や型、または何かが存在することだけを検証するテスト。
- 1つの入力軸だけが異なり、1つのパラメーター化されたケースリストにまとめるべき手書きのテスト関数。
- 防御対象のバグで失敗するところを一度も確認していないガードテスト。
- それがなくても明白に失敗するケースや、ツールチェーンが自動で修正するケースを検出するチェック。または、プロジェクトが依存しているにもかかわらず「いずれにせよ失敗する」としてテストされていない、表面化しない失敗。
- 読み込むソースをそのまま言い換える新しいテスト(
needsを YAML 内のリストに固定するワークフローテスト、定数を自身のリテラル値に固定するテスト、配布される設定ファイルを解析して同じ値を再検証するテストなど)、または、テスト名や最初の行で、これがなければ何が気付かれないまま変わるのかを示していないテスト。 - PR 本文やランディングレポートに削除対象の全数調査を記載する代わりに、独自の振る舞いを持たない削除のために作られたテスト。
- 実データから記録したフィクスチャ、それを示す由来に関するコメント、または既定の出力先やリポジトリ内の出力先を持つ、実データを測定するツール。
- 特殊扱い:変動する軸をパラメーターにすべきなのに、既存ロジックをほぼ複製した新しいコード。
- 差分を小さく保つために追加された複雑さ。より明快なリファクタリングや、より強い型で対処できるフラグ、ネスト、繰り返しのチェックなど(型レベルの修正については
/no-invalid-statesスキルを参照してください)。 - リポジトリにすでにある適切なライブラリやツールが担う処理を全面的に担う、手書きのコード。そのコードが追加、移動、変更、再利用、または依存される場合が該当します。指摘では、ライブラリ名と、そのライブラリが担う処理を明記してください。ライブラリで対処できる種類の変更なのに、その記録(ブリーフ、次に PR 本文またはランディングレポート)にライブラリも検索も記載されていない場合も該当します。
- スキルのスクリプトをリポジトリにコピーすること。また、推移的依存関係やライブラリのプライベートモジュールを、リポジトリにすでに存在するものとして数えるライブラリに関する指摘。
- コードから読み取れること、つまりコードの動作、型、制御フロー、履歴、代替案を説明するコメント。
- 読者が一度で把握できないコメント。均一な形式(段落、または2文以内の簡潔な説明なしに、すべての事実をそれぞれ独立した行に並べたもの)、1文に複数の考えを詰め込んだもの、上限に収めるために文章を詰め込んだもの。
- 回避策を正当化する段落の長さのコメント(コメントだけでなく、根本のコードを指摘してください)。
- ツールが出力し、曖昧さなく修復できる状態を拒否する境界処理、ツールが読み込むだけの入力を書き換える処理、不正な入力を後続の処理で失敗するまで通す処理。また、ルールを明記せず、弁明するコメントが付いた修復処理。
- 最初の関数より後にあるモジュール定数、呼び出し先より前に置かれていない関数、分割すべき箇所にあるセクション区切り、名前を付けられる2つの概念を含む関数、独立した概念ではないのに呼び出し元から切り離された呼び出し元が1つだけの処理、分割するか理由を添えて設定レベルに引き上げる代わりにインラインで抑制された複雑さの指摘、または言語ページの下限より厳しいリント上限。
- ネストした条件式、条件付きスプライス、キー付きテーブルなら一度で読み取れるのに最初に一致したものを検索する処理、条件内の代入、制御フローとしての
and/or、本体がelseで囲まれたガード、continueで省略できる処理をネストしたループ、または言語が取得と解放を結び付けているのに手書きされた後始末ブロック。 - 条件判断の間に空行がない関数本体、型が指定されていないシグネチャ、言語の形式に沿ったドキュメントコメントがない公開項目、短い段落3つを超える docstring、または関数の振る舞いを語るだけで戻り値を述べない docstring、モジュールの利用者が触れられるモジュールレベルまたは属性の名前がアンダースコアで始まるもの。
- 関数やモジュールに処理を転送するだけのバレルファイル、再エクスポート用のシム、または中継関数。
- 2つの主要なものを含むファイル、複数のファイルに分散した概念、含む内容と異なる名前のファイル、
records、constants、utilモジュール以外で独立したモジュールに置かれた、呼び出し元が1つだけのヘルパーまたは定数、フォルダー内のものと内部テンプレートが異なる兄弟ファイル、または兄弟段階で表記が異なる概念。 - 変更したパスを修正せずに残す移動(インポーター、ワークフローやマニフェストのパス、コメント、移動したファイル内の相対パスなど)、同じ PR で移動対象のパス以外のコードも編集すること、またはエクスポートの全数調査とテスト数の記録がない移動。ファイルの移動は「変更が増えるだけ」という理由で、分かりにくいレイアウトを維持すること。
- 作業パッケージ、フェーズ、コードネーム、指摘番号などの計画用成果物を、コードやコメントで参照すること。
- コードや別のドキュメントから推測できる内容(レイアウトツリー、強制されるチェックリスト、モジュールの動作など)、長い段落、または本文を固定するテストを含む AGENTS.md や CLAUDE.md。
- コミットメッセージや PR の説明にある、帰属を示す行や、固定幅で改行された本文。
- チェックして失敗する処理、または修正を書き込んで失敗する処理以外のことを行うプレコミットフック。ステージング、コミット、書き込みを行う Git コマンド、修正後に成功する処理、ネットワークアクセス、インストール、ツールの取得などが該当します。 上記の基準に照らして指摘事項を評価します。各基準はそれぞれ一つの項目に対応しています。構成とレイアウトの基準はデフォルトです。これらに関する指摘事項では、どのようにすれば読みやすくなるかを示しますが、著者が一文で説明できる逸脱であれば、そのままで問題ありません。
参考資料
言語を問わず適用される基準(各ページに一つずつ):
references/design.md:問題の種類を正すこと、最低限の品質を守ること、特殊ケースより汎用性を優先すること(概念ごとにパイプラインを一つにする、DRY の境界を設ける)、労力より保守性を優先すること、ライブラリを優先すること、境界で問題を解決することreferences/tests.md:テストの最低基準、ずれの確認、ガードテストの証明、削除時の全数確認ルール、手書きのフィクスチャreferences/comments.md:良いコメントに含める内容、先に説明してから例を示すこと、二つの質問によるテスト、具体例、TODO の禁止、計画への参照references/shape.md:モジュールのレイアウト、使用前の定義、関数ごとに一つの概念、ガードと早期リターン、分かりにくいコードを明快にする表、段落の具体例、型とドキュメントreferences/structure.md:バレル、互換性のための再エクスポート、エスコート関数、移行の段階分け、予測可能なレイアウトとそのツリー例、純粋な移動のみの PR、再編成後の目標レイアウトreferences/artifacts.md:簡潔な AGENTS.md、内容のみを記述するコミットメッセージと二つの例外、チェックのみを行いコミットはしないフック
各言語での構成とバレルのルール、そのリンターの最低基準と慣用表現:
references/languages/python.md:ruff の設定ブロック、順序チェッカー、__all__、with、Google スタイルの docstringreferences/languages/typescript.md:biome の設定ブロック、no-use-before-define、オプションオブジェクト、usingreferences/languages/rust.md:clippy のしきい値、let ... else、Dropガード、mod.rsreferences/languages/go.md:golangci-lint の設定ブロック、defer、オプション構造体、パッケージを単位とすること