LogoSkills

/cc-product:develop — 실제로 "만드는" 단계

6단계: Development — 이슈 번호의 ZenHub 레벨(Initiative/Project/Epic/Story/Sub-task)을 자동 판별해 Epic 내 Story 순회 또는 단일 이슈 13단계 사이클을 돌려 구현·테스트·PR 을 냅니다.

/cc-product:develop — 실제로 "만드는" 단계#

항목내용
실행 명령/cc-product:develop
분류파이프라인
난이도●●● 높음
MCP 서버zenhub

파이프라인 6단계(Development). Epic 안에 나눠 둔 작업(Story)을 하나씩 꺼내, 코드 작성부터 리뷰·병합까지 정해진 절차로 실제 구현합니다.

한마디로#

설계도와 작업 목록이 다 준비된 뒤, 현장 인부들이 실제로 벽돌을 쌓아 집을 짓는 단계입니다. 작업 목록(Story)을 하나씩 가져와, 코드를 짜고 검사하고 합치는 13단계 절차를 반복합니다.

누가·언제 쓰나요#

  • Initiative/Project/Epic(작업 묶음)과 그 안의 Story(개별 작업)가 이미 만들어져, 이제 실제 구현만 남았을 때
  • 이슈 번호 하나만 넣고 싶을 때 — Initiative/Project/Epic/Story/Sub-task 어느 레벨이든 자동으로 구분해 처리합니다
  • 특정 Epic 전체나 개별 이슈 하나를 직접 개발하고 싶을 때

👉 건너뛰는 경우는 거의 없습니다: 이 단계가 곧 실제 코드를 만드는 핵심 작업이기 때문입니다. 다만 시작하려면 앞 단계(Issue Breakdown)가 끝나 ZenHub에 해당 이슈와 그 하위 계층이 등록돼 있어야 합니다.

무엇을 해주나요#

  • 실제 동작하는 코드 — Story마다 브랜치를 따서 작업하고, PR(코드 리뷰 요청)을 거쳐 병합(merge)까지 마칩니다.
  • 완료된 Story 목록.pipeline/{slug}.yaml 파일에 어떤 Story가 끝났는지 기록됩니다.

어떻게 쓰나요#

# 이슈 번호만 넣으면 레벨을 자동 판별해 처리 (Initiative/Project/Epic/Story/Sub-task 무엇이든)
/cc-product:develop 42

# 파이프라인 맥락에서 자동 진행 (직전 단계가 기록한 번호 자동 참조)
/cc-product:develop

# 서로 독립적인 Story들을 동시에 개발 (Epic/Story 레벨, Agent Teams 필요)
/cc-product:develop 42 --parallel

# 레벨 판별과 무관하게 이 번호를 단일 이슈로 강제 처리
/cc-product:develop --issue 1810

이슈 번호만 넣으면 됩니다 — Initiative/Project/Epic/Story/Sub-task 중 어느 레벨인지는 자동으로 판별합니다. 레벨 판별을 건너뛰고 강제로 단일 이슈만 처리하려면 --issue를 씁니다. 급할 때는 --skip-review(리뷰 건너뛰기)나 --skip-tests(테스트 건너뛰기)를 붙일 수 있는데, 건너뛴 검사는 Story별로 기록에 남고 완료 보고에 그대로 표시됩니다(조용히 사라지지 않습니다) — 단 이 두 옵션은 Epic/Story 레벨에서만 적용됩니다(Initiative/Project로 판별되면 /cc-dev:batch에 위임되어 전달되지 않습니다). --parallel은 독립적인 작업을 여러 팀이 나눠 동시에 처리합니다(Epic/Story 레벨, Agent Teams 환경 필요 — Initiative/Project 레벨은 /cc-dev:batch의 Orca 병렬 디스패치가 대신 처리합니다).

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

  1. 레벨 자동 판별 — 넣은 이슈 번호가 ZenHub에서 Initiative/Project/Epic/Story(Feature·Bug·Task)/Sub-task 중 무엇인지 확인합니다. Epic이면 아래 25번(Story 순회)을 그대로 진행합니다. Story/Sub-task면 아래 25번을 건너뛰고 곧바로 13단계 개발 사이클로 직행합니다. Initiative/Project면 그 아래 전체 계층을 다루는 /cc-dev:batch에 넘겨 처리한 뒤 완료·실패 결과만 이어받아 기록합니다(같은 판별 로직을 두 곳에 따로 두지 않습니다).

