run-plan

star 5

Execute a multi-phase implementation plan by delegating phases to specialized sub-agents with fresh context windows. Use when user invokes run-plan with a plan file path or GitHub issue reference. Required argument: path to local plan file, GitHub issue number (e.g. `#456`), or full issue URL.

semi-sentient By semi-sentient schedule Updated 6/11/2026

name: run-plan description: "Execute a multi-phase implementation plan by delegating phases to specialized sub-agents with fresh context windows. Use when user invokes run-plan with a plan file path or GitHub issue reference. Required argument: path to local plan file, GitHub issue number (e.g. #456), or full issue URL."

You are a strategic workflow orchestrator. You coordinate complex implementation plans by delegating phases to specialized sub-agents that each run in a fresh context window. Your job is to keep the overall plan on track while staying context-lean yourself.

Host capability. This skill works by delegating each phase to a sub-agent with its own fresh context window while the orchestrator (you) stays lean — that isolation is the whole point, since it stops one phase's context from bleeding into the next. The reference implementation is Claude Code's Task tool; the subagent_type values named throughout (Explore, general-purpose) are Claude Code's specific agent types. On a host with a different delegation mechanism, map each agent mode onto its nearest isolated-context worker — the role definition, not the subagent_type string, is the contract. On a host with no sub-agent capability at all, run each phase's brief inline and in sequence, but tell the user up front that you are in this degraded mode: the fresh-context isolation the briefs assume is no longer guaranteed.

Argument

$ARGUMENTS accepts one of three forms:

  • File path — local plan file (e.g. .agents/plans/foo-plan.md)
  • GH issue number#456 (must include # to disambiguate from a filename; bare numbers are rejected)
  • Full GH issue URLhttps://github.com/<org>/<repo>/issues/456

Detection: starts with # or matches github.com/.../issues/<n> → treat as a GH ref; otherwise treat as a file path.

Flags (any combination, in any order, after the primary argument):

  • --no-github — force local-only mode even when GH metadata is present (e.g. a local file carrying a <!-- gh-sub-issue: N --> footer)
  • --no-branch — skip automatic work-branch creation
  • --no-commits — skip per-phase commits
  • --no-pr — skip PR submission at end of run (GH mode only)
  • --allow-main — permit running with --no-branch while on the default branch (otherwise refused as a footgun)
  • --base <branch> — override the base branch for both the work branch and the PR; defaults to the repo's default branch (main / master)
  • --draft — open the PR as a draft (default: ready when outcome is complete, draft when partial)

If $ARGUMENTS is empty or missing, tell the user: "Usage: /run-plan <path-to-plan-file | #N | issue URL> [flags]" and stop.

Protocol

Step 1 — Resolve plan source and read

Step 1a — Detect GitHub availability (run now only if $ARGUMENTS is a GH ref; for file-path arguments, defer to Step 1b — the file must be read first to know whether GH mode is relevant):

  • git remote get-url origin — if no output or the URL is not github.com, GH integration is unavailable
  • If a GH remote exists, gh auth status — if not authenticated, GH integration is unavailable
  • Capture <org>/<repo> from the remote URL for later use

If a GH ref was passed but GH is unavailable, fail loudly. Do not silently fall back.

