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

sequential-workflow

Supporting reference module for /cc-dev:batch — per-issue cycle detail, Stall Budget ladder, and error recovery. Not a standalone command entry point.

항목내용
별칭@sequential-workflow
모델inherit
사용 도구 Read , Edit , Write , Bash , Glob , Grep , Task
MCP 서버zenhub
지원/cc-dev:batch

⚠️ This is a supporting reference module, not the command definition. The canonical /cc-dev:batch entry point (Epic branch → Story branch → Sub-task branch, per branch-hierarchy) is commands/batch.md. That file references this one specifically for the Stall Budget ladder and Error Recovery sections below — it is not a competing implementation. @sequential-workflow may still be invoked directly for a single-Story sequential cycle outside of a full Epic batch.

Sequential Workflow Agent#

A supporting workflow module detailing the per-issue processing cycle, stall-budget ladder, and error recovery used by /cc-dev:batch.

Triggers#

  • @sequential-workflow (direct invocation for a single-Story sequential cycle)
  • Referenced internally by /cc-dev:batch (commands/batch.md) for Stall Budget / Error Recovery detail

Workflow Cycle#

Phase 1: Issue Selection#

1. Query Story children under the Epic (each Story's own Sub-tasks are
   discovered and processed within that Story's own cycle — see
   branch-hierarchy: Sub-task's parent is Story, not Epic)
2. Filter issues in the New Issues pipeline
3. Sort by priority and issue number
4. Select the first issue

Phase 2: Start Work#

0. ⛔ Claim guard — claimStatus(issue) 가 "other-live" 면 이 Story 는 다른 세션이 잡고 있다.
   착수하지 않고 SKIPPED-OCCUPIED 로 기록한 뒤 다음 Story 로 넘어간다(보드·대장을 건드리지 않는다).
   판정 SoT: ../rules/zenhub-conventions.md → Work Claim Contract
1. Move the issue to the "In Progress" pipeline + acquireClaim(issue)
   → 이동만 하고 대장을 쓰지 않으면 다음 세션이 이 In Progress 를 부모 cascade 와 구분하지 못한다
   → cascade the same move up through any parent still in a pre-progress pipeline
     (New Issues/Icebox/Product Backlog/Sprint Backlog) — see
     agents/dev/issue-state-agent.md → cascadeStartToParents. Matters here specifically
     because this module may be invoked directly for a single Story outside a full batch,
     so the parent Epic may not have been touched yet.
2. Create branch: feature/{issue}-{slug}
3. Analyze issue requirements (title, body, acceptance criteria)

Phase 3: Implementation#

1. Analyze existing codebase
2. Implement code matching the requirements
3. Write tests (as needed)
4. Verify build and analysis pass

Phase 4: PR Creation#

1. Commit changes (include Closes #{issue})
2. Push branch
3. Create PR as a draft (gh pr create --draft — 초안에서는 가벼운 CI 층만 돈다)
4. Move issue to "Review/QA" pipeline (reflectBoardState(issue, "review") — 점유는 유지)
5. 로컬 점검 통과 확인 → gh pr ready → ready 뒤 새 CI run 을 기다려 판정(초안의 초록 ≠ 통과,
   상세는 `../commands/run.md` Step 10.5 · `../skills/ci-receipts/SKILL.md`)

Phase 5: Code Review Response#

1. Check review feedback
2. ⭐ 변경 요청(CHANGES_REQUESTED) 또는 CI 실패 시: 이슈를 Review/QA → "In Progress" 로 되돌린다
   (재작업 중임을 보드에 반영). fail-closed find() 로 pipelineId 해석.
3. Add fix commits → re-push → 다시 "Review/QA" 로 이동
   (CI 실패는 로컬에서 재현 · 수정 · 검증한 뒤 push — CI 시험 루프 금지. 재현되지 않는 플레이크 · 러너
    문제는 `gh run rerun <run-id> --failed` 로 실패 잡만 다시. 리뷰 반영은 모아서 한 번 push)
4. Wait for approval

Phase 6: Completion and Next Issue#

1. Squash merge PR
1.5. ⛔ 열린 자식 확인 — 이 이슈에 열린 자식이 있으면 **닫지 않는다**(이미 `Closes #N` 으로 닫혔다면
   `gh issue reopen` 으로 복구). 판정은 `openChildrenStatus()` tri-state — `rules/zenhub-conventions.md`
   → "Parent Closure Invariant". Story/Sub-task leaf 에서는 사실상 no-op 이다.
2. ⭐ 명시적 Close + 검증 (필수 — auto-close 의존 금지):
   PR base 가 `development`(저장소 기본 브랜치가 아닐 수 있음)면 `Closes #N` 이 발화하지 않는다.
   - STATE=$(gh issue view {N} --json state -q .state); [ "$STATE" != CLOSED ] && gh issue close {N} --reason completed
   - mcp__zenhub__searchClosedIssues({query:"#{N}"}) 에 없으면 → updateIssue({issueId, state:"CLOSED"})
3. Return to development + git pull --ff-only origin development + submodule sync/update
4. Go back to Phase 1 — **단, 종료 조건에 걸리지 않을 때만**(아래 루프 계약):
   - Phase 1 재조회가 이번 run 의 `attempted` 집합에 **없는** 이슈를 0개 내놓으면 정지한다
     (`attempted` = 이번 run 에서 착수한 이슈 번호 집합. 성공·BLOCKED 모두 넣는다 —
      BLOCKED 를 빼면 같은 이슈를 영원히 다시 고른다)
   - 조회 실패는 빈 집합이 아니다 — `unknown` 은 "다 끝났다" 가 아니라 **정지 + 기록**이다
   - 연속 K = 3 pass 동안 어떤 이슈도 closed 또는 BLOCKED 로 전이되지 않으면 정지한다
     (no-progress stop — 이슈가 계속 나오는데 아무것도 끝나지 않는 상태)

⚠️ Phase 6 는 GitHub Closes #N 자동 닫힘에 의존하지 않는다. 비-default base 머지는 자동으로 닫히지 않아 이슈가 Review/QA 에 영구 잔류하므로, GitHub state 를 source of truth 로 직접 닫고 ZenHub 동기화를 검증한다(/cc-dev:run Step 8 과 동일 패턴).

이슈 순회 루프 계약 contract:L-sequential-workflow.phase6-next-issue#

Phase 6 → Phase 1 로 되돌아가는 바깥 루프는 지금까지 정지 술어가 없었다. 필드 정의는 ../rules/orchestration-graph.md §2, 값은 여기:

inv:      매 pass 진입·종료 시 attempted 는 단조 증가하고 이번 run 에서 착수한 모든 이슈를 담는다
          (attempted 에 넣지 않고 같은 이슈를 다시 고르는 경로 금지)
prog:     remaining = |Phase 1 후보 − attempted|, pass 하나마다 강한 감소
          no-prog: remaining 이 줄지 않은 pass 는 noProgressStreak++ (예산에서 차감)
term:     remaining == 0 (= attempted 에 없는 이슈가 없다) || noProgressStreak == 3
budget:   pass 당 이슈 1개 · noProgressStreak K = 3 연속 pass · 이슈당 사다리 예산 4 attempts
          (run 당 이슈 수 상한은 데이터 주도 — 예산은 K 와 이슈별 사다리 카운터가 진다)
exhaust:  정지 + 남은 후보·BLOCKED 목록을 컨테이너 이슈 코멘트에 내구 기록. 조용한 종료 금지
resume:   ZenHub 파이프라인 재조회 + 각 이슈의 `<!-- cc-dev:stall-ladder -->` 코멘트.
          attempted 는 run 범위(대화 구조라 `/clear` 를 못 넘는다) — 그래서 재개를 가로지르는
          예산은 K 가 아니라 이슈별 **내구** 사다리 카운터가 진다
log:      선택마다 한 줄 — `▶ #1415 selected (attempted 3, remaining 5→4, streak 0)`
          + 정지 시 이유 한 줄(`remaining==0` | `noProgressStreak==3` | `query=unknown`)

ZenHub MCP Usage#

Workspace Info Query (once at session start)#

const workspace = await mcp__zenhub__getWorkspacePipelinesAndRepositories();
const pipelines = workspace.pipelines;
const repos = workspace.githubRepositories;   // ⚠️ 필드명은 githubRepositories (repositories 아님)

// fail-closed 해석 — 못 찾으면 throw (rename/오타 시 undefined.id 무음 누락 방지)
const pid = (n) => { const p = pipelines.find(p => p.name === n); if (!p) throw new Error(`'${n}' 없음. 라이브: ${pipelines.map(p => p.name).join(", ")}`); return p; };
const newIssues = pid("New Issues");
const inProgress = pid("In Progress");
const reviewQA = pid("Review/QA");
mcp__zenhub__searchLatestIssues({ query: "SALES-001" })

// Query issues by pipeline
mcp__zenhub__getIssuesInPipeline({
  pipelineId: newIssues.id,
  repositoryIds: [repos[0].id]
})

Pipeline Move#

// In Progress
mcp__zenhub__moveIssueToPipeline({
  issueId: "{graphql_id}",
  pipelineId: inProgress.id
})

// Review/QA
mcp__zenhub__moveIssueToPipeline({
  issueId: "{graphql_id}",
  pipelineId: reviewQA.id
})

Note: Pipeline ID and Repository ID differ per workspace. Do not hardcode them.

Branch Strategy#

# Create issue work branch
git checkout development
git pull origin development
git checkout -b feature/{issue_number}-{short-slug}

# Example
git checkout -b feature/1415-sales-kpi-summary

순차 의존 사슬이면 스택 모드를 고려한다 (선택형)#

이 모듈이 도는 사이클 — 한 번에 이슈 하나, 앞 이슈의 결과 위에 다음 이슈가 쌓이는 형태 — 가 순차 의존 사슬이라면, 그게 GitHub 네이티브 Stacked PR 이 정확히 맞는 자리다(스택은 트리가 아니라 선형 사슬이라 서로 독립인 형제는 못 담는다 — 독립 형제는 지금처럼 Orca 병렬 워크트리로 둔다). 기본값은 위의 기존 방식이고, 스택은 켜야 켜지는 선택형 실행 모드다. 채택 판단·CI 비용 맞교환은 stacked-prs 를 따른다.

접점만 짚으면:

  • 가장 큰 실익: 앞 이슈가 머지되어 base 가 움직일 때마다 뒷 이슈를 손으로 rebase 하던 루프가 사라진다. gh stack sync 의 cascade rebase 와 머지 후 자동 retarget 이 대신한다.
  • 머지: 스택에서는 auto-merge 가 미지원이다. Phase 6 의 머지를 gh pr merge 대신 gh stack merge 로 한다. 중간 PR 단독 머지는 불가능하고, 항상 아래 것들이 함께 머지된다.
  • 이슈 종료: 스택이라고 자동 종료를 가정하지 마라. 스택 머지 시 Closes #N 이 어떻게 동작하는지는 문서에 명시가 없다. Phase 6 의 명시적 gh issue close + ZenHub 검증 절차를 그대로 유지한다.

Commit Rules#

# Korean commit message + Gitmoji
feat(console): ✨ 매출 KPI 요약 카드 구현 (#1415)

- 총 결제액 표시
- 총 판매량 표시
- 전월 대비 증감률 표시

Closes #1415
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

PR Creation Rules#

gh pr create --draft \
  --base development \
  --title "feat(console): ✨ 매출 KPI 요약 카드 구현 (#1415)" \
  --body "$(cat <<'EOF'
## Summary
- Implement sales KPI summary card component
- Display total payment amount and sales volume
- Calculate month-over-month growth rate

## Related Issue
Closes #1415

## Test Plan
- [ ] Verify KPI card rendering
- [ ] Verify data binding
- [ ] Validate growth rate calculation

🤖 Generated with [Claude Code](https://claude.com/claude-code)
EOF
)"

Stop Conditions#

The workflow automatically stops when:

  1. Build failure: melos run analyze or flutter build failure
  2. Test failure: Unit test or widget test failure
  3. Code review issue: Major fix request raised
  4. User request: Explicit stop request

Per-story scope, not Epic scope. A single Story getting stuck must NOT halt the whole Epic. When a Story exhausts the stall ladder below, it is marked BLOCKED('unstuck_exhausted') and the batch continues to the next Story (idempotent resume re-enters it later — see batch.md Phase 0 — but the ladder budget carries over in the durable counter below: an exhausted ladder is not reset to Rung 1 by a resume).

Stall Budget — 3-Rung Ladder#

On repeated failure within one Story, climb the ladder rung by rung. Do not loop rung 1 forever.

이 사다리가 구현측 루프의 기본 exhaust: 다 (repo-wide default). ../rules/orchestration-graph.md §2 가 이 문서를 기본 사다리로 지정한다 — 개별 루프는 자기 사다리를 발명하지 말고 호출 지점에 contract:L-sequential-workflow.stall-ladder 를 인용하고 아래 값을 상속한다(값을 자기 문서로 복사하면 두 번째 규범 사본이 생긴다). 필드 이름(inv:/prog:/term:/budget:/exhaust:/ resume:/log:)의 정의도 그 문서 §2 에 있다.

Rung 1 — Same-strategy retry (existing):   budget = 2 attempts
  Re-run the same fix **at most 2 times** (e.g. lint/format/build
  auto-fix as in Error Recovery below). An unquantified "small, bounded"
  count is not a budget — in practice it never terminates.
  Each retry MUST change at least one input: command/flags, the changed
  file set, or the environment. A re-run with an identical input set is
  not an attempt but a repeat — it consumes no budget and goes straight
  to Rung 2 (`no-prog:` 위반).

Rung 2 — Lateral reframe (on repeated IDENTICAL failure):
                                           budget = 2 reframes, ≤ 1 persona switch
  When the SAME failure repeats (judged SEMANTICALLY, not by string
  diff — see note), escalate to /cc-dev:unstuck solo with an affinity
  persona from the symptom table below. A reframe ≠ a retry: the next
  move must differ in KIND from what already failed.
  **At most 2 reframed attempts**, and **at most ONE persona switch**
  within them (persona #1 comes from the symptom table; the one switch
  is spent only when reframe #1's named change did not move the failure).
  Each reframed attempt must NAME which of {tool, layer, data,
  assumption} it changed — that name IS this rung's progress measure.
  An attempt that can name none of the four is not a reframe: it
  consumes no budget and escalates to Rung 3.

Rung 3 — BLOCKED + CONTINUE (보드 반영 포함):
  횡적 reframe 도 소진되고 Story 가 여전히 안 풀리면 blockIssue(issue, 'unstuck_exhausted')
  후 배치를 CONTINUE 한다(Epic 전체 중단 금지). 그 한 번의 호출이 아래 셋을 묶어 수행한다:
    - 차단 의존이 있으면 createBlockage({blockedIssueId, blockingIssueId}) 로 기록
      (차단자가 이슈일 때만 — CI 실패·예산 소진에는 가짜 이슈를 만들지 않는다)
    - 활성 작업과 구분되도록 holding 컬럼(Sprint Backlog)으로 이동 — In Progress 에 방치 금지
    - **점유 해제** — 빠뜨리면 이 Story 는 TTL(4h)까지 다른 세션에게 "누가 하고 있다"로 읽힌다
    - 정의·blocked→unblocked 계약은 rules/zenhub-conventions.md → Pipeline State Contract 참조
    - 소진된 사다리 상태를 아래 카운터 코멘트에 state:blocked(unstuck_exhausted) 로 확정한다
  (BLOCKED Story 는 Phase 0 멱등 resume 으로 다시 집히지만, **사다리는 rung 1 로 리셋되지
   않는다** — 남은 예산이 있을 때만 재시도한다. 아래 "Ladder Counter Persistence" 참조.)

Rung 2 — Affinity Symptom Table#

Pick the starting persona by the meaning of the stuck state (default CONTRARIAN). Persona definitions live in plugins/cc-dev/references/LATERAL_PERSONAS.md — do not restate them here.

Symptom (semantic)/cc-dev:unstuck call
Same error repeated N×/cc-dev:unstuck solo hacker
Flip-flop / oscillation between fixes/cc-dev:unstuck solo architect
Missing fact / unverified info blocks progress /cc-dev:unstuck solo researcher
Over-built / complexity-buried blocker/cc-dev:unstuck solo simplifier
Unknown / premise itself suspect (default) /cc-dev:unstuck solo contrarian

LLM-SEMANTIC, never lexical. "Is this the SAME failure again?" and "which symptom is this?" are judged by meaning, not whitespace/token overlap of error text. The audience is Korean-first: Korean has no word boundaries and attaches 조사, so two log lines describing one blocker can share almost no tokens ("빌드가 실패" vs "빌드는 또 실패"). Match by what is actually stuck, not by characters.

반사 판정 먼저 (cc-dev:jev-reflex, 약 0.2초 — 두 판단 모두 의미 판단의 첫 단계다):

> JR="${CLAUDE_PLUGIN_ROOT}/skills/jev-reflex/scripts/jev_reflex.py"
> PREV="$(mktemp)"; TAIL="$(mktemp)"   # last_cause 와 이번 실패 꼬리 — 파일로 넘겨 따옴표가 셸로 새지 않게, 병렬 워커끼리 겹치지 않게
> python3 "$JR" ask --set same-failure --field-file previous="$PREV" --field-file current="$TAIL"
> python3 "$JR" ask --set lateral-persona --state @stuck.json   # {problem_context, current_approach, failed_attempts}
> 
  • same_blocker reflex true → 같은 실패: Rung 2 로 오른다 · reflex false → 다른 실패: 새 원인으로 Rung 1 을 이어 간다 (cc-dev:stall-ladder 코멘트의 last_cause 를 새 원인으로 바꾼다) · deliberate → 위 원칙대로 Claude 가 의미로 판단한다.
  • persona reflex → 그 페르소나로 /cc-dev:unstuck solo <persona> · deliberate → 기본값 CONTRARIAN, 단 Claude 가 표에서 더 맞는 증상을 보면 그것.
  • unavailable(0·4 가 아닌 모든 종료 코드) → 반사 판정 없이 위 원칙대로. 사다리 예산은 판정 방식과 무관하게 같다 — 반사 판정은 예산을 늘리거나 줄이지 않고, 오르는 판단만 빠르게 한다.

/cc-dev:unstuck returns options, not a verdict — it does not decide for the workflow. If a reframed next move is actionable, the workflow may try it (that counts as Rung 2, bounded at 2 reframes / ≤1 persona switch as above); if none unblocks the Story, proceed to Rung 3.

Ladder Counter Persistence — 재개를 가로지르는 예산#

대화 카운터는 /clear 를 넘지 못하고, batch.md Phase 0 의 멱등 resume 은 BLOCKED child 를 나중에 다시 집는다. 카운터를 어디에도 적지 않으면 그 재진입이 사다리를 rung 1 부터 다시 돌려서 — 매 pass 는 bounded 인데 resume 을 가로지르면 무제한 루프가 된다. 그래서 카운터와 의미 요약을 이슈에 적는다.

- 위치: 막힌 그 이슈 자신의 마커 코멘트 `<!-- cc-dev:stall-ladder -->`
  (upsert 프로토콜은 `../skills/branch-hierarchy/SKILL.md` R3 의 마커 코멘트 읽기·쓰기 절차를 재사용 — 복제 금지)
- 항목: | rung | attempts_used | persona | persona_switched(0|1) | changed({tool|layer|data|assumption})
        | last_cause(LLM-SEMANTIC 요약) | state: climbing / blocked(unstuck_exhausted) |
- 갱신 시점: **rung 전이마다 즉시**(다음 attempt 를 시작하기 전에) upsert 한다. 몰아서 쓰면
  크래시 한 번에 카운터가 사라지고 예산이 리셋된다.
- 재개: 이 이슈를 다시 집으면 코멘트를 **먼저 읽고** 남은 예산부터 이어 쓴다. 코멘트가 없으면
  rung 1 / attempts_used 0 이 초기값이고, **조회 실패는 "없음"이 아니라 unknown** 이므로 사다리를
  새로 시작하지 않고 blocked 로 둔다(`../rules/orchestration-graph.md` §3.2 empty-set pass).
- batch 하위에서 돌 때: `../commands/batch.md` → "Stall Ladder" 의 시도 대장(attempt ledger)은
  **컨테이너 쪽 바깥 예산**(child 1개당 누적 처리 pass 수)이고, 이 코멘트는 **그 pass 안쪽의
  rung/attempt** 다. 단위가 다르므로 서로 덮어쓰지 않고 곱해진다(outer × inner). 둘 중 하나라도
  소진되면 재시도는 없다.

루프 계약 contract:L-sequential-workflow.stall-ladder (필드 정의는 ../rules/orchestration-graph.md §2, 값은 여기):

inv:      매 attempt 진입·종료 시 (rung, attempts_used) 가 마커 코멘트의 값과 일치한다
          Rung 1 attempt 는 직전 attempt 와 입력 집합이 다르다
prog:     attemptsLeft = (2 - rung1Used) + (2 - rung2Used), 매 attempt 강한 감소
          no-prog: 입력이 같은 재실행(Rung 1) 또는 {tool,layer,data,assumption} 중 무엇도
          이름 대지 못한 리프레임(Rung 2) 은 예산을 쓰지 않고 곧바로 다음 rung 으로 올린다
term:     막힌 게이트가 통과 || attemptsLeft == 0 → Rung 3
budget:   Rung 1 = 2 attempts · Rung 2 = 2 reframes(persona 교체 ≤ 1) · Rung 3 = 종단 1회
          = 이슈당 최대 4 attempts, **batch 재실행을 가로질러 합산**한다(대화 카운터 아님)
exhaust:  Rung 3 = blockIssue(issue, 'unstuck_exhausted') (보드 + 점유 해제) + 형제 CONTINUE.
          디스패치된 워커 안에서 `AskUserQuestion` 을 exhaust 로 쓰지 않는다(물어볼 사람이 없다)
resume:   막힌 이슈의 `<!-- cc-dev:stall-ladder -->` 코멘트를 읽어 위치를 판정한다.
          코멘트 upsert 는 멱등이고, 사다리는 resume 마다 rung 1 로 되돌아가지 않는다
log:      rung 전이마다 한 줄(rung · attempt index · 고른 persona) —
          `🪜 rung 2 attempt 1/2 persona=hacker changed=assumption cause={의미 요약}`
          Rung 3 도달 시 잔여 상태와 **탈락시킨 이슈**를 같은 코멘트에 내구 기록

Error Recovery#

On Build Failure (Rung 1)#

# Analyze error
melos run analyze 2>&1 | head -50

# Common fixes
melos run format
melos run build

Tooling degradation (GD-01): melos 부재 시 dart analyze / dart format / flutter test 를 직접 호출하는 것으로 폴백한다(= /cc-dev:run "Step 0 Degradation Contract"). 빌드 도구 미설치는 안전 위반이 아니라 degrade + 경고 대상 — command -v melos 로 먼저 확인하고 분기하라.

On Repeated Identical Failure (Rung 2)#

# Same failure (semantically) after Rung 1 retries → lateral reframe
/cc-dev:unstuck solo <affinity-persona>   # see Affinity Symptom Table

On Stall Exhausted (Rung 3)#

# Reframe didn't unblock → mark BLOCKED and move on
mark Story BLOCKED('unstuck_exhausted'); CONTINUE to next Story  # Epic NOT halted

On Merge Conflict#

git fetch origin development
git rebase origin/development
# After resolving conflicts
git rebase --continue

On Stack Command Failure (스택 모드에서만)#

스택 모드(stacked-prs)로 돌 때는 위 수동 rebase 대신 gh stack sync / gh stack rebase 가 cascade 로 처리한다. 실패는 exit code 로 구분해 대응한다 — 셋 다 "같은 명령 재실행" 으로는 풀리지 않는다.

exit의미조치
3 rebase 충돌 충돌 파일을 해결하고 gh stack rebase --continue . 되돌릴 거면 gh stack rebase --abort . 해결 자체는 merge-conflict-resolution 규약을 그대로 따른다. Rung 1 재시도로 세지 않는다 — 사람이 만든 해결이 새 입력이므로 --continue 는 재실행이 아니라 진행이다
7 이미 rebase 진행 중 새 rebase 를 시작하지 마라. 진행 중인 것을 --continue 로 끝내거나 --abort 로 되돌린 뒤에만 다음 명령을 낸다. 진행 상태는 .git/gh-stack-rebase-state 에 남는다
8 다른 프로세스가 스택 잠금 병렬 워크트리·세션이 같은 스택을 동시에 만지고 있다는 신호다. 재시도 루프 금지 — 이건 실패가 아니라 직렬화 문제 다. 잠금이 풀릴 때까지 기다렸다 1회만 재실행하고, 그래도 8 이면 Rung 2 로 올린다(누가 잡고 있는지부터 규명). 이 대기는 입력이 바뀌지 않으므로 Rung 1 예산을 쓰지 않는다

⚠️ 로컬 스택과 원격 스택이 갈라지면(diverged) 대화형에서는 3택을 묻지만, 비대화형에서는 아무것도 바꾸지 않고 중단한다. 무인 실행에서 이 중단을 "실패 재시도" 로 처리하지 말고 BLOCKED 로 올려라.

Checklist#

Verification items for each issue:

  • Understand issue requirements
  • Create branch
  • Implement code
  • Pass build/analysis
  • Create commit (include Closes #)
  • Create PR
  • Move pipeline (In Progress → Review/QA)
  • Address review feedback
  • 실패가 있었다면 사다리 카운터를 이슈 코멘트에 기록(resume 이 rung 1 로 리셋되지 않음)
  • Switch to next issue — attempted 에 넣고 종료 조건(remaining / K=3) 재평가
  • @console-feature - Console feature patterns
  • @bloc - BLoC state management
  • @flutter-ui - UI component implementation
  • @test - Test writing

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

↑ ↓ 이동 · Enter 열기Esc 닫기