plot-approve
Plot: Approve Plan
Merge an approved plan and fan out into implementation branches. This workflow can be run manually (using git and forge CLI), by an AI agent interpreting this skill, or via a workflow script (once available).
Input: $ARGUMENTS is the <slug> of an existing idea.
Example: /plot-approve sse-backpressure
Setup
Add a ## Plot Config section to the adopting project's CLAUDE.md:
## Plot Config
- **Project board:** <your-project-name> (#<number>) <!-- optional, for `gh pr edit --add-project` -->
- **Branch prefixes:** idea/, feature/, bug/, docs/, infra/
- **Plan directory:** docs/plans/
- **Active index:** docs/plans/active/
- **Delivered index:** docs/plans/delivered/
Model Guidance
| Steps | Min. Tier | Notes |
|---|---|---|
| 1-2. Parse and PR State | Small | Git/gh commands, helper script, state checks |
| 2b. Suggest Tracer Bullet | Mid | Heuristic evaluation of plan design and branch structure |
| 3. Merge Plan PR | Small | Single gh command |
| 4. Read and Parse Plan | Small | Structured markdown parsing |
| 4b. Branch Conflicts | Mid | Cross-referencing multiple plan files |
| 5-8. Create Branches through Summary | Small | Git/gh commands, templates |
Nearly all steps are mechanical. Steps 2b and 4b require mid-tier reasoning — heuristic evaluation and cross-plan comparison respectively.
1. Parse Input
If $ARGUMENTS is empty or missing:
- List open plan PRs:
gh pr list --json number,title,headRefName --jq '.[] | select(.headRefName | startswith("idea/"))' - If exactly one exists, propose: "Found plan
<slug>. Approve it?" - If multiple exist, list them and ask which one to approve
- If none exist, explain: "No open plan PRs found. Create one first with
/plot-idea <slug>: <title>."
Extract slug from $ARGUMENTS (trimmed, lowercase, hyphens only).
Batch Mode
If the user asks to approve multiple plans at once ("approve all", or lists multiple slugs):
- Verify all plan PRs are non-draft or already merged
- Merge each plan PR sequentially (step 3)
- Create all implementation branches (steps 4-5)
- Print a combined summary
This works naturally — loop the single-plan flow for each slug. No special syntax needed.
2. Determine Plan PR State
Run the helper to get plan PR state:
../plot/scripts/plot-pr-state.sh <slug>
Handle each case:
- Plan PR is a draft: Error — "Plan is still a draft. Mark it ready for review first:
gh pr ready <number>" - Plan PR is open and non-draft (ready for review): Proceed to merge it (step 3)
- Plan PR is already merged: That's the approval signal — skip merge, proceed directly to creating impl branches (step 4)
- Plan PR is closed (not merged): Error — "Plan PR is closed. Reopen it or create a new one."
- No PR found: Error — "No PR found for branch
idea/<slug>. Run/plot-idea <slug>: <title>first."
2b. Suggest Tracer Bullet (optional)
Before merging, check if a tracer bullet might be valuable. This is a suggestion, never a hard gate.
Read the plan file and check for a ### Tracer subsection under ## Branches:
- If
### Tracerexists withStatus: Complete: proceed normally. Mention in summary: "Tracer bullet validated." - If
### Tracerexists but incomplete: warn: "This plan has an incomplete tracer bullet. Consider finishing it with thetracer-bulletsskill before approving. Proceed anyway?" - If no
### Tracersubsection: apply suggestion heuristics:- Strongly suggest when the
## Designsection describes unfamiliar technology, experimental approaches, or patterns without established docs/tutorials - Strongly suggest when the plan has 3+ branches AND they show a natural core-plus-extras decomposition
- If heuristic triggers: "Consider using the
tracer-bulletsskill to validate the architecture first. Add a### Tracersubsection to the plan, or proceed without one?" - If heuristic does not trigger: proceed silently
- Strongly suggest when the
Smaller models: Skip heuristic evaluation. Only check for an existing
### Tracersubsection. If present and incomplete, warn. Otherwise proceed silently.
3. Merge Plan PR (if open and non-draft)
gh pr merge <number> --merge --delete-branch
This lands the plan file on main and deletes the idea/<slug> branch.
Default to merge commits to preserve granular commit history (plan refinement steps are valuable context). If the project's CLAUDE.md specifies a different merge strategy, follow that instead.
4. Read and Parse Plan
Pull main to get the (just-merged or previously-merged) plan:
git checkout main
git pull origin main
Find the plan file: ls docs/plans/active/<slug>.md resolves to the date-prefixed file (e.g., docs/plans/YYYY-MM-DD-<slug>.md). Read it and parse the ## Branches section. If the plan has a Sprint: <name> field in its Status section, note the sprint membership for the summary. Expected format:
- `type/name` — description
Each line must have a backtick-quoted branch name (e.g. feature/sse-backpressure) and a description after the — dash.
Example — a valid Branches section:
## Branches
- `feature/sse-backpressure` — Handle client disconnects gracefully
- `bug/sse-memory-leak` — Fix connection pool leak on timeout
Parsing rules:
- Find the
## Branchessection - Check for subsections:
### Tracerand### Implementation- If
### Implementationexists, parse branches from that subsection only (skip### Tracer— tracer branches are managed by thetracer-bulletsskill) - If no subsections exist, parse branches directly from
## Branches(original behavior)
- If
- For each line starting with
- \``: extract the branch name between backticks, extract the description after— ` - Skip comment lines (
<!-- ... -->) and blank lines - If no branches are listed (or section is empty/only has the template comment), error: "No branches listed in the plan. Add branches to the
## Branchessection before approving." - Validate each branch name starts with a known prefix:
feature/,bug/,docs/,infra/
Note: if a pre-approval tracer was completed on the idea/<slug> branch, tracer commits merge to main with the plan PR. Mention in the summary: "Tracer code merged to main with the plan."
4b. Check for Branch Conflicts
Before creating branches, check if any branch name from the ## Branches section already exists in another Draft/Approved plan:
- Read all active plan files via
docs/plans/active/*.mdon main (excluding the current plan) - For each plan, parse its
## Branchessection for branch names - If any branch name in the current plan already appears in another plan, warn the user and ask to confirm before proceeding
Also check if any of the branches already exist as remote branches (git ls-remote --heads origin <branch-name>). If so, warn — the branch may be from a previous run of /plot-approve or from unrelated work.
Smaller models: Skip cross-plan branch conflict detection. Only check if the branch already exists on the remote (
git ls-remote --heads origin <branch>). Cross-plan overlap detection requires mid-tier reasoning.
5. Create Implementation Branches and PRs
Collect approval metadata once (reuse for all branches):
APPROVED_AT=$(date -u +%Y-%m-%dT%H:%M:%SZ)
APPROVED_BY=$(gh api user --jq '.login')
For each branch in the parsed list (use the APPROVED_AT and APPROVED_BY values collected above):
git checkout -b <type>/<name> origin/main
Update the plan file (date-prefixed) on the branch to reflect the approval:
- Change
**Phase:** Draft→**Phase:** Approved - Insert an
## Approvalsection immediately after the## Statusblock:
## Approval
- **Approved:** <APPROVED_AT>
- **Approved by:** <APPROVED_BY>
- **Assignee:** <APPROVED_BY>
This provides the initial commit needed for PR creation (no empty commits).
git add docs/plans/YYYY-MM-DD-<slug>.md
git commit -m "plot: approve <slug>"
git push -u origin <type>/<name>
gh pr create \
--draft \
--assignee @me \
--title "<description>" \
--body "$(cat <<'EOF'
## Plan
Part of [<slug>](../blob/main/docs/plans/YYYY-MM-DD-<slug>.md).
---
*Created with `/plot-approve`*
EOF
)"
(Replace YYYY-MM-DD with the actual date prefix from the plan filename.)
Read the ## Plot Config section from CLAUDE.md for the project board name. If configured:
gh pr edit <number> --add-project "<project board name>"
Collect all created PR numbers and URLs.
6. Check for Release Note Requirements
After creating implementation PRs, check for project-specific release note tooling:
- Changesets: Does
.changeset/config.jsonexist? If so, the project uses@changesets/cli. - Project rules: Read
CLAUDE.mdandAGENTS.mdfor release note instructions (e.g., custom scripts, specific commands). - Custom scripts: Check
package.jsonfor release-related scripts (e.g.,release,version,changelog).
If tooling is found, note the specific tool for the summary (step 8).
If no tooling is found, skip — the plan's ## Changelog section will be used during /plot-release.
7. Update Plan File on Main
After all branches are created, update the plan file on main (date-prefixed path) to reflect the approval and link the implementation PRs.
- Change
**Phase:** Draft→**Phase:** Approved - Insert an
## Approvalsection immediately after the## Statusblock (same content as step 5):
## Approval
- **Approved:** <APPROVED_AT>
- **Approved by:** <APPROVED_BY>
- **Assignee:** <APPROVED_BY>
- In the
## Branchessection, append→ #<number>to each branch line.
Before:
- `feature/sse-backpressure` — Handle disconnects
- `bug/sse-memory-leak` — Fix connection leak
After:
- `feature/sse-backpressure` — Handle disconnects → #12
- `bug/sse-memory-leak` — Fix connection leak → #13
- Update sprint file (if the plan has a
Sprint:field): find the[<slug>]item in the sprint file and add an annotation comment:
- [ ] [slug] description <!-- pr: #<number>, status: draft, branch: <type>/<name> -->
If the plan spawns multiple branches, annotate the item with the first (primary) PR.
git checkout main
git add docs/plans/YYYY-MM-DD-<slug>.md docs/sprints/
git commit -m "plot: link implementation PRs for <slug>"
git push
8. Summary
Print:
- Plan merged: PR # (or "already merged" if it was pre-merged)
- Implementation PRs created:
type/name→ PR # (URL)type/name→ PR # (URL)
- If release note tooling was found in step 6: "Remember to add release note entries on each implementation branch (e.g.,
pnpm exec changeset)." - If the plan has a Sprint field: "Part of sprint
<sprint-name>." - Progress:
[ ] Draft > [x] Approved > [ ] Delivered > [ ] Released - Suggested next actions:
- Check out a branch and start implementing:
git checkout <type>/<name> - When implementation is done:
/plot-deliver <slug>
- Alternative: work on multiple branches in parallel using worktrees
- Check out a branch and start implementing: