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.

Informations de source

Dépôt
markshust/hcf
Dernière activité de la source
8 octobre 2026 à 12:48
Langue détectée de SKILL.md
anglais
Étoiles
78
Forks
14

Options d'installation

Le prompt qui vérifie d'abord la source est sélectionné par défaut. Vous pouvez passer à une commande directe ou télécharger une copie locale.

Vérifiez les fichiers source

Lisez SKILL.md et les fichiers associés affichés par SkillsMP avant de décider de l'installer.

Affichage de SKILL.md

SKILL.md
Instructions source · Aperçu en lecture seule
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
Voir sur GitHub
Ce SKILL.md est tres volumineux, SkillsMP affiche donc ici seulement la premiere section. Voir sur GitHub