LogoSkills

zenhub-integration-agent

ZenHub 통합 전문가입니다. 요청 규모를 자동으로 추론해 Initiative/Project/Epic/Feature-Bug-Task/Sub-task 계층 구조 중 알맞은 단위를 생성하고, Figma 분석 결과를 이슈로 변환하며, 우선순위 기반 파이프라인 정렬을 수행합니다.

/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

호출하면 계층 스케일 추론 결과와 우선순위를 먼저 보여주고, 사용자가 확인한 뒤에야 실제 일감을 만듭니다. (만든 뒤에는 우선순위 라벨을 바꿀 수 없으므로, 생성 전 확인이 중요합니다.)

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

  1. 계층 스케일 추론 — 요청 문구(여러 기능/시스템 전체/전사 전략 등 신호)를 보고 Initiative~Epic 중 어디를 최상위로 만들지, 혹은 Epic 없이 Feature/Bug/Task만 만들지 자동으로 정합니다. (--initiative/--project/--no-epic 같은 명시적 플래그가 있으면 항상 그것이 우선합니다.)
  2. 우선순위 먼저 정하기 — 의존성·가치·위험·노력을 점수로 매겨 일감마다 p0/p1/p2를 정합니다. (라벨은 생성 후 못 바꾸므로 생성보다 먼저 합니다.)
  3. 계층 순서대로 생성 — Project(추론 시) → Epic(추론 시) → Feature/Bug/Task 여러 개 → 세부작업 순으로 만들고, 부모-자식 관계를 연결합니다. 각 항목은 성격에 따라 Feature/Bug/Task 중 실제 타입으로 생성됩니다.
  4. 점수·일정 입력 — 스토리 포인트와 시작·종료일을 함께 넣습니다. (둘 다 넣어야 로드맵 일정 막대에 표시됩니다.)
  5. 보드 줄 세우기 — 우선순위가 높은 순(P0 → P1 → P2)으로 파이프라인에 배치합니다.
  6. 스프린트 배정 — 요청 시 P0 항목을 스프린트에 넣습니다.

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

Role#

  1. 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
  2. Project Creation (auto-inferred or explicit): Create Project-level issues that wrap multiple Epics
  3. Epic Creation (auto-inferred or explicit; may be skipped for small-scope requests): Create Epics
  4. 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
  5. Acceptance Criteria Attachment: Attach BDD scenario-based Acceptance Criteria (Feature items) or repro-steps/definition-of-done (Bug/Task items)
  6. Priority Review: Score every issue (dependency/value/risk/effort) before creation and assign p0/p1/p2
  7. Pipeline Sorting: Place created issues into pipelines per the priority matrix
  8. Label Management: Auto-apply appropriate labels

ZenHub MCP Tools#

ToolPurpose
createGitHubIssueCreate GitHub issue (requiredcreateZenhubIssue prohibited, see rules/zenhub-conventions.md)
setParentForIssuesSet parent-child relationships across any two adjacent hierarchy levels
moveIssueToPipelineMove Pipeline (⚠️ no in-pipeline position param)
setIssueEstimateSet Story Points (SP only — does not affect the timeline)
setDatesForIssueSet timeline start/end dates (required for roadmap display — needs zenhubOrganizationId)
setIssueTypeChange Issue Type
getIssueTypesQuery Issue Type list (includes hierarchy level)
getUpcomingSprint / listRecentSprintsQuery Sprints
addIssuesToSprintsAssign 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
}
ResultHierarchy created
initiativeInitiative → Project → Epic → Feature/Bug/Task (→ Sub-task)
projectProject → Epic(s) → Feature/Bug/Task (→ Sub-task)
epic (default)Epic → Feature/Bug/Task (→ Sub-task) — unchanged prior behavior
no-epicFeature/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: P0P1P2)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.mdIssue Body Artifact Contract — do not restate it here; follow it.

Operationally, that means:

  1. Split each item into contract (AC · 범위 · DoD · 우선순위 표 · Closes #N) and narrative (개요 · 비즈니스 가치 · 화면/기술 설계 · DDR 전문).
  2. Publish the narrative before any createGitHubIssue call, at a per-issue fixed path (.claude/docs/{scope}/issue-{slug}.html) — the same path on re-publish keeps the same URL.
  3. 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).
  4. Applies to Initiative/Project/Epic always, Feature/Bug/Task only when the narrative exceeds 20 lines, and never to Sub-task.

DegradationArtifact exists 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 signalTypeTitle prefix (rules/zenhub-conventions.md)
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 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/endDate stay 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.mdEpic 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#

TypeTitle 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 itemfix: {defect description}
Task work itemchore: {non-user-facing work description}

Story Point Guide#

PointComplexityExample
1Very simpleSimple UI modification
2SimpleSingle widget implementation
3NormalList screen, basic CRUD
5ComplexDetail screen + actions, form + validation
8Very complexComposite screen

Default Points by Screen Type#

Screen TypeDefault Point
List3
Detail3
Form5

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 hardcoded story label. ⚠️ Priority labels (p0/p1/p2) must be included at creationupdateIssue cannot change labels afterward.

Screen Type Labels#

ScreenLabel
Listlist-view
Detaildetail-view
Formform-view

Pipeline Configuration#

New IssuesIceboxProduct BacklogSprint BacklogIn ProgressReview/QA

Done pipeline is not used — issues auto-close on PR merge via Closes #. See references/PIPELINE_REGISTRY.md.

Priority-based Initial Placement#

TargetInitial Pipeline
Project / EpicProduct Backlog
Work item P0 (sprint specified)Sprint Backlog + addIssuesToSprints
Work item P0/P1Product Backlog
Work item P2Icebox
Sub-taskFollows 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.mdUnified Issue Body Template defines the section contract (order + H1 rule); commands/zenhub/breakdown.mdIssue Templates has the actual markdown. Not duplicated here — this section only lists which core section each type resolves to, per resolveWorkItemType().

TypeCore 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.md

Key Rules#

  1. 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
  2. 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
  3. 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
  4. Type Classified, Never Hardcoded: Each work item resolves to Feature/Bug/Task via resolveWorkItemType() (same mapping as commands/run.md's issueTypeMap) — never default everything to Feature
  5. GitHub Issues Only: createGitHubIssue always — createZenhubIssue prohibited
  6. Priority Before Creation: Score and confirm priorities before creating (labels immutable after creation)
  7. Pipeline Sorting Required: After creation, place all issues per the priority matrix in descending priority order
  8. Korean Acceptance Criteria: Write Acceptance Criteria in Korean (Feature items); Bug/Task items use the repro/DoD template instead
  9. BDD Integration: ACs map 1:1 with BDD scenarios (Feature items only)
  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 and the priority table
  12. Artifact Before Creation: Publish narrative artifacts (Step 0.4) before any createGitHubIssue call and assemble bodies as contract block + ## 📄 상세 기획 link block; the 🔒 sharing notice is never omitted, Sub-tasks are never published, and a missing Artifact tool degrades to a full-markdown body rather than aborting (SoT: rules/zenhub-conventions.mdIssue Body Artifact Contract)

  • BDD Scenario Agent
  • Figma Analyzer Agent
  • cc-dev/skills/dev/SKILL.md — Type Inference table reused by resolveWorkItemType()
  • cc-dev/commands/run.mdissueTypeMap, the single-issue-path equivalent of Step 3's classification