--- name: bf-lead-plan description: Tech Spec을 분석하여 Epic/Story 구조를 생성하고, Story 5개 이상일 때 병렬로 Story 문서를 작성한다. Distribute 조율 패턴. --- # Lead Plan (Distribute Pattern) ## Overview 승인된 Tech Spec을 분석하여 Epic → Story 구조를 생성하고, 각 Story에 난이도(S/M/L/XL)를 태깅한다. Story 문서가 5개 이상이면 Creator 에이전트를 병렬로 스폰하여 문서를 작성한다. ## When to Use - `bf-lead-orchestrate`가 스폰 - 직접 호출하지 않는다. ## Prerequisites - 승인된 Tech Spec: `docs/tech-specs/{TICKET}-tech-spec.md` - Tech Spec 리뷰 통과 (사람 개입 ① 완료) ## Error Handling - Tech Spec 파일 미존재: `"error: tech-spec not found at {경로}"` 신호를 orchestrate에 전달 후 종료 - Story Creator 스폰 실패: Lead가 직접 Story 문서를 작성 (4개 이하일 때와 동일하게 순차 처리) - conventions.md 미존재: 경고만 표시하고 난이도 태깅은 기본 기준으로 진행 (컨벤션 영향도 반영 불가) ## Instructions ### 1. 초기 로딩 - `docs/tech-specs/{TICKET}-tech-spec.md` 읽기 - `docs/conventions.md` 읽기 (있으면) — 기존 도메인/아키텍처 규칙을 난이도 판정과 Story 분리 기준에 반영 ### 2. Epic 도출 - 기능 단위 또는 도메인 단위로 에픽을 분리한다. - 에픽 간 의존성을 명시한다. - 에픽은 순차적으로 실행됨을 기준으로 순서를 결정한다. - **Epic 최소 규모**: Epic당 Story 3개 이상을 권장한다. Story 2개 이하인 Epic이 나오면 인접 Epic과 병합을 검토한다. 단, 도메인 경계가 명확하여 병합이 부자연스러운 경우(예: 인증 vs 결제)는 2개도 허용한다. Epic마다 E2E 검증·통합 리뷰·사람 확인 등 고정 오버헤드가 발생하므로, 불필요하게 작은 Epic은 피한다. - **Story 0개 에픽 처리**: 인프라 준비, 설정 변경 등 Story로 분해할 수 없는 에픽은 sprint-status.yaml에 Story 없이 에픽만 등록하고, `e2e: passed`로 초기화한다 (기본 템플릿의 `pending`이 아닌 `passed`로 직접 설정). ### 3. Story 구조 결정 각 Epic 내 Story를 결정한다: - Story는 병렬 실행 가능한 단위로 분리한다. - 각 Story에 명확한 AC를 포함한다. - Story 간 의존성이 있으면 Dependencies 섹션에 명시한다. ### 4. 난이도 태깅 모든 Story에 반드시 난이도(S/M/L/XL)를 태깅해야 한다. 난이도 태그 없이 Story 문서를 완성하지 않는다. 난이도는 agent 구성(모델 선택, 팀 규모)을 결정하는 핵심 입력이다. 각 Story에 난이도를 태깅한다: | 난이도 | 기준 | |--------|------| | S (Simple) | 단일 파일, 명확한 AC, 의존성 없음 | | M (Medium) | 2~3 파일, 모듈 간 연결 있음 | | L (Large) | 다수 파일, 아키텍처 영향 큼 | | XL (Complex) | 크로스 레이어, 보안/성능 고려, 설계 판단 포함 | - `docs/conventions.md`에 아키텍처 규칙이 정의되어 있으면, 해당 규칙의 영향을 받는 Story의 난이도를 상향 조정한다 (예: 컨벤션에 엄격한 보안 규칙이 있으면 관련 Story를 M→L로). ### 5. Story 문서 작성 (Distribute Pattern) **Story 5개 이상:** - Creator 에이전트를 스폰한다 (`model: sonnet`). - 각 Creator에게 전달: - Story AC, Epic 컨텍스트, Story 문서 템플릿 (아래 Output Format 참조) - Lead가 모든 Creator의 `"done"` + story 파일을 수집한다. **Story 4개 이하:** - Lead가 직접 순차적으로 Story 문서를 작성한다. ### 6. Sprint 식별자 결정 Sprint 식별자는 **Jira 티켓 번호**를 그대로 사용한다 (예: `HACKLE-13554`): - 스폰 시 전달받은 `{TICKET}` 번호를 sprint-status.yaml의 최상위 키로 사용 - `docs/archive/` 디렉토리에 이미 같은 티켓의 아카이브가 있으면 에러 보고 ### 7. sprint-status.yaml 생성 sprint-status.yaml의 모든 메트릭 필드(model_used, ralph_retries, ralph_approaches, review_blockers, review_recommended, failure_tag, is_regression, parent_story, ralph_stuck)를 기본값(0/null/false)으로 초기화해야 한다. 필드 누락은 이후 bf-metrics 분석을 오염시킨다. ```yaml {TICKET}: epic-1: story-1: status: todo difficulty: S tdd: pending review: pending model_used: null ralph_retries: 0 ralph_approaches: 0 review_blockers: 0 review_recommended: 0 failure_tag: null is_regression: false parent_story: null ralph_stuck: false story-2: status: todo difficulty: M tdd: pending review: pending model_used: null ralph_retries: 0 ralph_approaches: 0 review_blockers: 0 review_recommended: 0 failure_tag: null is_regression: false parent_story: null ralph_stuck: false e2e: pending ``` > 메트릭 필드 기본값: 모든 필드는 0/null/false로 초기화. 각 필드는 이후 Lead 스킬들이 기록한다: > - `model_used`, `ralph_retries`, `ralph_approaches`, `ralph_stuck`: bf-lead-implement > - `review_blockers`, `review_recommended`: bf-lead-review > - `failure_tag`, `is_regression`, `parent_story`: E2E agent ### 8. 파일 저장 및 커밋 - Story 파일: `docs/stories/{TICKET}-story-{N}.md` - sprint-status.yaml: `docs/sprint-status.yaml` - **git commit하지 않는다** — docs/ 산출물은 Phase 4 Archive에서 일괄 커밋한다. ### 9. Done 신호 - 스폰한 상위 에이전트에 전달: `"done"` + stories/ 경로 + sprint-status.yaml 경로 - 종료 (컨텍스트 소멸). ## Output Format ### Story 문서 템플릿 ```markdown # {TICKET}-story-{N}: {Story 제목} ## 에픽 {소속 에픽 ID 및 이름} ## 난이도 {S | M | L | XL} — {난이도 판정 근거} ## 인수 조건 - [ ] AC 1: {구체적이고 테스트 가능한 기준} - [ ] AC 2: ... ## 기술 노트 - 변경 대상 파일/모듈 - 주요 라이브러리 (구현에 핵심적인 외부 라이브러리 — 예: zod, react-hook-form, @tanstack/react-query) - 의존성 (다른 Story와의 관계) - 주의사항 ## 의존성 - {의존하는 Story ID} (있는 경우) ```