Skip to content

Commit ec27963

Browse files
etoyamaclaude
andcommitted
chore: update yaml-edit-resilience tasks.md to checklist format with team-review results
Convert task format from heading-based to checklist-based (- [x]) so that spec-workflow MCP correctly tracks 7/7 tasks as completed. Add team review results section with findings and resolution decisions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 382c262 commit ec27963

1 file changed

Lines changed: 77 additions & 76 deletions

File tree

  • .spec-workflow/specs/yaml-edit-resilience

.spec-workflow/specs/yaml-edit-resilience/tasks.md

Lines changed: 77 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -11,82 +11,61 @@ F1(Extra Field Preservation)と F2(Corrupt File Isolation)は独立し
1111

1212
## Tasks
1313

14-
### Task 1.1: Write F1 model-layer unit tests (Red)
15-
16-
| Field | Value |
17-
|-------|-------|
18-
| **File** | `tests/test_design_models.py` |
19-
| **Purpose** | extra フィールド保全の model 層テストを追加し、Red 状態を確立する |
20-
| **Leverage** | 既存テストの fixture パターン(`_base_design_data()`)、`model_dump(mode="json")` の既存テスト |
21-
| **Requirements** | REQ-1 (FR-1.1, FR-1.2) |
22-
| **Prompt** | Test Design の Unit-01〜06, Unit-12, Unit-13, Unit-16 を実装。全テストで `model_dump(mode="json")` を明示使用。Unit-16 は parametrize で 4 StrEnum の不正値を検証 |
23-
| **Dependencies** | None |
24-
25-
### Task 1.2: Implement ConfigDict(extra="allow") on 5 models (Green)
26-
27-
| Field | Value |
28-
|-------|-------|
29-
| **File** | `src/insight_blueprint/models/design.py` |
30-
| **Purpose** | 5つの BaseModel サブクラスに `ConfigDict(extra="allow")` を追加し、Task 1.1 のテストを Green にする |
31-
| **Leverage** | Pydantic v2 `ConfigDict` の標準機能。既存の全 validator・フィールド定義は変更なし |
32-
| **Requirements** | REQ-1 (FR-1.1, FR-1.2) |
33-
| **Prompt** | `ExplanatoryVariable`, `Metric`, `ChartSpec`, `Methodology`, `AnalysisDesign` の 5 クラスに `model_config = ConfigDict(extra="allow")` を追加。import に `ConfigDict` を追加。既存コードは一切変更しない |
34-
| **Dependencies** | 1.1 |
35-
36-
### Task 1.3: Write F1 service-layer verification tests (Verification)
37-
38-
| Field | Value |
39-
|-------|-------|
40-
| **File** | `tests/test_designs.py` |
41-
| **Purpose** | `update_design()` 経由の extra フィールド round-trip と `referenced_knowledge` merge との相互作用を検証する。Task 1.2 の model 変更のみで Green が期待される(service 層の変更なし) |
42-
| **Leverage** | 既存の `service` fixture、`write_yaml` / `read_yaml` ヘルパー |
43-
| **Requirements** | REQ-1 (FR-1.3, FR-1.4) |
44-
| **Prompt** | Test Design の Unit-03, Unit-14, Integ-01 を実装。Unit-03: YAML に手動で extra field を追加後 `update_design()` で保持確認。Unit-14: `referenced_knowledge` merge 後に extra 保持確認。Integ-01: top-level + metrics-level の extra が YAML round-trip で保持される統合テスト。service 層の変更なしで全テスト Green になることを確認 |
45-
| **Dependencies** | 1.2 |
46-
47-
### Task 2.1: Write F2 service-layer unit tests (Red)
48-
49-
| Field | Value |
50-
|-------|-------|
51-
| **File** | `tests/test_designs.py` |
52-
| **Purpose** | corrupt ファイル隔離の service 層テストを追加し、Red 状態を確立する |
53-
| **Leverage** | 既存の `service` fixture、`write_yaml` による corrupt ファイル直接書き込み。`yaml_syntax_error` パターンは YAML ファイルに不正構文を直接書き込む(`write_yaml` ではなく `Path.write_text`|
54-
| **Requirements** | REQ-2 (FR-2.1, FR-2.2, FR-2.3) |
55-
| **Prompt** | Test Design の Unit-07〜11, Unit-15 を実装。Unit-15 は pytest.mark.parametrize で 5 corrupt パターン(yaml_syntax_error, non_dict_root, missing_required, invalid_enum, invalid_nested_enum)を検証。`yaml_syntax_error``non_dict_root``Path.write_text()` で直接ファイル書き込み(`read_yaml()` レベルでエラーを起こすため)。Unit-08 は `caplog` で warning ログ出力を確認。Unit-10 は `pytest.raises(ValidationError)` |
56-
| **Dependencies** | None |
57-
58-
### Task 2.2: Implement corrupt file isolation in list_designs (Green)
59-
60-
| Field | Value |
61-
|-------|-------|
62-
| **File** | `src/insight_blueprint/core/designs.py` |
63-
| **Purpose** | `list_designs()` に per-file try/except + warning ログを追加し、Task 2.1 のテストを Green にする |
64-
| **Leverage** | 既存の `list_designs()` ループ構造に try/except を追加するだけ。`logging` 標準ライブラリ |
65-
| **Requirements** | REQ-2 (FR-2.1, FR-2.2) |
66-
| **Prompt** | `list_designs()` の try/except を `read_yaml(file_path)` から `AnalysisDesign(**data)` まで包含するスコープで追加。理由: `yaml_syntax_error``read_yaml()` 段階で `YAMLError` を raise するため、`AnalysisDesign(**data)` だけを囲むと不十分。`except Exception as exc` で catch し(`YAMLError`, `ValidationError`, `TypeError` 等を一括補足)、`logger.warning("Skipping corrupt design file %s: %s", file_path.name, exc)` を出力して `continue`。module-level で `logger = logging.getLogger(__name__)` を定義。`get_design()` は変更なし(ValidationError はそのまま伝播) |
67-
| **Dependencies** | 2.1 |
68-
69-
### Task 2.3: Write F2 REST API test + implement ValidationError handler (Red → Green)
70-
71-
| Field | Value |
72-
|-------|-------|
73-
| **File** | `tests/test_web.py`, `src/insight_blueprint/web.py` |
74-
| **Purpose** | REST API で corrupt design → 422 レスポンスを返すテストと実装 |
75-
| **Leverage** | 既存の exception handler パターン(`ValueError → 400`)、既存の TestClient fixture |
76-
| **Requirements** | REQ-2 (FR-2.4) |
77-
| **Prompt** | Red: `test_get_design_corrupt_returns_422` を追加。corrupt YAML を直接書き込み、`GET /api/designs/{id}` で 422 + `error` フィールド確認。Green: `web.py``@app.exception_handler(ValidationError)` を追加。`from pydantic import ValidationError` を import(web.py では `from pydantic import BaseModel, Field` が既にある箇所に追加)。status_code=422, content=`{"error": f"Invalid design data: {exc.error_count()} validation error(s)"}` |
78-
| **Dependencies** | 2.1 |
79-
80-
### Task 3.1: Run regression tests + coverage confirmation
81-
82-
| Field | Value |
83-
|-------|-------|
84-
| **File** | (テスト実行のみ、ファイル変更なし) |
85-
| **Purpose** | 既存 681 テスト + 新規 18 テストの全 pass と `models/design.py` coverage 100% を確認する |
86-
| **Leverage** | `uv run pytest -v` + `uv run pytest --cov=src/insight_blueprint/models/design --cov-report=term-missing` |
87-
| **Requirements** | NFR-B.1, NFR-B.2, NFR-B.3 |
88-
| **Prompt** | `uv run pytest -v` で全テスト pass を確認。`uv run pytest --cov=src/insight_blueprint/models/design --cov-report=term-missing` で design.py のカバレッジ 100% 維持を確認。`uv run ruff check .` でリントエラーなしを確認 |
89-
| **Dependencies** | 1.3, 2.3 |
14+
- [x] 1.1. Write F1 model-layer unit tests (Red)
15+
- File: `tests/test_design_models.py`
16+
- Purpose: extra フィールド保全の model 層テストを追加し、Red 状態を確立する
17+
- Leverage: 既存テストの fixture パターン(`_base_design_data()`)、`model_dump(mode="json")` の既存テスト
18+
- Requirements: REQ-1 (FR-1.1, FR-1.2)
19+
- Prompt: Test Design の Unit-01〜06, Unit-12, Unit-13, Unit-16 を実装。全テストで `model_dump(mode="json")` を明示使用。Unit-16 は parametrize で 4 StrEnum の不正値を検証
20+
- Dependencies: None
21+
22+
- [x] 1.2. Implement ConfigDict(extra="allow") on 5 models (Green)
23+
- File: `src/insight_blueprint/models/design.py`
24+
- Purpose: 5つの BaseModel サブクラスに `ConfigDict(extra="allow")` を追加し、Task 1.1 のテストを Green にする
25+
- Leverage: Pydantic v2 `ConfigDict` の標準機能。既存の全 validator・フィールド定義は変更なし
26+
- Requirements: REQ-1 (FR-1.1, FR-1.2)
27+
- Prompt: `ExplanatoryVariable`, `Metric`, `ChartSpec`, `Methodology`, `AnalysisDesign` の 5 クラスに `model_config = ConfigDict(extra="allow")` を追加。import に `ConfigDict` を追加。既存コードは一切変更しない
28+
- Dependencies: 1.1
29+
30+
- [x] 1.3. Write F1 service-layer verification tests (Verification)
31+
- File: `tests/test_designs.py`
32+
- Purpose: `update_design()` 経由の extra フィールド round-trip と `referenced_knowledge` merge との相互作用を検証する。Task 1.2 の model 変更のみで Green が期待される(service 層の変更なし)
33+
- Leverage: 既存の `service` fixture、`write_yaml` / `read_yaml` ヘルパー
34+
- Requirements: REQ-1 (FR-1.3, FR-1.4)
35+
- Prompt: Test Design の Unit-03, Unit-14, Integ-01 を実装。Unit-03: YAML に手動で extra field を追加後 `update_design()` で保持確認。Unit-14: `referenced_knowledge` merge 後に extra 保持確認。Integ-01: top-level + metrics-level の extra が YAML round-trip で保持される統合テスト。service 層の変更なしで全テスト Green になることを確認
36+
- Dependencies: 1.2
37+
38+
- [x] 2.1. Write F2 service-layer unit tests (Red)
39+
- File: `tests/test_designs.py`
40+
- Purpose: corrupt ファイル隔離の service 層テストを追加し、Red 状態を確立する
41+
- Leverage: 既存の `service` fixture、`write_yaml` による corrupt ファイル直接書き込み。`yaml_syntax_error` パターンは YAML ファイルに不正構文を直接書き込む(`write_yaml` ではなく `Path.write_text`
42+
- Requirements: REQ-2 (FR-2.1, FR-2.2, FR-2.3)
43+
- Prompt: Test Design の Unit-07〜11, Unit-15 を実装。Unit-15 は pytest.mark.parametrize で 5 corrupt パターン(yaml_syntax_error, non_dict_root, missing_required, invalid_enum, invalid_nested_enum)を検証。`yaml_syntax_error``non_dict_root``Path.write_text()` で直接ファイル書き込み(`read_yaml()` レベルでエラーを起こすため)。Unit-08 は `caplog` で warning ログ出力を確認。Unit-10 は `pytest.raises(ValidationError)`
44+
- Dependencies: None
45+
46+
- [x] 2.2. Implement corrupt file isolation in list_designs (Green)
47+
- File: `src/insight_blueprint/core/designs.py`
48+
- Purpose: `list_designs()` に per-file try/except + warning ログを追加し、Task 2.1 のテストを Green にする
49+
- Leverage: 既存の `list_designs()` ループ構造に try/except を追加するだけ。`logging` 標準ライブラリ
50+
- Requirements: REQ-2 (FR-2.1, FR-2.2)
51+
- Prompt: `list_designs()` の try/except を `read_yaml(file_path)` から `AnalysisDesign(**data)` まで包含するスコープで追加。理由: `yaml_syntax_error``read_yaml()` 段階で `YAMLError` を raise するため、`AnalysisDesign(**data)` だけを囲むと不十分。`except Exception as exc` で catch し、`logger.warning("Skipping corrupt design file %s: %s", file_path.name, exc)` を出力して `continue`。module-level で `logger = logging.getLogger(__name__)` を定義。`get_design()` は変更なし(ValidationError はそのまま伝播)
52+
- Dependencies: 2.1
53+
54+
- [x] 2.3. Write F2 REST API test + implement ValidationError handler (Red → Green)
55+
- File: `tests/test_web.py`, `src/insight_blueprint/web.py`
56+
- Purpose: REST API で corrupt design → 422 レスポンスを返すテストと実装
57+
- Leverage: 既存の exception handler パターン(`ValueError → 400`)、既存の TestClient fixture
58+
- Requirements: REQ-2 (FR-2.4)
59+
- Prompt: Red: `test_get_design_corrupt_returns_422` を追加。corrupt YAML を直接書き込み、`GET /api/designs/{id}` で 422 + `error` フィールド確認。Green: `web.py``@app.exception_handler(ValidationError)` を追加。status_code=422, content=`{"error": f"Invalid design data: {exc.error_count()} validation error(s)"}`
60+
- Dependencies: 2.1
61+
62+
- [x] 3.1. Run regression tests + coverage confirmation
63+
- File: (テスト実行のみ、ファイル変更なし)
64+
- Purpose: 既存 681 テスト + 新規 25 テストの全 pass と `models/design.py` coverage 100% を確認する
65+
- Leverage: `uv run pytest -v` + `uv run pytest --cov=src/insight_blueprint/models/design --cov-report=term-missing`
66+
- Requirements: NFR-B.1, NFR-B.2, NFR-B.3
67+
- Prompt: `uv run pytest -v` で全テスト pass を確認。`uv run pytest --cov=src/insight_blueprint/models/design --cov-report=term-missing` で design.py のカバレッジ 100% 維持を確認。`uv run ruff check .` でリントエラーなしを確認
68+
- Dependencies: 1.3, 2.3
9069

9170
---
9271

@@ -119,3 +98,25 @@ Task 3.1 は両トラック完了後に実行。
11998
| design.md の `GET /api/designs` corrupt 混在テストが test-design.md に未反映 | Important | Unit-07 で service 層をカバー済み。REST 層は `list_designs()` をそのまま呼ぶだけなので service テストで十分。Integration テスト追加は不要と判断 |
12099
| Task 2.1 が大きい(分割検討) | Moderate | parametrize で共通 fixture を使うため分割すると重複が増える。現状維持 |
121100
| Task 2.3 の依存が 2.2 だが独立可能 | Important | 依存を 2.1 に変更(REST handler は service 実装と独立) |
101+
102+
## Team Review Results (2026-03-08)
103+
104+
**Commit**: `8f156f6` (実装) + `382c262` (review 修正)
105+
106+
| カテゴリ | Critical | High | Medium | Low |
107+
|---------|----------|------|--------|-----|
108+
| Security | 0 | 0 | 3 | 2 |
109+
| Quality | 0 | 0 | 1 | 7 |
110+
| Test | - | - | 2 | 3 |
111+
| Requirements | 12/12 ACs Covered | 11/11 NFRs Covered | - | - |
112+
113+
### 修正済み (commit 382c262)
114+
115+
- **S-05**: `web.py``validation_error_handler` に handler 優先順序の NOTE コメント追加
116+
- **T-04**: `test_list_designs_with_corrupt_returns_valid_only` テスト追加 (707 tests)
117+
118+
### 対応不要と判断
119+
120+
- **S-02**: `except Exception` スコープ — design doc で意図的に選択。YAMLError/ValidationError/TypeError 一括捕捉のため
121+
- **S-01**: `extra="allow"` 蓄積リスク — REST API request model は extra="allow" なし。侵入経路はローカルのみ
122+
- **Q-01**: テスト ID 重複 — docstring のみ、実害なし

0 commit comments

Comments
 (0)