SuperAPI AI Directory

wtf.create-pr

Coding & development

View repository

Updated 10-16 02:14

About this skill

Create PR

Open a pull request for a completed trace branch.

This skill reads the full spec hierarchy (Trace + Feature + Epic) and the branch diff. It writes a PR description that explains why the change exists, not only what it does.

Process

0. GitHub CLI setup

Run steps 1–2 of ../references/gh-setup.md (install check and auth check). Stop if gh is not installed or not authenticated. Extensions are not required for this skill.

Skip this step if invoked from wtf.verify-trace or another skill that already ran gh-setup this session.

1. Confirm the branch

Check the current branch. Verify it is not main:

git branch --show-current

If on main, call AskUserQuestion (per ../references/questioning-style.md):

  • question: "Which branch should I open a PR from?"
  • header: "Branch"
  • options: from git branch --list (local branches)

Check whether a PR already exists for this branch:

gh pr list --head <branch_name> --state open

If an open PR already exists, print its URL and call AskUserQuestion (per ../references/questioning-style.md):

  • question: "A PR already exists for this branch. Would you like me to update its description instead?"
  • header: "Existing PR"
  • options:
    • Update description → skip to step 5, targeting the existing PR for update via gh pr edit <pr_number>
    • Open a new one → create a new PR anyway

2. Identify the Trace (if any)

