476 lines
16 KiB
Markdown
476 lines
16 KiB
Markdown
---
|
||
description: プロンプトベースで対話的に仕様を策定し、TDD前提のタスクに分解する(ネガティブチェック・認知バイアス除去含む)
|
||
argument-hint: "<要望内容>" [--id=custom-id]
|
||
allowed-tools: Bash, Read, Write, Edit, Glob, AskUserQuestion
|
||
---
|
||
|
||
# プロンプトベース仕様策定・タスク分解
|
||
|
||
プロンプトで記述された要望を、対話を通じて**網羅的な仕様**(正常系・異常系・エッジケース)に昇華し、TDD前提の実装タスクに分解します。
|
||
|
||
## 実行モード
|
||
|
||
```bash
|
||
/task-spec "ユーザー認証機能を実装したい"
|
||
/task-spec "データ検索APIを作りたい" --id=search-api
|
||
```
|
||
|
||
## 実行フロー
|
||
|
||
### Phase 1: 網羅的仕様策定(20-30分)
|
||
|
||
#### Step 1: 要望分析
|
||
```bash
|
||
# ユーザープロンプト解析
|
||
- キーワード抽出(認証、API、UI、データ処理など)
|
||
- 既存コードベースとの関連確認
|
||
- 初期スコープ推定
|
||
```
|
||
|
||
#### Step 2: ポジティブ仕様の明確化(5-8分)
|
||
|
||
対話形式で以下を確定:
|
||
|
||
```
|
||
=== Step 2: ポジティブ仕様の明確化 ===
|
||
|
||
Q1: 入力は何ですか?
|
||
(例: ユーザーID、メールアドレス、JSONペイロード)
|
||
|
||
Q2: 期待される出力は何ですか?
|
||
(例: 認証トークン、ユーザー情報、HTTPステータス)
|
||
|
||
Q3: 成功の条件を具体的に教えてください
|
||
(例: 「有効な認証情報で200 + JWT返却」)
|
||
|
||
Q4: 制約や前提条件はありますか?
|
||
(例: PostgreSQL使用、既存API互換性必須)
|
||
```
|
||
|
||
#### Step 3: ネガティブチェック(認知バイアス除去)(10-15分)
|
||
|
||
##### 3-1. 失敗シナリオ分析
|
||
|
||
```
|
||
=== Step 3-1: 失敗シナリオ分析 ===
|
||
Progress: ▓▓▓▓░░░░░░ (4/10)
|
||
|
||
確証バイアスを排除するため、「どこで壊れるか」を先に考えます。
|
||
|
||
Q: この機能が失敗する可能性があるケースを選択してください(複数選択可)
|
||
|
||
1. 入力が不正(型違い、範囲外、フォーマット不正)
|
||
2. 依存リソースが存在しない(ファイル、DB、API)
|
||
3. 権限不足・認証失敗
|
||
4. タイムアウト・ネットワークエラー
|
||
5. リソース枯渇(メモリ、ディスク、CPU)
|
||
6. 並行実行による競合
|
||
7. その他(自由記述)
|
||
|
||
選択: 1,2,3
|
||
|
||
→ 選択された各ケースについて詳細を質問
|
||
```
|
||
|
||
##### 3-2. エッジケース網羅
|
||
|
||
```
|
||
=== Step 3-2: エッジケース網羅 ===
|
||
|
||
正常系偏重を避けるため、境界値での振る舞いを確認します。
|
||
|
||
以下のケースで期待される動作を確認してください(該当するものにチェック):
|
||
|
||
□ 空文字列 / 空配列 / 空オブジェクト
|
||
→ どう処理すべきですか? (1. エラー / 2. デフォルト値 / 3. そのまま通す)
|
||
|
||
□ null / undefined / NaN
|
||
→ どう処理すべきですか? (1. エラー / 2. 無視 / 3. デフォルト値)
|
||
|
||
□ 最小値・最大値(数値、文字数、配列長)
|
||
→ 境界値は? (例: 0-255文字、1-100件)
|
||
|
||
□ 0, -1, Infinity
|
||
→ 許可しますか? 許可する場合の意味は?
|
||
|
||
□ 特殊文字(<>"'&;など)
|
||
→ エスケープ必要? どのレベルで?
|
||
|
||
□ 非ASCII文字(絵文字、全角、Unicode)
|
||
→ サポートしますか? 制限は?
|
||
|
||
□ 巨大なデータ(1MB超の文字列、10万件の配列)
|
||
→ 制限値は? 超えた場合の処理は?
|
||
```
|
||
|
||
##### 3-3. セキュリティリスク分析
|
||
|
||
```
|
||
=== Step 3-3: セキュリティリスク分析 ===
|
||
|
||
楽観バイアスを排除し、攻撃シナリオを想定します。
|
||
|
||
該当する脅威を選択してください(複数選択可):
|
||
|
||
1. XSS(クロスサイトスクリプティング)
|
||
- ユーザー入力を画面表示する箇所がある
|
||
|
||
2. SQLインジェクション
|
||
- SQL文を動的生成している
|
||
|
||
3. CSRF(クロスサイトリクエストフォージェリ)
|
||
- 状態変更操作(POST/PUT/DELETE)がある
|
||
|
||
4. 権限昇格
|
||
- 他ユーザーのデータにアクセスする可能性
|
||
|
||
5. DoS(サービス拒否)
|
||
- 大量リクエストで停止する可能性
|
||
|
||
6. 情報漏洩
|
||
- エラーメッセージに秘密情報が含まれる可能性
|
||
|
||
選択: 1,3,4
|
||
|
||
→ 各脅威に対する対策を質問
|
||
```
|
||
|
||
##### 3-4. 認知バイアスチェック
|
||
|
||
```
|
||
=== Step 3-4: 認知バイアスチェック ===
|
||
|
||
以下のバイアスを意識的に排除したか確認します:
|
||
|
||
✓ 確証バイアス
|
||
「うまくいくはず」ではなく「どこで壊れるか」を先に考えた
|
||
|
||
✓ 正常系偏重
|
||
正常系:異常系 = 1:3 の比率でテストケースを設計した
|
||
|
||
✓ 楽観バイアス
|
||
「たぶん大丈夫」を「証明されるまで信用しない」に変換した
|
||
|
||
✓ 可用性バイアス
|
||
「よくあるケース」だけでなく「レアだが致命的なケース」も網羅した
|
||
|
||
全てチェック完了後、次へ進みます。
|
||
```
|
||
|
||
#### Step 4: 失敗するテスト生成(5分)
|
||
|
||
```
|
||
=== Step 4: 失敗するテスト生成 ===
|
||
|
||
確定した仕様から、Red状態のテストコードを自動生成します。
|
||
|
||
テスト比率:
|
||
- 正常系テスト(20%): 2件
|
||
- 異常系テスト(50%): 5件
|
||
- エッジケーステスト(30%): 3件
|
||
|
||
合計: 10件のテストケース
|
||
|
||
生成されたテストは tasks/pbi-{id}/tests/ に保存されます。
|
||
```
|
||
|
||
### Phase 2: タスク分解(既存Group 1-3 + ネガティブレビュー)
|
||
|
||
#### Group 1: 要件・制約の確定(5-8分)
|
||
- 処理方式の選択
|
||
- 機能範囲の決定
|
||
- セキュリティレベルの設定
|
||
- 非機能要件の確認
|
||
|
||
#### **Group 1.5: ネガティブケース・レビュー(5分)**
|
||
```
|
||
=== Group 1.5: ネガティブケース・レビュー ===
|
||
|
||
Phase 1で抽出したネガティブケースを確認します:
|
||
|
||
【失敗シナリオ】
|
||
1. 入力不正(空文字列、型違い) - Priority: High
|
||
2. DB接続失敗 - Priority: Critical
|
||
3. 権限不足 - Priority: High
|
||
|
||
【エッジケース】
|
||
1. 最大長超過(255文字) - Priority: Medium
|
||
2. 特殊文字(XSSペイロード) - Priority: Critical
|
||
3. 並行実行 - Priority: Low
|
||
|
||
Q: 追加で考慮すべき失敗シナリオはありますか?
|
||
(あれば記述、なければEnter)
|
||
|
||
→ ユーザー入力を反映してspecs.mdを更新
|
||
```
|
||
|
||
#### Group 2: 技術・アーキテクチャ設計(8-12分)
|
||
- 技術スタックの選択
|
||
- データ設計・モデル構造
|
||
- API設計・インターフェース
|
||
- UI/UX設計方針
|
||
|
||
#### Group 3: 実装・タスク構成(5-8分)
|
||
- タスク分解粒度の決定(ネガティブケース考慮)
|
||
- 実装優先順位の設定
|
||
- 依存関係の整理
|
||
- 最終タスクリストの確認
|
||
|
||
## 生成されるファイル構造
|
||
|
||
```
|
||
tasks/pbi-{timestamp or custom-id}/
|
||
├── specs.md # 網羅的仕様書(正常系+異常系+エッジケース)
|
||
├── tests/
|
||
│ ├── spec-test-positive-1.md # 正常系テスト(Red状態)
|
||
│ ├── spec-test-negative-1.md # 異常系テスト(Red状態)
|
||
│ ├── spec-test-edge-1.md # エッジケーステスト(Red状態)
|
||
│ └── tdd-log.md # Red→Green遷移記録
|
||
├── README.md # リファインメント履歴・タスク一覧
|
||
├── todo-{category}-N.md # 実装タスク(ネガティブケース含む)
|
||
└── .refine-progress.json # 進捗管理
|
||
```
|
||
|
||
### specs.md フォーマット
|
||
|
||
```markdown
|
||
---
|
||
created: 2024-01-01T10:00:00Z
|
||
updated: 2024-01-01T10:30:00Z
|
||
status: confirmed
|
||
coverage_score: 85 # ネガティブチェック網羅率
|
||
---
|
||
|
||
# 仕様: ユーザー認証機能
|
||
|
||
## 要望(オリジナルプロンプト)
|
||
ユーザー認証機能を実装したい
|
||
|
||
## 確定した仕様
|
||
|
||
### 機能概要
|
||
メールアドレスとパスワードでユーザー認証を行い、JWTトークンを返却する
|
||
|
||
### 入力
|
||
- email: string(必須、メール形式、最大255文字)
|
||
- password: string(必須、最小8文字、最大128文字)
|
||
|
||
### 出力
|
||
- 成功時: 200 OK + { token: string, userId: string }
|
||
- 失敗時: 適切なHTTPステータス + エラーメッセージ
|
||
|
||
### 制約
|
||
- JWT有効期限: 24時間
|
||
- パスワードハッシュ: bcrypt
|
||
- データベース: PostgreSQL
|
||
|
||
### 成功条件(正常系)
|
||
- [ ] 有効な認証情報で200 + JWT返却
|
||
- [ ] トークンでユーザー情報取得可能
|
||
|
||
## ネガティブケース分析
|
||
|
||
### 失敗シナリオ
|
||
|
||
#### 入力不正
|
||
- [ ] 空文字列のemail → 400 + "email is required"
|
||
- [ ] 無効なメール形式 → 400 + "invalid email format"
|
||
- [ ] パスワード7文字 → 400 + "password must be at least 8 characters"
|
||
- [ ] 型違い(数値) → 400 + "email must be a string"
|
||
|
||
#### 依存リソース欠如
|
||
- [ ] DB接続失敗 → 503 + "service temporarily unavailable" + リトライ
|
||
- [ ] DBクエリタイムアウト → 504 + "gateway timeout"
|
||
|
||
#### 権限・認証
|
||
- [ ] 存在しないユーザー → 401 + "invalid credentials"
|
||
- [ ] パスワード不一致 → 401 + "invalid credentials"
|
||
- [ ] アカウント無効化済み → 403 + "account disabled"
|
||
- [ ] ログイン試行回数超過 → 429 + "too many attempts"
|
||
|
||
#### 並行実行
|
||
- [ ] 同一ユーザーの多重ログイン → 許可(トークン複数発行)
|
||
|
||
### エッジケース
|
||
|
||
| ケース | 入力例 | 期待される振る舞い |
|
||
|--------|--------|-------------------|
|
||
| 空文字列 | `email=""` | 400 + ValidationError |
|
||
| null | `email=null` | 400 + ValidationError |
|
||
| 最大長 | 256文字のemail | 400 + "email too long" |
|
||
| 最大長境界 | 255文字のemail | 正常処理 |
|
||
| 特殊文字 | `email="<script>"` | エスケープ処理 + 通常検証 |
|
||
| 絵文字 | `password="👍pass"` | 正常処理(UTF-8対応) |
|
||
| SQL注入試行 | `email="' OR '1'='1"` | プレースホルダーで無害化 |
|
||
|
||
### セキュリティ考慮事項
|
||
- [ ] パスワードは平文ログ出力禁止
|
||
- [ ] エラーメッセージで存在ユーザーを推測不可(401で統一)
|
||
- [ ] ブルートフォース対策: 5回失敗で15分ロック
|
||
- [ ] HTTPS必須(平文通信禁止)
|
||
- [ ] CSRF対策: 状態変更なしのため不要
|
||
- [ ] レート制限: 1IP 10req/min
|
||
|
||
### 想定される失敗モード(FMEA的分析)
|
||
|
||
| 失敗モード | 発生頻度 | 影響度 | 検出容易性 | 対策 |
|
||
|-----------|---------|--------|-----------|------|
|
||
| DB接続断 | 低 | 高 | 容易 | コネクションプール + リトライ |
|
||
| パスワード平文ログ出力 | 低 | 致命的 | 困難 | ログフィルター + コードレビュー |
|
||
| ブルートフォース | 高 | 中 | 容易 | レート制限 + アカウントロック |
|
||
| タイミング攻撃 | 低 | 中 | 困難 | 固定時間比較 |
|
||
|
||
## 対話履歴
|
||
|
||
### Q1: 入力は何ですか?
|
||
A: メールアドレスとパスワード
|
||
|
||
### Q2: 失敗シナリオ - 入力不正
|
||
Q: 空文字列が渡された場合の振る舞いは?
|
||
A: 400 BadRequestでValidationErrorを返す
|
||
|
||
### Q3: エッジケース - 最大長
|
||
Q: メールアドレスの最大長は?
|
||
A: 255文字。超過時は400エラー
|
||
|
||
### Q4: セキュリティ - ブルートフォース
|
||
Q: 連続失敗時の対策は?
|
||
A: 5回失敗で15分間アカウントロック
|
||
|
||
## テスト戦略
|
||
|
||
### 正常系テスト(20%)
|
||
- test_001: 有効な認証情報で200 + JWT
|
||
- test_002: トークンでユーザー情報取得成功
|
||
|
||
### 異常系テスト(50%)
|
||
- test_101: 空文字列emailで400
|
||
- test_102: 無効なメール形式で400
|
||
- test_103: 短いパスワードで400
|
||
- test_104: 存在しないユーザーで401
|
||
- test_105: パスワード不一致で401
|
||
- test_106: DB接続失敗で503
|
||
- test_107: ログイン試行超過で429
|
||
|
||
### エッジケーステスト(30%)
|
||
- test_201: 最大長境界値(255文字)
|
||
- test_202: 最大長超過(256文字)
|
||
- test_203: XSSペイロード試行
|
||
- test_204: SQL注入試行
|
||
- test_205: パスワードにUnicode文字
|
||
|
||
### カバレッジ目標
|
||
- 行カバレッジ: 90%以上
|
||
- 分岐カバレッジ: 85%以上
|
||
- 異常系カバレッジ: 100%
|
||
```
|
||
|
||
### todo-{category}-N.md フォーマット(拡張版)
|
||
|
||
```markdown
|
||
---
|
||
parent: auth-feature
|
||
category: services
|
||
priority: high
|
||
estimated_hours: 6
|
||
negative_cases: 7 # このタスクがカバーすべき異常系の数
|
||
edge_cases: 5 # エッジケースの数
|
||
test_ratio: "2:7:5" # 正常:異常:エッジ
|
||
---
|
||
|
||
# ユーザー認証API実装
|
||
|
||
## やること
|
||
specs.mdに基づき、ユーザー認証エンドポイントを実装
|
||
|
||
## 成功条件(正常系)
|
||
- [ ] POST /api/auth/login で200 + JWT返却
|
||
- [ ] 有効なトークンでユーザー情報取得可能
|
||
|
||
## 失敗条件(異常系)
|
||
- [ ] 空email → 400 + ValidationError
|
||
- [ ] 無効なメール形式 → 400 + validation message
|
||
- [ ] パスワード7文字 → 400 + length requirement
|
||
- [ ] 存在しないユーザー → 401 + generic message
|
||
- [ ] パスワード不一致 → 401 + generic message
|
||
- [ ] DB接続失敗 → 503 + retry logic
|
||
- [ ] ログイン試行5回超過 → 429 + lockout period
|
||
|
||
## エッジケース
|
||
- [ ] メール255文字(境界値) → 正常処理
|
||
- [ ] メール256文字 → 400 error
|
||
- [ ] XSSペイロード → エスケープして検証
|
||
- [ ] SQL注入試行 → prepared statementで無害化
|
||
- [ ] Unicode文字パスワード → 正常処理
|
||
|
||
## 技術仕様
|
||
- パスワードハッシュ: bcrypt(salt rounds: 10)
|
||
- JWT署名: HS256 + 環境変数シークレット
|
||
- DB: prepared statement必須
|
||
- エラーログ: パスワード除外
|
||
|
||
## 制約
|
||
- specs.md#セキュリティ考慮事項 を全て遵守
|
||
- 認証失敗はタイミング攻撃対策で固定時間応答
|
||
- エラーメッセージでユーザー存在を推測不可
|
||
|
||
## 実装メモ
|
||
(TDD Red→Green→Refactorサイクルを記録)
|
||
```
|
||
|
||
## 実行後の出力
|
||
|
||
```
|
||
✅ 仕様策定完了
|
||
|
||
【生成ファイル】
|
||
- tasks/pbi-auth-feature/specs.md
|
||
- tasks/pbi-auth-feature/tests/spec-test-positive-1.md
|
||
- tasks/pbi-auth-feature/tests/spec-test-negative-1.md
|
||
- tasks/pbi-auth-feature/tests/spec-test-negative-2.md
|
||
- tasks/pbi-auth-feature/tests/spec-test-negative-3.md
|
||
- tasks/pbi-auth-feature/tests/spec-test-negative-4.md
|
||
- tasks/pbi-auth-feature/tests/spec-test-negative-5.md
|
||
- tasks/pbi-auth-feature/tests/spec-test-edge-1.md
|
||
- tasks/pbi-auth-feature/tests/spec-test-edge-2.md
|
||
- tasks/pbi-auth-feature/tests/spec-test-edge-3.md
|
||
- tasks/pbi-auth-feature/README.md
|
||
|
||
【ネガティブチェック網羅率】
|
||
- 失敗シナリオ: 7件
|
||
- エッジケース: 5件
|
||
- セキュリティ: 6項目
|
||
- カバレッジスコア: 85/100
|
||
|
||
【タスク数】
|
||
- Setup: 1タスク
|
||
- Models: 1タスク
|
||
- Services: 1タスク(正常2 + 異常7 + エッジ5 = 14テストケース)
|
||
- UI: 1タスク
|
||
- Tests: 1タスク
|
||
|
||
次のステップ:
|
||
1. /task-next で最初のタスクを実行
|
||
2. /task-status auth-feature で進捗確認
|
||
```
|
||
|
||
## エラーハンドリング
|
||
|
||
### 実行前チェック
|
||
- tasksディレクトリの存在確認
|
||
- プロンプトの最小文字数確認(10文字以上)
|
||
- カスタムIDの重複チェック
|
||
|
||
### 進行中のエラー処理
|
||
- 不正な選択肢入力時の再プロンプト
|
||
- ネットワークエラー時の状態保存
|
||
- 強制終了時の進捗復旧(.refine-progress.json)
|
||
|
||
## 完了条件
|
||
|
||
- Phase 1, 2の全ステップが正常完了
|
||
- specs.mdにネガティブケース分析が記録されている
|
||
- テストファイルが正常系:異常系:エッジ = 2:5:3の比率で生成されている
|
||
- 各タスクに異常系・エッジケースが割り当てられている
|
||
- カバレッジスコアが80以上
|