---
name: pstack-execute
preamble-tier: 3
version: 0.3.0
description: |
  Pick up a GitHub issue and implement it. On the first story for an Epic,
  freezes the drafty spec from the Epic body into docs/specs/<name>.md as
  part of the story's PR. Worktree defaults to Y for monorepos. Orchestrates
  TDD, systematic debugging, and pre-completion verification via superpowers;
  optional Codex second opinions for architectural choices.
  Use when asked to "execute issue", "/pstack-execute", "pick up issue",
  or "implement <issue#>".
triggers:
  - /pstack-execute
  - execute issue
  - pick up issue
  - implement issue
allowed-tools:
  - Bash
  - Read
  - Write
  - Edit
  - Glob
  - Grep
  - Skill
---

# pstack-execute

Implement work against a GitHub issue. Handles two issue shapes:

- **Epic-backed story** (from `/pstack-plan`): issue body contains
  `Parent Epic: #N`. On the first story for the Epic, the Epic body is
  frozen to `docs/specs/<name>.md` as part of the PR.
- **Single-issue work** (from `/pstack-issue` or a non-tech-user's Feature
  Request): no Parent Epic. Issue body is the spec; no freeze step.

## Skills orchestrated

| Skill | When |
|---|---|
| `superpowers:using-git-worktrees` | Step 2, when worktree mode is chosen |
| `superpowers:test-driven-development` | Step 4 default — write failing test first |
| `superpowers:systematic-debugging` | Step 4, when implementation hits unexpected behavior — Iron Law: root cause before fix |
| gstack `/investigate` | Step 4, when a non-trivial bug or regression surfaces — alternative entry point to systematic debugging with the Four Phases |
| gstack `/codex consult` | Step 4, when an architectural choice has multiple valid approaches and a second opinion is wanted |
| `superpowers:verification-before-completion` | Step 5 — evidence before "done" assertions |

## Args

`/pstack-execute <issue-number-or-url>`

## Steps

### 1. Load issue and detect shape

```bash
ISSUE_NUM=$1
ISSUE_JSON=$(gh issue view "$ISSUE_NUM" --json title,body,labels,url,number)
ISSUE_TITLE=$(echo "$ISSUE_JSON" | jq -r '.title')
ISSUE_BODY=$(echo "$ISSUE_JSON" | jq -r '.body')

# Detect parent Epic link (format: "Parent Epic: #N")
EPIC_NUM=$(echo "$ISSUE_BODY" | grep -oE 'Parent Epic: #[0-9]+' | grep -oE '[0-9]+' | head -1)

if [ -n "$EPIC_NUM" ]; then
  echo "Epic-backed story (parent Epic: #$EPIC_NUM)"
else
  echo "Single-issue work (no parent Epic)"
fi
```

### 2. Worktree prompt (monorepo-aware default)

Detect monorepo:

```bash
MONOREPO="no"
if [ -f turbo.json ] || [ -f pnpm-workspace.yaml ] || [ -f lerna.json ]; then
  MONOREPO="yes"
fi
```

Ask:

- **Monorepo** (`MONOREPO=yes`): "Create a fresh worktree for this issue? (Y/n)" — default Y. Builds/installs are expensive enough that worktrees earn their keep here.
- **Single-app** (`MONOREPO=no`): "Create a fresh worktree for this issue? (y/N)" — default N. Branch-switching is cheap enough that worktrees add friction without payoff.

If yes, invoke `superpowers:using-git-worktrees` — the skill handles the
worktree creation with safety checks (verifies the parent repo is clean,
picks a non-colliding path, sets upstream tracking). Pass the issue number
and a slugified title as inputs.

Fallback if the skill is unavailable:
```bash
SLUG=$(echo "$ISSUE_TITLE" | tr '[:upper:]' '[:lower:]' | tr -c 'a-z0-9-' '-' | tr -s '-' | sed 's/^-//;s/-$//' | cut -c1-40)
git worktree add ../worktrees/issue-$ISSUE_NUM -b issue-$ISSUE_NUM-$SLUG
cd ../worktrees/issue-$ISSUE_NUM
```

### 2.5. Freeze spec on first story (if Epic-backed)

Skip this step if `EPIC_NUM` is empty (single-issue work).

```bash
# Fetch the Epic body
EPIC_BODY=$(gh issue view "$EPIC_NUM" --json body --jq '.body')

# Extract the feature name from the spec frontmatter (name: field)
FEATURE_NAME=$(echo "$EPIC_BODY" | awk '/^---$/{f++;next} f==1 && /^name:/{print $2; exit}')

# Fallback: slugify the Epic title if no frontmatter name
if [ -z "$FEATURE_NAME" ]; then
  EPIC_TITLE=$(gh issue view "$EPIC_NUM" --json title --jq '.title')
  FEATURE_NAME=$(echo "$EPIC_TITLE" | tr '[:upper:]' '[:lower:]' | tr -c 'a-z0-9-' '-' | tr -s '-' | sed 's/^-//;s/-$//')
fi

SPEC_PATH="docs/specs/$FEATURE_NAME.md"

if [ ! -f "$SPEC_PATH" ]; then
  # First story for this Epic — freeze the spec
  mkdir -p docs/specs
  echo "$EPIC_BODY" > "$SPEC_PATH"
  echo "Frozen spec: $SPEC_PATH (from Epic #$EPIC_NUM)"
  git add "$SPEC_PATH"
  git commit -m "docs(spec): freeze $FEATURE_NAME spec from Epic #$EPIC_NUM

Captures the spec body as it existed at the start of implementation.
Future Epic body edits do not propagate here — this is the
permanent record of what was built against."
else
  echo "Spec already frozen at $SPEC_PATH — subsequent story for Epic #$EPIC_NUM"
fi
```

