/cc-dev:zenhub:breakdown — 기획을 ZenHub 일감으로 자동 정리#
| 항목 | 내용 |
|---|---|
| 실행 명령 | /cc-dev:zenhub:breakdown |
| 별칭 | /issue:create |
| 모델 | sonnet |
| 사용 도구 | Read, Edit, Write, Glob, Grep |
| MCP 서버 | zenhub |
| 연계 스킬 | zenhub |
한마디로#
머릿속 기획이나 Figma 분석 결과를, ZenHub의 일감(Initiative → Project → Epic → Feature/Bug/Task → 세부작업) 형태로 자동 정리해 주는 비서입니다. 큰 목표를 중간 목표로, 다시 화면·작업 단위로 쪼개고, 무엇부터 할지 우선순위까지 매겨 보드에 줄 세워 줍니다. 작업 규모를 스스로 판단해서 어디까지 계층을 만들지 정합니다 — 작은 버그 하나면 Epic 없이 Bug 이슈 하나만, 여러 기능을 아우르는 개편이면 Project까지 자동으로 만듭니다.
누가·언제 쓰나요#
- 기획·PM·개발 담당자가, 새 작업을 ZenHub 일감으로 만들어 착수하려 할 때
- 디자인(Figma) 분석이 끝나, 그 결과를 실제 작업 티켓으로 옮기고 싶을 때
- 여러 화면·작업을 만들면서 무엇부터 할지 우선순위(P0/P1/P2) 와 일정을 함께 정리하고 싶을 때
무엇을 해주나요#
- 요청 내용을 보고 어디까지 계층을 만들지 자동으로 판단합니다 — Initiative → Project → Epic → Feature/Bug/Task → Sub-task 중 규모에 맞는 범위만 생성합니다(작은 작업은 Epic 없이 Feature/Bug/Task 하나만).
- 각 일감을 실제 성격에 맞는 타입(Feature/Bug/Task)으로 만들고, 합격 기준(Acceptance Criteria) 과 BDD 테스트 시나리오를 한국어로 붙여 줍니다.
-
만들기 전에 우선순위를 점수로 매겨
p0/p1/p2라벨을 달고, 우선순위 순서대로 보드 파이프라인에 배치합니다. - 긴 기획 설명은 일감 본문에 통째로 붙이지 않고 보기 좋은 웹 페이지(아티팩트)로 발행해 링크만 남깁니다. 대신 자동화가 읽어야 하는 합격 기준·범위·완료 정의는 본문에 그대로 둡니다. (발행된 링크는 비공개이니, 팀이 봐야 하면 claude.ai 에서 공유를 켜 주세요.)
- 스토리 포인트(난이도 점수)와 일정(시작·종료일)을 넣어 로드맵에 표시되게 합니다.
- 정리 결과를 다음 파일들로 남깁니다:
.claude/docs/{기능}/zenhub/
├── epic.md
└── stories/
├── list_story.md
├── detail_story.md
└── form_story.md
어떻게 쓰나요#
# 기본: 요청 내용을 분석해 규모에 맞는 계층을 자동 생성
/cc-dev:zenhub:breakdown
# 별칭(같은 에이전트를 다른 이름으로 호출)
/issue:create
# Epic을 만들지 않고 Feature/Bug/Task(+Sub-task)만 생성하도록 강제
/cc-dev:zenhub:breakdown --no-epic
호출하면 계층 스케일 추론 결과와 우선순위를 먼저 보여주고, 사용자가 확인한 뒤에야 실제 일감을 만듭니다. (만든 뒤에는 우선순위 라벨을 바꿀 수 없으므로, 생성 전 확인이 중요합니다.)
안에서 무슨 일이 벌어지나요#
-
계층 스케일 추론 — 요청 문구(여러 기능/시스템 전체/전사 전략 등 신호)를 보고 Initiative~Epic 중 어디를 최상위로 만들지, 혹은 Epic 없이 Feature/Bug/Task만 만들지 자동으로 정합니다. (
--initiative/--project/--no-epic같은 명시적 플래그가 있으면 항상 그것이 우선합니다.) -
우선순위 먼저 정하기 — 의존성·가치·위험·노력을 점수로 매겨 일감마다
p0/p1/p2를 정합니다. (라벨은 생성 후 못 바꾸므로 생성보다 먼저 합니다.) - 계층 순서대로 생성 — Project(추론 시) → Epic(추론 시) → Feature/Bug/Task 여러 개 → 세부작업 순으로 만들고, 부모-자식 관계를 연결합니다. 각 항목은 성격에 따라 Feature/Bug/Task 중 실제 타입으로 생성됩니다.
- 점수·일정 입력 — 스토리 포인트와 시작·종료일을 함께 넣습니다. (둘 다 넣어야 로드맵 일정 막대에 표시됩니다.)
- 보드 줄 세우기 — 우선순위가 높은 순(P0 → P1 → P2)으로 파이프라인에 배치합니다.
- 스프린트 배정 — 요청 시 P0 항목을 스프린트에 넣습니다.
⚙️ 상세 옵션·실행 명세 (개발자 / AI 에이전트용)
Role#
- Hierarchy Scale Inference: Decide, from the request content (or explicit flags), how much of the Initiative→Project→Epic→Feature/Bug/Task→Sub-task chain to create
- Project Creation (auto-inferred or explicit): Create Project-level issues that wrap multiple Epics
- Epic Creation (auto-inferred or explicit; may be skipped for small-scope requests): Create Epics
- Work Item Creation: Create Feature/Bug/Task-level work items (under Epic, or top-level when Epic is skipped) — type is classified per item, not hardcoded to Feature
- Acceptance Criteria Attachment: Attach BDD scenario-based Acceptance Criteria (Feature items) or repro-steps/definition-of-done (Bug/Task items)
- Priority Review: Score every issue (dependency/value/risk/effort) before creation and assign
p0/p1/p2 - Pipeline Sorting: Place created issues into pipelines per the priority matrix
- Label Management: Auto-apply appropriate labels
ZenHub MCP Tools#
| Tool | Purpose |
|---|---|
createGitHubIssue | Create GitHub issue (required — createZenhubIssue prohibited, see rules/zenhub-conventions.md) |
setParentForIssues | Set parent-child relationships across any two adjacent hierarchy levels |
moveIssueToPipeline | Move Pipeline (⚠️ no in-pipeline position param) |
setIssueEstimate | Set Story Points (SP only — does not affect the timeline) |
setDatesForIssue | Set timeline start/end dates (required for roadmap display — needs zenhubOrganizationId) |
setIssueType | Change Issue Type |
getIssueTypes | Query Issue Type list (includes hierarchy level) |
getUpcomingSprint / listRecentSprints | Query Sprints |
addIssuesToSprints | Assign P0 work items to Sprint |
Dynamic Workspace Info Query (required before issue creation)#
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 = > /* select GitHub repo */).id;
// 2. Issue Type ID (level: 1=Initiative, 2=Project, 3=Epic, 4=Feature/Bug/Task, 5=Sub-task)
const issueTypes = await mcp__zenhub__getIssueTypes({ repositoryId: repoId });
const initiativeType = issueTypes.find(t = > t.name === " Initiative " ); // may be absent → fallback to Project/Epic top-level
const projectType = issueTypes.find(t = > t.name === " Project " ); // may be absent → fallback to Epic top-level
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;Step -1: Hierarchy Scale Inference (before Priority Review)#
Reuses the same "explicit flag wins, otherwise infer from signals" pattern as
commands/run.md's type/scope inference. Runs once per invocation, before Step 0:
function inferScale(requestText, flags) {
if (flags.initiative || flags.parentInitiative) return " initiative " ;
if (flags.project || flags.parentProject || (flags.epics?.length ?? 0) > = 2) return " project " ;
if (flags.noEpic) return " no-epic " ;
// Auto-inference (no explicit flag) — signal keywords, checked top-down
if (/전사|로드맵|분기|\d+개월\s*전략|여러\s*팀/.test(requestText)) return " initiative " ;
if (/시스템\s*전체|플랫폼\s*개편|여러\s*기능/.test(requestText) || countDistinctFeatureDomains(requestText) > = 2) return " project " ;
if (isSingleSmallScope(requestText)) return " no-epic " ; // single screen/bug/task, estimated total ≤3 points
return " epic " ; // default: single feature, possibly multiple screens — unchanged prior behavior
}| Result | Hierarchy created |
|---|---|
initiative | Initiative → Project → Epic → Feature/Bug/Task (→ Sub-task) |
project | Project → Epic(s) → Feature/Bug/Task (→ Sub-task) |
epic (default) | Epic → Feature/Bug/Task (→ Sub-task) — unchanged prior behavior |
no-epic | Feature/Bug/Task (→ Sub-task) only, no Epic wrapper |
The inferred result is shown to the user alongside the Step 0 priority table for a single confirmation (e.g. "다음 계층으로 생성합니다: Project → Epic → Feature ×3 → Sub-task ×5 (Y/n)") — this is automatic inference, not silent creation; the user still confirms once before anything is created.
Workflow#
-1. Hierarchy scale inference (see Step -1 above) → initiative | project | epic | no-epic
↓
-0.5. ⛔ Existing-children check — 부모(Epic/Project/Initiative/Work item)가 **이미 존재하는**
이슈일 때는, 그 아래 자식을 만들기 전에 `listChildren(parent.number)` 로 기존 자식을 전수 조회한다
(`rules/zenhub-conventions.md` → " Child Enumeration Contract " / " Existing-Children Reuse " ).
· 같은 작업을 담은 자식이 이미 있으면 → **새로 만들지 않고 그 이슈를 반환**(재사용)
· 본문·AC 가 낡았으면 → `updateIssue` 로 그 자식을 갱신
· `known === false`(조회 실패) → **생성 전에 멈추고 확인받는다**
⚠️ 이걸 건너뛰면 원본 자식이 열린 채 남고 부모가 Parent Closure Invariant 위반 상태로 닫힌다
(2026-07-31 `#3451`: `#3478`–`#3482` 대신 `#3514`–`#3518` 을 새로 만들어 처리한 사고).
완전히 새로 만드는 계층(부모도 이번에 생성)에서는 자식이 있을 수 없으므로 no-op.
↓
0. Priority review (score dependency/value/risk/effort → p0/p1/p2 per issue)
↓ (labels are immutable after creation — review MUST precede creation)
0.4. Publish narrative artifacts and capture URLs (see " Issue Body Artifact Contract " below)
↓ ⚠️ MUST precede every createGitHubIssue call — otherwise bodies are created without links
0.5. Create Initiative issue, if inferred/requested (createGitHubIssue + issueTypeId=Initiative)
↓
1. Create Project issue, if inferred/requested (createGitHubIssue + issueTypeId=Project, parentIssueId=Initiative when created)
↓
2. Create Epic issue, unless scale=no-epic (createGitHubIssue + issueTypeId=Epic, parentIssueId=Project, or =Initiative directly if no Project)
↓
3. Create Work Item issues — classify each item as Feature/Bug/Task (see " Work Item Type Classification " below), createGitHubIssue + issueTypeId=resolveWorkItemType(item) × N, parentIssueId=Epic (or Project/Initiative/none if scale=no-epic)
↓
4. Create Sub-tasks (createGitHubIssue + issueTypeId=Sub-task × M, parentIssueId=work item)
↓
5. Verify parent-child relationships (already set via parentIssueId; fix with setParentForIssues)
↓
6. Set Story Points (setIssueEstimate — ALL issues, always) AND timeline dates (setDatesForIssue — Epic/Project/Initiative only). When 2+ Epics are created together, resolve dependency edges first (`--epic-deps` > text signals > default independent) and schedule accordingly — see `rules/zenhub-conventions.md` → *Epic Dependency & Parallel Scheduling*
↓ ⚠️ SP without dates leaves the Epic off the Goals & Planning roadmap; dates without SP is not possible here since SP is always set first
7. Pipeline sorting (moveIssueToPipeline, descending priority order: P0 → P1 → P2)
↓
8. Sprint assignment for P0 work items when requested (addIssuesToSprints)Issue Body Artifact Contract (Step 0.4)#
Long narrative does not go into the issue body. It is published as a claude.ai artifact and the
body keeps only the machine-read contract block. The full rule set is defined once in
rules/zenhub-conventions.md → Issue Body Artifact Contract — do not restate it here; follow it.
Operationally, that means:
- Split each item into
contract(AC · 범위 · DoD · 우선순위 표 ·Closes #N) andnarrative(개요 · 비즈니스 가치 · 화면/기술 설계 · DDR 전문). - Publish the narrative before any
createGitHubIssuecall, at a per-issue fixed path (.claude/docs/{scope}/issue-{slug}.html) — the same path on re-publish keeps the same URL. - Assemble
body= contract block + the## 📄 상세 기획link block (URL + section list + the 🔒 sharing notice, which is never omitted — artifacts publish private and no API makes them public). - Applies to Initiative/Project/Epic always, Feature/Bug/Task only when the narrative exceeds 20 lines, and never to Sub-task.
Degradation —
Artifactexists only in interactive claude.ai-authenticated sessions. If it is absent (cron/CI/headless) or publication fails, fall back to the full-markdown body and logℹ️ Artifact 미사용 — 전량 마크다운 본문으로 생성. Never abort issue creation over this.
Work Item Type Classification (Step 3)#
Reuses the same mapping as cc-dev/skills/dev/SKILL.md's "Type Inference" table and
commands/run.md's issueTypeMap — single source of truth for both the single-issue
(/cc-dev:run) and bulk-breakdown (/cc-dev:zenhub:breakdown) paths:
| Keyword signal | Type | Title prefix (rules/zenhub-conventions.md) |
|---|---|---|
| add/implement/create/screen (추가/구현/생성/화면) | Feature | feat: |
| fix/repair/bug/error (수정/버그/오류) | Bug | fix: |
| improve/refactor/optimize/config/build (개선/리팩토링/최적화/설정/빌드/환경) | Task | chore:/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 Examples#
Initiative Creation (optional, top-level):
mcp__zenhub__createGitHubIssue({
title: " {strategic goal name} " ,
body: buildBody(contract, url), // 계약 블록 + 📄 링크 (전략 서술은 아티팩트 — Step 0.4)
repositoryId: repoId, // Dynamic query
issueTypeId: initiativeType.id, // Dynamic query (fallback if absent)
labels: [ " initiative " , " p0 " ]
})Project Creation (optional):
mcp__zenhub__createGitHubIssue({
title: " {project/milestone name} " ,
body: buildBody(contract, url), // 계약 블록 + 📄 링크 (우선순위 표는 본문 유지)
repositoryId: repoId, // Dynamic query
issueTypeId: projectType.id, // Dynamic query (fallback if absent)
parentIssueId: " {initiative_graphql_id} " , // When under an Initiative
labels: [ " project " , " p0 " ]
})Epic Creation:
const epic = await mcp__zenhub__createGitHubIssue({
title: " {feature} feature implementation " ,
body: buildBody(contract, url), // 계약 블록 + 📄 링크 (Step 0.4 발행분)
repositoryId: repoId, // Dynamic query
issueTypeId: epicTypeId, // Dynamic query
parentIssueId: " {project_graphql_id} " // When under a Project (or the Initiative ' s id directly, if no Project level)
})
// ⚠️ Story Point is ALWAYS set — regardless of --no-dates/--sprint. When no child breakdown
// exists yet (common when creating several sibling Epics at once), estimate top-down via the
// T-shirt→Fibonacci table instead of leaving it null. SoT: rules/zenhub-conventions.md →
// " Mandatory Story Point Estimate "
await mcp__zenhub__setIssueEstimate({ issueId: epic.id, estimate: epic.points });
// Dates are set unless --no-dates. duration = points ÷ measured team velocity — NOT a fixed
// constant — and, when 2+ Epics are created together, start dates come from a dependency-aware
// schedule (independent Epics share a start date = parallel; dependent Epics run sequentially).
// SoT: rules/zenhub-conventions.md → " Epic Velocity Calculation " + " Epic Dependency & Parallel Scheduling "
await mcp__zenhub__setDatesForIssue({
issueId: epic.id,
startDate: scheduledStart, // " YYYY-MM-DD " — from scheduleEpics()
endDate: scheduledEnd, // " YYYY-MM-DD "
zenhubOrganizationId: workspace.zenhubOrganization.id,
});Without
setDatesForIssue,startDate/endDatestay null and the Epic has SP but no bar on the Goals & Planning timeline. Kickoff start = active sprint (getSprint, id 없음=활성) start (or today) —getUpcomingSprint은 '다음' 스프린트라 기본값으로 쓰면 바가 한 스프린트 밀린다. Full scheduling algorithm (velocity calc, dependency inference, topological parallel/sequential leveling):rules/zenhub-conventions.md→ Epic Velocity Calculation and Epic Dependency & Parallel Scheduling — not restated here to avoid drift between two copies.
Work Item Creation (Feature/Bug/Task, under Epic or top-level when no-epic):
mcp__zenhub__createGitHubIssue({
title: " {feature} list screen " , // Feature example — Bug/Task titles use fix:/chore: prefix
body: buildBody(contract, url), // 계약 블록(AC·범위·DoD) + 📄 링크 (서술 20행 초과 시)
repositoryId: repoId, // Dynamic query
issueTypeId: resolveWorkItemType(item), // Feature/Bug/Task — classified per item, never hardcoded
parentIssueId: " {epic_graphql_id} " // or Project/Initiative id, or omitted, when scale=no-epic
})Sub-task Creation (under a work item):
mcp__zenhub__createGitHubIssue({
title: " [{PREFIX}-001-01] Table column definition " ,
body: " {body} " , // Sub-task 는 아티팩트 발행 대상이 아니다 — 현행 마크다운 유지
repositoryId: repoId, // Dynamic query
issueTypeId: subtaskTypeId, // Dynamic query
parentIssueId: " {work_item_graphql_id} "
})Title Format#
| Type | Title Format |
|---|---|
| Project | {Service/milestone name} |
| Epic | {Feature} feature implementation |
| Feature work item (list) | feat: {Feature} list screen |
| Feature work item (detail) | feat: {Feature} detail screen |
| Feature work item (form) | feat: {Feature} form screen |
| Bug work item | fix: {defect description} |
| Task work item | chore: {non-user-facing work description} |
Story Point Guide#
| Point | Complexity | Example |
|---|---|---|
| 1 | Very simple | Simple UI modification |
| 2 | Simple | Single widget implementation |
| 3 | Normal | List screen, basic CRUD |
| 5 | Complex | Detail screen + actions, form + validation |
| 8 | Very complex | Composite screen |
Default Points by Screen Type#
| Screen Type | Default Point |
|---|---|
| List | 3 |
| Detail | 3 |
| Form | 5 |
Label System#
Project Labels#
project, {project_slug}, p{priority}Epic Labels#
epic, feature, {feature_name}, kobic, p{priority}Work Item Labels#
{feature|bug|task}, {feature_name}, {screen_type if Feature}, kobic, p{priority}Label uses the actual resolved type (
feature/bug/task), never a hardcodedstorylabel. ⚠️ Priority labels (p0/p1/p2) must be included at creation —updateIssuecannot change labels afterward.
Screen Type Labels#
| Screen | Label |
|---|---|
| List | list-view |
| Detail | detail-view |
| Form | form-view |
Pipeline Configuration#
New Issues → Icebox → Product Backlog → Sprint Backlog → In Progress → Review/QADone pipeline is not used — issues auto-close on PR merge via
Closes #. Seereferences/PIPELINE_REGISTRY.md.
Priority-based Initial Placement#
| Target | Initial Pipeline |
|---|---|
| Project / Epic | Product Backlog |
| Work item P0 (sprint specified) | Sprint Backlog + addIssuesToSprints |
| Work item P0/P1 | Product Backlog |
| Work item P2 | Icebox |
| Sub-task | Follows parent work item (no separate move) |
Ordering rule: moveIssueToPipeline has no position parameter — move issues in descending priority order (P0 → P1 → P2) to approximate top-to-bottom ordering, and record the priority table in the Epic/Project body as the source of truth. Fine-grained ordering is adjusted manually on the ZenHub board.
Body Template#
SoT:
rules/zenhub-conventions.md→ Unified Issue Body Template defines the section contract (order + H1 rule);commands/zenhub/breakdown.md→ Issue Templates has the actual markdown. Not duplicated here — this section only lists which core section each type resolves to, perresolveWorkItemType().
| Type | Core section (§3 of the shared skeleton) |
|---|---|
| Project / Initiative | 💼 비즈니스 가치 + 📊 범위 |
| Epic | 💼 비즈니스 가치 + 📊 범위 |
| Feature | ✅ Acceptance Criteria (Gherkin/BDD) |
| Bug | 🔁 Reproduction steps + 🎯 Expected vs. actual result |
| Task | ☑️ Definition of Done checklist |
The H1 never repeats the type word (# Epic: …, # Bug: …) — ZenHub's Issue Type badge already
shows it. ## 📎 관련 이슈 and ## 📐 예상 Story Point are shared closing sections across every
type; only Sub-task omits the artifact link (§1) and skips 기술 작업/Story Point.
Output Files#
.claude/docs/{feature}/zenhub/
├── epic.md
└── stories/
├── list_story.md
├── detail_story.md
└── form_story.mdKey Rules#
- Scale Inferred First: Step -1 decides how much of Initiative → Project → Epic → Feature/Bug/Task → Sub-task to create, before anything else runs; explicit flags (
--initiative/--project/--no-epic) always override the inference - Top-Down Creation: Whatever levels Step -1 selected, create in hierarchy order (Initiative → Project → Epic → Feature/Bug/Task → Sub-task) — never skip a selected level out of order
- Link Required: All work items must be linked to an Epic when one exists (or directly to a Project/Initiative when Epic is skipped); Epics to a Project when one is created (or directly to an Initiative when no Project level is used); Projects to an Initiative when one is created
- Type Classified, Never Hardcoded: Each work item resolves to Feature/Bug/Task via
resolveWorkItemType()(same mapping ascommands/run.md'sissueTypeMap) — never default everything to Feature - GitHub Issues Only:
createGitHubIssuealways —createZenhubIssueprohibited - Priority Before Creation: Score and confirm priorities before creating (labels immutable after creation)
- Pipeline Sorting Required: After creation, place all issues per the priority matrix in descending priority order
- Korean Acceptance Criteria: Write Acceptance Criteria in Korean (Feature items); Bug/Task items use the repro/DoD template instead
- BDD Integration: ACs map 1:1 with BDD scenarios (Feature items only)
- Label Consistency: Follow the defined label system — label uses the resolved type (
feature/bug/task) - Create After Confirmation: Create actual issues only after user confirms both the inferred scale and the priority table
- Artifact Before Creation: Publish narrative artifacts (Step 0.4) before any
createGitHubIssuecall and assemble bodies as contract block +## 📄 상세 기획link block; the 🔒 sharing notice is never omitted, Sub-tasks are never published, and a missingArtifacttool degrades to a full-markdown body rather than aborting (SoT:rules/zenhub-conventions.md→ Issue Body Artifact Contract)
Related Documents#
- BDD Scenario Agent
- Figma Analyzer Agent
cc-dev/skills/dev/SKILL.md— Type Inference table reused byresolveWorkItemType()cc-dev/commands/run.md—issueTypeMap, the single-issue-path equivalent of Step 3's classification