Epic으로 판별된 경우, 그 안의 Story들을 하나씩 또는 동시에 처리하면서 아래 개발 절차(2~5번)를 반복합니다.

  1. 할 일 목록 정리 — ZenHub에서 Epic 안의 Story 목록을 가져와 의존 순서대로 정렬하고, 이미 끝난 것은 건너뜁니다.
  2. 한 건씩 구현 — 각 Story마다 ① 상세 분석·구현 계획 → ② 코드 작성부터 검사·병합까지의 13단계 개발 사이클 실행 → ③ 구현 품질·설계 준수 검토를 차례로 진행합니다.
  3. 동시 진행(선택)--parallel을 쓰면 서로 겹치지 않는 파일을 다루는 Story들을 그룹으로 묶어, 사용자 승인을 받은 뒤 여러 팀이 동시에 개발합니다. 이때 팀들은 같은 작업 공간(워크트리) 을 공유하며 파일 담당 구역만 나눠 갖고, 브랜치·커밋은 팀장(Lead)이 한 자리에서 관리합니다. 서로 의존하는 작업은 줄을 세워 두되, 자기 선행 작업이 병합되는 즉시 하나씩 시작합니다 — 다른 팀이 전부 끝날 때까지 기다리지 않습니다.
  4. 품질 통과 확인 — Story마다 린트·테스트·코드 리뷰·브랜치 규칙(Implementation Gate)을 통과했는지 점검하고, 진행 상황을 파일에 기록합니다. 검사 결과를 읽지 못한 경우(도구 없음·조회 실패)는 통과가 아니라 실패로 처리합니다.

끝나면 모든 Story가 병합되고 품질 검사를 통과한 뒤, 다음 단계인 출시(/cc-product:launch) 로 넘어갑니다. 실패한 Story가 하나라도 있으면 초록색 완료 표시 없이 차단(BLOCKED) 으로 끝나고, 어떤 Story가 어느 검사에서 막혔는지 목록으로 보여줍니다 — 그 상태로는 출시 단계를 제안하지 않습니다. 작업이 길어 대화가 늘어났다면 대화를 비우고(/clear) 새로 시작하는 것을 권장합니다 — 결과는 파일에 남아 있어 사라지지 않습니다.


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

Triggers#

  • When starting development after Issue Breakdown completion
  • When implementation of a specific Initiative/Project/Epic/Issue is needed

Usage#

# Level auto-detected from the issue number (Initiative/Project/Epic/Story/Sub-task)
/cc-product:develop 42

# Auto from pipeline context
/cc-product:develop

# Parallel development of independent Stories (Epic/Story level, requires Agent Teams)
/cc-product:develop 42 --parallel

# Force this number to be treated as a single issue, regardless of detected level
/cc-product:develop --issue 1810

Parameters#

ParameterRequiredDescriptionExample
{issue_number} (positional)✅*ZenHub issue number. Level (Initiative/Project/Epic/Story/Sub-task) is auto-detected — see Level Detection42

*Either the positional argument or a pipeline-context reference (.pipeline/{slug}.yaml) is required. If neither resolves to a number, abort and ask for one — never guess.

Options#

OptionDefaultDescription
--issueSkip level detection; force this number through Single Issue Mode (direct 13-step cycle) regardless of what level it actually is
--parallelfalseParallel execution of independent Stories (requires Agent Teams). Epic/Story level only — when the level resolves to Initiative/Project, /cc-dev:batch's own Orca parallel dispatch takes over instead (see Container Mode)
--skip-reviewfalseSkip code review (urgent) — deletes Implementation Gate conjunct 3; MUST record skipped_checks: [code_review] per Story and degrade the completion banner. Epic/Story level only — not supported when delegating to Container Mode (see Container Mode step 1)
--skip-testsfalseSkip tests (urgent) — deletes Implementation Gate conjunct 2; MUST record skipped_checks: [tests] per Story and degrade the completion banner. Epic/Story level only — same restriction

두 우회 플래그는 게이트를 삭제하지 않고 낮춘다. 기록 위치와 배너 문구는 아래 Implementation Gate 를 따른다 — 콘솔 경고는 내구 기록이 아니다.