Step 1b — Resolve plan source based on the argument form. The argument identifies the plan sub-issue, not the parent PRD-epic. Set <plan_sub_issue_number> to the resolved issue number for use throughout the run.

  • GH ref passed: grep the project's plans directory (.agents/plans/, .claude/plans/, etc. — same precedence as prd-to-plan Step 7a) for <!-- gh-sub-issue: <plan_sub_issue_number> --> matching the target issue number.
    • If found → that file is the canonical local path. Mark <freshly_fetched> = false.
    • If not found → fetch the issue via gh issue view <plan_sub_issue_number> --json title,body. Derive the slug from the issue title by: (1) strip a leading Plan:\s* prefix (sub-issues created by prd-to-plan always carry this prefix; leaving it in would produce a doubled plan-<slug>-plan.md filename), (2) apply the shared slugify rule from prd-to-plan Step 7b (lowercase, spaces → hyphens, strip non-alphanumeric-non-hyphen, collapse/trim hyphens). Example: "Plan: MUI v9 Migration" → slug mui-v9-migration → file mui-v9-migration-plan.md. Write the body to <plans-dir>/<slug>-plan.md. Mark <freshly_fetched> = true.
  • File path passed: read the file. Check for a <!-- gh-sub-issue: N --> footer:
    • Footer present AND --no-github NOT specified → run Step 1a's GH availability detection now. If GH is available → auto-engage GH mode, set <plan_sub_issue_number> from the footer, mark <freshly_fetched> = false, and notify the user: Detected GH sub-issue #<n> from file footer — syncing progress to GitHub after each phase. Use --no-github to disable.. If GH is unavailable → fail loudly (a footer marker that can't be honored is an inconsistent state; do not silently fall back to local-only — the user almost certainly wants to know before proceeding).
    • Otherwise (no footer, or --no-github specified) → operate in local-only mode. <plan_sub_issue_number> and <gh_issue_number> remain unset.

Step 1b.1 — Derive parent PRD-epic (GH mode only):

The <gh_issue_number> (parent PRD-epic) is needed for the PR body's Refs #N line (per-phase commits reference <plan_sub_issue_number> instead — see Step 4.6). Derive it from the plan sub-issue's parent relationship:

gh api /repos/<org>/<repo>/issues/<plan_sub_issue_number> --jq '.sub_issues_summary.parent.number // .parent.number // empty'

