Skip to main content

plan-orchestrate

Execute implementation plans with parallel TDD workers. Use when ready to run, execute, or start a plan. Triggers on "run the plan", "execute the plan", "implement the plan", "start the plan", "start implementation", "orchestrate", "begin autonomous execution". Requires a plan created by plan-create.

Source facts

Repository
markshust/hcf
Last source activity
October 8, 2026 at 12:48
Detected SKILL.md language
English
Stars
78
Forks
14

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
plan-orchestrate
description
Execute implementation plans with parallel TDD workers. Use when ready to run, execute, or start a plan. Triggers on "run the plan", "execute the plan", "implement the plan", "start the plan", "start implementation", "orchestrate", "begin autonomous execution". Requires a plan created by plan-create.
model
sonnet
argument-hint
[plan-name]
allowed-tools
Read, Write, Edit, Bash, Glob, Grep, Task
# Plan Orchestrate Execute all tasks in a plan using parallel TDD workers. Fully autonomous after invocation. ## Usage ``` plan-orchestrate {plan-name} ``` Example: `plan-orchestrate user-auth` ## Prerequisites **First, resolve the plans directory,** once, and reuse `$PLANS_DIR` for every path below. It is `.claude/plans` unless the project overrides it in `.claude/hcf.json` (see [Plans Directory](#plans-directory) in the README). The script answers with an absolute path resolved from the project root, so the result does not depend on the working directory: ```bash PLANS_DIR="$("{skill-base-dir}/../../hooks/resolve-plans-dir.sh")" || exit 1 ``` **Never substitute a hand-written `jq` line or a literal `.claude/plans`.** A non-zero exit means the project root or the configured value is unusable; surface the script's stderr verbatim and stop. Quote every path built from `$PLANS_DIR` — a configured directory may contain spaces. Then: 1. Plan must exist at `$PLANS_DIR/{plan-name}/` 2. Project must be configured (`.claude/testing.md` exists) 3. Plan status must be `ready` or `in_progress` Check prerequisites: ```bash ls "$PLANS_DIR/{plan-name}/_plan.md" .claude/testing.md 2>/dev/null ``` If not found, output error and stop. 4. Must be on the correct feature branch Verify the current branch matches `feature/{plan-name}`: ```bash git branch --show-current ``` If the current branch is not `feature/{plan-name}`: - Output an error explaining which branch is expected - Ask the user if they'd like to check out `feature/{plan-name}` - Do NOT proceed until on the correct branch ## Project Configuration <testing> @.claude/testing.md </testing> <code-standards> @.claude/code-standards.md </code-standards> ## Execution Algorithm ### Step 0: Suggest Unattended Completion via /goal Claude Code's built-in `/goal` command keeps a session working toward a verifiable end state — its evaluator runs after each turn and pushes execution to continue until the condition is met. Only the user can set a goal (`/goal` is a user-typed command and cannot be invoked from a skill), so surface a copy-pasteable tip and continue immediately. This is informational, never a gate — do not wait for a response. Display: ``` Tip: for large plans, you can keep this run going unattended with Claude Code's built-in /goal command (interrupt me now to set it, or set it before a future run): /goal the {plan-name} plan run reached a terminal state: plan-orchestrate output ALL_TASKS_COMPLETE or TASKS_BLOCKED Either way, an interrupted run resumes from disk — just re-run plan-orchestrate {plan-name}. ``` The suggested condition deliberately names **both** terminal outputs. A goal phrased as only `ALL_TASKS_COMPLETE` leaves the evaluator demanding more turns after a legitimately blocked run, when the correct behavior is to stop and report the blockage. ### Step 1: Load Plan Context Read plan files: - `$PLANS_DIR/{plan-name}/_plan.md` - Plan overview - `$PLANS_DIR/{plan-name}/*.md` - All task files (excluding _plan.md) Note: Testing and code standards are auto-included above. Parse each task file to extract: - Task number (from filename) - Status (pending | in_progress | completed | blocked) - Dependencies (from `Depends on` field) - Requirements (checkboxes) - Retry count Build a dependency graph as a data structure. ### Step 2: Update Plan Status If plan status is `ready`, change to `in_progress`: - Edit `$PLANS_DIR/{plan-name}/_plan.md` - Set `## Status` to `in_progress` **Establish the run fingerprint.** Every hook call below passes this back via `--expect=`, so that agent files changing mid-run halt the orchestration rather than silently swapping the pipeline. Read `$PLANS_DIR/{plan-name}/.hook-fingerprint` and handle three distinct states — conflating them is the mistake to avoid: | State | Action | |-------|--------| | **Present and parseable** (one line: `discover-hooks-fingerprint-v1 <64-hex>`) | Use it as `$RUN_FINGERPRINT`. Pass the file's contents **verbatim** — do not trim, reformat, or re-derive them. | | **Missing** | Not an error. Plans created before this feature have none. Capture one and write it to the plan directory so a resumed run is covered too, then continue: `"{skill-base-dir}/../../hooks/discover-hooks.sh" --fingerprint > "$PLANS_DIR/{plan-name}/.hook-fingerprint"` | | **Present but unparseable** (empty, truncated, prose, wrong length) | **Halt.** Do not silently recapture — that would mask a botched write. Tell the user to delete the file to re-baseline. | **Never reconstruct, abbreviate, or recall a fingerprint from memory.** It is only ever produced by running the script. A hallucinated digest fails every subsequent hook with bogus drift and bricks the run. ### Step 2a: Pre-Implementation Hook Run the `pre-implementation` hook **once**, after the status is set to `in_progress` and **before** the first batch is launched. Resolve and run enrolled agents via the **HOOKS.md discovery routine** (see [Hook Discovery](#hook-discovery) below) with `HOOK = pre-implementation`. Pass each agent the project context as described in [Spawning hook agents](#spawning-hook-agents). **Exit 0 with empty stdout** is an empty hook: return immediately, log nothing, do no work, and proceed to Step 3. **Any non-zero exit stops the run** — see [Hook Discovery](#hook-discovery) for the full result table. ### Step 3: Find Ready Tasks Execution is a **rolling** loop, not a lockstep one. Each task starts as soon as its own dependencies are complete; it never waits for unrelated tasks that happened to start alongside its dependencies. Track a **running set** — the tasks with a worker in flight in this session. A task is **ready** when: - Status is `pending` (an `in_progress` task from an interrupted run counts as pending — see [Task Already In Progress](#task-already-in-progress)) - ALL dependencies have status `completed` - It is **not** in the running set ``` ready_tasks = [] for each task in tasks (in task-number order): if task.status == "pending" and task not in running: if all(dep.status == "completed" for dep in task.dependencies): ready_tasks.append(task) ``` ### Step 4: Check Termination Conditions **All Complete:** ``` if all(task.status == "completed" for task in tasks): Run Step 4a: End-of-Run Hooks (quality gates + commit sequence before final completion) STOP ``` **Waiting:** ``` if len(ready_tasks) == 0 and len(running) > 0: # Nothing new can start yet, but workers are in flight Go to Step 6 and wait for the next completion ``` **Blocked State:** ``` if len(ready_tasks) == 0 and len(running) == 0: if any(task.status == "pending" for task in tasks): # Tasks exist but none are ready and nothing is running - dependency deadlock or all blocked blocked_tasks = [t for t in tasks if t.status == "blocked"] Output: TASKS_BLOCKED: {list blocked task numbers and reasons} STOP ``` ## Hook Discovery All hooks in this skill (`pre-implementation`, `pre-batch`, `post-batch`, `post-implementation`, `pre-commit`, `post-commit`) resolve their enrolled agents by running **`hooks/discover-hooks.sh`**, the single implementation of [HOOKS.md → Discovery Routine](../../HOOKS.md#discovery-routine). **Never enumerate agent files by hand and never write a glob loop to do it.** For a given `HOOK`: ```bash "{skill-base-dir}/../../hooks/discover-hooks.sh" --hook=<HOOK> --expect="$RUN_FINGERPRINT" ``` `{skill-base-dir}` is the **`Base directory for this skill`** value stated when this skill loaded — it is given verbatim, so no path inference is needed. `${CLAUDE_PLUGIN_ROOT}` is **not** available in a skill's Bash calls. `$RUN_FINGERPRINT` is the value established at [Step 2](#step-2-update-plan-status). Then, by result: - **Exit 0, empty stdout → empty hook.** Return immediately — no staging, no diffing, no spawns, and **no logging or narration**. "No narration" is literal and is the rule most often broken: do not name the hook, do not say it is empty/skipped, do not explain *why* it is empty, and **do not say the discovery script returned no agents**. A filtered query prints zero bytes precisely so there is nothing to echo. An empty hook is **completely invisible** in the user-facing output. See [HOOKS.md → Empty-hook fast path](../../HOOKS.md#empty-hook-fast-path). - **Exit 0, output → PRINT it verbatim** as the resolved order, then spawn. - **Exit 1 or 2 → stop the run.** Surface stderr verbatim. - **Exit 3 → stop the run.** An agent file declares an invalid `phase` or `mode`. Surface stderr verbatim; it names the file and the fix. - **Exit 4 → halt HCF.** Hook enrollment changed since this run started, so the remaining hooks would execute a different pipeline than the plan was reviewed against. Surface stderr verbatim. Stop launching (see [Stopping mid-run](#stopping-mid-run)) and do **not** commit. - **Script missing or not executable → hard failure.** Say so and stop. There is no prose fallback; reconstructing the routine by hand is the failure this design exists to end. **Only exit 0 with empty stdout is an empty hook.** Every other non-zero exit is an error to report loudly. On a normal (exit 0, non-empty) result, spawn each agent per its **`mode` field** (`single` → one subagent for the whole plan; `batch` → split the relevant file list into batches of ~10 and spawn parallel subagents, one Task call per batch, all in a single message). The spawn mode comes from the agent's `mode` frontmatter field — never from sniffing the agent body text. ### Spawning hook agents Hook agents are spawned with the Task tool using `subagent_type="{agent-name}"`. The orchestrator only has `<testing>` and `<code-standards>` in context (see [Project Configuration](#project-configuration)) — it does NOT have `<architecture>`. Pass each hook agent the project context it needs verbatim: > **CRITICAL: Pass the COMPLETE, VERBATIM content of the `<code-standards>` and > `<testing>` tags above. Do NOT summarize, condense, or paraphrase. The full > documents contain nuanced rules that are lost when summarized. Copy-paste the > entire content between the tags.** For a **`batch`** agent, send one prompt per batch: ```markdown ## Code Standards {paste the COMPLETE content of <code-standards> verbatim — do NOT summarize} ## Testing Standards {paste the COMPLETE content of <testing> verbatim — do NOT summarize} ## Files to Review {list of files in this batch, one per line} ``` For a **`single`** agent, send one prompt covering the whole plan, including the plan name, the changed-files list, and `<testing>` + `<code-standards>` verbatim. > If a hook agent needs project architecture, that is out of scope for this > orchestrator — it does not load `<architecture>`. Do NOT fabricate an > `## Project Architecture` paste here. ### Step 4a: End-of-Run Hooks (Post-Implementation → Tests → Commit) When all tasks are complete, run the end-of-run hook sequence. The control flow is strictly: **post-implementation → run full test suite → pre-commit → commit → post-commit** > **CRITICAL INVARIANT: NOTHING is committed until AFTER the full test suite > passes.** This ensures no broken code is ever committed. The `pre-commit` hook > runs *after* tests pass and *before* the commit; `post-commit` runs *after* > the commit and *before* the push/PR prompt. **1. Run the `post-implementation` hook:** Resolve and run enrolled agents via the [Hook Discovery](#hook-discovery) routine with `HOOK = post-implementation`. To give batch agents a file list, first compute the changed files (this stages everything only to read the list, then unstages — nothing is committed). The plans directory is left out: plan files are working state, not code for agents to review. ```bash git add -A && git reset -q -- "$PLANS_DIR" && git diff --name-only --cached && git reset HEAD ``` Then spawn the resolved agents per their `mode` (see [Spawning hook agents](#spawning-hook-agents)). **Exit 0 with empty stdout** is an empty hook: return immediately, no logging, no work, and proceed to step 2. **Any non-zero exit stops the run** — see [Hook Discovery](#hook-discovery). **2. After ALL post-implementation agents complete, run validation:** ```bash # Run full test suite {parallel test command from testing.md} ``` > **CRITICAL: Nothing is committed until AFTER the full test suite passes.** This ensures no broken code is ever committed. **3. On test failure** — isolate the cause (see [Test-failure isolation](#test-failure-isolation) below), then either commit the implementation only or output `TASKS_BLOCKED`. **4. On tests passing — run the `pre-commit` hook:** Resolve and run enrolled agents via [Hook Discovery](#hook-discovery) with `HOOK = pre-commit`. These run *after* the suite passes and *before* the commit. **Exit 0 with empty stdout** is an empty hook (silent no-op); **any non-zero exit stops the run before the commit** — see [Hook Discovery](#hook-discovery). > If a `pre-commit` agent modifies files, those edits are part of this commit. A > pre-commit agent that changes files could break tests; that risk is covered by > the [Test-failure isolation](#test-failure-isolation) stash, which now spans > both post-implementation and pre-commit hook output. **5. Commit:** First, update `_plan.md` status to `completed`. Then stage and commit the implementation in a **single commit**, leaving the plans directory out: ```bash # 1. Update plan status (local working state — it is not committed) # (edit $PLANS_DIR/{plan-name}/_plan.md — set Status to "completed") # 2. Stage implementation + hook agent fixes, then unstage the plans directory git add -A git reset -q -- "$PLANS_DIR" git commit -m "feat({plan-name}): {plan title summary}" ``` > **IMPORTANT:** There must be exactly ONE commit here. **Never commit plan > files.** Plans are ephemeral: once the work is committed, the code and its > tests are the source of truth, and a plan kept in the repo goes stale > alongside them. Unstaging `$PLANS_DIR` (rather than excluding it with a > pathspec) works whether the directory is untracked, gitignored, or was > committed by an older HCF version. **6. After the commit succeeds — run the `post-commit` hook:** Resolve and run enrolled agents via [Hook Discovery](#hook-discovery) with `HOOK = post-commit`. These run *after* the commit and *before* the push/PR prompt (the [Output Summary](#output-summary) at the end of this skill). **Exit 0 with empty stdout** is an empty hook (silent no-op); **any non-zero exit is reported loudly** — see [Hook Discovery](#hook-discovery). The commit has already happened, so report the failure rather than trying to undo it. > **`post-commit` agents that produce uncommitted changes are REPORTED, not > silently committed.** The commit above already happened; do not amend or > create a second commit. Surface any working-tree changes a post-commit agent > left behind so the user can decide what to do. Output: `ALL_TASKS_COMPLETE` #### Test-failure isolation If the full test suite fails at step 3 (or after pre-commit edits), isolate whether the **hook agents** (any `post-implementation` or `pre-commit` agent that edited files) broke things versus the implementation itself. The git stash isolation spans **both** the post-implementation and pre-commit hook output: ```bash git stash
View on GitHub
This SKILL.md is very large, so SkillsMP previews the first section here. View on GitHub