#13 親Issueからアトミックな子Issueへの分解 - Python OSS開発記録
「この機能作って」って言われたIssue、大きすぎて何から手をつけていいか分からない...ってことありませんか?
親Issueからアトミックな子Issueに分解する技術で、大きなタスクを管理可能な粒度に落とし込めます。
KEY TAKEAWAYS
この記事でわかること
- Issue分解の原則(1人・1PR・1日以内)
- 親Issueの書き方(要件定義・技術設計・受入基準)
- wagtail-reusable-blocks Issue #1の分解実例
用語の定義
TERM 01
Issue分解 (Issue Decomposition)
大きなIssue(親Issue)を、実装可能な小さなIssue(子Issue)に分割するプロセスです。1人・1PR・1日以内で完結する粒度を目標にします。
TERM 02
アトミック粒度 (Atomic Granularity)
これ以上分解する必要がない、最小単位のタスク粒度のことです。目安は数時間〜1日、1PR、明確な完了条件。「atomicラベル」で識別します(トピック#12参照)。
TERM 03
受入基準 (Acceptance Criteria)
Issueが「完了した」と判断できる条件のことです。曖昧さを排除し、レビュアーと実装者の認識を揃える役割を果たします。
TERM 04
依存関係 (Dependencies)
Issue間の前後関係のことです。「IssueAが完了しないとIssueBに着手できない」といった関係を指します。GitHubのSub-issue/Blocked by機能で表現できます(トピック#14で詳説)。
Issue分解の原則
wagtail-reusable-blocksでは、「1人・1PR・1日以内」を目標にIssueを分解しています。この粒度が、進捗の見える化とレビューのしやすさを両立させてくれます。
分解の3原則
原則1: 1人で完結
1つのIssueは1人で完了できる粒度にします。担当者が明確になり、責任範囲もはっきり。並行作業もしやすくなります。
原則2: 1PRで完結
1つのIssueは1つのPRで解決します。レビューしやすく、変更範囲が明確。マージ後の影響も限定的です。
原則3: 1日以内で完結
数時間〜1日で完了する粒度を目指します。進捗が見える、モチベーションが続く、途中で迷わない。
分解が不十分なIssueの例
「Reusable Blocks機能を実装する」
問題点:
- 範囲が広すぎます。モデル・ブロック・テンプレート・管理画面、全部含まれています
- 1人では終わりません。数週間かかります
- 1PRにはなりません。変更が巨大でレビュー不可能です
- これは親Issueとして扱い、分解が必要です
適切に分解されたIssueの例
「ReusableBlockモデルを実装する」
良い点:
- 範囲が明確です。モデル定義のみに絞られています
- 1人で終わります。数時間〜1日程度の作業量です
- 1PRになります。models.py, tests/test_models.py の変更だけで済みます
- これがアトミックIssueです
参考: 9 Powerful Techniques For Splitting User Stories - StoriesOnBoard
実例: Issue #1の分解プロセス
wagtail-reusable-blocksのIssue #1「[v0.1.0] Reusable Blocks MVP」を、8つのアトミックIssueに分解した過程を見ていきましょう。
parent Issue #1: [v0.1.0] Reusable Blocks MVP
親Issueの構成
Issue #1には以下のセクションが含まれています:
- Overview: 機能の概要
- Background: なぜこの機能が必要か
- Requirements: 機能要件(FR-1〜FR-4)と非機能要件(NFR-1〜NFR-3)
- Technical Design: モデル・ブロック・設定の設計
- Acceptance Criteria: 完了条件
- Out of Scope: 含まないもの(次のマイルストーンで実装)
要件の抜粋
親Issueには機能要件(Functional Requirements)が明記されています。この要件をベースに、アトミックIssueへと分解していきます。
- FR-1: ReusableBlockモデルの作成
- FR-2: ReusableBlockChooserBlockの実装
- FR-3: テンプレートレンダリング
- FR-4: 管理画面連携
## Requirements ### Functional Requirements #### FR-1: ReusableBlock Model - [ ] Create a Snippet model `ReusableBlock` - [ ] Register as Wagtail Snippet with admin UI #### FR-2: ReusableBlockChooserBlock - [ ] Create a custom StreamField block - [ ] Support nested rendering
親Issueの役割:
全体像を示し、何を作るか・なぜ作るか・どう作るかを明確にします。
実装は子Issueで行うため、親Issue自体はクローズしないのがポイントです(全ての子Issueが完了したらクローズ)。
分解の流れ: FR-1〜FR-4からアトミックIssueへ
要件をアトミックタスクに分解する
Issue #1の機能要件(FR-1〜FR-4)と非機能要件(NFR-1〜NFR-3)を読み、実装タスクに落とし込みます。受入基準を見ながら分解するのがコツです。
| 要件 | 分解されたアトミックIssue | Issue番号 |
|---|---|---|
| NFR-1〜NFR-3(セットアップ) | Setup test environment and CI workflow | #10 |
| FR-1: ReusableBlock Model | Implement ReusableBlock model | #11 |
| FR-2: ReusableBlockChooserBlock | Implement ReusableBlockChooserBlock | #12 |
| FR-3: Template Rendering | Create default template and template override system | #13 |
| FR-3(設定システム) | Implement settings system | #14 |
| FR-4: Admin Integration | Customize admin UI for ReusableBlock | #15 |
| FR-2(ネスト対応) | Implement nested rendering and circular reference detection | #16 |
| NFR-2(ドキュメント) | Write documentation for v0.1.0 | #17 |
依存関係の整理
各アトミックIssueの前後関係を考えます。どれを先にやるべきか、どれが並行できるかを明確にしておくと、作業がスムーズです。
- #10: Setup test environment最初に必要
- #11: Implement ReusableBlock model #10の後、他の前提
- #12: Implement ReusableBlockChooserBlock #11に依存
- #13: Create default template #12に依存
- #14: Implement settings system #11に依存(並行可能)
- #15: Customize admin UI #11に依存(並行可能)
- #16: Implement nested rendering #12, #13に依存
- #17: Write documentation全ての実装完了後
トピック#14で詳説: これらの依存関係をGitHubのSub-issue/Blocked by機能で明示的に設定する方法は、次のトピック#14で解説します。
分解結果: 8つのアトミックIssue
全てにatomicラベルとimplementationまたはdocumentationラベルが付与されています。
- atomicimplementation#10: Setup test environment and CI workflow
- atomicimplementation#11: Implement ReusableBlock model
- atomicimplementation#12: Implement ReusableBlockChooserBlock
- atomicimplementation#13: Create default template and template override system
- atomicimplementation#14: Implement settings system
- atomicimplementation#15: Customize admin UI for ReusableBlock
- atomicimplementation#16: Implement nested rendering and circular reference detection
- atomicdocumentation#17: Write documentation for v0.1.0
参考: Splitting User Stories with Acceptance Criteria - Agile Learning Labs
親Issueの書き方
親Issueは全体像を示す設計書の役割を果たします。必要なセクションを見ていきましょう。
親Issueの必須セクション
7つの必須セクション
- Overview: 機能の概要(1〜2行)
- Background: なぜ必要か(課題・動機)
- Requirements: 何を作るか(FR-1, FR-2...)
- Technical Design: どう作るか(設計案)
- Acceptance Criteria: 完了条件
- Out of Scope: 含まないもの
- References: 参考リンク
## Overview Implement the core functionality... ## Background Currently in Wagtail, content editors... ## Requirements ### Functional Requirements #### FR-1: ReusableBlock Model - [ ] Create a Snippet model... ## Technical Design [コード例・設計図] ## Acceptance Criteria - [ ] User can create... ## Out of Scope - Slot system (v0.2.0)
なぜこの構成なのか
実装者視点
Requirements → 何を作るか明確
Technical Design → 実装の指針がある
Acceptance Criteria → 完了条件が明確
レビュアー視点
Background → 変更の意図を理解できる
Out of Scope → やらないことが明確
「これも必要では?」と迷わない
参考: GitHub Best Practices: Taking Issues from Good to Great - Zenhub
アトミック粒度の判定基準
「このIssueはアトミックか?」を判断する基準を見ていきましょう。5つの質問に答えるだけで判定できます。
アトミックIssueの条件
以下の5つの質問に「はい」と答えられたら、アトミックです:
| 質問 | 理想的な答え |
|---|---|
| 1人で完了できますか? | はい。複数人の協力が不要です。 |
| 1PRで完結しますか? | はい。変更が1つのPRに収まります。 |
| 1日以内で終わりますか? | はい。数時間〜1日で完了できます。 |
| 完了条件が明確ですか? | はい。「〇〇が動く」など、判定可能です。 |
| さらに分解できますか? | いいえ。これ以上分けると意味が薄いです。 |
判定例
アトミック: #11 Implement ReusableBlock model
- 1人で完了できる
- 1PR(models.py, tests/)
- 数時間で終わる
- 「モデルが動く」が明確
- 分解すると細かすぎる
非アトミック: #1 [v0.1.0] MVP全体
- 複数人必要
- 複数PR必要
- 数週間かかる
- 完了条件は明確
- 分解可能(8個に分割)
参考: What are User Stories and Why Should You Split Them? - NRI
プロジェクト形態別: Issue分解の違い
プロジェクトの性質によって、Issue分解のアプローチは異なります。OSS、企業Agile、企業Waterfallのそれぞれを見ていきましょう。
OSS: 外部コントリビューター対応
wagtail-reusable-blocksでは、外部コントリビューターが迷わず着手できるよう、アトミックIssueを充実させています。
OSS Issue分解のポイント
- アトミック粒度を徹底: 初めてのコントリビューターでも1〜2時間で完結できる粒度
- 親Issueに詳細を集約: Technical Design, Acceptance Criteriaを丁寧に書く
- 「Good First Issue」ラベル: 特に簡単なアトミックIssueに付与
- 依存関係を明示: どの順序で着手すべきか分かりやすく
- 英語で記載: 国際的なコントリビューター対応
コントリビューター体験の向上
外部コントリビューターの視点
「このプロジェクトに貢献したい」と思った時:
- 親Issue #1を見る → 全体像を理解
- アトミックIssue #10〜#17を見る → 「#13なら自分にもできそう」
- 親Issue #1のTechnical Designを読む → 実装方針を理解
- #13にアサイン依頼 → 実装開始
- PR提出 → Acceptance Criteriaに沿ってレビュー
心理的ハードルを下げる:「これならできる」と思えるアトミック粒度がOSSの成功の鍵です。
大きすぎるIssueは誰も手を出しません。小さく分解することでコントリビューションを促進できます。
企業: チーム開発・スプリント管理
企業プロジェクトでは、スプリント単位での計画・見積もりが重要になります。
企業Issue分解のポイント
- スプリント計画に適した粒度: 1スプリント(1〜2週間)に収まるサイズ
- 見積もりの明確化: ストーリーポイント・工数見積もりを記載
- 担当者の明確化: チームメンバー名を記載(OSSは不要)
- ビジネス要件の追加: 「なぜ作るか」にビジネス価値を記載
- テストケース: QAチームとの連携、受入テスト項目を記載
企業プロジェクトでの親Issue例
追加セクション(企業向け)
- Business Value: この機能で売上XX%増加見込み、顧客満足度向上
- Stakeholders: PM(田中)、エンジニア(佐藤・鈴木)、QA(山田)
- Estimation: 合計20ストーリーポイント、2スプリント想定
- Test Plan: QAチームによる受入テスト項目、自動テスト要件
- Release Plan: v2.1.0で本番リリース予定
スプリント計画への活用
スプリント1(1週間)
- #10: Setup (2pt) - 佐藤
- #11: ReusableBlock model (5pt) - 鈴木
- #12: ReusableBlockChooserBlock (3pt) - 佐藤
スプリント2(1週間)
- #13: Template (3pt) - 佐藤
- #14: Settings (2pt) - 鈴木
- #15: Admin UI (3pt) - 鈴木
- #16: Nested rendering (5pt) - 佐藤
Issue分解 = スプリント計画の基礎
アトミック粒度に分解することで、正確な見積もりが可能になります。
大きなIssueのまま見積もると誤差が大きく、スプリント計画が破綻してしまいます。
企業Waterfall: WBS・工程管理
日本企業で未だ根強いウォーターフォールモデルでも、Issue分解は有効です。
従来のWBS(Work Breakdown Structure)をGitHub Issueに置き換えることで、進捗管理が一元化できます。
Waterfall Issue分解のポイント
- 工程単位での分解: 要件定義 → 基本設計 → 詳細設計 → 実装 → テスト
- ドキュメント成果物を明記: 各Issueに「作成すべきドキュメント」を記載
- 工程完了基準: レビュー承認、ドキュメント提出が完了条件
- 担当者・期限の明確化: ガントチャートとの連携
- 変更管理プロセス: 仕様変更時は親Issueを更新、影響範囲を記録
Waterfall型 親Issue構成
親Issue #1: 再利用ブロック機能開発
- 工程1: 要件定義 (#10) - 要件定義書作成、顧客レビュー
- 工程2: 基本設計 (#11, #12) - 基本設計書、I/F設計書
- 工程3: 詳細設計 (#13, #14, #15) - 詳細設計書、DB設計書
- 工程4: 実装 (#16, #17, #18) - ソースコード、単体テスト仕様書
- 工程5: 結合テスト (#19) - 結合テスト仕様書、不具合管理
- 工程6: 総合テスト (#20) - 総合テスト報告書、本番リリース
Waterfallの課題
- フィードバックが遅い: 実装後にしか問題が発覚しない
- 仕様変更に弱い: 後工程での変更は全ドキュメントの修正が必要
- 工程の境界が硬直的: 設計ミスが実装工程で発覚しても戻れない
- ドキュメント更新コスト: Word/Excel管理は追跡性が低い
Issue分解で改善できること
GitHub Issueを使うことで、ドキュメントとコードの紐付けが明確になります。
完全なAgile移行が難しい企業でも、Issue管理だけ導入する価値があります。
よくある質問
A: 全ての子Issueが完了したらクローズします。
親Issue自体は実装を行わないため、子Issueの進捗管理用です。
wagtail-reusable-blocksでは、Issue #10〜#17が全て完了したらIssue #1をクローズします。
Sub-issue機能(トピック#14)を使えば、進捗が自動表示されます。
A: 中間階層が必要な時に使います。
wagtail-reusable-blocksでは、parent(#1)→ atomic(#10〜#17)の2階層で十分でした。
もし#11をさらに分解する必要があったら、parent (#1) → child (#11) → atomic (#11-1, #11-2...) の3階層になります。
プロジェクト規模が大きい場合に使用します(トピック#12参照)。
A: さらに分解するか、見積もりが間違っていたか確認します。
1日で終わらない = 分解不足の可能性が高いです。
例: 「Implement ReusableBlock model」が2日かかる場合
→ 「Define model fields」(1時間)+ 「Implement model methods」(3時間)+ 「Write tests」(2時間)に分割
または、想定より複雑だった場合、Issue本文にその旨記載して延長を相談してみてください。
A: 親Issueでは推奨、アトミックIssueでは任意です。
親Issueには書くべきです(全体像を示すため)。
アトミックIssueは、親IssueのTechnical Designを参照すればいいので、詳細は不要です。
ただし、実装方針に迷う場合は、アトミックIssueにも簡単な設計メモを書くと良いでしょう。
A: はい、強く推奨します。
「やらないこと」を明示することで、スコープクリープを防げます。
レビュー時に「これも必要では?」と言われた時、「Out of Scopeに書いてあります、次のマイルストーンで」と答えられます。
Issue #1では、「Slot system (v0.2.0)」「Caching (v0.3.0)」を明記しています。
A: はい、できます。
既にアトミックIssue #10〜#17が存在している状態で、後から親Issue #1を作成しても問題ありません。
Sub-issue機能(トピック#14)で関連付けすれば、親子関係を設定できます。
最初からキレイに設計する必要はなく、必要に応じて整理していけばOKです。


まだコメントはありません。最初のコメントを残しませんか?