LogoSkills

zenhub-breakdown

ZenHub Initiative/Project/Epic/Feature-Bug-Task/Sub-task 생성(요구사항에서 규모 자동 추론), 우선순위 검토 및 파이프라인 정렬 포함

/cc-dev:zenhub:breakdown — 요구사항을 ZenHub 일감으로 자동 정리#

항목내용
실행 명령/cc-dev:zenhub:breakdown
분류워크플로우
난이도●●○ 보통
MCP 서버zenhub, sequential

한마디로#

기능 요구사항(또는 화면 캡처 이미지)을 넣으면, ZenHub에 "큰 일감 → 작은 일감"을 자동으로 만들어 주는 명령입니다. 큰 공사 계획서를 받아서 "프로젝트 → 단계 → 세부 작업"으로 쪼개고, 어떤 일을 먼저 할지 우선순위까지 매겨 일정표(보드)에 꽂아 주는 비서라고 보면 됩니다. 작업 규모를 스스로 판단해서 어디까지 계층을 만들지 정합니다 — 작은 버그 하나면 Epic 없이 Bug 이슈 하나만, 여러 Epic을 아우르는 개편이면 Project까지 자동으로 만듭니다.

누가·언제 쓰나요#

  • 기획/요구사항이 정리된 상태에서 ZenHub에 실제 일감(이슈)을 만들어야 할 때
  • 화면 캡처 이미지만 있고, 그걸 바탕으로 요구사항과 일감을 한 번에 뽑고 싶을 때
  • /cc-flutter:figma:analyze(피그마 분석)의 마지막 단계에서 자동으로 이어서 호출될 때
  • 여러 Epic을 묶는 상위 Project 단위 일감을 만들고 싶을 때 (자동 추론되거나, --project로 강제)

무엇을 해주나요#

  • 요구사항 규모를 보고 ZenHub 이슈 계층을 어디까지 만들지 자동 판단합니다: Initiative → Project → Epic(큰 일감) → Feature/Bug/Task(화면·작업별 일감) → Sub-task(세부 작업) 중 규모에 맞는 범위만 생성 (작은 작업은 Epic 없이 Feature/Bug/Task 하나만).
  • 각 일감을 실제 성격(신규 기능/버그/작업)에 맞는 타입으로 만들고, 우선순위(P0/P1/P2) 를 매겨 그 근거 표를 Epic 본문에 넣어 줍니다.
  • Epic에 일정(시작일~종료일)과 Story Point(예상 작업량) 를 넣어 로드맵에 막대로 표시되게 합니다 — 기간은 팀의 최근 실측 스프린트 속도(포인트 트렌드 포함)로 산출하고, Story Point는 하위 분해가 아직 없어도(스프린트 배정 여부와 무관하게) 항상 채웁니다
  • 여러 Epic을 한 번에 만들 때는 Epic 간 의존 관계를 확인해, 서로 의존이 없는 Epic끼리는 같은 기간에 나란히(병렬), 의존이 있으면 선행 Epic이 끝난 뒤로 순차 배치합니다
  • 만든 이슈들을 우선순위에 맞는 파이프라인(Product Backlog / Sprint Backlog / Icebox) 으로 배치합니다
  • 이미지 분석을 쓰면 요구사항·BDD 시나리오 문서까지 자동으로 만들어 .claude/docs/{기능명}/ 아래에 저장합니다 (requirements.md, bdd/, zenhub/epic.md, priority.md 등)

어떻게 쓰나요#

# 가장 기본 — community 기능, Post 엔티티로 규모에 맞는 계층 자동 생성
/cc-dev:zenhub:breakdown community Post

# 여러 Epic을 묶는 상위 Project까지 한 번에 만들기 (2개 이상 --epics는 Project를 자동 유발)
/cc-dev:zenhub:breakdown --project  " 어드민 콘솔 v2 "   --epics  " auth,community,payment " 

 # 이미 있는 Project 이슈(: 1024) 밑에 Epic 연결
/cc-dev:zenhub:breakdown community Post --parent-project 1024

# 화면 캡처 이미지로부터 요구사항+일감 자동 생성
/cc-dev:zenhub:breakdown community Post --images  " list.png,detail.png,form.png " 

 # 스프린트·라벨 지정
/cc-dev:zenhub:breakdown community Post --labels  " sprint-1,mvp "   --sprint current

# 일정 직접 지정 (또는 --no-dates 로 일정 비우기)
/cc-dev:zenhub:breakdown community Post --start-date 2026-06-16 --end-date 2026-07-14

# 여러 Epic 사이 의존 관계를 명시해 병렬/순차 타임라인 산출
/cc-dev:zenhub:breakdown --project  " 출판사 정산 시스템 확장 "   --epics  " 정산엔진API,정산배치,정산리포트,알림발송 "   \
  --epic-deps  " 정산배치:정산엔진API,정산리포트:정산엔진API " 

 # 작은 버그 1건 — Epic 없이 Bug 이슈 하나만 강제 생성
/cc-dev:zenhub:breakdown --no-epic  " 로그인 버튼 텍스트 오타 수정 "

자주 쓰는 옵션 몇 가지:

  • --images / --images-dir: 화면 캡처로 요구사항·BDD까지 자동 생성
  • --points "3,3,5": 화면별 예상 작업량(Story Point)을 직접 지정 (지정 안 해도 항상 자동 추정되어 채워집니다)
  • --epic-deps "B:A,C:A": 여러 Epic 생성 시 의존 관계 명시(B, C가 A에 의존) — 미지정 시 요구사항 신호로 자동 추론, 신호 없으면 독립(병렬)
  • --velocity 170: 팀 스프린트 속도를 직접 지정 (미지정 시 최근 완료 스프린트 실측 평균)
  • --no-sort: 파이프라인 자동 정렬을 건너뜀
  • --no-dates: Epic 일정 설정을 건너뜀 (Story Point는 이 옵션과 무관하게 항상 설정됩니다)
  • --no-epic: Epic을 만들지 않고 Feature/Bug/Task(+Sub-task)만 최상위로 생성

안에서 무슨 일이 벌어지나요#

대략 이런 순서로 진행되고, 중요한 분기마다 "이대로 진행할까요?"라고 사람에게 확인을 받습니다.

  1. (이미지가 있으면) 화면 분석 — 캡처가 목록/상세/폼 중 무엇인지 알아내고, 거기서 Entity 필드와 BDD 시나리오, 요구사항 문서를 자동으로 뽑습니다.
  2. 요구사항 읽기 — 방금 만든(또는 기존) 요구사항·BDD 문서를 불러옵니다.
  3. 계층 스케일 추론 — 요구사항 규모(여러 Epic/시스템 전체/전사 전략 신호, 또는 화면 1개짜리 작은 작업)를 보고 Initiative~Epic 중 어디를 최상위로 만들지, 혹은 Epic 없이 Feature/Bug/Task만 만들지 자동으로 정합니다. 명시적 플래그(--initiative/--project/--no-epic)가 있으면 항상 그것이 우선합니다.
  4. 우선순위 검토 — 만들 일감마다 의존성·중요도·위험·작업량을 따져 P0/P1/P2 등급을 매기고, 추론된 계층과 함께 표로 보여 준 뒤 확인을 받습니다. (라벨은 생성 후 못 바꾸므로 미리 정합니다.)
  5. 이슈 생성 — 추론된 범위대로 Project → Epic → Feature/Bug/Task → Sub-task 순서로 ZenHub 이슈를 만들고 서로 부모-자식으로 연결합니다. 각 항목은 성격에 따라 Feature/Bug/Task 중 실제 타입으로 생성됩니다.
  6. 일정·작업량 설정 — 최근 완료 스프린트의 실측 속도(포인트 트렌드 포함)로 Epic 기간을 산출해 시작/종료일과 Story Point를 넣습니다. 여러 Epic을 함께 만들 때는 Epic 간 의존 관계를 확인해, 의존이 없는 Epic끼리는 같은 기간에 병렬로, 의존이 있으면 선행 Epic이 끝난 뒤로 순차 배치합니다. Story Point는 하위 분해가 없어도 항상 채웁니다. 하위 항목들도 Epic 기간 안에서 순서대로 나눠 배치합니다.
  7. 파이프라인 정렬 — 우선순위에 따라 각 이슈를 알맞은 보드(파이프라인)로 옮기고, P0 항목은 (요청 시) 스프린트에 넣습니다.
  8. 결과 기록 — 만든 내용과 우선순위·배치 결과를 .claude/docs/{기능명}/ 아래 문서로 남깁니다.
  9. 다음 단계 연결 — 만든 일감을 바로 개발로 넘길지 묻습니다. "바로 개발 시작"을 고르면 Epic은 /cc-dev:batch, 단독 이슈는 /cc-dev:run으로 즉시 이어집니다. /cc-dev:go에서 호출된 경우에는 묻지 않고 /cc-dev:go가 알아서 이어받습니다.

