LogoSkills

sequential-workflow

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

ํ•ญ๋ชฉ๋‚ด์šฉ
supports/dev:batch
Aliases@sequential-workflow
ToolsRead, Edit, Write, Bash, Glob, Grep, Task
MCP Serverszenhub
Modelinherit

โš ๏ธ This is a supporting reference module, not the command definition. The canonical /dev:batch entry point (Epic branch โ†’ Story branch โ†’ Sub-task branch, per branch-hierarchy) is commands/dev/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 /dev:batch.

Triggers#

  • @sequential-workflow (direct invocation for a single-Story sequential cycle)
  • Referenced internally by /dev:batch (commands/dev/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#

1. Move the issue to the  " In Progress "   pipeline
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 (gh pr create)
4. Move issue to  " Review/QA "   pipeline

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 "   ๋กœ ์ด๋™
4. Wait for approval

Phase 6: Completion and Next Issue#

1. Squash merge PR
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 6 ๋Š” GitHub Closes #N ์ž๋™ ๋‹ซํž˜์— ์˜์กดํ•˜์ง€ ์•Š๋Š”๋‹ค. ๋น„-default base ๋จธ์ง€๋Š” ์ž๋™์œผ๋กœ ๋‹ซํžˆ์ง€ ์•Š์•„ ์ด์Šˆ๊ฐ€ Review/QA ์— ์˜๊ตฌ ์ž”๋ฅ˜ํ•˜๋ฏ€๋กœ, GitHub state ๋ฅผ source of truth ๋กœ ์ง์ ‘ ๋‹ซ๊ณ  ZenHub ๋™๊ธฐํ™”๋ฅผ ๊ฒ€์ฆํ•œ๋‹ค(/dev:run Step 8 ๊ณผ ๋™์ผ ํŒจํ„ด).

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

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 \
  --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 covers it later โ€” see batch.md Phase 0).

Stall Budget โ€” 3-Rung Ladder#

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

Rung 1 โ€” Same-strategy retry (existing):
  Re-run the same fix at most a small bounded number of times
  (e.g. lint/format/build auto-fix as in Error Recovery below).

Rung 2 โ€” Lateral reframe (on repeated IDENTICAL failure):
  When the SAME failure repeats (judged SEMANTICALLY, not by string
  diff โ€” see note), escalate to /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.

Rung 3 โ€” BLOCKED + CONTINUE (๋ณด๋“œ ๋ฐ˜์˜ ํฌํ•จ):
  ํšก์  reframe ๋„ ์†Œ์ง„๋˜๊ณ  Story ๊ฐ€ ์—ฌ์ „ํžˆ ์•ˆ ํ’€๋ฆฌ๋ฉด BLOCKED( ' unstuck_exhausted ' )
  ํ‘œ์‹œ ํ›„ ๋ฐฐ์น˜๋ฅผ CONTINUE ํ•œ๋‹ค(Epic ์ „์ฒด ์ค‘๋‹จ ๊ธˆ์ง€). ๋™์‹œ์— ์ฐจ๋‹จ์„ ๋ณด๋“œ์— ๋ฐ˜์˜ํ•œ๋‹ค:
    - ์ฐจ๋‹จ ์˜์กด์ด ์žˆ์œผ๋ฉด createBlockage({blockedIssueId, blockingIssueId}) ๋กœ ๊ธฐ๋ก
    - ํ™œ์„ฑ ์ž‘์—…๊ณผ ๊ตฌ๋ถ„๋˜๋„๋ก holding ์ปฌ๋Ÿผ(Sprint Backlog)์œผ๋กœ ์ด๋™ โ€” In Progress ์— ๋ฐฉ์น˜ ๊ธˆ์ง€
    - blockedโ†’unblocked ๊ณ„์•ฝ์€ rules/zenhub-conventions.md  " Blocked Issue Contract "   ์ฐธ์กฐ
  (BLOCKED Story ๋Š” Phase 0 ๋ฉฑ๋“ฑ resume ์œผ๋กœ ๋‚˜์ค‘์— ์žฌ์‹œ๋„๋œ๋‹ค.)

Rung 2 โ€” Affinity Symptom Table#

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

Symptom (semantic)/dev:unstuck call
Same error repeated Nร—/dev:unstuck solo hacker
Flip-flop / oscillation between fixes/dev:unstuck solo architect
Missing fact / unverified info blocks progress /dev:unstuck solo researcher
Over-built / complexity-buried blocker/dev:unstuck solo simplifier
Unknown / premise itself suspect (default) /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.

/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, still bounded); if none unblocks the Story, proceed to 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 ๋ฅผ ์ง์ ‘ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์œผ๋กœ ํด๋ฐฑํ•œ๋‹ค(= /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
/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

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
  • Switch to next issue
  • @console-feature - Console feature patterns
  • @bloc - BLoC state management
  • @flutter-ui - UI component implementation
  • @test - Test writing