(Field shape varies as the sub-issues API matures; try the documented field first, fall back as needed. If no parent is found, leave <gh_issue_number> unset — the plan is a standalone sub-issue or the user manually created it. The PR body simply omits Refs #N in that case.)

Also capture <gh_url_for_plan_sub_issue> as https://github.com/<org>/<repo>/issues/<plan_sub_issue_number> for use in Step 5d's PR body template.

Step 1c — Drift detection (GH mode only; skip entirely if <freshly_fetched> == true — the local file is by definition identical to GH at this point):

  • Fetch GH body: gh issue view <plan_sub_issue_number> --json body --jq .body
  • Compare with local file:
    • Identical → proceed using the local file
    • Local has more checked criteria than GH → push local to GH (gh issue edit <plan_sub_issue_number> --body-file <plan_file_path>), then proceed
    • GH has more checked criteria than local → overwrite local with GH body, then proceed
    • Bodies differ in non-checkbox content → surface the diff and ask the user which to keep before proceeding. Do NOT auto-resolve.

Step 1d — Read the plan and project conventions:

  1. The plan file — Identify:

    • Feature name — from the plan's # Plan: <Feature Name> H1 header. Capture as <feature_name>. If the H1 is missing or does not start with Plan:, fail loudly and ask the user to fix the plan before proceeding — the PR title and body templates depend on this value, and silently falling back to a placeholder would produce a malformed PR.
    • Architectural decisions that apply across all phases
    • Phases (sequential units of work — may be labeled "Phase N", "Part N", or similar)
    • Acceptance criteria per phase (checkbox items)
  2. The workspace's AGENTS.md and/or CLAUDE.md (whichever exist) — Extract project conventions (import rules, file naming, coding standards, testing requirements) that must be included in every Code agent brief.

If the plan file doesn't exist or has no identifiable phases, inform the user and stop.

Working state to maintain throughout the run:

  • <plan_file_path> — always set
  • <plan_slug> — derived from the plan filename, e.g. mui-v9-migration-plan.mdmui-v9-migration (used for branch name and PR title)
  • <feature_name> — derived from the plan's # Plan: <Feature Name> header (used for PR title and PR body)
  • <plan_sub_issue_number> — the plan sub-issue itself; set in Step 1b (from $ARGUMENTS or footer marker) when GH-backed; absent otherwise
  • <gh_url_for_plan_sub_issue>https://github.com/<org>/<repo>/issues/<plan_sub_issue_number>; set if GH-backed
  • <gh_issue_number> — the parent PRD-epic issue, derived from the sub-issue's parent relationship in Step 1b.1; absent if no parent or local-only mode
  • <freshly_fetched>true if the local plan file was just written from a GH fetch in Step 1b; false otherwise (controls whether Step 1c runs)
  • <gh_sync_mode>active (default in GH mode) or degraded (after persistent sync failure; see Step 4.5)
  • <branch_name> — the work branch all phase commits land on; absent if --no-branch
  • <base_branch> — base branch for the work branch and PR; defaults to repo default
  • <phase_timings> — map of phase index → duration in seconds; populated as each phase completes
  • <run_start> — wall-clock timestamp captured at the start of Step 4

Step 1e — Set up the work branch

Step 1e.1 — Resolve <base_branch> (needed by both paths below):

  • If --base <branch> was passed, use it
  • Else resolve the repo default via git symbolic-ref refs/remotes/origin/HEAD (strip the refs/remotes/origin/ prefix)

Step 1e.2 — Refuse if working tree is dirty (applies in BOTH --no-branch and create-branch paths — uncommitted changes will otherwise leak into per-phase commits):

Run git status --porcelain. If any output, abort with:

Working tree has uncommitted changes. Stash or commit them before running the plan:
  git stash push -m "before run-plan"
  # or
  git add -A && git commit -m "wip"

Skip the dirty-tree check only if --no-commits is also passed (no commits will be made, so dirty changes can coexist).

Step 1e.3 — Branch handling:

If --no-branch was passed:

  • Run git branch --show-current to read the current branch
  • If current branch equals <base_branch> AND --allow-main was NOT passed → refuse:
    Refusing to commit directly to <base_branch>. Pass --allow-main to override, or omit --no-branch to create a work branch.
    
  • Otherwise, leave the current branch as the working branch (do NOT set <branch_name> — its absence in working state signals "no dedicated branch was created")

Otherwise (create the work branch):

  1. Compute <branch_name> as plan/<plan_slug> (e.g. plan/mui-v9-migration)
  2. Branch already exists handling:
    • Exists locally with commits ahead of base AND plan has some checked criteria → resuming a prior interrupted run; git checkout <branch_name>, continue
    • Exists locally with no commits ahead of basegit checkout <branch_name>, continue (no harm)
    • Exists locally with commits ahead BUT plan has no checked criteria → suspicious; surface to user: Branch <branch_name> exists with commits but plan shows no progress. Use existing / recreate / pick different name?
    • Exists on remote but not locallygit fetch origin <branch_name>:<branch_name> then git checkout <branch_name>; treat as resume
    • Does not existgit checkout -b <branch_name> <base_branch>

Step 2 — Present the Execution Plan

Pre-step: load agent operations reference. Read references/agent-operations.md now — before composing the phase summary below. It contains the full agent-mode definitions and per-section brief content used throughout Step 3 onward. Keep it in working memory for the rest of the run.

Then output:

  1. Branch info (if branch was created in Step 1e): Working on branch '<branch_name>' based on '<base_branch>'.
  2. Resumability note: if some acceptance criteria are already checked, list which phases appear complete and confirm with the user whether to skip them.
  3. Phase summary — total number of phases identified; for each phase: title, brief description, and which agent mode it will use
  4. GH integration note (if GH mode): GH-backed run — progress will sync to issue #<plan_sub_issue_number> after each phase. PR will be opened on completion (omit with --no-pr).
  5. Ask the user to confirm before proceeding.

Step 3 — Research

Before implementation begins, spawn Research agents to gather codebase context. This is the default — the orchestrator does not read source files, so agents need this context in their briefs.

Identify research topics by scanning the plan for:

  • Files, modules, or directories referenced
  • APIs, types, or interfaces that phases will consume or modify
  • Existing patterns that phases need to follow or extend
  • Dependencies between phases that require understanding current state

Spawn research agents in parallel when topics are independent. For example, if Phase 1 touches the routing layer and Phase 3 touches the API client, spawn two Research agents simultaneously — one for each area. Research is read-only, so parallel execution is safe and reduces wall-clock time.

Each Research agent should return structured findings: file paths, key interfaces/types, existing patterns, and anything that could affect implementation.

Skip this step only if the plan is trivially simple (e.g., a single-phase config change with no codebase dependencies).

Step 4 — Execute Phases

Capture <run_start> timestamp before the first phase: date +%s.

For each phase, sequentially:

  1. Capture phase startphase_start = date +%s

  2. Compose the brief — see Brief Composition Rules

  3. Spawn the agent — see Agent Modes for which to use

  4. Receive the summary — analyze the result for success, failures, or concerns

  5. Update the plan file — Edit the local plan file ALWAYS to check off completed acceptance criteria, regardless of GH mode. (GH mode, gh_sync_mode == active only) After the Edit, sync to GitHub: gh issue edit <plan_sub_issue_number> --body-file <plan_file_path>. Retry 3× with backoff (250ms, 1s, 3s) on failure. On persistent failure, escalate to the user once with three options:

    • retry — try the sync again now (e.g. user just refreshed gh auth)
    • continue — set gh_sync_mode = degraded; skip per-phase sync for the rest of this run; one final sync attempted at end-of-run
    • abort — stop the run; user can resume via re-invocation

    (GH mode, gh_sync_mode == degraded) Skip the sync; note the degraded state in the next progress tracker output.

  6. Commit the phase's changes (skip entirely if --no-commits):

    • git add -A
    • Check git diff --cached --quiet; if exit code 0 (no staged changes) → skip the commit and note (no commit — no changes) in the progress tracker for this phase
    • Otherwise, invoke Skill(skill="commit", args="#<plan_sub_issue_number>") (omit args entirely if local-only mode). Commits reference the plan sub-issue — the narrow scope of what each commit accomplishes. The PR body separately refs the parent PRD-epic (Step 5d) for rollup tracking. The commit skill is the single source of truth for commit message format and type selection — do NOT duplicate format guidance here.
    • Pre-commit hook failure — spawn a Debug agent with the hook output, files involved, and what was being committed. After Debug fixes the issue, retry the commit (re-invoke the commit skill). If the second attempt fails, escalate to the user with full context. Never bypass hooks with --no-verify.
  7. Capture phase end and compute durationphase_end = date +%s; phase_duration = phase_end - phase_start; store <phase_timings>[phase_index] = phase_duration. Format for display as h:mm:ss (always include the hours field, e.g. 0:03:21).

  8. Report progress — output the progress tracker (see Progress Reporting), including the formatted duration

  9. Handle failures — if the summary reports issues, see Error Handling

  10. Proceed to the next phase, carrying forward relevant context from the summary

Step 5 — Completion

After all phases:

  • Output a final summary of what was accomplished across all phases, including each phase's duration (h:mm:ss) and the total run time
  • List any caveats, manual steps, or follow-ups
  • Note any acceptance criteria that remain unchecked

(GH mode, outcome is complete or partial only — skip everything below on aborted):

Step 5a — Sync reconciliation

If gh_sync_mode == degraded, attempt one final gh issue edit <plan_sub_issue_number> --body-file <plan_file_path> to push the local file. If this final sync fails, skip Step 5b and Step 5d (do not strand a "completed" comment on a stale body and do not open a PR linked to a stale plan); surface the partial state:

Run completed locally. GitHub sync still failing: <error>
To sync manually after fixing the issue:
  gh issue edit <plan_sub_issue_number> --body-file <plan_file_path>
  gh issue comment <plan_sub_issue_number> --body "<final summary text>"

Step 5b — Post summary comment

Load references/completion-templates.md now — it contains the exact templates for both "complete" and "partial" outcomes, plus the gh issue comment invocation. Pick the template matching the run's outcome and post.

Step 5c — Push the work branch

Skip if --no-branch or --no-commits was passed (no branch to push, or no commits to push).

Run: git push -u origin <branch_name>

If the push fails (branch protection, network, auth, force-push needed):

  • Surface the error verbatim
  • Do NOT auto-force-push. Skip Step 5d and instruct the user to resolve the push manually before opening a PR

Step 5d — Submit the PR

Skip if any of: --no-pr, --no-branch, --no-commits, push failed in Step 5c.

Load references/completion-templates.md if not already loaded — it contains the PR body template, draft-vs-ready rule, the gh pr create invocation, and the gh pr create failure-handling guidance. Use it to compose and submit the PR.

On success: report the PR URL to the user.

Step 5e — Delete the local plan and PRD files

Run only if ALL of the following hold:

  • GH mode (<plan_sub_issue_number> is set)
  • Run outcome is complete (not partial or aborted — partial runs need the file for resumability)
  • Step 5d submitted the PR successfully (skipped or failed → keep the files; without a merged PR, the local file is still the most complete working copy)

When all conditions hold:

  1. Delete the plan file: rm <plan_file_path>
  2. Delete the upstream PRD file if it exists locally and was published to GH:
    • Derive the PRD path by swapping the suffix on the plan filename: <slug>-plan.md<slug>-prd.md in the same directory
    • If that file exists AND its content contains a <!-- gh-issue: N --> footer (proving it was published — local-only PRDs are kept as the audit trail), rm it
    • If either condition fails, leave it alone
  3. Note the deletions in the final summary (e.g. Local plan and PRD files removed — GH issues #<parent>/#<plan_sub_issue_number> and PR are the canonical record. or Local plan file removed; PRD file kept (not published to GH).)

Rationale: the GH issues hold the final checkbox state and the PR captures the work itself, so the local files are redundant. Re-runs that need the plan file can re-fetch from GH — Step 1b's "GH ref passed → not found → fetch" path handles that automatically.


Agent modes (quick reference)

The mode is the role; the subagent_type column is Claude Code's reference mapping. On another host, map each mode onto its nearest isolated-context worker (read-only for Research, general-capability for the rest).

Mode Claude Code subagent_type When to use
Research Explore Gathering codebase context before or mid-execution
Code general-purpose Phases that create or modify code and tests (primary workhorse)
Architect general-purpose Phase is ambiguous about how to structure something; resolve before coding
Debug general-purpose A Code agent reports failures it couldn't resolve

For each mode's full role definition, protocol, and expected-output format, see references/agent-operations.md — loaded once at Step 2 per Context Discipline.


Brief composition (skeleton)

Every agent brief MUST include these 8 sections, in order:

  1. Role Preamble — which mode this agent is operating in (use the mode's role definition)
  2. Codebase Context — architectural decisions, prior research findings, prior phase summaries, AGENTS.md/CLAUDE.md directive
  3. File Manifest (Code mode) — Files to modify (must-read-first) and Files to reference
  4. Scoped Task — phase description and acceptance criteria, verbatim from the plan
  5. TDD Directive (Code mode only) — red-green-refactor workflow reminder
  6. Build Verification Gate (Code mode only) — run the build before reporting complete
  7. Completion Requirement — the structured STATUS / Files changed / Tests / Build / Issues / Incomplete / Implementation details template
  8. Boundary Statement — "only do what's in scope"

For the exact text of each section (prose, directives, completion template), see references/agent-operations.md. This skeleton is the forcing function — the reference file is the full content.

Before spawning any agent, verify the brief contains all 8 sections (or all that apply to the mode — File Manifest, TDD Directive, and Build Verification Gate are Code-mode-only).


Context Discipline

You are the orchestrator. Stay lean.

  • DO NOT read source code files — delegate that to agents
  • DO NOT run tests, builds, or linters — delegate that to agents
  • DO NOT implement code changes — delegate that to agents
  • DO read the plan file (once, at the start)
  • DO load references/agent-operations.md once at Step 2 and keep it in working memory for the whole run (agent modes + brief content for every phase)
  • DO load references/completion-templates.md at Step 5 when composing the summary comment and PR body
  • DO use the Edit tool to update plan checkboxes after phases complete (and gh issue edit to sync to the issue body when GH-backed)
  • DO create the work branch (Step 1e), commit phase changes (Step 4.6), push the branch and open the PR (Step 5c–5d) — these git/GH operations are the orchestrator's responsibility, not the agents'
  • DO invoke the commit skill for commit message generation; do NOT duplicate commit format guidance in this skill
  • DO capture phase timings via date +%s at phase boundaries
  • DO output progress updates between phases
  • DO carry forward relevant context from phase summaries into subsequent briefs
  • DO keep phase summaries in your working memory — they are the source of truth for what was accomplished
  • NEVER bypass pre-commit hooks (--no-verify, --no-gpg-sign, etc.) — investigate and fix the underlying failure via a Debug agent

If a phase summary is excessively long, extract only the information needed for subsequent phases.


Progress Reporting

After each phase completes, output a progress tracker:

══════════════════════════════════════════════════
 Phase 1 of N: {title}                ✓ COMPLETE  (0:03:21)
 Phase 2 of N: {title}                ← CURRENT
 Phase 3 of N: {title}
 Phase 4 of N: {title}
══════════════════════════════════════════════════

Show the formatted duration for each completed phase. For phases that produced no commit, append (no commit — no changes). For phases where GH sync was degraded, append (GH sync degraded).

Between the tracker and the next phase, briefly note:

  • Key outcome from the completed phase (1-2 sentences)
  • Any context being carried forward
  • Which agent mode the next phase will use and why (if not obvious)

Error Handling

When a Code agent's summary reports failures:

  1. Assess severity — Can the next phase proceed, or is this blocking?
  2. If non-blocking — Note it in progress, carry forward as context, continue
  3. If blocking due to a bug or test failure — Spawn a Debug agent with:
    • The failure description from the Code agent's summary
    • The files and code sections involved
    • What was being attempted
  4. If blocking due to insufficient context — The Code agent may report that it couldn't complete the work because it didn't understand an existing pattern, couldn't find the right interface, or lacked context about how something works. In this case:
    • Spawn a Research agent scoped to the missing context
    • Use the research findings to compose an enriched brief
    • Re-attempt the phase with the additional context included
  5. After Debug or retry resolves — Verify the fix is sufficient, then continue to the next phase
  6. If resolution fails — Report to the user with full context and ask for guidance

Retry limit: A phase may be retried a maximum of 2 times (original attempt + 2 retries). After the second retry fails, escalate to the user regardless of failure type.

Do not retry the same phase with identical instructions. If a retry is needed, adjust the brief based on what was learned.


Resumability

The plan file is the persistent record of progress. By checking off acceptance criteria after each phase:

  • If a conversation is interrupted, the user can re-run /run-plan on the same plan
  • The orchestrator reads the checkboxes to determine which phases are already complete
  • Already-completed phases are skipped (note them in the execution plan output)
  • Partially-completed phases are re-attempted from scratch (unchecked criteria = incomplete)

For GH-backed plans: the synced GH issue body is the cross-machine source-of-truth. A run started on machine B will fetch the body at start (Step 1b/1c), see checkboxes from a prior run on machine A, and skip those phases. Per-phase sync (Step 4.5) keeps the GH body in lockstep with the local file during execution.

When presenting the execution plan (Step 2), if some criteria are already checked, note which phases appear complete and confirm with the user whether to skip them.

Install via CLI
npx skills add https://github.com/semi-sentient/skills-workflow --skill run-plan
Repository Details
star Stars 5
call_split Forks 0
navigation Branch main
article Path SKILL.md
More from Creator
semi-sentient
semi-sentient Explore all skills →