⚙️ 상세 옵션·실행 명세 (개발자 / AI 에이전트용)

Triggers#

  • When creating issues from feature requirements
  • When called from /cc-flutter:figma:analyze Phase 4
  • When manually creating ZenHub issues
  • When creating a Project-level issue that wraps multiple Epics (auto-inferred, or forced via --project)
  • When a request is small enough that no Epic wrapper is warranted (auto-inferred, or forced via --no-epic)

Context Trigger Pattern#

/cc-dev:zenhub:breakdown {feature_name} {entity_name} [--options]

Parameters#

Required Parameters#

ParameterDescriptionExample
feature_nameFeature name (snake_case)community
entity_nameEntity name (PascalCase)Post

Image Analysis Options (Optional)#

ParameterDescriptionExample
--imagesImage files to analyze (comma-separated)"list.png,detail.png,form.png"
--images-dirImage directory path./screenshots/
--attach-imagesAttach to Issue after committing to repo (default: false)true/false
--min-confidenceMinimum confidence for screen type identification (default: 70%)80
--skip-analysisSkip image analysistrue/false
--no-cacheIgnore cache and re-analyzetrue/false

Hierarchy Options (Optional)#

ParameterDescriptionExample
--initiativeCreate an Initiative-level issue (wraps the Project/Epic(s) as children)--initiative "2026 H2 전략 목표"
--parent-initiativeLink the created Project (or top-level Epic) to an existing Initiative issue (issue number)--parent-initiative 900
--projectCreate a Project-level issue and link the Epic(s) as children--project "어드민 콘솔 v2"
--parent-projectLink the Epic to an existing Project issue (issue number)--parent-project 1024
--epicsMultiple Epic names under one Project (comma-separated; default: single Epic). 2 or more entries auto-infers Project scale even without --project"auth,community,payment"
--epic-depsDependency edges between Epics named in --epics (B:A = B depends on A; multiple deps per Epic comma-joined within its own pair via ;). Omitted → inferred from requirement-text/scope signals; no signal → independent (parallel candidate). SoT: rules/zenhub-conventions.mdEpic Dependency & Parallel Scheduling"community:auth,payment:auth"
--no-epicForce-skip the Epic level — create Feature/Bug/Task (+ Sub-task) directly, no Epic wrappertrue/false

--project and --parent-project are mutually exclusive; so are --initiative and --parent-initiative; so are any of those and --no-epic. If none are given, Hierarchy Scale Inference (see Behavioral Flow → Step 1.5) auto-decides the top-level anchor from the request content — this replaces the old "Epic is always top-level unless a flag says otherwise" default. --initiative/--parent-initiative may be combined with --project/--parent-project (Initiative wraps Project) or used alone (Initiative wraps Epic directly, when no Project level is requested).

Other Options (Optional)#

ParameterDescriptionExample
--requirementsRequirements document path.claude/docs/community/requirements.md
--bdd-dirBDD scenario directory.claude/docs/community/bdd/
--labelsAdditional labels"sprint-1,mvp"
--screensScreens to generate"list,detail,form"
--pointsStory Point setting. Always set regardless of this flag — when omitted, auto-estimated (Fibonacci for work items; T-shirt→Fibonacci top-down for Epics with no child breakdown yet). SoT: rules/zenhub-conventions.mdMandatory Story Point Estimate"3,3,5"
--sprintSprint assignment (current=활성/next=다음/숫자·이름)"current"
--start-dateEpic timeline start date (ISO YYYY-MM-DD). Default: 활성 스프린트 시작 (or today)2026-06-16
--end-dateEpic timeline end date (ISO YYYY-MM-DD). Default: start + computed duration2026-07-14
--durationTimeline length in weeks (used when --end-date omitted). Default: auto from total points ÷ measured team velocity (not a fixed constant) — see rules/zenhub-conventions.mdEpic Velocity Calculation4
--velocityStory points per sprint, overriding the measured-velocity calculation (e.g. team size just changed)170
--no-sortSkip the priority review/pipeline sorting step (Step 5)true/false
--no-datesSkip timeline date setting (Epic created without a period). Story Point estimate is still always set — unaffected by this flagtrue/false

Workspace Info Query (required — before Step 0)#

Issue Type ID, Repository ID, and Pipeline ID differ per workspace. Dynamically query based on the workspace configured in .mcp.json at the project root:

// 1. Repository ID + Pipeline ID
const workspace = await mcp__zenhub__getWorkspacePipelinesAndRepositories();
const repoId = workspace.githubRepositories.find(r = >   /* GitHub 레포 선택 */).id;

// 2. Issue Type ID (includes hierarchy level: lower = higher level)
const issueTypes = await mcp__zenhub__getIssueTypes({ repositoryId: repoId });
const initiativeType = issueTypes.find(t = >   t.name ===  " Initiative " );  // may be absent
const projectType = issueTypes.find(t = >   t.name ===  " Project " );  // may be absent
const epicTypeId = issueTypes.find(t = >   t.name ===  " Epic " ).id;
const featureTypeId = issueTypes.find(t = >   t.name ===  " Feature " ).id;
const bugTypeId = issueTypes.find(t = >   t.name ===  " Bug " ).id;
const taskTypeId = issueTypes.find(t = >   t.name ===  " Task " ).id;
const subtaskTypeId = issueTypes.find(t = >   t.name ===  " Sub-task " ).id;

// Initiative type fallback: if --initiative given but type absent,
// warn the user and create the Project (or Epic, if no --project) as top level instead
if (useInitiativeLevel  & &   !initiativeType) {
  // ⚠️  " 이 워크스페이스에는 Initiative Issue Type이 없습니다. Project(또는 Epic)를 최상위로 생성합니다. " 
 }

// Project type fallback: if --project given but type absent,
// warn the user and create Epic(s) as top level instead
if (useProjectLevel  & &   !projectType) {
  // ⚠️  " 이 워크스페이스에는 Project Issue Type이 없습니다. Epic을 최상위로 생성합니다. " 
 }

Behavioral Flow#

Step 0: Image Analysis (when --images provided)#

Executed when --images or --images-dir parameter is provided.

0.1 Image Load

Supported formats: PNG, JPG, JPEG, WEBP Recommended size: Max 5MB/file, 1920x1080 or smaller recommended

# Specify individual files
--images  " list.png,detail.png,form.png " 

 # Specify directory (auto-filter supported formats)
--images-dir ./screenshots/

0.2 Screen Type Identification

Identify each image via Claude multimodal analysis:

ImageScreen TypeConfidenceKey Components
list.pngList95%AppBar, ListView, FAB
detail.pngDetail90%SliverAppBar, ContentSection
form.pngForm92%Form, TextField, Button

