Imported from aidotters/document-parser-evaluation (
.codex/skills/validation/SKILL.md). Install upstream withnpx skills add aidotters/document-parser-evaluation --skill validation. Copyright stays with the author.
Validation スキル
実装コードの品質検証と要件との整合性確認を行うスキルです。
スキルの目的
- スペック(要件/設計)との整合性確認
- コード品質(コーディング規約、ベストプラクティス)の検証
- テストカバレッジの確認
- セキュリティの検証
- パフォーマンスの検証
- 検証レポートの生成
使用タイミング
このスキルは以下のスキルから呼び出されます:
- validate-code: コード品質の検証
- acceptance-test: 受け入れ条件の検証
モード1: スペックとの整合性
目的
requirements.md/design.mdの仕様とコードの対応を確認します。
手順
-
要件の抽出
Read('[steeringディレクトリ]/requirements.md') → 「受け入れ条件」セクションから条件リストを抽出 -
設計の抽出
Read('[steeringディレクトリ]/design.md') → クラス設計、インターフェース、データフローを抽出 -
条件の分類
- 自動検証可能: コードの存在、API仕様、設定値など
- 手動確認必要: 動作確認、UX、パフォーマンスなど
-
自動検証の実行
各条件について:
# 例: 「XxxAnalyzerクラスが存在する」 Grep('class XxxAnalyzer', 'minitools/') # 例: 「設定ファイルにYYYY項目がある」 Grep('YYYY', '.env') # または src/config.py のパターン # 例: 「インターフェースが設計通り」 Grep('def fetch\(', '[対象ファイル]') -
結果の照合
- 条件ごとに PASS / FAIL / NEEDS_REVIEW を判定
- 根拠となるコード箇所を記録
出力形式
## スペックとの整合性
### 要件トレーサビリティ
| 要件ID | 条件 | 結果 | 根拠 |
|--------|------|------|------|
| REQ-01 | {条件1} | PASS | {ファイル}:{行} |
| REQ-02 | {条件2} | FAIL | 該当コードなし |
| REQ-03 | {条件3} | NEEDS_REVIEW | 手動確認必要 |
### 設計との整合性
| 設計項目 | 期待 | 実装 | 結果 |
|----------|------|------|------|
| {クラス名} | {設計仕様} | {実装状況} | PASS/FAIL |
| {メソッド名} | {シグネチャ} | {実装状況} | PASS/FAIL |
モード2: コード品質
目的
コーディング規約とベストプラクティスへの準拠を検証します。
手順
-
ruff check の実行
Bash('ruff check [対象パス] --output-format=grouped') -
ruff の結果解析
- エラー数、警告数をカウント
- カテゴリ別に分類(E: エラー、W: 警告、F: pyflakes、B: bugbear)
- 重大な問題(E9xx系など)を抽出
-
mypy の実行
Bash('mypy [対象パス] --show-error-codes') -
mypy の結果解析
- 型エラーの数と種類を分類
- 未解決のimportエラーを特定
- any型の過剰使用を検出
-
ベストプラクティスの確認
- 適切なエラーハンドリング
- ログ出力の適切さ
- 関数/クラスの単一責任
- DRY原則への準拠
チェック項目
| カテゴリ | チェック内容 |
|---|---|
| 命名規則 | PEP8準拠、プロジェクト規約 |
| インポート | 順序、未使用インポート |
| 型ヒント | 関数シグネチャ、戻り値 |
| ドキュメント | docstring、コメント |
| 複雑度 | 関数の長さ、ネスト深度 |
| 重複 | コピペコード検出 |
出力形式
## コード品質
### 静的解析結果
#### ruff check
- **合計**: {N}件の問題
- エラー (E): {N}件
- 警告 (W): {N}件
- pyflakes (F): {N}件
- bugbear (B): {N}件
| ファイル | 行 | コード | 内容 | 優先度 |
|----------|-----|--------|------|--------|
| {path} | {line} | {code} | {message} | 高/中/低 |
#### mypy
- **合計**: {N}件の型エラー
| ファイル | 行 | コード | 内容 |
|----------|-----|--------|------|
| {path} | {line} | {code} | {message} |
### ベストプラクティス
| 項目 | 状態 | コメント |
|------|------|----------|
| エラーハンドリング | OK/NG | {詳細} |
| ログ出力 | OK/NG | {詳細} |
| 単一責任 | OK/NG | {詳細} |
| DRY原則 | OK/NG | {詳細} |
モード3: テストカバレッジ
目的
テストの網羅性と品質を確認します。
手順
-
テストファイルの存在確認
Glob('tests/**/test_*.py') → 対象モジュールに対応するテストファイルを特定 -
テスト実行とカバレッジ計測
Bash('pytest [対象テスト] --cov=[対象モジュール] --cov-report=term-missing') -
カバレッジ分析
- 行カバレッジ率
- 未カバー行の特定
- 分岐カバレッジ(可能な場合)
-
テスト品質の確認
- 正常系テストの存在
- 異常系テストの存在
- エッジケースのテスト
- モックの適切な使用
チェック項目
| 項目 | 基準 |
|---|---|
| カバレッジ率 | 80%以上を推奨 |
| 主要パス | 全ての主要機能がテスト済み |
| エッジケース | 境界値、空値、異常値 |
| エラーケース | 例外発生時の動作 |
出力形式
## テストカバレッジ
### カバレッジサマリー
| モジュール | 行数 | カバー | 率 |
|------------|------|--------|-----|
| {module1} | {total} | {covered} | {rate}% |
| {module2} | {total} | {covered} | {rate}% |
| **合計** | {total} | {covered} | **{rate}%** |
### 未カバー箇所
| ファイル | 行 | 内容 | 理由 |
|----------|-----|------|------|
| {path} | {lines} | {description} | {reason} |
### テスト品質
| 種類 | 件数 | 状態 |
|------|------|------|
| 正常系テスト | {N} | OK/不足 |
| 異常系テスト | {N} | OK/不足 |
| エッジケース | {N} | OK/不足 |
モード4: セキュリティ
目的
セキュリティ上の脆弱性やリスクを検出します。
手順
-
ハードコードされた機密情報の検出
Grep('password|secret|api_key|token', '[対象パス]', ignore_case=True) Grep('AKIA|sk-|ghp_', '[対象パス]') # AWS/OpenAI/GitHub keys -
危険なパターンの検出
# SQLインジェクション Grep('execute\(.*%s|execute\(.*\.format', '[対象パス]') # コマンドインジェクション Grep('os\.system|subprocess\.call.*shell=True', '[対象パス]') # 安全でないデシリアライズ Grep('pickle\.load|yaml\.load\(', '[対象パス]') # eval/execの使用 Grep('eval\(|exec\(', '[対象パス]') -
入力検証の確認
- ユーザー入力のサニタイズ
- ファイルパスのバリデーション
- URL/外部入力の検証
-
依存関係の脆弱性チェック
Bash('pip-audit') # 利用可能な場合
チェック項目
| カテゴリ | チェック内容 | 重大度 |
|---|---|---|
| 機密情報 | ハードコード、ログ出力 | 高 |
| インジェクション | SQL、コマンド、XSS | 高 |
| 認証/認可 | 適切なチェック | 高 |
| 入力検証 | サニタイズ、バリデーション | 中 |
| 暗号化 | 適切なアルゴリズム | 中 |
| エラー処理 | 情報漏洩防止 | 中 |
出力形式
## セキュリティ
### 検出された問題
| 重大度 | カテゴリ | ファイル | 行 | 内容 |
|--------|----------|----------|-----|------|
| 高 | {category} | {path} | {line} | {description} |
| 中 | {category} | {path} | {line} | {description} |
### 詳細
#### [高] {問題タイトル}
- **場所**: {ファイル}:{行}
- **問題**: {詳細説明}
- **リスク**: {影響範囲}
- **推奨対応**: {修正方法}
### セキュリティチェックリスト
| 項目 | 状態 |
|------|------|
| 機密情報のハードコード | OK/NG |
| SQLインジェクション対策 | OK/NG/N/A |
| コマンドインジェクション対策 | OK/NG/N/A |
| 入力バリデーション | OK/NG |
| エラーメッセージの安全性 | OK/NG |
モード5: パフォーマンス
目的
パフォーマンス上の問題やボトルネックを検出します。
手順
-
非効率なパターンの検出
# N+1クエリパターン Grep('for.*in.*:.*\n.*fetch|for.*in.*:.*\n.*query', '[対象パス]') # 非効率なループ内処理 Grep('for.*:.*\n.*\.append\(', '[対象パス]') # 同期的なI/O Grep('requests\.get|requests\.post', '[対象パス]') # async推奨の場合 -
リソース使用の確認
# 大きなデータのメモリ展開 Grep('\.read\(\)|list\(.*generator', '[対象パス]') # ファイルハンドルのリーク Grep('open\((?!.*with)', '[対象パス]') # コネクションプール未使用 Grep('aiohttp\.ClientSession\(\)', '[対象パス]') -
async/await の適切な使用
# 同期関数内でのasync呼び出し Grep('asyncio\.run\(', '[対象パス]') # await漏れ Grep('(?<!await )async_function\(', '[対象パス]') -
キャッシュの活用確認
- 重複計算の有無
- メモ化の適用可能性
チェック項目
| カテゴリ | チェック内容 | 影響度 |
|---|---|---|
| I/O効率 | 非同期処理、バッチ処理 | 高 |
| メモリ | 大量データ処理、リーク | 高 |
| アルゴリズム | 計算量、データ構造 | 中 |
| キャッシュ | 重複計算、メモ化 | 中 |
| 並行処理 | セマフォ、スレッド安全 | 中 |
出力形式
## パフォーマンス
### 検出された問題
| 影響度 | カテゴリ | ファイル | 行 | 内容 |
|--------|----------|----------|-----|------|
| 高 | {category} | {path} | {line} | {description} |
### 詳細
#### [高] {問題タイトル}
- **場所**: {ファイル}:{行}
- **問題**: {詳細説明}
- **影響**: {パフォーマンスへの影響}
- **推奨対応**: {最適化方法}
### パフォーマンスチェックリスト
| 項目 | 状態 | コメント |
|------|------|----------|
| 非同期I/O活用 | OK/NG | {詳細} |
| メモリ効率 | OK/NG | {詳細} |
| N+1問題 | OK/NG | {詳細} |
| リソース解放 | OK/NG | {詳細} |
| 適切な並行数 | OK/NG | {詳細} |
モード6: レポート生成
目的
全検証結果を統合し、最終レポートを生成します。
レポート構造
# 検証レポート
> 生成日時: {YYYY-MM-DD HH:MM}
> 対象: {機能名 / steeringディレクトリ}
## エグゼクティブサマリー
| 検証項目 | 結果 | 詳細 |
|----------|------|------|
| スペック整合性 | {PASS/FAIL} | {充足率}% |
| コード品質 | {PASS/FAIL} | {問題数}件 |
| テストカバレッジ | {PASS/FAIL} | {カバレッジ率}% |
| セキュリティ | {PASS/FAIL} | {高}件/{中}件 |
| パフォーマンス | {PASS/FAIL} | {問題数}件 |
| **総合判定** | **{PASS/FAIL/CONDITIONAL_PASS}** | |
## 1. スペックとの整合性
{モード1の出力}
## 2. コード品質
{モード2の出力}
## 3. テストカバレッジ
{モード3の出力}
## 4. セキュリティ
{モード4の出力}
## 5. パフォーマンス
{モード5の出力}
## 6. 問題点と推奨事項
### 優先度: 高(修正必須)
- {問題1}: {推奨される対応}
### 優先度: 中(修正推奨)
- {問題2}: {推奨される対応}
### 優先度: 低(検討事項)
- {問題3}: {推奨される対応}
## 7. 次のアクション
- [ ] {必要なアクション1}
- [ ] {必要なアクション2}
判定基準
各項目の合否
| 項目 | PASS条件 | CONDITIONAL_PASS条件 |
|---|---|---|
| スペック整合性 | 100%充足 | 90%以上充足 |
| コード品質 | エラー0件 | 軽微な警告10件以下 |
| テストカバレッジ | 80%以上 | 60%以上 |
| セキュリティ | 高0件、中0件 | 高0件、中3件以下 |
| パフォーマンス | 高0件 | 高0件、中3件以下 |
総合判定
| 条件 | 判定 |
|---|---|
| 全項目PASS | PASS |
| 高優先度の問題が1件以上 | FAIL |
| CONDITIONAL_PASSが1項目以上 | CONDITIONAL_PASS |
トラブルシューティング
ruff/mypyが見つからない場合
Bash('uv sync --dev')
pytestが実行できない場合
Bash('uv add --dev pytest pytest-cov')
検証対象が特定できない場合
- 最新の
.steering/ディレクトリを探す - git diffで変更ファイルを特定する
Bash('ls -t .steering/ | head -1')
Bash('git diff --name-only HEAD~5')