The spec freeze becomes the first commit on the story's branch. The PR
includes this commit alongside the implementation commits.

### 3. Pre-implementation context check

Load context in priority order:

1. **Spec:**
   - If `docs/specs/<feature-name>.md` exists (frozen): read it.
   - Else if `EPIC_NUM` is set: read the live Epic body via `gh issue view`.
   - Else: the issue body is the spec.
2. **Domain doc:** if the spec references a domain, read `docs/domains/<name>.md` (including `paths:` frontmatter for code locations and `depends_on:` / `consumers:` for interface boundaries).
3. **Vision context:** find the project's Vision Issue via `gh issue list --label vision --state open` (or `mcp__github__search_issues` with `label:vision is:open`). Fetch its body for strategic anchors (Narrowest wedge / Out of scope).
4. **Anti-patterns:** read `docs/anti-patterns.md` — search for keywords from the issue and spec.

Surface a short context summary to the user before editing code.

### 4. Implementation

**Default — TDD via `superpowers:test-driven-development`:**
1. Write failing test that captures the acceptance criterion
2. Run, verify red
3. Implement minimal code to pass
4. Run, verify green
5. Refactor if needed
6. Commit

**If implementation hits unexpected behavior** (test fails for a reason you don't understand, code does something you didn't expect, regression in unrelated tests):

- Invoke `superpowers:systematic-debugging` — Iron Law: root cause before fix. Four phases: investigate, analyze, hypothesize, implement.
- Alternative entry point: gstack `/investigate` — same discipline, slightly different framing. Either works; pick whichever the user is more familiar with.

**Do not** patch around an unexpected failure without understanding why. Bypass-style fixes regress.

**If an architectural choice has multiple valid approaches** (e.g., "should this be a hook, a context, or a prop drill?") and you're genuinely uncertain:

- Optional: invoke gstack `/codex consult` for an independent second opinion. Codex sees only the code and your question, so it can spot tradeoffs without our session's framing bias.
- Use sparingly — most choices are clear from the spec + domain doc.

**For `--type=docs` issues (lighter mode):**
1. Make the doc edit
2. Run link/spell check
3. Commit

### 5. Self-review

Before opening a PR, invoke `superpowers:verification-before-completion`.
**Iron Law: no completion claims without fresh verification evidence.**

Run and confirm output for each of:
- All acceptance criteria checked off (read the spec, tick the boxes)
- Tests pass: `pnpm test` (or project equivalent) — paste fresh output
- Type check: `pnpm typecheck` — paste fresh output
- Lint: `pnpm lint` — paste fresh output

If any check fails, fix and re-verify. **Stale output from earlier in the
session is not acceptable** — code changed since then.

### 6. Hand off to pstack-pr

When implementation is done, suggest: "Ready to open PR? Run `/pstack-pr`."

If this PR includes the spec-freeze commit (first story for an Epic), call
that out so the reviewer knows what they're looking at: "PR includes the
frozen spec at `docs/specs/<name>.md` — first story for Epic #N."

## GitNexus integration

In Step 3 (pre-implementation context check), if GitNexus is running, query
callers for the files referenced in the issue's "Files likely to touch":

```bash
if GITNEXUS=$(${CLAUDE_SKILL_DIR}/../../scripts/gitnexus-check.sh); then
  for file in <files-from-issue>; do
    ${CLAUDE_SKILL_DIR}/../../scripts/gitnexus-query.sh callers "$file" 2>/dev/null || true
  done
fi
```

Surface the results to the developer before editing. If a file has >10
inbound callers, flag it as "high blast radius — read the spec carefully
and consider whether this change should be split."

If GitNexus is unreachable, fall back to `grep -r "<symbol>" <project>/`
for the most-relevant exports.

## Do not

- Do not auto-merge.
- Do not commit speculative changes outside the issue's scope. If you discover
  related issues, file them with `pstack-issue` and continue.
- Do not modify the Epic body to match `docs/specs/<name>.md` after freeze.
  They're allowed to diverge; the spec snapshot captures intent at
  implementation time. Refinements happen in the Epic body and land in
  future stories' freezes (or never — the snapshot is the source of truth
  for what was built).
- Do not skip `superpowers:verification-before-completion` in Step 5. Claiming
  work is complete without evidence is dishonesty, not efficiency.
- Do not patch around unexpected failures without root cause analysis
  (`superpowers:systematic-debugging` or gstack `/investigate`).
