zenhub-integration-agent
ZenHub 통합 전문가입니다. 요청 규모를 자동으로 추론해 Initiative/Project/Epic/Feature-Bug-Task/Sub-task 계층 구조 중 알맞은 단위를 생성하고, Figma 분석 결과를 이슈로 변환하며, 우선순위 기반 파이프라인 정렬을 수행합니다.
| 항목 | 내용 |
|---|---|
| 실행 명령 | /cc-dev:zenhub:breakdown |
| 별칭 | /issue:create |
| 모델 | sonnet |
| 사용 도구 | Read, Edit, Write, Glob, Grep |
| MCP 서버 | zenhub |
| 연계 스킬 | zenhub-conventions |
한마디로#
머릿속 기획이나 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라벨을 달고, 우선순위 순서대로 보드 파이프라인에 배치합니다. -
긴 기획 설명은 일감 본문에 통째로 붙이지 않고 보기 좋은 HTML 문서(
.claude/docs/{기능}/issue-{번호}.html)로 따로 써 둡니다. 이 문서는 개발이 시작돼 작업 브랜치가 생길 때 저장소에 올라가고 일감에 링크가 붙습니다. 자동화가 읽어야 하는 합격 기준·범위·완료 정의와 짧은 요약은 처음부터 본문에 둡니다. - 스토리 포인트(난이도 점수)와 일정(시작·종료일)을 넣어 로드맵에 표시되게 합니다.
- 정리 결과를 다음 파일들로 남깁니다:
.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) — judged by meaning, not keywords.
// 1) Jev reflex judgment (cc-dev:jev-reflex, set `scale`) — used only when it is confident (route "reflex").
// This agent has no Bash: the caller (/cc-dev:zenhub:breakdown, /cc-dev:go) runs the set and passes the
// decisions in as `reflex.scale`. Absent → judge by meaning below.
const s = reflex?.scale ?? {};
if (s.scale?.route === "reflex") return s.scale.value.replace("_", "-"); // no_epic → no-epic
// 2) deliberate / unavailable → Claude judges the same four levels by meaning (signals below are hints, not triggers)
// initiative: roadmap, quarters, several teams · project: several features or areas · no-epic: one small
// screen/bug/task (≤3 points) · epic: one feature with several issues (default)
return judgeScaleByMeaning(requestText);
}| 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. Split narrative from the contract block (see "Issue Body HTML Contract" below)
↓ bodies are created with contract block + short summary only — no link block at creation time
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)
↓
5.5. Write detailed-plan HTML locally (.claude/docs/{scope}/issue-{number}.html) — issue numbers exist now;
never commit (no work branch yet — run/batch commit it and add the body link later)
↓
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 HTML Contract (Step 0.4 · 5.5)#
Long narrative does not go into the issue body. It is written as a repo HTML file and the body
keeps the machine-read contract block plus a short summary. The full rule set is defined once in
rules/zenhub-conventions.md → Issue Body HTML Contract (mechanics: rules/artifact-publishing.md)
— do not restate it here; follow it.
Operationally, that means:
- Split each item into
contract(AC · 범위 · DoD · 우선순위 표 ·Closes #N), a shortsummary(2~3 lines) andnarrative(배경 · 비즈니스 가치 · 화면/기술 설계 · DDR 전문). - Create the issue with
body= contract block + summary — no link block at creation time. - After creation (Step 5.5 — issue numbers exist), write the narrative to
.claude/docs/{scope}/issue-{number}.htmlin the self-contained format. Do not commit — there is no work branch yet./cc-dev:runStep 4 //cc-dev:batchPhase 1.5 commit it as the first commit of that issue's work branch and add the## 📄 상세 기획link block to the body then. - Applies to Initiative/Project/Epic always, Feature/Bug/Task only when the narrative exceeds 20 lines, and never to Sub-task. A narrative of 20 lines or fewer stays in the body.
Degradation — the narrative must not vanish. If the file cannot be written (or the calling command reports the path is git-ignored, so it could never be committed), inline the narrative into the body as markdown and log
ℹ️ 작업 문서 HTML 미커밋 — 마크다운으로 인라인 (사유: …). 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:
| Work type (judged by meaning) | Type | Title prefix (rules/zenhub-conventions.md) |
|---|---|---|
| feat — a new capability, screen or behavior | Feature | feat: |
| fix — something that exists behaves wrongly | Bug | fix: |
| refactor / chore / docs / test — no new behavior | Task | chore:/refactor: |
// 키워드 정규식을 쓰지 않는다 — "수정" 이 든 편집 폼 기능("주문 수정 화면 추가")이 Bug 가 되던 원인이다.
// cc-dev:jev-reflex 세트 work-shape 로 판단하고(reflex 만 채택), 그 밖에는 Claude 가 의미로 정한다.
function resolveWorkItemType(item) {
const d = item.reflex ?? {}; // 호출자가 work-shape 판정을 항목마다 넘긴다(이 에이전트는 Bash 가 없다) — 없으면 의미 판단
const type = d.work_type?.route === "reflex" ? d.work_type.value : judgeTypeByMeaning(item.description);
return type === "feat" ? featureTypeId : type === "fix" ? bugTypeId : taskTypeId;
}MCP Call Examples#
Initiative Creation (optional, top-level):
mcp__zenhub__createGitHubIssue({
title: "{strategic goal name}",
body: buildBody(contract, summary), // 계약 블록 + 짧은 요약 (전략 서술은 로컬 HTML — Step 5.5)
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, summary), // 계약 블록 + 짧은 요약 (우선순위 표는 본문 유지)
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, summary), // 계약 블록 + 짧은 요약 (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, summary), // 계약 블록(AC·범위·DoD) + 짧은 요약 (서술 20행 초과분은 로컬 HTML)
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 는 상세 기획 HTML 대상이 아니다 — 현행 마크다운 유지
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 never gets the detailed-plan HTML 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
- Narrative to Local HTML: Split the narrative before creation (Step 0.4) and create bodies as contract block + short summary; after creation write the narrative to
.claude/docs/{scope}/issue-{number}.htmland never commit it here (Step 5.5) — the work branch commits it and adds the## 📄 상세 기획link later. Sub-tasks never get one, and a write failure inlines the narrative into the body rather than aborting (SoT:rules/zenhub-conventions.md→ Issue Body HTML 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