본문으로 건너뛰기
cccskills
무료GitHub에 공개

stack-mode

Detects shared stack membership and iterates a command across all PRs in base-to-tip order. Use when a command supports --stack flag for multi-PR iteration.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

연동 도구GitHubGitLab
설치 방법 보기

포함된 파일(1)

  • SKILL.md10.1 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

Stack Mode

Shared contract for commands that need to operate across a whole stack of dependent PRs in one invocation. Used by /pr-review --stack and /fix-pr --stack.

The goal is one simple thing: when a PR is part of a stack targeting a common base branch, loop the command's normal workflow across every PR in the stack in base-to-tip order and emit one consolidated summary on the stack root.

When To Use

Load this skill when a command accepts a --stack flag (or auto-detects stack membership) and needs to iterate its normal workflow across multiple PRs.

Do NOT load this skill for single-PR workflows. The per-PR workflow stays unchanged; stack mode wraps it.

When NOT To Use

  • Creating the stack (use sanctum:stack-create)
  • Cascading a rebase through it (use sanctum:stack-rebase)

Contract

A calling command MUST:

  1. Accept a --stack boolean flag AND a --base <branch> override (default: master).
  2. Call Step 1 below to resolve stack membership BEFORE running its main workflow.
  3. Run its main workflow per PR in the resolved order.
  4. Emit per-PR outputs unchanged (thread replies, issue links, etc.).
  5. Emit ONE stack-level summary comment on the root PR using the format in Step 4.
  6. Respect per-PR Gate rules (every PR still needs its own thread resolution and issue tracking).

A calling command MAY:

  • Auto-detect stack membership and prompt the user rather than requiring --stack explicitly.
  • Short-circuit iteration when a per-PR failure leaves downstream PRs with stale context.

Required Progress Tracking

The caller creates TodoWrite items:

  1. stack-mode:membership-resolved
  2. stack-mode:iteration-complete
  3. stack-mode:root-summary-posted

Step 1: Resolve Stack Membership (membership-resolved)

Given a starting PR number $PR_NUM and optional base $BASE (default: master), try three strategies in order and stop at the first that yields a stack of size

= 2.

Strategy A: Branch-name convention (cheapest)

START_HEAD=$(gh pr view "$PR_NUM" \
  --json headRefName -q .headRefName)

# stack/<feature-name>/<slice-name>
if [[ "$START_HEAD" =~ ^stack/([^/]+)/.+$ ]]; then
  FEATURE="${BASH_REMATCH[1]}"
  PREFIX="stack/${FEATURE}/"

  # All local branches with the same prefix
  STACK_BRANCHES=$(git branch --list "${PREFIX}*" \
    | sed 's/^[* ]*//' | sort)

  # Map branches -> PR numbers (skip branches with no PR)
  STACK_PRS=()
  for branch in $STACK_BRANCHES; do
    pr=$(gh pr list --head "$branch" \
      --json number --jq '.[0].number')
    [ -n "$pr" ] && STACK_PRS+=("$pr")
  done

  echo "strategy=A prs=${STACK_PRS[*]}"
fi

Strategy B: Stack summary comment (most reliable)

stack-push posts a ## Stack markdown table on the root PR with columns # | Branch | PR. Parse it:

# Find the root PR of the stack containing $PR_NUM
# The current PR may be the root, or may link to it via
# a "Part of stack `stack/<feature>`" phrase in its body
BODY=$(gh pr view "$PR_NUM" --json body -q .body)