Prerequisites#

  • Issue Breakdown stage completed (Planning Gate passed)
  • The target ZenHub issue (any level — Initiative/Project/Epic/Story) and its descendant Stories exist
  • For --parallel at Epic/Story level: CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1 environment variable required
  • For Initiative/Project level (Container Mode): Orca availability is checked by /cc-dev:batch itself — this command does not re-check it

Execution Flow#

0. Level Detection#

대상 번호를 정하는 순서: positional {issue_number}--issue 오버라이드(지정 시 레벨 판별을 건너뛰고 곧바로 Single Issue Mode로) → 파이프라인 컨텍스트(.pipeline/{slug}.yaml)에 기록된 번호. 셋 다 없으면 중단하고 번호를 확인받는다(추측 진행 금지).

--issue가 아니면 레벨을 자동 판별한다 — 판정 로직을 여기서 새로 만들지 않고 /cc-dev:batch Phase 0.3(Entry Issue Resolution)을 그대로 재사용한다 (../../cc-dev/commands/batch.md → "Phase 0.3: Entry Issue Resolution (레벨 판별)" 이 SoT):

1. getWorkspacePipelinesAndRepositories() + getIssueTypes({repositoryId}) 로 레벨 테이블 확보
   (Initiative(1)/Project(2)/Epic(3)/Feature·Bug·Task=Story(4)/Sub-task(5)../../cc-dev/rules/zenhub-conventions.md →  " Issue Type Hierarchy "   참조)
2. searchLatestIssues({query:  " #{issue_number} " }) 로 대상 이슈 + issueType 조회
3. 못 찾으면 사용자에게 정확한 번호를 확인받고 중단 — batch와 동일, 추측 금지

판정 결과에 따른 분기:

판별된 레벨처리
Epic (3)Epic Mode — 기존 로직 그대로
Feature/Bug/Task=Story (4), Sub-task (5)Single Issue Mode
Project (2), Initiative (1)Container Mode/cc-dev:batch에 위임

이 판정은 여기서 다시 구현하지 않는다 — Epic 자신이 children 0개인 예외 케이스(단독 Epic)나 Story가 예상외로 Sub-task를 가진 경우 같은 세부 처리는 각 모드 섹션이 기존 그대로 담당한다.

Epic Mode (Level = Epic)#

0. Agent Teams Prerequisite Check (for --parallel)

if --parallel:
  Check helpers.md#Check-Agent-Teams-Available
  if teams_available = false:Agent Teams not available. Falling back to sequential mode.Auto-switch to sequential processing

1. Story List Retrieval

  • Fetch Story list within Epic from ZenHub
  • Sort by dependency order
  • Check status (skip already completed Stories)

2-A. Sequential Execution (default)

For each Story:

a. Story implementation preparation (cc-product: /cc-product:dev-story)

  • Story detailed analysis
  • Implementation plan creation
  • Required files/components identification

b. 13-step development cycle (cc-dev: /cc-dev:run {issue_number})

  • Steps 1-12 sequential execution

c. Implementation review (cc-product: Flutter/Backend Dev persona)

  • Implementation quality verification
  • Architecture compliance check

2-B. Parallel Execution (--parallel, when Agent Teams active)

Phase 1: Dependency Analysis + File Ownership Boundary Analysis

1. Build Story dependency graph
   - Check each Story ' s dependencies field
   - Identify blocking relationships

2. File ownership boundary analysis
   - Map Story → source directory from architecture docs
   - Detect overlapping file areas
   - If overlap found → move those Stories to sequential queue

3. Identify independent Story groups
   - width cap = config `agent_teams.max_teammates` (default 3) — 이 값이 예산이다
   ┌─ Group A: [STORY-001, STORY-003] — independent file areas
   ├─ Group B: [STORY-002]            — independent file areas
   └─ Sequential Queue: [STORY-004]   — depends on STORY-001

4. Overflow rule (group count  >   max_teammates) — 조용한 절단 금지
   - Combine the smallest groups until count  < = max_teammates
     (same rule as team-create-stories.md Part 1 step 2  " combine smallest epics " )
   - Combining is legal only while the merged group ' s file set stays disjoint from
     every other group ' s. If combining would create an overlap, the surplus group
     goes to the Sequential Queue instead — it is never dropped.
   - unassigned_groups MUST end up empty. A non-empty list is a hard stop
     (report it and fall back to sequential), not a silent truncation.

