# Phase 1 Test Marker Rollout Plan

## 1. Policy Overview
- Adopt **Option A**: every new pytest test must declare at least one technique marker (`boundary`, `equivalence`, `happy_path`, `error_case`, `state_transition`, `security`).
- Treat Phase 0 results (`results/PHASE0_FINAL_SUMMARY.md`) as the authoritative baseline.
- Trigger Option B (stratified sampling review) if two or more marker-classification discrepancies are reported during code review within the first two weeks of rollout. Pre-assign reviewer(s) and a 1–2 hour timebox for `results/stratified_sampling_review.md`.

## 2. Near-Term Reinforcement Roadmap
| Sprint | Focus | Targets |
|--------|-------|---------|
| 1 | Domain services & repositories | +5 `error_case` tests (raises coverage), +3 `security` tests (I/O boundary) |
| 2 | State transitions & adapters | +5 `error_case` tests (workflow edge cases), +2 `security` tests (path traversal/authorization) |

- Capture candidate test files with `pytest.raises` gaps or external I/O entry points and assign owners.
- Record marker expectations in backlog tickets so reviewers can verify intent quickly.

## 3. Communication Package
### Slack Announcement Template
```
:checkered_flag: Phase 1 pytest marker rollout

From today, every new pytest must include technique markers (boundary / equivalence / happy_path / error_case / state_transition / security).
- Templates: docs/TEST_TEMPLATES.md
- Developer guide: docs/DEVELOPER_TEST_GUIDELINES.md
- Baseline context: results/PHASE0_FINAL_SUMMARY.md

Please emphasise error_case & security scenarios. We'll review adoption after two weeks.
```

### PR Template Addition (see .github/pull_request_template.md)
- [ ] ✅ 新規テストに適切な pytest マーカーを付与した
- [ ] ✅ 異常系・セキュリティ観点を検討し、必要ならマーカーを追加した

### Meeting Talking Points
- Share Phase 0 findings (error_case 2.4%, security 0%).
- Reiterate Option A policy and Option B trigger.
- Ask reviewers to flag mismatches between code behaviour and declared markers.

## 4. Weekly Marker Monitoring
1. Run the helper script:
   ```
   bin/test-marker-stats
   ```
2. Capture counts for `boundary`, `error_case`, `security`.
3. Post a weekly summary (e.g., Friday morning) to #testing with trends against KPIs:
   - ≥80% of new tests carry ≥1 marker.
   - `error_case` ≥5% of collected tests.
   - `security` total ≥10 tests.
4. Log each snapshot under `reports/test_marker_stats_YYYY-MM-DD.md` (lightweight markdown table).

## 5. References
- results/PHASE0_FINAL_SUMMARY.md
- results/PHASE0_FILE_STRUCTURE_ANALYSIS.md
- results/PHASE1_IMPLEMENTATION_GUIDE.md
- docs/TEST_TEMPLATES.md
- docs/DEVELOPER_TEST_GUIDELINES.md

## 6. Sprint 1 Backlog（error_case 5件 / security 3件）

