문서 목차
이 페이지에서목차

ZenHub Pipeline Registry

---

ZenHub pipeline dynamic query guide


Workspace Info Query#

Pipeline ID, Repository ID, and Issue Type ID differ per workspace. Dynamically query based on the X-zh-workspace configured in the project root's .mcp.json:

// Pipeline ID + Repository ID
const workspace = await mcp__zenhub__getWorkspacePipelinesAndRepositories();
// workspace.pipelines → [{ id, name }, ...]
// workspace.githubRepositories → [{ id, name }, ...]

// Issue Type ID
const issueTypes = await mcp__zenhub__getIssueTypes({ repositoryId });
// issueTypes → [{ id, name, level }, ...]
// (Initiative L1, Project L2, Epic L3, Feature/Bug/Task L4, Sub-task L5, ...)

Query Issue Type IDs via mcp__zenhub__getIssueTypes().


Two States: Pipeline vs GitHub State ⚠️#

ZenHub tracks two independent states for every issue. Confusing them is the #1 source of "issue stuck open" bugs:

StateOwnerWhat it means
Pipeline ZenHub The board column (New Issues, In Progress, Review/QA, Done, …). Moving columns is purely a board position.
GitHub state GitHub The issue's actual open / closed flag.

Key consequences:

  • Done pipeline ≠ closed. Moving an issue to a Done column does not close the GitHub issue — it stays open. Done means "ready to close", not "closed".
  • Closed pipeline = GitHub closed, 1:1. ZenHub does not treat "Closed" as an ordinary column; it is wired directly to the GitHub closed state. ZenHub's own API says to judge open/closed by state, not by pipeline.
  • An issue becomes truly Closed in exactly one of three ways:
    1. Dragged into the Closed pipeline (→ GitHub closes it), or
    2. Closed directly on GitHub (→ ZenHub auto-moves it to Closed), or
    3. A linked PR merges with Closes #N in its body (→ GitHub auto-closes → ZenHub syncs to Closed).

This repo's policy = (B) "merge = Close". AI agents run full-stack E2E tests + review before merge, so a merged PR is treated as Done and Closed. We therefore rely on mechanism #3 (Closes #N) and never park issues in a Done column. Because #3 can silently fail (missing keyword, ZenHub sync lag), every merge is followed by a closure verification + fallback (see below).

Pipeline Transitions by Workflow#

Issue Processing Workflow#

New Issues → Product Backlog → Sprint Backlog → In Progress → Review/QA → [Merge = Close → Closed]

Note: Done pipeline is not used. On PR merge, Closes # auto-closes the GitHub issue, which syncs the ZenHub issue to the Closed pipeline. Always verify the Closed state after merge and fall back to an explicit close if the sync did not happen.

StepTriggerPipeline / State
Issue creationAutomaticNew Issues
Backlog registrationAfter triageProduct Backlog
Sprint assignmentSprint planningSprint Backlog
Start workOn branch creationIn Progress
Request review After PR creation Review/QA
Complete (merge = Close) PR merge → GitHub auto Close → ZenHub sync Closed (verify + fallback). Done not used.
Blocked (BLOCKED(*)) Budget exhausted / worker timeout / merge conflict Sprint Backlog (holding) + createBlockage + reason comment + claim release
Aborted (INCOMPLETE(*) after start) Tooling missing / approval unavailable / session stop Sprint Backlog (holding) + reason comment + claim release
Abandoned PR PR closed without merge In Progress (awaiting rework) + claim release
Occupied Another session holds the claim ⛔ no move — never touch someone else's claim

⚠️ 규범은 rules/zenhub-conventions.md → Pipeline State Contract 다. 이 표는 파생 뷰이며, 어긋나면 그쪽이 이긴다. 착수(In Progress) 시점에는 파이프라인 이동과 함께 점유 대장을 쓴다 (Work Claim Contract) — 이동만으로는 cascade 로 올라간 부모와 구분되지 않는다.

Priority-based Initial Placement (issue creation flows)#

Issues created via /cc-dev:zenhub:breakdown / /cc-product:breakdown skip New Issues triage — they are placed directly by priority tier (see rules/zenhub-conventions.md → Priority Review and Pipeline Sorting):