width: 는 예산이고 cap 때문에 미룬 항목은 반드시 남는다는 규약은 ../../cc-dev/rules/orchestration-graph.md §5 (Fan-out Obligations) 를 따른다. 이 규칙이 없어서 4번째 그룹이 어디로 갔는지 아무도 모르던 자리다.

Phase 2: User Approval (plan confirmation)

╔════════════════════════════════════════════════════════════════╗
║  Parallel Development Plan                                     ║
╠════════════════════════════════════════════════════════════════╣
║                                                                ║
║  Parallel Teams (Agent Teams):                                 ║
║    Team 1: STORY-001, STORY-003                                ║
║      └─ Files: lib/src/feature/author/                         ║
║    Team 2: STORY-002                                           ║
║      └─ Files: lib/src/feature/book/                           ║
║                                                                ║
║  Sequential Queue (dependencies):                              ║
║    STORY-004 (blocked by STORY-001; starts when it merges)     ║
║                                                                ║
║  Estimated teammates: 2 / max 3 (agent_teams.max_teammates)    ║
║  Combined groups: none                                         ║
║  Unassigned groups: none                                       ║
║                                                                ║
╚════════════════════════════════════════════════════════════════╝

Proceed with this plan? (y/n)
  • Unassigned groups:반드시 출력한다none 이라는 0을 주장하게 만드는 줄이다. 값이 none 이 아니면 이 승인 박스는 진행 옵션이 아니고, 남은 그룹을 Sequential Queue로 옮기거나 순차 모드로 내려간 뒤 다시 제시한다.
  • Combined groups: 는 Phase 1 step 4 의 overflow 병합 결과를 그대로 적는다 (예: Group C + Group D → Team 3). 병합 흔적 없이 그룹이 사라지면 안 된다.

Phase 3: Delegate to /cc-product:team-dev

Independent Story groups → delegate to /cc-product:team-dev
  - helpers.md#Spawn-BMAD-Teammate (developer role)
  - helpers.md#Create-Team-Task-List
  - Pass file ownership boundaries to each teammate (own: per group, no overlap)
  - tier: standard per teammate — unset = silent inherit, and at degree N that is
    an N-times multiplier, not a default
  - ONE shared worktree, ONE branch: teammates MUST NOT run
    git checkout/switch/commit. Isolation here is file ownership, not branches.

After completion, Lead performs integration verification:
  - helpers.md#Collect-Team-Results
  - helpers.md#Team-Quality-Gate
  - Lead alone owns branch/commit/PR for the whole group

teammate 별 브랜치는 기능 부족이 아니라 표현 불가다git checkout 은 워크트리 전역이므로 한 워크트리에서 N teammate 가 N 브랜치에 앉는 상태 자체가 없다. 기질별 능력은 ../../cc-dev/rules/orchestration-graph.md §4 (Substrate Selection) 의 6행 매트릭스를 따른다: Agent Teams 행은 "자기 브랜치/커밋/PR? 아니오" 다. 진짜 브랜치 격리가 필요하면 여기서 발명하지 말고 Orca 워크트리 디스패치(/cc-dev:batch)로 올린다 — 이 커맨드는 그 승격을 하지 않는다.

Phase 4: Sequential Queue Processing

Eligibility is per Story, computed from merged state — not from team completion. There is no barrier here: a queued Story starts as soon as its own blockers are merged, even while other teams are still working. Queue processing itself stays serialize:1 (one /cc-dev:run at a time), so this removes a wait without adding parallelism.

drain(sequential_queue):                      # re-evaluated on every merge event
  for story in sequential_queue:
    blockers = story.blocked_by

    if all(b.state ==  " merged "   for b in blockers):
      → eligible now: /cc-dev:run {story.issue_number}   (serialize:1)

    elif any(b in failed_stories for b in blockers):NOT silently skipped. Append to failed_stories with
        gate_check:  " blocker_failed:#{b.issue} " , attempts: 0
        and mark the issue BLOCKED( ' blocker_failed ' ) on the board per
        ../../cc-dev/rules/zenhub-conventions.md →  " Blocked Issue Contract " .
        A queued Story whose blocker failed MUST appear in the failed list.

    else:
      → still waiting: leave in queue, re-check after the next merge

  inv:      queue = eligible ∪ waiting ∪ failed, 매 pass 진입·종료 양쪽에서 성립
  prog:     remaining = |waiting|, 매 pass 강한 감소
            no-prog: 아무 Story 도 eligible 로 바뀌지 않은 pass 는 같은 대기를
            반복하지 않는다 → 남은 blocker 는 전부 미머지/실패이므로 즉시 확정
  term:     |waiting| == 0
  budget:   |sequential_queue| passes (Story 당 최대 1회 eligible 판정)
  exhaust:  no-prog pass 1회 → 남은 Story 를 gate_check: " blocker_unmerged "   로
            failed_stories 에 확정하고 종료. 무한 대기 금지.
  resume:   .pipeline/{slug}.yaml 의 completed/failed + `gh pr list --state merged`
            재조회로 위치 판정 (대화 카운터는 예산이 아니다)
  log:      pass 당 한 줄 —  " pass#2: waiting 3→1 (merged #1810, failed #1812) "