Screen Type Identification Criteria:

  • List: Multiple repeating cards/items, scrollable layout, FAB
  • Detail: Full info of single item, large image/gallery, action buttons
  • Form: Input fields (TextField, Dropdown, etc.), save/cancel buttons

Confidence threshold (--min-confidence, default: 70%):

  • Screens below threshold request manual user confirmation
  • e.g.: With --min-confidence 80, confidence below 80% needs confirmation

0.3 Entity Field Extraction

Infer Entity fields from UI elements in images:

entity:
  name: {EntityName}
  fields:
    - name: title
      type: String
      required: true
      ui_component: TextField
      validation:
        max_length: 100
      source_screen: form.png

    - name: content
      type: String
      required: true
      ui_component: TextArea
      validation:
        max_length: 5000
      source_screen: form.png

    - name: category
      type:  " {EntityName}Category " 
       required: true
      ui_component: Dropdown
      options: [general, notice, event]
      source_screen: form.png

    - name: imageUrls
      type:  " List < String > ? " 
       required: false
      ui_component: ImagePicker
      validation:
        max_count: 5
      source_screen: form.png

0.4 BDD Scenario Generation

Apply default BDD scenario templates based on screen type.

Language: BDD scenarios are generated in Korean (project convention).

List screen:

  • List loading success
  • Pull to refresh
  • Infinite scroll
  • Card tap → navigate to detail
  • Apply filter
  • Empty list

Detail screen:

  • Display detail info
  • Like toggle
  • Edit/delete
  • Go back

Form screen:

  • Valid form submission
  • Required field missing
  • Image attachment
  • Cancel creation

0.5 Requirements Document Generation

Save analysis results as markdown:

Path: .claude/docs/{feature_name}/requirements.md

# {Feature} Requirements Specification

 >   Auto-generated from image analysis

## Entity Definition

### {Entity}
| Field | Type | Required | Description |
|------|------|------|------|
| title | String || Title |
| content | String || Content |
...

## Screen Definition

### 1. List Screen (list.png)
- Components: AppBar, ListView, FAB
- Actions: Card tap → navigate to detail, FAB tap → create
...

0.6 Image Save and URL Generation (with --attach-images true)

Default: --attach-images is disabled (false) by default. You must explicitly specify --attach-images true to commit images to the repo.

Save images to repo and generate GitHub raw URLs:

⚠️ Caution: Pushes directly to the current branch. May fail for protected branches (main/development).

User confirmation prompt:

🖼️ 이미지를 repo에 commit하시겠습니까?

- 대상 파일: list.png, detail.png, form.png
- 저장 경로: .claude/docs/{feature}/screenshots/
- 현재 브랜치: {current_branch}

**계속하시겠습니까? (y/N)**
# 1. Copy images to .claude/docs
cp {input_images} .claude/docs/{feature}/screenshots/

# 2. Add to Git (current branch)
git add .claude/docs/{feature}/screenshots/
git commit -m  " docs: 📸 {feature} 스크린샷 추가 " 
 git push origin HEAD

# 3. Generate GitHub raw URLs
# https://raw.githubusercontent.com/{owner}/{repo}/{branch}/.claude/docs/{feature}/screenshots/{image}

Protected Branch Handling:

  • Recommend running from feature branch
  • If push fails, proceed without image URLs (use local paths)

0.7 User Confirmation

## 📸 이미지 분석 결과

### 식별된 화면
| # | 이미지 | 화면 타입 | 컴포넌트 수 |
|---|--------|----------|-----------|
| 1 | list.png | List | 5 |
| 2 | detail.png | Detail | 4 |
| 3 | form.png | Form | 6 |

### 추출된 Entity 필드
| 필드 | 타입 | 필수 | 출처 |
|------|------|------|------|
| title | String || form.png |
| content | String || form.png |
| category | Enum || form.png |

### 생성할 BDD 시나리오
- 목록: 8- 상세: 6-: 7**분석 결과가 정확합니까? (Y/n)**

0.8 Error Handling

SituationHandling
Image file not foundOutput ❌ File not found: {path} and exit
Unsupported formatOnly PNG, JPG, JPEG, WEBP supported. Other formats ignored with warning
Git push failureProceed without image URLs, use local paths (show warning)
Analysis confidence < thresholdRequest manual user confirmation: ⚠️ Confidence {n}% - please verify screen type
No images in directoryOutput ⚠️ No supported images in directory: {path} and exit
Entity field extraction failureProceed with empty fields, request manual input from user

Step 1: Load Requirements#

Priority:

  1. Requirements generated in Step 0 (when using --images)
  2. File specified via --requirements
  3. Default path: .claude/docs/{feature}/requirements.md
## 요구사항 로드

1. .claude/docs/{feature}/requirements.md 읽기
2. BDD 시나리오 파일들 읽기 (있는 경우)
3. Entity 필드 정의 추출
4. 화면 정의 추출

Step 1.5: Hierarchy Scale Inference (before Priority Review)#

Decide how much of Initiative → Project → Epic → Feature/Bug/Task → Sub-task to create. Explicit flags always win; otherwise infer from the request content, reusing the same "explicit override > keyword inference" pattern as commands/run.md's type/scope inference:

SignalResult
--initiative/--parent-initiativeinitiative
--project/--parent-project, or --epics with 2+ entriesproject
--no-epicno-epic
Auto + "전사"/"로드맵"/"분기"/"N개월 전략"/"여러 팀" signalsinitiative
Auto + "시스템 전체"/"플랫폼 개편"/"여러 기능" signals, or 2+ distinct feature domains namedproject
Auto + single screen/single bug/single small task, estimated total ≤3 pointsno-epic
Auto, none of the above (default — unchanged prior behavior)epic
## 📐 계층 스케일 추론 결과

**판단**: ProjectEpicFeature ×3 (근거: auth/community/payment 3개 기능 도메인 언급)

**이 계층으로 진행하시겠습니까? (Y/n)**

The inferred scale is shown alongside the Step 1.6 priority table for a single combined confirmation before anything is created — see the "우선순위 검토 결과" prompt below.

Step 1.6: Priority Review (before creation)#

⚠️ updateIssue cannot change labels — priority labels must be decided before issue creation.

Score every issue to be created (per the Step 1.5 scale — Epic/Feature/Bug/Task/Sub-task) and assign a tier per rules/zenhub-conventions.mdPriority Review and Pipeline Sorting:

AxisQuestion
DependencyDo other Stories depend on this? (Entity/API foundation = P0)
Business valueCore user path of the Epic?
RiskTechnically uncertain → earlier
EffortAmong equals, smaller points first

Matrix(impact×effort) 신호 영속화 (C6): effort 는 setIssueEstimate(Story Point)로, impact 는 별도 라벨 impact-high|impact-med|impact-low 로 저장한다(라벨 불변 → 생성 시 확정). impact = Business value + Dependency + Risk (effort 제외 — effort 를 impact 에 섞으면 ZenHub Matrix 에서 이중 계산된다). P-tier 와 독립된 축이며, 이걸 채워야 Matrix Y축이 의미를 갖는다.

Point (필수, 스프린트 배정 여부와 무관): 모든 이슈는 여기서 Fibonacci 포인트를 확정한다 (rules/zenhub-conventions.mdMandatory Story Point Estimate). Epic 자체는 하위 항목이 이 실행에서 함께 만들어지면 그 합, 아직 하위 분해가 없으면(다중 Epic 생성 시 흔함) T-shirt→Fibonacci 하향식 추정으로 채운다 — 0/null 로 남기지 않는다.

선행(의존) (Epic을 2개 이상 함께 만들 때만): 이 이슈가 다른 Epic의 산출물(Entity/API/데이터 모델 등)을 전제로 하면 그 Epic 번호/이름을 적는다. rules/zenhub-conventions.mdEpic Dependency & Parallel Scheduling 의 신호표를 따르며, 신호가 없으면 빈칸(독립 — 병렬 후보)이 기본값이다. --epic-deps 로 명시된 값이 있으면 그것이 최우선이다.

