green-gate について
Dart と Flutter のパッケージを対象に、解析、フォーマット、テスト、カバレッジが同一ラウンドで確認できるまで反復する品質ゲートスキルです。MCP ツールで各ゲートを実行し、進展の停滞や判断の曖昧さがあればエスカレーションします。
主な機能
- 01解析・フォーマット・テスト・カバレッジのゲート
- 02各ラウンドですべてのゲートを再確認
- 03客観的な失敗を自動修正
- 04カバレッジに基づくテスト改善
- 05停滞や曖昧さがあればエスカレーション
活用シーン
- 01リリース前の Dart パッケージ検査
- 02解析やテストの失敗への対処
- 03未カバーコード向けテストの追加
- 04Flutter パッケージ品質の検証
MCP 対応
Dart の解析、フォーマット、カバレッジ付きテストに MCP ツールを使用します。記載された Claude Code の手順ではシェルの同等コマンドを使わず、MCP サーバーがない他の環境ではコマンドラインを使用できます。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ verygoodopensource/ vgv-ai-flutter-plugin --skill green-gateインストール後、Claude Code で/green-gateを入力して読み込まれたか確認します。
同梱ファイルagents/openai.yamlreferences/coverage.md
詳細
Green Gate
Dart および Flutter パッケージ向けの自律型品質ゲートループです。analyze、format、test、coverage の4つのゲートを実行し、実際のツール出力を読み取り、失敗を修正するためにコードとテストを編集して、観測された数値とともに、4つすべてが同時に合格したことを最終イテレーションで確認できるまでループします。客観的な失敗には自律的に対処し、停滞、真の曖昧さ、またはインフラストラクチャの障害がある場合にのみエスカレーションします。
このスキルはツールを調整し、ファイルを編集します。テストの作成方法は testing スキルに委ねており、モック、構成、カバレッジパターンに関するガイダンスを重複させることはありません。
基本標準
Green Gate の作業すべてに、以下を適用します。
- MCP ツールのみを使用し、Bash による代替手段は使わない — analyze には
mcp__dart__analyze_files、format にはmcp__dart__dart_format、test と coverage にはmcp__very-good-cli__testを使用します。各ゲートには MCP ツールがあり、シェルコマンド経由で実行するものはありません。Bash によるテスト実行方法(very_good test、flutter test、dart test)はblock-cli-workarounds.shによってフックでブロックされ、拒否されます。また、Bash 経由のdart analyze/dart formatは MCP ツールと重複します。 ループで実行する唯一の Bash は、テスト結果にLines not covered:ブロックが含まれない場合のcoverage/lcov.infoの解析用フォールバックのみです。 この MCP のみというルールは、フックによって強制される Claude Code の制約です。このフックは他のホストでは実行されません。ハーネスをまたぐ場合のフォールバック: フックがなく、MCP サーバーにも接続されていないホストでは、MCP サーバーがないことを理由に停止せず、代わりに同等のdart analyze、dart format、very_good testCLI コマンドを実行します。 - 計画のみの依頼も、このスキルの対象です — ユーザーがどのツールをどの引数で使うか、またはゲートをどの順番で実行するかを尋ね、まだ実行を希望していない場合は、このスキルに基づいて回答します。つまり、重要となる優先順位ルールとともに、ゲートの順番に従って同じツール呼び出し(
applyFixes: trueを指定したmcp__dart__analyze_files、mcp__dart__dart_format、カバレッジパラメーターを指定したmcp__very-good-cli__test)を案内します。ループが実際に実行するツールの代わりに、即席のflutter analyze/flutter test --coverageシェルプランを提示してはいけません。 - 成功状態をキャッシュしない — ラウンドごとにすべてのゲートを再評価します。analyze または test の失敗を修正したり、新しいテストファイルを作成したりすると、format とカバレッジの分母の両方に影響するため、以前に合格したゲートが再び不合格になる可能性があります。
- 観測された数値に基づいてのみ終了する — analyze に問題がなく、format が変更ゼロを報告し、すべてのテストが合格し、
min_coverageが満たされていることを、すべて同じラウンドで確認できた最終イテレーションの後にのみループを終了します。 coverage: true、min_coverage、check_ignore: true、show_uncovered: trueを同時に渡す —coverage: trueを省略するとlcov.infoが出力されず、設定ミスと同様の状態になります。check_ignore: trueを省略すると、// coverage:ignoreによる対処が機能しません。show_uncovered: trueを省略すると、ファイルごとの未カバー行が結果から除外され、ツールから返されるはずだった情報を得るために、ループが lcov ファイルを参照することになります。show_uncoveredは、プラグインの最小バージョンであるvery_good_cli1.5.0 で追加されました。- テストの作成は
testingスキルに委ねる — 修正にテストの作成が必要な場合は、構成、モック、命名について、そのスキルに従います。 - 症状ではなく根本原因を修正する — ゲートに合格するために基準を緩めてはいけません(失敗するアサーションを削除したり、作業を避けるために目標値を下げたり、到達可能なコードに
// coverage:ignoreを付けたりしないでください)。真の製品や API に関する判断が必要な場合は、推測せずにエスカレーションします。 - 客観的な失敗には自律的に対処する — アナライザーのエラー、失敗したテスト、カバレッジの不足は、再度指示を求めずに修正します。マトリックスに従い、該当する場合にのみエスカレーションします。
ループ
各パッケージルート(再帰 / モノレポを参照)について、次のアルゴリズムを実行します。
- 検出 — パッケージルート(
directory引数またはワークスペースルート)を解決し、pubspec.yamlが存在することを確認します。ループの状態(反復カウンター0、空のフィンガープリント、空の変更対象ファイルセット)を初期化します。 - 分析 —
mcp__dart__analyze_filesをapplyFixes: trueで実行します。エラーが残っている場合、これが有効なゲートです。修正してフィンガープリントを記録し、ステップ 7 に進みます。 - フォーマット — パッケージルートで
mcp__dart__dart_formatを実行します。パッケージ全体をその場で再フォーマットします。変更されたファイルが報告された場合、次のラウンドではこのゲートは合格になります。 - テスト — 今回のラウンドで分析が合格した場合にのみ実行します。テストゲートのカバレッジパラメーターを使用して
mcp__very-good-cli__testを実行します。テストが失敗した場合は、修正してフィンガープリントを記録し、ステップ 7 に進みます。 - カバレッジ — 今回のラウンドでテストに合格した場合にのみ実行します。MCP の
min_coverageの結果を合否判定の正式な基準とし、Lines not covered:ブロックでファイルごとの修正対象を確認します。このブロックがない場合に限り、coverage/lcov.infoを解析します。目標未達の場合は、カバレッジが低いファイルのうち優先度の高いものに対するテストを(testingスキルを使用して)作成し、ステップ 7 に進みます。 - 終了 — この同じ反復ですべてのゲートに合格した場合は、観測された数値を確認して成功を確定し、停止します。これが唯一の合格終了経路です。
- 再検証 — 反復カウンターを増やし、失敗フィンガープリントを再計算して、エスカレーションのトリガー(進展なし、振動、上限)を確認します。トリガーが発生した場合はエスカレーションし、それ以外の場合はステップ 2 に戻ってすべてのゲートを再評価します。
1 回で完了する変更なしの経路 — すでにすべてのゲートに合格しているパッケージに対して実行します。反復 1 で分析に問題がなく、フォーマットによる変更が 0 件と報告され、すべてのテストに合格し、カバレッジが目標以上であることを確認します。ループは合格を確認して終了し、ファイルを 1 つも編集しません。合格済みのパッケージの検証にかかる反復は正確に 1 回です。
ループの状態
反復をまたいで引き継がれる状態です。これがないと、「進展なし」かどうかを判定できません。
| 状態 | 目的 |
|---|---|
| 反復カウンター | 上限(既定ではパッケージごとに 5 回)を適用する |
| ゲートごとの失敗フィンガープリント(前回) | 進展なしや振動を検出する |
| 今回のラウンドで変更したファイル | 変更なしのラウンドと進展なしのラウンドを区別し、エスカレーション報告に記載する |
ゲートごとのフィンガープリントキー:
| ゲート | フィンガープリント |
|---|---|
| 分析 | diagnosticCode @ file:line のソート済みセット |
| フォーマット | フォーマットゲートが書き換えたファイルのセット(空 = 合格) |
| テスト | 失敗したテスト ID / 名前のセット |
| カバレッジ | 観測された割合 + カバレッジ不足のファイルパスのソート済みセット |
定義:
- 進展なし — 現在の失敗フィンガープリントが前回のラウンドと同一、または失敗数が減少していない状態です。エスカレーションします。
- 振動 — 2 つの同じゲートが、連続する 2 回のラウンドで合格 / 不合格を交互に繰り返す状態です(例:フォーマット修正によって分析が再び失敗し、その修正によってフォーマットが再び失敗する)。エスカレーションします。
ゲートの優先順位
固定順序:analyze → format → test → coverage。この順序を定めるルールは2つあります。
- このラウンドでは、上流のゲートがグリーンになるまで下流のゲートを評価しません。 アナライザーでエラーが発生するとテストのコンパイルに失敗する可能性があります。テストが通らない状態ではカバレッジに意味はありません。コンパイルに失敗した後にカバレッジの問題を診断してはいけません。analyze の後に format を実行するのは、analyze の
applyFixesが書き換えようとしているコードに対して、format が再フォーマットを繰り返さないようにするためです。 - すべてのゲートを各ラウンドで再評価します。グリーンの状態はキャッシュされません。 終了するには、最後の反復で4つすべてがグリーンである必要があります。
Analyze ゲート
mcp__dart__analyze_filesをapplyFixes: trueで実行し、診断結果が返る前にクイックフィックスを適用します。rootsには[{ root: "file:///abs/path" }]を渡します。これはパッケージルートを示すfile:URI です。再帰フラグはありません。スキルがパッケージルートを自ら列挙して、それぞれを渡します。- エラーがゼロであればゲートはグリーンです。エラー重大度の診断はブロッキングとして扱います。修正対象の範囲内にある警告や情報も解消しますが、無関係な既存の情報メッセージによってゲートをブロックしてはいけません。
- フックとの相互作用 — PostToolUse の
analyze.shフックは Edit/Write のたびに実行され、修正によって新たな analyze エラーが発生すると、終了コード 2 でブロックします。この拒否は別の失敗モードではなく、同じラウンドにおける analyze ゲートからのフィードバックとして扱います。編集は反映されていないため、修正内容を見直してください。
Format ゲート
- 各ラウンドで
mcp__dart__dart_formatを実行します。rootsにはanalyze_filesと同じ[{ root: "file:///abs/path" }]の形式を渡します。オプションのpathsは省略し、パッケージ全体をその場でフォーマットします。これにより、ゲートは対象ファイルを確認する方式になります(ループ内で編集したファイルだけでなく、手動編集や既存のフォーマットのずれも検出します)。また、自動修正も行われるため、1回の呼び出しでパッケージがグリーンになり、2回目の呼び出しでは変更がゼロと報告されます。 - ステータスではなく変更数を確認します — ツールは書き換えの有無にかかわらず成功するため、エラーのない結果だけでは何も証明されません。出力の末尾は
Formatted N files (M changed)となります。Mが0の場合にのみゲートはグリーンです。Mがゼロ以外のラウンドでは、ファイルはすでに修正されています。修正によってグリーンと判定するのではなく、次のラウンドでゲートを再実行し、0になることを確認してください。 - format がフックだけでなく実際のゲートである理由 — PostToolUse の
format.shフックが実行されるのは、ループ内で Edit/Write によって編集したファイルだけです。ループが触れない手動編集済みまたは既存の未フォーマットファイルがあると、ゲートがグリーンになった後に CI で失敗する可能性があります。パッケージ全体をフォーマットすることで、この抜けを防ぎます。
Test ゲート
mcp__very-good-cli__testをcoverage: true、min_coverage: <target>、check_ignore: true、show_uncovered: true、およびexclude_coverageglob(以下を参照)とともに実行します。- Dart と Flutter の使い分け — ツールが自動判定できるよう、
dartは省略します(Flutter プロジェクトが検出された場合は Flutter が実行されます)。純粋な Dart パッケージがツールによって誤判定される場合にのみ、dart: trueを渡します。 directory— パッケージがワークスペースのルートにない場合(モノレポのサブパッケージ)は指定します。pubspec.yamlがルートにある場合にのみ省略します。timeout_seconds— 常に上限を設定します(例:120)。Flutter テストでは、pumpAndSettle()をタイムアウトなしで実行すると、無期限にハングすることがあります。上限を設定するとループが停止するのではなく、実行を強制終了します。タイムアウトによる強制終了はテストの失敗ではなく、ツールの失敗です。マトリックスに従ってエスカレーションしてください。- すべてのテストが通ればゲートはグリーンです。テストの失敗は、実際のプロダクト上の判断を示すものでない限り、自律的に修正します(マトリックスに従ってエスカレーションしてください)。
カバレッジゲート
MCP の min_coverage 結果は合否判定の唯一の基準であり、show_uncovered: true を指定すると、ファイルごとの修正対象も含まれます。
Expected coverage >= 100.00% but actual is 33.33%.
Lines not covered:
- lib/src/weather_repository.dart: 4, 5
そのブロックからファイルを順位付けします。coverage/lcov.info の解析は、そのようなブロックがない結果に対するフォールバックです。lcov は診断対象とは別の実行によって残された可能性がありますが、結果は古くなることがありません。
- デフォルトの目標値は
100(VGV の標準)で、実行ごとに上書き可能です(例:レガシーまたは非テンプレートのパッケージでは80)。生成ファイルはexclude_coverageによって分母から除外され、check_ignore: trueによって// coverage:ignoreが尊重されるため、100% はテスト可能な手書きコードの100%を意味します。 - デフォルトの
exclude_coverage—**/*.{g,freezed,gen}.dartと生成ディレクトリおよび l10n ディレクトリです。glob 文字列は1つです(波括弧展開を使用します。CLI ビルドで機能しない場合は**/*.g.dartにフォールバックします)。 coverage: true、min_coverage、check_ignore: true、show_uncovered: trueをまとめて指定します — Core Standards を参照してください。- 結果に
Lines not covered:ブロックが含まれない場合は、references/coverage.mdに従ってcoverage/lcov.infoにフォールバックします。このドキュメントでは、show_uncovered自体、lcov が存在しない3つの原因、古い lcov の処理、lcov レコードのフィールド(SF/LF/LH/DA)、フォールバックがゲートと同じ基準を使うルール、およびcheck_ignoreが Dart のみに適用される制限を扱います。
修正
- 失敗した項目のみ修正します — 今回検出された診断、テスト、またはカバレッジ不足のファイルに対処します。無関係なコードはリファクタリングしません(YAGNI)。
- カバレッジの修正ではテストを作成します — カバレッジ不足のファイルを順位順に確認し、それぞれについて
testingスキルに沿ったテストを作成します。未カバーの行数を基準にファイルの優先順位を決めます。行数は、結果に記載されたファイルごとの行番号、または lcov フォールバックのLF - LHを使用します。 - 1回の作業で修正するファイル数を絞ります — 関連するまとまりごとに修正してから再検証します。バッチごとにゲートを再実行することで「進捗なし」を検出でき、別のゲートをひそかに壊しながら1つのゲートだけを修正する事態を防げます。
エスカレーション
次の場合は作業を中止し、ユーザーに状況を伝えます:
| トリガー | 詳細 |
|---|---|
| ラウンド間で進展がない | 失敗フィンガープリントが同一、または悪化していない |
| 振動 | 2 つのゲートが、2 ラウンドにわたって交互に緑/赤になる |
| 上限に到達してもゲートが赤のまま | 終了条件です。各ゲートの残りの失敗をフィンガープリントとともに報告します |
| 実際のバグによるテスト失敗 | コーディングミスではなく、実際の製品上の判断に見える失敗 |
| 修正が曖昧 | 有効な解決策が複数ある場合(例:API の変更と lint の抑制)です。根本原因への対処を優先し、製品や API に関する判断であればエスカレーションします |
| 到達不能コードのカバレッジ不足 | 100% を追求するのではなく、// coverage:ignore を提案します(check_ignore: true が必要です。Dart のみ) |
| 分母の整備 | 生成ファイルが除外用 glob に一致しない場合は、// coverage:ignore ではなく exclude_coverage の範囲を広げます |
| ツール/フックの失敗 | MCP テストのタイムアウト(timeout_seconds による強制終了)、アナライザーのクラッシュ、CLI が見つからずフックで拒否された場合(インストールヒント dart pub global activate very_good_cli を添えてエスカレーション)、または修正後も必要な編集を妨げる _analyze.sh_ の拒否が繰り返される場合です。拒否が 1 回だけなら、ループ内の analyze ゲートからのフィードバックです(Analyze Gate を参照)。エスカレーションには該当しません |
| エスカレーションする際は、赤信号になっているゲート(analyze、format、test、coverage)を明記し、 | |
| そのフィンガープリントの項目をそのまま記載してください(analyze の場合は | |
diagnosticCode @ file:line、test の場合は失敗したテスト名、coverage の場合はカバレッジ不足のファイルパス)。 | |
| 変更したファイル、反復回数、ユーザーが決定する必要がある事項を1つ示してください。 | |
| 単なる件数の要約(「エラーが4件残っています」)は報告ではありません。ユーザーが対処できないためです。 |
引き続き作業するという継続的な指示があっても、トリガーは無効になりません。「何度でも再試行して、こちらには戻ってこないで」という指示は、変化が止まったフィンガープリントに予算を費やしてよいという意味ではありません。トリガーに達したら停止し、報告して待ってください。
再帰処理/モノレポ
- すべてのパッケージで成功する必要があります — 失敗しても続行し(失敗したパッケージをすべて修正し)、 その後、各パッケージの結果を確認してください。1つのパッケージのゲートが赤でも、ほかのパッケージを中止しないでください。
- パッケージごとの反復予算 — 上限の5回は全体ではなく、パッケージごとに適用されます。そのため、 12パッケージのモノレポでも、最初のパッケージで全体の予算を使い切ることはありません。
- パッケージルートの共通検出 —
pubspec.yamlファイルを探して走査してください。analyze_filesのrootsセットは、mcp__very-good-cli__test --recursive(recursive: true)が対象とするパッケージのセットと一致させる必要があります。 - lcov のフォールバックパスは
<package>/coverage/lcov.info— 検出した各ルートに対して解決します。 - 単一の
min_coverageをすべてのパッケージに適用 — 文書化されている制限事項:ツールのスキーマには、パッケージごとのカバレッジ上書き設定がありません。カバレッジを確認する際は、共通の目標値を明記してください。
追加リソース
references/coverage.md— green-gate のカバレッジゲートの詳細(デフォルトの目標値、除外グロブ、show_uncovered、lcov のフォールバックとそのフィールド、判断ツリー、check_ignore、古い lcov)。testingスキル — テストの規約と、ファイルごとの不足を解消するためのカバレッジリファレンス。