TargetInitial Pipeline
Project / EpicProduct Backlog
Work item P0 (sprint specified)Sprint Backlog
Work item P0/P1Product Backlog
Work item P2Icebox
Sub-taskFollows parent work item

moveIssueToPipeline has no in-pipeline position param — move in descending priority order (P0 → P1 → P2).

MCP Call Examples#

// Query workspace info (once at session start)
const workspace = await mcp__zenhub__getWorkspacePipelinesAndRepositories();
const inProgress = workspace.pipelines.find(p => p.name === "In Progress");
const reviewQA = workspace.pipelines.find(p => p.name === "Review/QA");

// On work start (move to In Progress)
mcp__zenhub__moveIssueToPipeline({
  issueId: "{issue.graphqlId}",
  pipelineId: inProgress.id
})

// After PR creation (move to Review/QA)
mcp__zenhub__moveIssueToPipeline({
  issueId: "{issue.graphqlId}",
  pipelineId: reviewQA.id
})

// After PR merge: do NOT move to Done. "merge = Close".
// `Closes #N` should auto-close GitHub → ZenHub syncs to Closed.
// ⚠️ Verify it actually happened, fall back to explicit close otherwise:

// 1. GitHub is the source of truth for open/closed — verify it first.
const ghState = await Bash(`gh issue view ${issueNumber} --json state -q .state`);
if (ghState.trim() !== "CLOSED") {
  // `Closes #N` did not fire (missing keyword, cross-repo link, etc.) → close explicitly
  await Bash(`gh issue close ${issueNumber} --reason completed`);
}

// 2. Confirm ZenHub synced the GitHub closed → Closed pipeline.
//    Closing on GitHub normally syncs automatically; if lagging, force the state.
const closed = await mcp__zenhub__searchClosedIssues({ query: `#${issueNumber}` });
if (!closed.find(i => i.number === issueNumber)) {
  await mcp__zenhub__updateIssue({ issueId: "{issue.graphqlId}", state: "CLOSED" });
}

GitHub Issue Creation Example#

const workspace = await mcp__zenhub__getWorkspacePipelinesAndRepositories();
const repoId = workspace.githubRepositories.find(r => /* select GitHub repo */).id;
const issueTypes = await mcp__zenhub__getIssueTypes({ repositoryId: repoId });

mcp__zenhub__createGitHubIssue({
  repositoryId: repoId,
  title: "feat(scope): Feature title",
  body: "## Summary\n...\n\n## Acceptance Criteria\n- [ ] ...",
  issueTypeId: issueTypes.find(t => t.name === "Feature").id,
  labels: ["feature"],
})

Workspace Initialization#

To set up a new workspace with the standard pipeline structure, use the /cc-dev:zenhub:init-workspace command:

/cc-dev:zenhub:init-workspace

Standard structure:

New Issues → Icebox → Product Backlog → Sprint Backlog → In Progress → Review/QA

If a Done pipeline exists, internal issues are Closed and manual deletion is guided.


Referencing Skills/Agents#

Files that reference this registry:

FilePurpose
commands/run.mdFull workflow
commands/batch.mdSequential issue processing
agents/dev/issue-state-agent.mdIssue state management
commands/zenhub/init-workspace.mdWorkspace pipeline initialization
commands/zenhub/manage.mdPR linking + pipeline move
commands/zenhub/breakdown.md Initiative/Project/Epic/Feature/Bug/Task 생성(규모 자동 추론) + 우선순위·타임라인 배치
commands/zenhub/changelog.md닫힌 이슈 윈도우 집계 → 릴리스 노트
commands/zenhub/sprint-rollover.md미완료 이슈 다음 스프린트 carryover
commands/zenhub/triage.md외부 피드백 dedup → New Issues 인입
commands/zenhub/rerank.md전역 백로그 우선순위 재정렬
commands/zenhub/team-align.md팀 부하·우선순위 충돌 리포트

Important Notes#

  1. No Hardcoded IDs: All IDs must be dynamically queried via MCP tools
  2. .mcp.json Based: Per-project workspace is determined by the X-zh-workspace header in .mcp.json
  3. ID Query: All IDs obtained via getWorkspacePipelinesAndRepositories() + getIssueTypes() combination

검색어를 입력하면 문서를 찾습니다.

↑ ↓ 이동 · Enter 열기Esc 닫기