Try to extract a trace number from the branch name (e.g. trace/42-date-range-filter → #42). A legacy task/42-<slug> branch also matches — treat that issue as a legacy Trace per ../references/issue-classification.md.

If found, call AskUserQuestion (per ../references/questioning-style.md):

  • question: "I found Trace # linked to this branch. Is that the right trace?"
  • header: "Linked trace"
  • options:
    • Yes, that's correct → use Trace #
    • No, use a different trace → I'll provide the correct issue number

If not found or the user says no, call AskUserQuestion (per ../references/questioning-style.md):

  • question: "Is there a Trace issue linked to this work?"
  • header: "Linked trace"
  • options:
    • No linked trace → proceed without a trace link
    • Yes — I'll provide the number → enter the trace issue number

3. Lifecycle check (if Trace linked)

If no Trace is linked, skip this step.

Apply the absent-label gate from ../references/lifecycle-labels.md for the verified label on the Trace — recommended skill wtf.verify-trace, header Verify first?. On Verify first → follow wtf.verify-trace passing the Trace number as context. On Open PR anyway → proceed.

4. Fetch the spec hierarchy

If a Trace issue is known, walk Trace → Feature → Epic per ../references/spec-hierarchy.md. Extract the story, the Scenario Claim, the Spine position, the Technical Approach, and the DoD from the Trace. Extract ACs, the Trace Plan, any delivery override, and constraints from the Feature. Extract the Goal from the Epic. For a legacy Task, extract the old sections instead (Functional Description, Gherkin, Contracts, DoD, Test Mapping).

Resolve the delivery mode per ../references/branch-setup.md ("Resolve the delivery mode") — the Feature's override wins.

If no Trace issue, skip hierarchy fetch. The PR will be written from diff context alone (step 5).

5. Inspect the diff

Determine the base branch per the Base-branch policy in ../references/branch-setup.md, resolved with its "Resolve the stack base" procedure (same as step 8). Then collect the branch diff against that base:

git log <base_branch>..HEAD --oneline
git diff <base_branch>...HEAD --stat

This avoids unrelated merged commits when the branch has a long history against main. Use --stat output only unless a specific commit message is ambiguous and cannot be resolved without the diff.

6. Draft the PR

Apply strict STE per ../references/ste-writing.md before writing any durable body.

Title generation: Spawn a subagent using the claude-haiku-4-5-20251001 model — apply ../references/subagent-protocol.md for the spawn — to generate a PR title per ../references/commit-conventions.md. Pass in the trace title (if available), the commit log, and whether this is a breaking change. If the subagent returns nothing usable, generate the title directly following the same rules. Examples: feat(search): add date range filter, fix(payments): prevent double settlement, refactor(orders): extract fulfilment service.

Body: Load the PR template per ../references/issue-template-loading.md (verify .github/pull_request_template.md exists, halt-or-setup if missing). Complete all sections:

  • Summary: derived from the Trace's story and its Spine position — what this pass adds to the Spine (Skeleton | Extension | Deepening, and which Traces it builds on). Explain the why. If no Trace, derive from commit messages.
  • Changes: grouped logical summary of git diff --stat output — not a file list.
  • Test plan: if a Trace exists, one checklist item per claimed scenario name from the Scenario Claim. If no Trace, derive from changed files and commit messages. At minimum one item per observable behavior changed.
  • Related: closure keywords per ../references/commit-conventions.md, one per line. If a Trace exists, include Closes #<trace_number>. In trunk delivery, when this Trace exhausts the Feature's Trace Plan, add Closes #<feature_number> on its own line. For a feature-branch PR (staged), include Closes #<feature_number> plus one Closes #<trace_number> line per completed Trace.

7. Review with user

Show the draft title and body. Then call AskUserQuestion (per ../references/questioning-style.md):

  • question: "Does this look right?"
  • header: "Review"
  • options:
    • Looks good — create the PR → proceed with PR creation
    • I have changes → adjust first

Apply edits, then proceed.

8. Create the PR

Determine the base branch from the current branch name and the delivery mode, per the Base-branch policy table in ../references/branch-setup.md. The base is the stack base the branch was cut from. Resolve it with the ## Resolve the stack base procedure in ../references/branch-setup.md — read Builds on from the Trace body, look up trace/<n>-* on origin, fall back to the feature branch (staged) or main (trunk). Never derive it from git upstream: before the first push the branch has none, and after git push -u the upstream is the branch itself.

  • trace/* branch stacked on a still-open Trace → target that trace/* branch
  • trace/* branch whose base Trace already merged (its branch is gone), staged delivery → target the parent feature branch (feature/<feature-number>-<feature-slug>)
  • trace/* branch whose base Trace already merged, trunk delivery → target main
  • Skeleton trace/* branch → the feature branch (staged) or main (trunk)
  • feature/* branch → target main
  • hotfix/* branch → target main
  • task/* branch (legacy) → target the parent feature branch
  • Other → call AskUserQuestion (per ../references/questioning-style.md):
    • question: "What branch should this PR target?"
    • header: "Base branch"
    • options: from git branch -r

Never target a branch this one did not fork from — the diff would carry the intervening Trace's commits. When the base is another trace/* branch and no native stack is used (see below), say so in the PR body: this is a stacked PR, it merges after its base, and GitHub retargets it automatically when the base merges with its head branch deleted.

Write the body to a temp file ($BODY) with the Write tool. Then create the PR via the gh body helper (../references/gh-body-helper.md) so the description survives UTF-8 on Windows:

# $BODY is the temp file you wrote the PR body to with the Write tool.

# stacked trace branch — base is the Trace it builds on:
python3 .wtf/gh-body.py create --pr \
  --title "<title>" \
  --body-file "$BODY" \
  --base trace/<base-trace-number>-<base-trace-slug>

# trace branch whose base Trace merged, or a Skeleton — staged delivery:
python3 .wtf/gh-body.py create --pr \
  --title "<title>" \
  --body-file "$BODY" \
  --base feature/<feature-number>-<feature-slug>

# trace branch — trunk delivery, or feature branch:
python3 .wtf/gh-body.py create --pr \
  --title "<title>" \
  --body-file "$BODY" \
  --base main

Print the PR URL.

Native stack (optional). If gh extension list shows gh-stack and the base is a trace/* branch, link the Feature's open Trace PRs into one native stack per ../references/branch-setup.md "Native stacks": gh stack unstack <stack-number> when one exists, then gh stack link <bottom-pr> ... <this-pr> bottom to top. GitHub then renders the stack on every PR, so do not add the "stacked PR" note to the body.

9. Update the Trace issue (if linked)

If a Trace issue is linked, post a comment linking the PR:

# Write "PR opened: <pr_url>" to a temp file with the Write tool ($COMMENT), then:
python3 .wtf/gh-body.py comment <trace_number> --body-file "$COMMENT"

10. Offer next steps

Call AskUserQuestion (per ../references/questioning-style.md):

  • question: "What's next?"
  • header: "Next step"
  • options:
    • Request a review → add reviewers to this PR now (default)
    • Done → exit, no further action

On Request a review → call AskUserQuestion (per ../references/questioning-style.md):

  • question: "Who should review this?"
  • header: "Reviewer"
  • options: from team member usernames inferred from recent git log authors or the repository's CODEOWNERS file

Then:

gh pr edit <pr_number> --add-reviewer <username>

For multiple reviewers, pass a comma-separated list: --add-reviewer user1,user2. Print the PR URL.

  • Done → exit.