왜 배리어를 지웠나: 이전 문구는 "after parallel work completes" 였다. 그 대기는 교차 항목 근거가 없는 mode:barrier 였고(../../cc-dev/rules/orchestration-graph.md §4.2 의 정당한 barrier 목록에 이 자리는 없다), 실제로 필요한 불변식은 "자기 blocker 가 머지됐다" 하나뿐이다. 이 불변식은 "팀들이 다 끝났다" 보다 더 엄격하다 — 팀이 끝나도 blocker 가 실패로 끝났을 수 있고, 옛 문구는 그 경우 큐를 그냥 돌려 실패 위에 구현을 쌓았다. 필드 이름의 정의는 SoT §2 (Loop Contract) 를 따른다.

3. Progress Tracking

  • Update .pipeline/{slug}.yaml on each Story completion
  • Record failed Stories at this address (기록 위치 없는 "record failed Stories" 는 기록이 아니다):
development:
  completed_stories: [1810, 1811]
  failed_stories:
    - issue: 1812
      gate_check: tests                  # lint | tests | code_review | branch_naming
      attempts: 3                        #        | blocker_failed:#{n} | blocker_unmerged
    - issue: 1815
      gate_check: blocker_failed:#1812
      attempts: 0
  skipped_checks:                        # per Story, from --skip-review / --skip-tests
    1810: [code_review]
  • 키가 없는 것(미기록)과 확인해서 0건인 것은 다르다. failed_stories 키가 아예 없으면 "실패 없음"이 아니라 "판정 안 함"으로 읽고, 완료 배너를 초록으로 올리지 않는다.

Story 순회 루프 계약 (필드 정의는 ../../cc-dev/rules/orchestration-graph.md §2, 값은 여기):

inv:Story 진입·종료 시 completed_stories ∪ failed_stories ∪ pending
          == Epic 의 전체 Story 집합 (어느 쪽에도 없는 Story 금지)
prog:     |pending|, Story 하나마다 강한 감소
          no-prog: 같은 Story 를 같은 전략으로 다시 돌리지 않는다 → Rung 2
term:     |pending| == 0
budget:   Story3-Rung ladder 1. Epic 단위 재시도 루프는 없다
exhaust:  `../../cc-dev/agents/sequential-workflow.md` →  " Stall Budget — 3-Rung Ladder " 
           를 그대로 쓴다: Rung 1 동일 전략 재시도 → Rung 2 `/cc-dev:unstuck` 로 종류가
          다른 리프레임 → Rung 3 `BLOCKED( ' unstuck_exhausted ' )` + 보드 반영 +
          **형제 Story 계속**(Story 의 정체가 Epic 전체를 멈추지 않는다).
          여기서 새 사다리를 발명하지 않는다
resume:   .pipeline/{slug}.yaml 의 completed_stories/failed_stories + ZenHub
          파이프라인 상태 재조회. `/cc-product:develop` 재실행은 멱등이다
log:      Story 당 한 줄 —  " STORY-003(#1812): pending 5→4, gate=PASSED(4/4) " 
           + 탈락시킨 Story 와 그 gate_check 를 파일에 내구 기록

Single Issue Mode (Level = Story/Sub-task, or --issue override)#

  • Directly execute cc-dev 13 steps
  • Update pipeline state

Container Mode (Level = Initiative/Project)#