| ID | Category | Target Test | Scenario (追加予定) | Marker | Owner |
|----|----------|-------------|----------------------|--------|-------|
| E-01 | error_case | `tests/unit/domain/services/test_plot_creation_service.py` | モックした `PlotWorkflow.can_execute_stage` が `False, ["stage locked"]` を返す場合に `execute_plot_creation` が失敗と理由を返す | `error_case` | Domain Services QA |
| E-02 | error_case | `tests/unit/application/use_cases/test_chapter_plot_with_scenes_use_case.py` | `PlotCreationResponse(success=False, error_message="...")` が戻ったとき ERROR ステータスを返す経路 | `error_case` | Application Use Case Squad |
| E-03 | error_case | `tests/unit/domain/services/test_quality_config_auto_update_service.py` | `project_repo.get_genre` が例外や不正値を返した場合に `UpdateResult.success` が False になること | `error_case` | Domain Services QA |
| E-04 | error_case | `tests/unit/domain/services/test_bulk_quality_check_service.py` | `episode_range=(5, 2)` などでフィルタ後に対象ゼロとなった際 `NoEpisodesFoundError` を握り潰さず失敗レスポンスを返す | `error_case` | Quality Tooling Team |
| E-05 | error_case | `tests/unit/domain/services/test_mcp_command_suggester.py` | 未知のコマンド `validate_command("unknown", {...})` を受けた際に `is_valid is False` とエラーメッセージを返す | `error_case` | MCP Experience Guild |
| S-01 | security | `tests/unit/infrastructure/test_path_service_adapter.py` | `strict=True` で既存フォールバックディレクトリが見つかった場合 `PathResolutionError` を投げる（ディレクトリ外遷移の防止） | `security` | Platform Security WG |
| S-02 | security | 新規: `tests/unit/infrastructure/repositories/test_yaml_project_repository_security.py` | `project_id="../outside"` を渡した際に `YamlProjectRepository` がベースパス外を許容しない（例外 or False を返す） | `security` | Platform Security WG |
| S-03 | security | `tests/unit/presentation/test_shared_utilities.py` | `CommonPathService._sanitize_filename` が `../evil?.yaml` などの入力から危険文字を除去することを確認 | `security` | Presentation Enablement Team |

### Sprint 1 Ticket Notes

- **E-01 PlotWorkflow failure handling**  
  - *Objective*: 失敗理由が `PlotCreationResult.error_message` に反映されることを検証。  
  - *Acceptance*: `execute_plot_creation` が `success=False` と理由メッセージを返し、`pytest.mark.error_case` を付与。  
  - *Tests*: 既存ファイルに `pytest.raises` が無いため、新規テスト関数を追加。

- **E-02 Plot orchestrator error propagation**  
  - *Objective*: ChapterPlotWithScenesUseCase が PlotCreation 失敗を受けて ERROR ステータスを返却する経路を追加。  
  - *Acceptance*: レスポンス `status == ERROR`、`plot_created is False`、`message` にエラー内容を含める。  
  - *Marker*: `pytest.mark.error_case`.

- **E-03 QualityConfigAutoUpdateService genre fallback**  
  - *Objective*: `project_repo.get_genre` が例外／不正値のときに `UpdateResult.success` が False となり message に原因を含む。  
  - *Acceptance*: `pytest.mark.error_case`、`UpdateResult.trigger is None` を確認。

- **E-04 BulkQualityCheck episode range validation**  
  - *Objective*: 不正レンジやフィルタ後ゼロ件を `NoEpisodesFoundError` として処理し、エラー配列にメッセージが入る。  
  - *Acceptance*: `BulkQualityCheckResult.success is False`、`errors[0]` が指定メッセージ、`pytest.mark.error_case`。

- **E-05 MCPCommandSuggester unknown command validation**  
  - *Objective*: 未知コマンドの検証失敗とエラーメッセージを網羅。  
  - *Acceptance*: `is_valid is False`、`errors` に "unsupported command" を含む。`pytest.mark.error_case`.

- **S-01 PathServiceAdapter strict fallback**  
  - *Objective*: strict モードでレガシーディレクトリを検知した際に `PathResolutionError` を投げる。  
  - *Acceptance*: `pytest.raises(PathResolutionError)`、`pytest.mark.security`。別パス traversal を伴う fixture を追加。

- **S-02 YamlProjectRepository path traversal guard**  
  - *Objective*: `project_id="../attack"` がベースディレクトリを外れた場合に拒否。  
  - *Acceptance*: `pytest.raises(ValueError)` または `exists` が False を返すテスト。`pytest.mark.security`。  
  - *Notes*: 新規 test ファイルを `tests/unit/infrastructure/repositories/test_yaml_project_repository_security.py` に追加。

- **S-03 CommonPathService filename sanitization**  
  - *Objective*: `safe_console_print` 経由で生成されるファイル名が危険文字を含まない。  
  - *Acceptance*: `_sanitize_filename` の戻り値が `..`, `/`, `?`, `*` 等を含まない。`pytest.mark.security`。