## 🔢 우선순위 검토 결과

| 순위 | 이슈 | 티어 | impact | Point | 선행(의존) | 근거 |
|------|------|------|--------|-------|-----------|------|
| 1 | {feature} 목록 화면 | P0 | high | 3 || 상세/폼 화면이 목록 Entity에 의존(value+dependency 높음) |
| 2 | {feature} 상세 화면 | P1 | med | 5 | #1 | 핵심 경로, 목록 Entity 사용 |
| 3 | {feature} 폼 화면 | P1 | low | 5 | #1 | 핵심 경로 |

**이 우선순위로 진행하시겠습니까? (Y/n)**

Confirmed tiers become p0/p1/p2 and impact-high|med|low labels passed to createGitHubIssue (both immutable post-creation), and the table is embedded in the Epic (or Project) body. Point becomes each item's setIssueEstimate value; 선행(의존) becomes the dependency edges resolved in Step 2.5.

Step 1.65: Artifact Publication (before any issue is created)#

Per rules/zenhub-conventions.mdIssue Body Artifact Contract, the long narrative goes to a claude.ai artifact and the issue body keeps only the machine-read contract block. Publish first, create second — reversing the order creates issues whose bodies have no link and then need patching.

For each issue that qualifies (Initiative/Project/Epic always; Feature/Bug/Task only when its narrative exceeds 20 lines; never Sub-task):

// 1) Split per the contract table — narrative out, contract block stays
const { contract, narrative } = splitBody(item);   // SoT: rules/zenhub-conventions.md

// 2) Write the narrative to a per-issue fixed path (same path on re-publish = same URL)
const filePath = `.claude/docs/${scope}/issue-${slug}.html`;

// 3) Publish → capture the URL
const url = await Artifact({ file_path: filePath, favicon, description });

// 4) Assemble the body: contract block + link block
const body = buildBody(contract, url);