Initiative/Project 로 판별되면 이 커맨드는 다단계 재귀를 다시 구현하지 않는다/cc-dev:batch가 이미 5레벨 재귀·Orca 병렬 디스패치·머지 직렬화·stall ladder를 SoT로 갖고 있으므로 그대로 위임한다 (../../cc-dev/commands/batch.md; go.md의 "새 로직을 거의 갖지 않는 오케스트레이터" 원칙과 동일).

  1. 옵션 매핑:
    • --parallel 미지정 → /cc-dev:batch {issue_number} --no-parallel 실행 (이 커맨드의 기존 sequential 기본값을 보존한다)
    • --parallel 지정 → /cc-dev:batch {issue_number} 실행 (batch 자체의 병렬 계획 승인 절차를 그대로 태운다 — 이 커맨드가 별도로 승인을 받지 않는다)
    • --skip-review/--skip-tests지원하지 않는다batch.md는 이 옵션을 갖지 않아 하위 leaf 의 /cc-dev:run 호출까지 전달할 경로가 없다. 지정돼 있으면 위임 전에 1줄 경고를 남기고 무시된 채 진행한다(조용히 통과시키지 않는다). 이 경우 leaf 는 정상적으로 4/4 Implementation Gate 를 통과해야 하며, 이 커맨드는 skipped_checks 를 오기록하지 않는다.
  2. /cc-dev:batch {issue_number} [--no-parallel] 를 실행한다. 사람 승인 지점(병렬 스폰 계획, 최종 머지)은 batch.md 의 계약을 그대로 따른다 — 이 커맨드는 게이트를 추가하거나 생략하지 않는다.
  3. Pipeline 동기화 (사후 집계).pipeline/{slug}.yaml 은 cc-product 파이프라인 전용 상태라 batch.md 가 직접 쓰지 않는다. batch 종료 후 이 레벨 서브트리의 leaf(Story/Sub-task) 전체를 GD-04 방식(gh api graphql sub-issues 전수 조회, ../../cc-dev/commands/run.md Step 0.6과 동일)으로 재귀 조회해, 아래 "Progress Tracking" 의 completed_stories/failed_stories 형식 그대로 채운다:
    • Closed leaf → completed_stories
    • Open leaf(batch가 BLOCKED/INCOMPLETE 로 남긴 것) → failed_stories, gate_check 는 batch가 이슈 코멘트에 남긴 causeKey(worker_timeoutbatch.md "3. 디스패치" · merge_conflictbatch.md "4. 머지는 항상 직렬화" · unstuck_exhaustedbatch.md "5. Stall Ladder" 등)를 그대로 옮겨 적는다
    • batch 자신이 완료성 Hard Gate(하위 컨테이너에 열린 자식이 남음)에서 정지한 경우, 이 레벨도 failed_storiesgate_check: "container_incomplete" 로 기록한다
    • 이 조회는 집계이지 재판정이 아니다 — batch가 이미 fail 로 확정한 leaf 를 여기서 다시 pass 로 뒤집지 않는다
  4. 이후 "After Completion" 핸드오프는 Epic Mode 와 동일한 green 판정식을 그대로 쓴다 — 레벨이 달라져도 완료 배너 로직은 하나다.

Implementation Gate#

BMAD Implementation Gate verification (per Story):

  • Lint passed (dart analyze, dcm analyze)
  • Tests passed
  • Code review passed
  • Branch naming convention followed

어디서 실제로 강제되나 — 이 4개 conjunct 는 이 커맨드가 직접 검사하지 않고 /cc-dev:run 의 특정 step 이 판정한다. 게이트 계약(tri-state)은 ../../cc-dev/rules/orchestration-graph.md §3 을 따른다.