# Look for a "## Stack" table in THIS PR's comments
TABLE=$(gh pr view "$PR_NUM" --json comments \
  --jq '.comments[] | select(.body | contains("## Stack"))
        | .body' | head -1)

# If not on this PR, look for the root PR reference
if [ -z "$TABLE" ]; then
  ROOT_REF=$(echo "$BODY" \
    | grep -oE 'stack/[^ `]+' | head -1)
  # ... resolve ROOT_REF -> root PR number and re-fetch
fi

# Parse the table: extract all `#<num>` from the PR column
STACK_PRS=($(echo "$TABLE" \
  | grep -oE '#[0-9]+' | tr -d '#' | sort -un))

echo "strategy=B prs=${STACK_PRS[*]}"

Strategy C: Base-chain walk (fallback)

Walk both directions from $PR_NUM:

  • Up: repeatedly resolve baseRefName until it equals $BASE. Each visited head is a stack member.
  • Down: find open PRs whose baseRefName equals one of the visited heads. Recurse.
# Ascend from $PR_NUM to the root
CUR=$PR_NUM
CHAIN=($CUR)
while true; do
  BASE_REF=$(gh pr view "$CUR" \
    --json baseRefName -q .baseRefName)
  [ "$BASE_REF" = "$BASE" ] && break

  PARENT=$(gh pr list --head "$BASE_REF" \
    --state open --json number --jq '.[0].number')
  [ -z "$PARENT" ] && break

  CHAIN=("$PARENT" "${CHAIN[@]}")
  CUR=$PARENT
done

# Descend from the root collecting children
ROOT=${CHAIN[0]}
FRONTIER=("$ROOT")
while [ ${#FRONTIER[@]} -gt 0 ]; do
  PARENT=${FRONTIER[0]}
  FRONTIER=("${FRONTIER[@]:1}")

  PARENT_HEAD=$(gh pr view "$PARENT" \
    --json headRefName -q .headRefName)

  CHILDREN=($(gh pr list --base "$PARENT_HEAD" \
    --state open --json number --jq '.[].number'))

  for c in "${CHILDREN[@]}"; do
    CHAIN+=("$c")
    FRONTIER+=("$c")
  done
done

STACK_PRS=("${CHAIN[@]}")
echo "strategy=C prs=${STACK_PRS[*]}"

Ordering

Regardless of strategy, order the final list base-to-tip (root PR first, leaf PR last). The root is the PR whose baseRefName equals $BASE.

ROOT_PR=""
for p in "${STACK_PRS[@]}"; do
  base=$(gh pr view "$p" --json baseRefName -q .baseRefName)
  if [ "$base" = "$BASE" ]; then
    ROOT_PR=$p
    break
  fi
done

If the stack size is 1, the command MUST fall back to single-PR mode and emit a warning: stack-mode: only one PR found; --stack has no effect, proceeding as single-PR.

GitLab / Bitbucket

See Skill(leyline:git-platform) for glab / Bitbucket equivalents of the gh calls above. The three strategies translate directly: GitLab MR dependencies replace base-chain walks, and the glab mr view --output json shape matches gh pr view.

Step 2: Confirm With User (if not explicit)

When the caller did NOT pass --stack but Step 1 resolved a stack of size >= 2, print the stack and ask:

Detected stack of N PRs rooted at #<root>:
  1. #<root>   <title>
  2. #<p2>     <title>
  ...

Run the workflow on the full stack? [y/N]

Default to "N" (single-PR mode). With --stack explicit, skip this prompt.

Step 3: Iterate (iteration-complete)

Run the caller's main workflow once per PR in base-to-tip order:

FAILED_PRS=()
for p in "${STACK_PRS[@]}"; do
  echo "=== stack-mode: PR #$p ($(($idx+1))/${#STACK_PRS[@]}) ==="

  # Caller hook: run the single-PR workflow on $p
  # This includes Gate 1 (thread resolution) and
  # Gate 2 (issue tracking) per the caller's contract.
  if ! run_single_pr_workflow "$p"; then
    FAILED_PRS+=("$p")
    # Stop iteration: downstream PRs may now be stale
    break
  fi
done

If any PR fails, the command MUST stop and report stack-mode: halted at #<pr>; downstream PRs untouched. Downstream PRs are intentionally left alone because their context may have shifted.

Step 4: Post Stack Summary on Root (root-summary-posted)

After successful iteration, post ONE consolidated summary comment on the root PR. This does NOT replace per-PR summaries: it links them together.

## Stack <Command Name> Summary

**Stack**: N PRs rooted at #<root>, base `<base-branch>`
**Command**: <command> (e.g., /fix-pr, /pr-review)
**Run**: <timestamp>

| # | PR | Branch | Status | Per-PR Summary |
|---|----|--------|--------|----------------|
| 1 | #<root> | `stack/<feat>/<root-slice>` | <done/skipped/failed> | [link to comment] |
| 2 | #<p2>   | `stack/<feat>/<slice-2>`    | <done/skipped/failed> | [link to comment] |
| ... | ... | ... | ... | ... |

### Cross-PR Notes

- <Any observations that spanned multiple PRs>
- <Issues created that reference multiple stack PRs>
- <Base-PR-merged cascade reminders, if any>

### Next Steps

- If root PR merges, run `Skill(sanctum:stack-rebase)` to
  cascade the base update through descendants.
- Reviewers: rebase-triggered stale-review flags on
  descendants are expected after any force-push.

Post via gh pr comment "$ROOT_PR" --body-file <file>.

Failure Modes and Recovery

FailureDetectionRecovery
Stack of size 1Step 1 returns one PREmit warning, fall back to single-PR mode
Base chain loopsVisited set on ascentHalt, report stack-mode: cycle detected
Mid-stack PR failed its GatesCaller raisesHalt iteration, leave downstream untouched
Strategy B table malformedParse failsFall through to Strategy C
Auth scope insufficientgh returns 403Halt with clear error; caller surfaces to user

Notes

  • Stack mode is ADDITIVE: single-PR behavior is unchanged. Only the iteration and root summary are new.
  • Per-PR Gate 1 (thread resolution) and Gate 2 (issue tracking) remain unchanged: each PR still passes its own gates independently.
  • Never merge Gate 1 across the stack. A resolved thread on one PR is not a resolved thread on another.
  • The root summary is idempotent: re-running stack mode should update (not duplicate) the summary comment. Match on ## Stack <Command Name> Summary as the key.
  • stack-mode is a read/orchestration skill; it does NOT push, rebase, or edit branches. Those concerns are in stack-create, stack-push, and stack-rebase.

Exit Criteria

  • Stack membership resolved using at least one of the three strategies (A: branch names, B: stack comment, C: base-chain walk) and PRs ordered base-to-tip before iteration starts
  • The 3 required TodoWrite items (stack-mode:membership-resolved, stack-mode:iteration-complete, stack-mode:root-summary-posted) are created and marked complete in sequence
  • Root PR receives exactly one consolidated ## Stack <Command> Summary comment after all PRs are processed
  • If stack size is 1, warning stack-mode: only one PR found; --stack has no effect is emitted and single-PR mode used
  • If a PR fails its gates, iteration halts and downstream PRs are left untouched with a stack-mode: halted at #<pr> report

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

Shapes turns action-first: action leads, steps numbered, state restated. Use for ADHD-friendly output. Do not use to trim tokens; use response-compression.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

athola/claude-night-market3422026년 10월 17일 업데이트

Inverts burden of proof for code additions. Use when reviewing PRs, planning refactors, or running unbloat to challenge every addition's necessity.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

athola/claude-night-market3422026년 10월 17일 업데이트

Tracks per-agent token usage and flags waste in parallel dispatch. Use when evaluating parallel agent efficiency or after a multi-agent run.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

athola/claude-night-market3422026년 10월 17일 업데이트

Coordinates Claude agent teams via filesystem protocol. Use when orchestrating parallel agents with task dependencies. Do not use for single-agent tasks.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

athola/claude-night-market3422026년 10월 17일 업데이트

Evaluates API surface design, consistency, and exemplar alignment. Use when reviewing public API changes or before releasing a new API surface.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

athola/claude-night-market3422026년 10월 17일 업데이트

Selects architecture paradigm via research before scaffolding. Use when architecture is undecided and the choice needs justification and documentation.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

athola/claude-night-market3422026년 10월 17일 업데이트

athola의 스킬 모두 보기

이 스킬의 문제 신고