The link block uses the fixed format from the SoT (## 📄 상세 기획 + URL + section list + the 🔒 sharing notice). Always include the sharing notice — the artifact is private on publish and there is no API to make it public, so the pipeline cannot produce a genuinely public link.

Degradation — if Artifact is unavailable (cron/CI/headless session) or publication fails, do not abort the breakdown. Fall back to the full-markdown body (prior behavior) and log ℹ️ Artifact 미사용 — 전량 마크다운 본문으로 생성, then continue to Step 1.7.

## 📄 아티팩트 발행 결과

| 이슈 | 아티팩트 | 비고 |
|------|----------|------|
| Project: {project_title} | ✅ 발행 | {url} |
| Epic: {epic_title} | ✅ 발행 | {url} |
| {feature} 목록 화면 || 서술 12(20행 이하 → 본문 유지) |
| {feature} 상세 화면 | ✅ 발행 | {url} |
| Sub-task ×5 || 규약상 발행 대상 아님 |

 >   🔒 발행된 링크는 비공개입니다 — 팀 열람이 필요하면 claude.ai 에서 공유를 켜주세요.

Step 1.7: Initiative Creation (scale=initiative)#

Create the Initiative-level issue first, one level above Project; the Project (or, if no --project, the Epic directly) is linked as its child.

const initiative = await mcp__zenhub__createGitHubIssue({
  title:  " {initiative_title} " ,
  body: buildBody(contract, artifactUrl.initiative),  // 📄 링크 + 계약 블록 (전략 서술은 아티팩트)
  repositoryId: repoId,
  issueTypeId: initiativeType.id,
  labels: [ " initiative " ,  " p{priority} " ]
});

With --parent-initiative {issue_number}, query the existing issue via searchLatestIssues and use its GraphQL ID instead of creating a new one.

Step 1.8: Project Creation (scale=project or initiative)#

Create the Project-level issue first; Epics are linked as children.

const project = await mcp__zenhub__createGitHubIssue({
  title:  " {project_title} " ,
  body: buildBody(contract, artifactUrl.project),  // 📄 링크 + 계약 블록 (우선순위 표는 본문 유지)
  repositoryId: repoId,
  issueTypeId: projectType.id,
  parentIssueId: initiative?.id, // when --initiative/--parent-initiative is used
  labels: [ " project " ,  " p{priority} " ]
});

With --parent-project {issue_number}, query the existing issue via searchLatestIssues and use its GraphQL ID as the parent instead of creating a new one.

When --initiative/--parent-initiative is used without --project, link the Epic directly to the Initiative instead (parentIssueId: initiative.id on the Epic in Step 2).

⚠️ breakdown 은 이슈만 만들고 브랜치는 만들지 않는다project/{n}-* 브랜치는 "그 아래 Epic 을 처음 진행하는 세션"이 그때 만든다. 그 세션이 다른 컴퓨터일 수 있으므로, 브랜치를 만들거나 찾는 쪽(/cc-dev:run·/cc-dev:batch)은 반드시 이슈 번호 글롭 + 브랜치 대장으로 조회해야 한다 (branch-hierarchy → "계층 브랜치 해석 계약"). 이 계약이 지켜지지 않으면 Epic 이 끝났을 때 Project 브랜치로 머지되지 않고, 같은 Project 에 두 번째 계층 브랜치가 생겨 한쪽이 빈 채로 남는다.

Step 2: Epic Creation (skipped when scale=no-epic)#

다중 Epic: --epics 에 2개 이상이 주어지면(scale=project/initiative) 이 Step 은 목록의 각 이름마다 반복해 Epic 이슈를 만든다. Step 2.5(타임라인)는 이 반복이 모두 끝난 뒤, 생성된 Epic 전체를 한 배치로 대상으로 실행한다 — Epic 하나만 보고는 그것이 다른 Epic과 병렬 가능한지 판단할 수 없기 때문이다(SoT: rules/zenhub-conventions.mdEpic Dependency & Parallel Scheduling).

MCP call example:

mcp__zenhub__createGitHubIssue({
  title:  " {feature} 기능 구현 " ,
  body: buildBody(contract, artifactUrl.epic),  // 📄 링크 + 계약 블록 (Step 1.65 발행분)
  repositoryId: repoId,      // getWorkspacePipelinesAndRepositories()에서 조회
  issueTypeId: epicTypeId,   // getIssueTypes()에서 조회
  parentIssueId: project?.id ?? initiative?.id, // --project/--parent-project 우선, 없으면 --initiative/--parent-initiative 직접 연결
  labels: [ " epic " ,  " feature " ,  " {feature_name} " ,  " p{priority} " ]
})

Per rules/zenhub-conventions.md, always use createGitHubIssuecreateZenhubIssue is prohibited (ZenHub-native issues cannot move pipelines or set timelines).

Step 2.5: Epic Timeline + Estimate (dates skip only with --no-dates; Story Point is ALWAYS set)

⚠️ Without this step the Epic never appears on the Goals & Planning timeline. setIssueEstimate controls SP; setDatesForIssue controls the timeline period. Setting SP alone (the previous behavior) leaves startDate/endDate null, so the Epic shows points but no bar on the roadmap. Always set both — and SP is set regardless of --no-dates/--sprint (rules/zenhub-conventions.mdMandatory Story Point Estimate): whether an Epic is on the roadmap and whether it has a point value are independent facts.

This step runs once per Epic-creation batch (a single Epic, or every Epic named in --epics) — the date computation needs every Epic's points and dependency edges together, not one Epic in isolation.

// 0) Story Point — ALWAYS, for every Epic in the batch, independent of --no-dates/--sprint.
//    SoT: rules/zenhub-conventions.md →  " Mandatory Story Point Estimate " 
 for (const epic of epicsInThisBatch) {
  epic.points = epic.childStories?.length
    ? epic.childStories.reduce((s, x) = >   s + x.point, 0)        // 같은 실행에서 Story까지 만든 경우: 롤업
    : options.points?.[epic.key] ?? estimateTshirtFibonacci(epic.scopeText); // 없으면 하향식 추정 — 0/null 금지
  await mcp__zenhub__setIssueEstimate({ issueId: epic.id, estimate: epic.points });
}

// 1) Organization ID (required by setDatesForIssue)
const orgId = workspace.zenhubOrganization.id;

// 2) 킥오프 시작일 — 명시 플래그  >   --sprint 셀렉터 스프린트 시작  >   오늘
//    ⚠️ getUpcomingSprint 는  ' 다음 '   스프린트다. 기본값으로 쓰면 Epic 바가 한 스프린트 밀린다.
//       기본(current)은 getSprint()(id 없음=활성)를 쓴다.
const kickoffSprint = options.sprint ===  " next " 
   ? await mcp__zenhub__getUpcomingSprint()
  : await mcp__zenhub__getSprint();
const kickoffStart =
  options.startDate ??
  kickoffSprint?.startAt?.slice(0, 10) ??
  todayISO();                                              //  " YYYY-MM-DD " 

 if (!options.noDates) {
  // 3) 팀 실측 속도 — 고정 상수(이전: ~5pt≈2주) 대체.
  //    SoT: rules/zenhub-conventions.md →  " Epic Velocity Calculation " 
   const velocity = options.velocity
    ? { velocityPerSprint: options.velocity, sprintLengthWeeks: 2, declining: false, avgCoverage: null }
    : await computeVelocity();
  if (velocity.reason ===  " insufficient_history " ) {
    log( " ℹ️ 완료 스프린트 데이터 부족 — 고정 폴백(Epic당 1스프린트)으로 진행 " );
  }
  if (velocity.avgCoverage != null  & &   velocity.avgCoverage  <   0.5) {
    log(`⚠️ 완료 이슈 중 포인트가 매겨진 비율 ${Math.round(velocity.avgCoverage * 100)}% — 속도는 하한값에 가깝습니다`);
  }
  if (velocity.declining) {
    log( " ⚠️ 최근 3개 스프린트 평균이 전체 평균보다 낮음(하락 추세) — 보수적 속도 적용 " );
  }

  // 4) 의존 그래프 — 명시(--epic-deps)  >   요구사항 텍스트/범위 신호 추론  >   기본 독립(병렬 후보).
  //    SoT: rules/zenhub-conventions.md →  " Epic Dependency  &   Parallel Scheduling " 
   const dependencyEdges = resolveEpicDependencies(epicsInThisBatch, options.epicDeps, requirementsText);
  for (const { blocked, blocking } of dependencyEdges) {
    await mcp__zenhub__createBlockage({ blockedIssueId: blocked.id, blockingIssueId: blocking.id });
  }

  // 5) 위상 레벨로 시작/종료일 계산 — 의존 없는 Epic끼리는 같은 시작일(병렬),
  //    의존이 있으면 선행 Epic 종료 뒤. options.duration/endDate 는 단일-Epic(scale=epic) 오버라이드로 우선 적용.
  const schedule = (options.duration || options.endDate)  & &   epicsInThisBatch.length === 1
    ? [{
        epic: epicsInThisBatch[0],
        start: kickoffStart,
        end: options.endDate ?? addWeeksISO(kickoffStart, options.duration),
      }]
    : scheduleEpics(epicsInThisBatch, dependencyEdges, kickoffStart, velocity.velocityPerSprint, velocity.sprintLengthWeeks);

  // 6) 실제 반영
  for (const { epic, start, end } of schedule) {
    await mcp__zenhub__setDatesForIssue({ issueId: epic.id, startDate: start, endDate: end, zenhubOrganizationId: orgId });
    epic.scheduledStart = start;
    epic.scheduledEnd = end;
  }
}

Verification: after the calls, re-query each issue and confirm estimate is non-null (always) and, unless --no-dates, startDate/endDate are non-null. If setDatesForIssue fails (e.g. missing zenhubOrganizationId), surface the error — do not silently continue, or the Epic stays off the timeline.

## Epic 생성 확인

**제목**: {feature} 기능 구현

**내용 미리보기** (본문 = 계약 블록 + 아티팩트 링크, H1 은 타입 단어 없이 제목만 — `rules/zenhub-conventions.md` → *Unified Issue Body Template*):
---
# {Feature} 기능 구현

## 📄 상세 기획
**{artifact_url}**

↳ 개요 · 비즈니스 가치 · 기술 노트 · 화면 설계

 >   🔒 이 아티팩트 링크는 발행 시점에 **비공개**입니다. 팀이 열어야 하면 claude.ai
 >   아티팩트 페이지의 공유 메뉴에서 직접 공유를 켜주세요.

## 🔢 우선순위
| 순위 | 이슈 | 티어 | impact | 근거 |
|------|------|------|--------|------|
| 1 | {feature} 목록 화면 | P0 | high | 상세/폼이 목록 Entity에 의존 |

## 📊 범위
- ✅ 목록 화면
- ✅ 상세 화면
- ✅ 폼 화면
---

 >   개요·비즈니스 가치·기술 노트는 아티팩트로 이동했습니다 — 우선순위 표와 범위는
 >   규약상 본문에 남습니다(`rules/zenhub-conventions.md` → *Issue Body Artifact Contract*).
 >   `Artifact` 도구가 없는 세션이면 위 링크 블록 없이 종전 전량 마크다운으로 표시됩니다.

**라벨**: epic, feature, {feature_name}, kobic

**📅 타임라인**: {start_date} ~ {end_date} ({weeks})Goals  &   Planning 로드맵에 표시됨
**📐 Story Point**: {total_points}

**생성하시겠습니까? (Y/n)**

타임라인을 비워두려면 --no-dates, 기간을 직접 지정하려면 --start-date/--end-date 또는 --duration 사용 (단일 Epic일 때만 — 다중 Epic 배치에서는 의존/속도 기반 산출이 우선한다).

다중 Epic (--epics 2개 이상)일 때는 위 단일-Epic 미리보기 대신 아래처럼 배치 전체의 속도·의존· 스케줄을 한 번에 보여주고 확인을 받는다:

## Epic 생성 확인 (다중 EpicProject: {project_title})

**팀 속도**: 최근 6스프린트 평균 {allAvg}pt/스프린트, 최근 3스프린트 평균 {recentAvg}pt/스프린트{declining ?  "   (⚠️ 하락 추세 → 보수치 적용) "   :  " " }
**포인트 커버리지**: 완료 이슈 중 {coveragePct}%에 실제 포인트가 매겨져 있음{coveragePct  <   50 ?  "   (⚠️ 속도는 하한값에 가까움) "   :  " " }

| Epic | 티어 | Point | 의존(선행) | 시작 | 종료 | 병렬 그룹 |
|------|------|-------|-----------|------|------|-----------|
| #1 정산 엔진 API | P0 | 13 || 8/23 | 9/6 | A |
| #2 정산 배치 | P0 | 8 | #1 | 9/6 | 9/13 | B |
| #3 정산 리포트 UI | P1 | 8 | #1 | 9/6 | 9/13 | B |
| #4 알림 발송 | P2 | 5 || 8/23 | 8/30 | A |

 >   " 병렬 그룹 " 이 같은 행끼리는 시작일이 같습니다(서로 의존이 없어 동시 진행 가능하다고 판단됨).
 >   의존이 있는 행은 선행 Epic 종료일 이후에 시작합니다. 의존 관계가 틀렸다면 `--epic-deps` 로
 >   직접 지정해 다시 실행하세요.

**이 스케줄로 진행하시겠습니까? (Y/n)**

Step 3: Work Item Creation (Feature/Bug/Task)#

Create per-item work items after confirmation. Type is classified per item, never hardcoded to Feature — reuses the same mapping as cc-dev/skills/dev/SKILL.md's "Type Inference" table and commands/run.md's issueTypeMap:

Keyword signalTypeTitle prefix
add/implement/create/screen (추가/구현/생성/화면)Featurefeat:
fix/repair/bug/error (수정/버그/오류)Bugfix:
improve/refactor/optimize/config/build (개선/리팩토링/최적화/설정/빌드)Taskchore:/refactor:
function resolveWorkItemType(item) {
  if (/fix|bug|error|수정|버그|오류/i.test(item.description)) return bugTypeId;
  if (/refactor|improve|optimize|config|build|개선|리팩토링|최적화|설정|빌드/i.test(item.description)) return taskTypeId;
  return featureTypeId; // default: add/implement/create/screen
}

MCP call example (repeated per item; body/template varies by resolved type — see "Feature/Bug/Task Templates" below):

mcp__zenhub__createGitHubIssue({
  title:  " {feature} {screen} 화면 " ,          // Feature example; Bug/Task use fix:/chore: prefix
  body: buildBody(contract, artifactUrl[item.key]),  // 서술 20행 초과분만 아티팩트 — 그 외 전량 마크다운
                                             // 계약 블록(AC·범위·DoD)은 항상 본문에 남는다
  repositoryId: repoId,         // getWorkspacePipelinesAndRepositories()에서 조회
  issueTypeId: resolveWorkItemType(item),   // Feature/Bug/Task — getIssueTypes()에서 조회한 값 중 실제 판정
  parentIssueId:  " {epic_id} " ,                                    // Epic과 연결 (scale=no-epic이면 생략 또는 Project/Initiative id)
  labels: [ " {feature|bug|task} " ,  " {feature_name} " ,  " {screen_type}-view " ,  " p{priority} " ,  " impact-{impact} " ]  // impact: high|med|low (Matrix Y축, C6)
})

// effort 축: Story Point 설정 (Matrix X축) — 필수, --sprint 미지정이어도 항상 호출
// (rules/zenhub-conventions.md →  " Mandatory Story Point Estimate " ; item.point 는 Step 1.6 에서 확정된 값)
await mcp__zenhub__setIssueEstimate({ issueId: item.id, estimate: item.point });

// ⚠️ 타임라인: setDatesForIssue 는 상위 타입(Epic/Project) 전용이므로 레벨4 항목에는 쓰지 않는다(off-spec).
//   Roadmap Visibility Contract(rules/zenhub-conventions.md)대로 레벨4는 **스프린트 멤버십**으로 노출한다 —
//   --sprint 가 주어지면 Step 5 에서 addIssuesToSprints 로 해당 스프린트 레인에 올린다.
//   즉 레벨4 항목의 로드맵 가시성 = 부모 Epic 의 기간 바 + 자신의 스프린트 레인.

레벨4 항목은 개별 날짜 대신 스프린트 레인으로 타임라인에 노출된다. Epic 만 명시적 기간(start/end)을 갖는다. 정밀 일정은 ZenHub 보드에서 드래그로 미세 조정하세요.

## Work Item 생성

| # | Type | Screen/Title | Point | Timeline | Acceptance Criteria Count |
|---|------|------|-------|----------|-------|
| 1 | Feature | {feature} 목록 화면 | 3 | {s1_start}~{s1_end} | 8 |
| 2 | Feature | {feature} 상세 화면 | 3 | {s2_start}~{s2_end} | 9 |
| 3 | Feature | {feature} 폼 화면 | 5 | {s3_start}~{s3_end} | 10 |

**Total Work Items**: 3
**Total Points**: 11
**Epic Timeline**: {epic_start} ~ {epic_end}

Step 3.5: Sub-task Creation (Optional)#

Create detailed tasks as Sub-tasks under work items.

Sub-task 는 아티팩트를 발행하지 않는다 (rules/zenhub-conventions.mdIssue Body Artifact Contract → 계층별 적용). 본문이 이미 3~5행이라 링크 오버헤드가 내용보다 크다 — 현행 마크다운 본문을 그대로 유지한다.

MCP call example:

mcp__zenhub__createGitHubIssue({
  title:  " [{PREFIX}-00X-0Y] {task_description} " ,
  body:  " {subtask_body} " ,
  repositoryId: repoId,         // getWorkspacePipelinesAndRepositories()에서 조회
  issueTypeId: subtaskTypeId,   // getIssueTypes()에서 조회
  parentIssueId:  " {work_item_id} " ,                               // 부모 work item과 연결
  labels: [ " subtask " ,  " {feature_name} " ,  " p{priority} " ]
})

Auto-generated Sub-tasks by screen type:

Screen TypeSub-task List
ListTable column definition, search, filter, sort, pagination
DetailData display, action buttons, edit/delete confirmation
FormField validation, form submission, cancel handling, image upload

Sub-task title format:

  • [{PREFIX}-001-01] : First Sub-task of work item 001
  • [{PREFIX}-001-02] : Second Sub-task of work item 001
  • PREFIX is based on feature_name (e.g., AUTH, INST, BOOK)

Step 4: Hierarchy Linking (Project-Epic-Work Item)#

## 연결 완료

✅ Project #{project_number} 생성 완료 (추론 또는 --project 사용 시)Epic #{epic_number} 생성 완료 (Project에 연결됨, scale=no-epic이면 생략)Feature #{item_1} 연결됨
✅ Feature #{item_2} 연결됨
✅ Feature #{item_3} 연결됨

### 생성된 이슈 링크
- Project: https://github.com/cocode/kobic/issues/{project_number}
- Epic: https://github.com/cocode/kobic/issues/{epic_number}
- 목록: https://github.com/cocode/kobic/issues/{item_1}
- 상세: https://github.com/cocode/kobic/issues/{item_2}
-: https://github.com/cocode/kobic/issues/{item_3}

Step 5: Pipeline Sorting (skipped with --no-sort)#

Place every created issue into its pipeline based on the Step 1.6 priority tiers. Placement matrix follows rules/zenhub-conventions.md:

TargetPipeline
Project / EpicProduct Backlog
Work item P0 (with --sprint)Sprint Backlog + addIssuesToSprints
Work item P0/P1 (no sprint)Product Backlog
Work item P2Icebox
Sub-taskFollows parent work item (no separate move)
// fail-closed 해석: 이름이 라이브 파이프라인과 다르면 throw (부분 배치 후 무음 중단 방지)
const pipelineByName = (name) = >   {
  const p = workspace.pipelines.find(p = >   p.name === name);
  if (!p) throw new Error(`파이프라인  ' ${name} '   없음. 라이브: ${workspace.pipelines.map(p = >   p.name).join( " ,  " )}`);
  return p;
};
const backlog = pipelineByName( " Product Backlog " );
const sprintBacklog = pipelineByName( " Sprint Backlog " );
const icebox = pipelineByName( " Icebox " );

// ⚠️ moveIssueToPipeline has no position param —
// move in DESCENDING priority order (P0 first) to approximate top-to-bottom ordering
for (const issue of issuesSortedByPriority) {
  await mcp__zenhub__moveIssueToPipeline({
    issueId: issue.id,
    pipelineId: pipelineFor(issue),  // matrix above
  });
}

// --sprint 사용 시 P0 work item을 해당 스프린트에 추가
if (options.sprint) {
  // 셀렉터 (rules/zenhub-conventions.md →  " Sprint Selector Resolution "   와 동일 규칙):
  //   current → 활성(getSprint, id 없음) · next → 다음(getUpcomingSprint) · 숫자/이름 → listRecentSprints 매칭
  const targetSprint =
    options.sprint ===  " next "      ? await mcp__zenhub__getUpcomingSprint() :
    options.sprint ===  " current "   ? await mcp__zenhub__getSprint()         :
    (await mcp__zenhub__listRecentSprints()).openSprints
      .find(s = >   s.name.includes(String(options.sprint)));
  if (!targetSprint?.id) throw new Error(`스프린트  ' ${options.sprint} '   해석 실패 — current/next/번호를 확인하라`);
  await mcp__zenhub__addIssuesToSprints({
    issueIds: p0WorkItemIds,
    sprintIds: [targetSprint.id],
  });
}
## 파이프라인 정렬 완료

| 이슈 | 티어 | 파이프라인 |
|------|------|-----------|
| Epic #{epic_number} || Product Backlog |
| #{item_1} 목록 화면 | P0 | Sprint Backlog (Sprint 12) |
| #{item_2} 상세 화면 | P1 | Product Backlog |
| #{item_3} 폼 화면 | P1 | Product Backlog |

 >   파이프라인 내 세부 순서는 MCP가 지원하지 않습니다.
 >   우선순위 순서대로 이동했으며, 미세 조정은 ZenHub 보드에서 드래그로 조정하세요.

Output Files#

.claude/docs/{feature_name}/
├── screenshots/              # 이미지 분석 시 저장 (--images 사용 시)
│   ├── list.png
│   ├── detail.png
│   └── form.png
├── image_analysis.md         # 이미지 분석 결과 (--images 사용 시)
├── requirements.md           # 요구사항 (자동 생성 또는 기존 파일)
├── bdd/                      # BDD 시나리오 (자동 생성)
│   ├── {feature}_list.feature
│   ├── {feature}_detail.feature
│   └── {feature}_form.feature
└── zenhub/
    ├── project.md            # Project 상세 정보 (--project 사용 시)
    ├── epic.md               # Epic 상세 정보
    ├── priority.md           # 우선순위 검토 결과 + 파이프라인 배치 기록
    └── stories/
        ├── list_story.md     # 목록 Story 정보
        ├── detail_story.md   # 상세 Story 정보
        └── form_story.md     # 폼 Story 정보

Issue Templates#

SoT: rules/zenhub-conventions.mdUnified Issue Body Template 이 섹션 순서·H1 규칙의 계약을 정의한다. 아래는 그 계약을 따르는 실제 마크다운이다 — 타입 단어는 어디에도 반복하지 않는다 (ZenHub Issue Type 배지가 이미 보여준다). Project/Epic 은 ## 💼 비즈니스 가치 + ## 📊 범위를 공유하고, Feature/Bug/Task 는 각자의 핵심 섹션(AC/재현절차/DoD)만 다르다 — 그 외 섹션 순서(개요 → 핵심 → 기술 → 관련 이슈 → Story Point → footer)는 전 타입 동일하다.

Project/Initiative Template#

# {Project/Milestone Name}

## 📄 상세 기획
**{artifact_url}**{아티팩트에 담긴 섹션 목록}

{공유 안내 문구 — Issue Body Artifact Contract 고정 문구}

## 📋 개요
{Project/Initiative에 대한 간략한 설명}

## 💼 비즈니스 가치
{Project/Initiative가 해결하는 문제와 기대 효과}

## 📊 범위

### 포함
-{epic_1}{한 줄 설명}
-{epic_2}{한 줄 설명}

### 제외
-(필요시 명시)

## 🔢 우선순위
| 순위 | Epic | 티어 | impact | 근거 |
|------|------|------|--------|------|
| 1 | {epic_1} | P0 | high | {근거} |

## 📎 관련 이슈
- 상위: #{parent_number} ({Initiative})ProjectInitiative 하위일 때만
- [ ] #{epic_1_number} - {epic_1}
- [ ] #{epic_2_number} - {epic_2}

---
 >   🤖 Generated by `/cc-dev:zenhub:breakdown`

Epic Template#

# {Feature} 기능 구현

## 📄 상세 기획
**{artifact_url}**{아티팩트에 담긴 섹션 목록}

{공유 안내 문구 — Issue Body Artifact Contract 고정 문구}

## 📋 개요
{Feature에 대한 간략한 설명}

## 💼 비즈니스 가치
**사용자로서**, {feature_capability}() 원합니다.
**그래서** {business_value}() 얻을 수 있습니다.

## 📊 범위

### 포함
-{screen_1} 화면
-{screen_2} 화면
-{screen_3} 화면

### 제외
-(필요시 명시)

## 🛠️ 기술 노트
| 항목 ||
|------|-----|
| Entity | `{EntityName}` |
| Backend | Serverpod endpoint |
| Caching | {SWR / Cache-First} |
| Location | `feature/{location}/{feature_name}` |

## 🎨 디자인 스크린샷

 >   `--images` 사용 시 자동 생성됨

### 목록 화면
![목록 화면](https://raw.githubusercontent.com/{owner}/{repo}/{branch}/.claude/docs/{feature}/screenshots/list.png)

### 상세 화면
![상세 화면](https://raw.githubusercontent.com/{owner}/{repo}/{branch}/.claude/docs/{feature}/screenshots/detail.png)

### 폼 화면
![폼 화면](https://raw.githubusercontent.com/{owner}/{repo}/{branch}/.claude/docs/{feature}/screenshots/form.png)

 >   또는 Figma 링크: {figma_urls}

## 🔢 우선순위
| 순위 | 이슈 | 티어 | impact | 근거 |
|------|------|------|--------|------|
| 1 | {feature} 목록 화면 | P0 | high | {근거} |

## 📎 관련 이슈
- 상위: #{project_number} ({Project})Project/Initiative 하위일 때만
- [ ] #{item_1_number} - 목록 화면
- [ ] #{item_2_number} - 상세 화면
- [ ] #{item_3_number} - 폼 화면

## 📐 예상 Story Point
{total_points} (하위 항목 롤업)

---
 >   🤖 Generated by `/cc-dev:zenhub:breakdown`

Feature/Bug/Task Templates#

Body content is chosen by resolveWorkItemType(item) — Feature keeps the existing screen/BDD-based core section; Bug and Task use lighter core sections that skip the screen/Gherkin content entirely (they don't apply to a defect report or a chore). The surrounding skeleton (개요 → 핵심 섹션 → 기술 작업 → 관련 이슈 → Story Point → footer) is identical across all three — only the 핵심 섹션 and whether 기술 작업 applies differ.

Feature Template (screen-based, existing behavior)

# {Screen Name}

## 📋 개요
**{user_type}로서**, {screen_capability}() 원합니다.
**그래서** {value}() 얻을 수 있습니다.

## ✅ 인수 기준 (Acceptance Criteria)

### AC1: {scenario_1_name}
gherkin

Given {precondition_1} When {action_1} Then {expected_result_1}

- **Priority**: {High/Medium/Low}
- **Tag**: @{tag}

### AC2: {scenario_2_name}
gherkin

Given {precondition_2} When {action_2} Then {expected_result_2}

- **Priority**: {High/Medium/Low}
- **Tag**: @{tag}

## 🛠️ 기술 작업

### Backend
- [ ] Serverpod endpoint 구현
- [ ] DTO 정의

### Domain
- [ ] Entity 정의
- [ ] Repository Interface 정의
- [ ] UseCase 구현
- [ ] UseCase 테스트 작성

### Data
- [ ] Repository 구현
- [ ] Serverpod Mixin 구현
- [ ] 캐싱 전략 적용

### Presentation
- [ ] BLoC 구현 (Event/State)
- [ ] Page 위젯 구현
- [ ] Widget 컴포넌트 구현
- [ ] Route 등록
- [ ] BDD 테스트 작성

### Widgetbook
- [ ] Component story 추가

## 🎨 디자인 참조

 >   `--images` 사용 시 자동 생성됨

![{screen_name}](https://raw.githubusercontent.com/{owner}/{repo}/{branch}/.claude/docs/{feature}/screenshots/{screen}.png)

 >   또는 Figma 링크: {figma_link}

## 📎 관련 이슈
- 상위: #{epic_number} (Epic)       ← scale=no-epic이면 생략 또는 Project/Initiative로 대체

## 📐 예상 Story Point
{point_value}

---
 >   🤖 Generated by `/cc-dev:zenhub:breakdown`

Bug Template (reproduction-focused, no screen/BDD sections)

# {defect_summary}

## 📋 개요
{what_is_broken}

## 🔁 재현 절차
1. {step_1}
2. {step_2}
3. {step_3}

## 🎯 기대 결과 vs 실제 결과
- **기대**: {expected}
- **실제**: {actual}

## ⚠️ 심각도
{Critical/High/Medium/Low}{rationale}

## 📎 관련 이슈
- 상위: #{epic_number} (Epic)       ← scale=no-epic이면 생략

## 📐 예상 Story Point
{point_value}

---
 >   🤖 Generated by `/cc-dev:zenhub:breakdown`

Task Template (definition-of-done, no screen/BDD sections)

# {work_summary}

## 📋 개요
{what_needs_to_be_done}

## ☑️ 완료 정의 (Definition of Done)
- [ ] {criterion_1}
- [ ] {criterion_2}
- [ ] {criterion_3}

## 🛠️ 기술 작업
- [ ] {implementation_step_1}
- [ ] {implementation_step_2}

## 📎 관련 이슈
- 상위: #{epic_number} (Epic)       ← scale=no-epic이면 생략

## 📐 예상 Story Point
{point_value}

---
 >   🤖 Generated by `/cc-dev:zenhub:breakdown`

MCP Integration#

TaskMCP ServerPurpose
Issue creationZenHubEpic/Feature/Bug/Task creation
Template structuringSequentialSystematic issue organization

Examples#

Basic Usage#

/cc-dev:zenhub:breakdown community Post

Small Scope — No Epic Wrapper (new)#

# Auto-inferred: a single small bug needs no Epic
/cc-dev:zenhub:breakdown  " 로그인 버튼 텍스트 오타 수정 " 

 # Force-skip Epic explicitly
/cc-dev:zenhub:breakdown community Post --no-epic

Project Level Creation#

# Create new Project + Epics under it
/cc-dev:zenhub:breakdown community Post --project  " 어드민 콘솔 v2 " 

 # Multiple Epics under one Project (2+ --epics entries auto-infers Project scale)
/cc-dev:zenhub:breakdown --project  " 어드민 콘솔 v2 "   --epics  " auth,community,payment " 

 # Link Epic to an existing Project issue
/cc-dev:zenhub:breakdown community Post --parent-project 1024

Specify Requirements File#

/cc-dev:zenhub:breakdown community Post \
  --requirements .claude/docs/community/requirements.md \
  --bdd-dir .claude/docs/community/bdd/

Specify Sprint and Labels#

/cc-dev:zenhub:breakdown community Post \
  --labels  " sprint-1,mvp "   \
  --sprint current

Custom Story Points#

/cc-dev:zenhub:breakdown community Post \
  --screens  " list,detail,form "   \
  --points  " 5,3,8 "

Create Epic from Image Files#

/cc-dev:zenhub:breakdown community Post \
  --images  " list.png,detail.png,form.png "

Create Epic from Image Directory#

/cc-dev:zenhub:breakdown community Post \
  --images-dir ./screenshots/community/

Images + Additional Options#

/cc-dev:zenhub:breakdown community Post \
  --images  " list.png,detail.png,form.png "   \
  --labels  " sprint-1,mvp "   \
  --sprint current

Analysis Only Without Image Attachment#

/cc-dev:zenhub:breakdown community Post \
  --images  " list.png,detail.png,form.png "   \
  --attach-images false

Downstream Handoff (실행 파이프라인 연결)#

이슈 생성·정렬·문서화가 끝나면 생성 결과를 실행 파이프라인으로 넘긴다. breakdown 은 "일감 생성"에서 끝나는 커맨드가 아니라 개발 루프의 상류다.

1. issueMap 정리 — 생성 시점에 확보한 이슈 번호를 구조로 보고 (출력 로그 재파싱 금지):
   { initiative?: #, project?: #, epics: [{number, title, priority, children: [#…]}], standalone: [#…] }
2. /cc-dev:go 컨텍스트 — /cc-dev:go Phase B 에서 호출된 경우: issueMap 반환 후 즉시 종료.
   후속 질문 금지 — 실행 여부는 /cc-dev:go Phase C(통합 계획 게이트)가 담당한다.
3. 단독 실행 컨텍스트 — 사람이 /cc-dev:zenhub:breakdown 을 직접 부른 경우, AskUserQuestion 1:
   - [바로 개발 시작]Epic 이 있으면 P0 Epic 부터 /cc-dev:batch {epic}, Epic 없이 standalone 뿐이면 /cc-dev:run {issue}
   - [이슈만 생성하고 종료] → 재개 명령을 안내하고 종료:
      " 이어서: /cc-dev:batch {epic} · /cc-dev:run {issue} · 처음부터 원스톱은 /cc-dev:go "

Reference Agent#

Detailed implementation rules: ${CLAUDE_PLUGIN_ROOT}/agents/zenhub-integration-agent.md

Key Rules#

  1. Scale Inferred First: Step 1.5 decides how much of Initiative → Project → Epic → Feature/Bug/Task → Sub-task to create, before priority review or any issue creation runs; explicit flags (--initiative/--project/--no-epic) always override the inference
  2. Top-Down Creation: Create in hierarchy order for whatever levels Step 1.5 selected — Initiative (if inferred) → Project (if inferred) → Epic (unless no-epic) → Feature/Bug/Task → Sub-task
  3. Link Required: All work items must be linked to Epic when one exists (or directly to Project/Initiative when Epic is skipped); Epics link to Project when inferred/--project/--parent-project (or directly to Initiative when used without a Project); Projects link to Initiative when both are used
  4. Type Classified, Never Hardcoded: Each work item resolves to Feature/Bug/Task via resolveWorkItemType() (Step 3) — never default everything to Feature
  5. GitHub Issues Only: Always use createGitHubIssue (createZenhubIssue prohibited — see rules/zenhub-conventions.md)
  6. Priority Before Creation: Run the Step 1.6 priority review first — labels (p0/p1/p2) cannot be changed after creation
  7. Timeline + Estimate (Step 2.5): setIssueEstimate (SP) is always set on every Epic — regardless of --no-dates/--sprint — auto-estimated (T-shirt→Fibonacci) when no child breakdown exists yet, never left null. setDatesForIssue (start/end) is set too, using duration = points ÷ measured team velocity (rules/zenhub-conventions.mdEpic Velocity Calculation, not a fixed constant); skip only with --no-dates. setDatesForIssue requires zenhubOrganizationId 7.5. Dependency-Aware Multi-Epic Scheduling: When creating 2+ Epics together, resolve dependency edges (--epic-deps > text signals > default independent) and record them via createBlockage; Epics with no edge between them share a start date (parallel), Epics with an edge run sequentially (rules/zenhub-conventions.mdEpic Dependency & Parallel Scheduling)
  8. Pipeline Sorting Required: After creation, always place issues per the priority → pipeline matrix (Step 5), moving in descending priority order
  9. Include Acceptance Criteria: Include BDD-based Acceptance Criteria in each Feature work item; Bug/Task work items use the repro/DoD template instead
  10. Label Consistency: Follow the defined label system — label uses the resolved type (feature/bug/task)
  11. Create After Confirmation: Create actual issues only after user confirms both the inferred scale (Step 1.5) and the priority table (Step 1.6)
  12. Documentation: Save creation results to .claude/docs (including priority.md)
  13. Image Analysis: Detailed analysis via Claude multimodal when using --images
  14. Image Attachment: On --attach-images true, commit to repo after user confirmation to attach URLs to Issues
  15. BDD Language: Auto-generated BDD scenarios are written in Korean (Feature items)
  16. Handoff Last: End with the Downstream Handoff — return the issueMap and hand off to /cc-dev:go (when called from it) or offer immediate /cc-dev:batch//cc-dev:run execution (standalone)