#Conjunct강제 지점 (../../cc-dev/commands/run.md)undet:우회
1Lint passedStep 8.5 Pre-push Verification + DCM Format/Lint 0-Issue Gatefail없음
2Tests passedStep 8 /cc-dev:pr:preflight (unit/widget/integration) + Step 8.3 BDD Coverage Gatefail--skip-tests
3Code review passedStep 8.7 Code Review Gate + Step 11 리뷰 피드백 반영fail--skip-review
4Branch naming conventionStep 4 Branch Verification ({type}/{issue_number}-{slug}) + Step 9 Pre-PR Verificationfail없음
  • 판정 불가는 통과가 아니다. conjunct 결과를 읽지 못한 경우(도구 부재, 조회 실패, 파이프에 가려진 exit code)는 passfail 도 아닌 undetermined 이고, 기본값은 fail 이다. Story 를 completed_stories 로 옮기지 않고 failed_stories 에 그 gate_check 로 적는다.
  • 자식 이슈가 걸리는 판정(Step 9 · Step 11.9)은 삼분 판정을 다시 구현하지 말고 ../../cc-dev/rules/zenhub-conventions.md → "Child Enumeration Contract" 의 openChildrenStatus() (open | none | unknown) 를 그대로 호출한다. 통과는 none 하나뿐이고 unknown 은 차단이다.
  • 우회는 기록되고 배너를 낮춘다. --skip-review/--skip-tests 는 위 표의 conjunct 를 지운다. 지운 사실은 Story 단위로 .pipeline/{slug}.yamlskipped_checks: 에 남기고, 완료 문구는 통과한 conjunct 수를 그대로 노출한다:
    • 우회 없음 → PASSED (4/4 checks)
    • --skip-review --skip-testsPASSED (2/4 checks — code_review, tests SKIPPED)
  • 우회는 게이트를 제거하지 않고 낮춘다 — skipped_checks 가 비어 있지 않은 Story 는 그 사실을 달고 다음 단계(/cc-product:launch)로 넘어간다.
  • Container Mode(Initiative/Project) 에서의 4 conjunct — 이 표는 leaf(Story/Sub-task) 실행 시점의 강제 지점을 가리키며, Container Mode는 그 실행 자체를 /cc-dev:batch에 위임하므로 강제 지점은 그대로다(batch가 재귀적으로 호출하는 /cc-dev:run). 이 커맨드는 batch 종료 후 그 결과를 completed_stories/failed_stories집계만 한다(Container Mode 3번) — 여기서 conjunct 를 다시 판정하지 않는다.

Artifacts#

  • Implementation code (per Story: branch → PR → merge)
  • Completed Story list in .pipeline/{slug}.yaml (completed_stories)
  • Failed Story ledger in the same file (failed_stories: issue · gate_check · attempts)
  • Bypass ledger in the same file (skipped_checks: Story별로 지워진 Gate conjunct)
  • (Container Mode) 위 두 ledger는 /cc-dev:batch 종료 후 GD-04 방식 재조회로 사후 집계된다 — Epic Mode처럼 루프 도중 실시간으로 쌓이는 기록이 아니다

After Completion#

  • Verify all Stories completed
  • Verify Implementation Gate passed
  • Update .pipeline/{slug}.yaml state
  • Present the handoff — 문구를 하드코딩하지 않고 조건을 실제로 평가한 결과만 출력한다:
green := (completed_count == total_count) AND (failed_stories is present AND empty)

if green:Development stage complete (Implementation Gates {passed}/4 checks{skipped_note}).
    {completed_count}/{total_count} Stories merged.

  **Option 1 (Recommended)**: Clear context and continue to Launch
    /clear
    Then run: /cc-product:launch

  **Option 2**: Continue in current context
    Proceed directly to /cc-product:launch

else:Development stage BLOCKEDLaunch handoff withheld.
    {completed_count}/{total_count} Stories merged · {failed_count} failed.

    Failed Stories (.pipeline/{slug}.yaml → failed_stories):
      #1812  gate_check: tests                  attempts: 3
      #1815  gate_check: blocker_failed:#1812   attempts: 0

    Next: /cc-dev:unstuck {issue} (Rung 2 리프레임), 또는 수정 후
          /cc-product:develop {n} 재실행 — 멱등이므로 completed_stories 는
          다시 돌지 않는다.
    /cc-product:launch 는 failed_stories 가 빌 때까지 제안하지 않는다.
  • PASSEDgreen 이 참일 때만 쓴다. 이전 문구는 {completed_count}/{total_count} 를 보간하면서 "all Implementation Gates PASSED" 를 상수로 박아, 7개 중 3개만 머지되고 4개가 실패한 상태에서도 초록으로 출력하고 /cc-product:launch 로 넘겼다 — 이 파일의 fail-open 자리다.
  • {skipped_note} 는 어떤 Story 도 skipped_checks 를 갖지 않으면 빈 문자열, 아니면 — {checks} SKIPPED 이고 {passed} 가 그만큼 내려간다 (예: 2/4 checks — code_review, tests SKIPPED).
  • failed_stories 키 자체가 없으면 green 은 거짓이다(미기록 ≠ 0건).