From root
Execute an approved Implementation Plan by walking through Execution Groups, validating at checkpoints, generating tests, resolving review, and merging.
How this command is triggered — by the user, by Claude, or both
Slash command
/root:implroot/The summary Claude sees in its command listing — used to decide when to auto-load this command
# /root:impl — Implementation Plan Executor Execute an approved Implementation Plan by walking through Execution Groups, validating at checkpoints, generating tests, resolving review, and merging. Parse the first word of the argument to determine the action: - A named subcommand (`run`, `resume`, `status`, `finalize`) — execute that subcommand explicitly. - An issue number or no argument — **phase-detect** from `board_status` and start at the correct step (see "Phase-Aware Dispatch" below). This is the default and preferred entry point. ## Shared Setup 1. **Session state**: Call `board_...
Execute an approved Implementation Plan by walking through Execution Groups, validating at checkpoints, generating tests, resolving review, and merging.
Parse the first word of the argument to determine the action:
run, resume, status, finalize) — execute that subcommand explicitly.board_status and start at the correct step (see "Phase-Aware Dispatch" below). This is the default and preferred entry point.board_status MCP tool with the issue number. Extract tier, planPath (as plan_path), and issue from the board stream. The board stream is the sole source of truth. Do NOT read /tmp/root-session.json.
root.config.json. Extract:
validation.lintCommand (e.g., npm run lint && npm run type-check)validation.testCommand (e.g., npm test -- <pattern>)codingStandards arrayproject.docsDir for doc generation/root:impl run docs/plans/my-feature.md)
b. Session state plan_path
c. If neither exists: "No plan found. Run /root <task> first." and stop.This contract applies across every step of /root:impl. Read the stream's autoApprove flag (from board_status) and honor it:
autoApprove: trueNever prompt the user. Do not call AskUserQuestion. Do not halt and ask "which option?" Do not wait for a reply. The flag exists to delegate judgment to you — exercise it.
When you encounter a judgment call (plan deviation, target metric miss, approach ambiguity, unexpected scope), follow this protocol:
Target metric misses are not deviations. If the plan has a "Target Metrics" section (LOC deltas, bundle size, test counts, etc.), missing a target is expected to be possible — those are directional, not contractual. Report actual vs target in the PR body's "Target Metrics" summary and proceed without surfacing it as a deviation.
Database migration deviations are a mandatory halt in auto mode. If a group touches a migration path (see Step 1) and the generated SQL diverges from the plan's Migration Safety section, OR any enumerated breaking-change risk is unaddressed by the generated SQL, OR the ORM workflow cannot be followed as documented — STOP and block. Do not auto-resolve. This is the one carve-out to the "decide and proceed" rule above. Migration shortcuts have repeatedly broken builds; the cost of halting is lower than the cost of a bad migration shipping under autoApprove.
The only legitimate halt in auto mode: an unrecoverable failure you cannot fix after best-effort attempts (tests fail deterministically after multiple fix attempts; build is broken and no rollback succeeds; MCP/gh/network outage persists), OR a migration deviation per the rule above. In that case:
board_run with a blocked signal (or update stream status to blocked via updateStream — the MCP tool handles this).autoApprove: false (manual)Prompt as documented at each step. AskUserQuestion is available. Checkpoints require human confirmation. This is the default.
Before this contract was explicit, /root:impl in auto mode still surfaced "which option?" prompts at points the protocol hadn't anticipated — notably plan-vs-actual deviations like LOC targets. That defeated the point of --auto. This section is the general rule; individual steps may further constrain behavior, but none may loosen it.
When /root:impl is invoked with an issue number or no argument (i.e., no named subcommand), run Shared Setup and then route based on the stream's status:
| Stream status | Starting step | Rationale |
|---|---|---|
approved / implementing | Step 1 (Parse Plan) | Full run through implementation → validation → PR → merge |
validating | Step 8 (Generate Documentation) | Implementation complete; finalize docs + validation + PR |
pr-ready | Step 10c (CI poll) | PR exists; drive CI polling, review resolution, and merge |
queued / planning | Stop with: "Plan not ready. Run /root #<issue> to plan first." | Nothing to execute yet |
plan-ready | Stop with: "Plan awaits approval. Run /root approve #<issue>." | Gated — requires human green-light |
merged / terminal | Stop with: "Stream # is complete." | Nothing left to do |
This makes /root:impl idempotent — re-invoking picks up exactly where the stream left off. The named subcommands (run, resume, status, finalize) remain as explicit overrides for unusual cases; phase-aware dispatch is the normal path and is what /root's orchestration loop calls.
When dispatching starts at Step 10c, the PR already exists. Look it up first:
board_status returns prNumber and/or prUrl after Step 10b stored it).gh pr list --head <branch> --json number --jq '.[0].number' using the stream's worktreeBranch.autoApprove from the stream record to decide auto vs manual merge.Subcommands that generate docs use these variables:
RAG_BIN="${HOME}/.root-framework/mcp/node_modules/mcp-local-rag/dist/index.js"
DB_PATH=$(python3 -c "import json; print(json.load(open('root.config.json')).get('ingest', {}).get('dbPath', '.root/rag-db'))" 2>/dev/null || echo ".root/rag-db")
CACHE_DIR="${HOME}/.cache/mcp-local-rag/models"
Before executing any plan, validate it against this rubric. If the plan fails, stop and report what needs more detail. Do NOT proceed with a plan that fails the rubric.
Every Change Manifest entry MUST have:
create: expected exports, function signatures with parameter types and return typesmodify: what the current behavior is AND what it becomesEvery Execution Group MUST have:
Verification Plan MUST have:
If any Change Manifest path matches a migration pattern, the plan MUST have a "Database Migration Safety" section. Migration patterns: prisma/schema.prisma, prisma/migrations/**, **/migrations/**/*.sql, alembic/versions/**, db/migrate/** (Rails), **/migrations/*.py (Django). The Migration Safety section MUST contain:
prisma migrate dev --create-only then read the file). Plans that say "Prisma will handle it" fail the rubric.If the plan touches migration paths but lacks this section, the rubric FAILS. Do not proceed.
Requirements and Verification items MUST be behavioral/capability-based, not metric-based. Pass/fail contracts describe what the system does ("FamilyCast path removed," "byte-parity with v1 fixtures," "regression test added for renderDeep"). Quantitative targets (LOC delta, bundle size, test count, duplication percentage, performance numbers) belong in the plan's Target Metrics section — where missing the number is reported, not blocked.
Reject any Requirement or Verification item matching patterns like:
If the plan is missing a Target Metrics section but has metric-shaped items in Requirements or Verification, the rubric fails with instruction to move them.
If the rubric fails, output:
## Plan Quality Check — FAILED
<n> issues found:
1. Change #3 (src/services/foo.ts): Description "update as needed" is not specific enough.
Required: describe what the current behavior is and what it becomes.
2. Group B: No test task specified.
Required: at least one test task with file path and scenarios.
Fix these issues in the plan before running /root:impl.
run [plan-path] (default)Execute the Implementation Plan.
Read the plan file. For Tier 1, extract:
-->) = hard dependencies. Dashed arrows (.->) = soft dependencies.While parsing, build a migration group set: the set of Execution Group letters that contain at least one Change Manifest entry whose path matches a migration pattern (prisma/schema.prisma, prisma/migrations/**, **/migrations/**/*.sql, alembic/versions/**, db/migrate/**, **/migrations/*.py). This set drives prompt injection in Step 6.
For Tier 2: parse as a numbered step list. Skip to the Tier 2 section below. Tier 2 plans that touch migration paths must be re-tiered — stop and report: "This plan modifies migration files. Re-plan as Tier 1 with a Migration Safety section."
Run the Plan Quality Rubric. If any entry fails, output the failures and stop.
Call board_analyze_plan MCP tool with the plan path. This parses the Mermaid dependency graph and identifies disconnected subgraphs — independent concerns that share no hard dependencies.
If shouldDecompose is true, the plan contains multiple independent concerns. Present the analysis:
## Decomposition Analysis
This plan contains <N> independent concerns:
Concern 1 (Groups A, B): <node labels>
- 8 file changes, REQ-001 through REQ-003
Concern 2 (Group C): <node labels>
- 4 file changes, REQ-004, REQ-005
These concerns share no hard dependencies and can be worked independently.
If the stream has autoApprove: true:
shouldDecompose is true: auto-decompose (see Decomposition Path below). Do NOT ask the user.shouldDecompose is false: auto-implement. Skip to Step 4.If the stream does NOT have autoApprove:
Use AskUserQuestion:
For each disconnected subgraph identified by the analysis:
<parent-issue-title>: <primary-group-name>gh issue create --title "<title>" --body "<body>"
board_start MCP tool with the new issue number, parentIssue: <parent-number>, and autoApprove inherited from the parent<plansDir>/<parent-slug>-<group-slug>.mdplanPathAfter all sub-issues are created:
status: "decomposed", childIssues: [<sub-issue-numbers>]Decomposed into <N> issues:
#201 — <parent-title>: Backend (Groups A, B)
#202 — <parent-title>: Notifications (Group C)
Parent #<parent> is now decomposed. Sub-issues will progress independently.
autoApprove: immediately begin board_run on each sub-issueFor each Execution Group that should become an issue (when user chooses "Create GitHub issues per group"):
gh issue create --title "Group <letter>: <name>" --body "<body>"
board_start MCP tool with the new issue number and parentIssue: <parent-number>. Inherit autoApprove from the parent.status: "decomposed", childIssues: [<sub-issue-numbers>]Created <n> issues:
#201 — Group A: Backend Pipeline
#202 — Group B: Frontend Components (depends on #201)
#203 — Group C: Integration Tests (depends on #201, #202)
Scan the Change Manifest Status column for completed markers:
[x] or [x] (<sha>) = complete[~] = in progress (treat as incomplete)[ ] = pendingIf completed groups exist: "Resuming from Group — of groups complete."
From the Dependency Graph, determine which groups can run simultaneously:
-->) are complete.->) can start but need integration after the dependency completesExample batch ordering:
Batch 1: Groups A, B (no dependencies)
Batch 2: Group C (depends on A), Group D (depends on B)
Batch 3: Group E (depends on C and D)
Tier 1 execution is owned by a deterministic Workflow script, not by hand-rolled prose orchestration. You do NOT spawn implementer/reviewer agents one-by-one from the main thread, and you do NOT edit files in the main thread. You build a structured argument object from the parsed plan, invoke the Workflow tool once (auto mode) or once per batch (manual mode), and act on the structured result. Invoking the Workflow tool here is explicitly authorized — these instructions require it.
The script lives inside the plugin at workflows/tier1-execution.mjs. Resolve its absolute path first:
echo "$CLAUDE_PLUGIN_ROOT/workflows/tier1-execution.mjs"
From the data parsed in Steps 1 and 5, construct this object (pass it as the Workflow tool's args):
{
issue: <board issue number>,
planPath: <plan file path>,
autoApprove: <stream.autoApprove>,
codingStandards: <root.config.json → codingStandards array>,
validation: { lintCommand: <…>, testCommand: <…> },
migrationGroups: <array of group letters in the migration group set from Step 1>,
migrationSafety: <verbatim "Database Migration Safety" section text, or null>,
migrationRules: <the verbatim "Migration Hard Rules" block below, or null if no migration groups>,
batches: <the ordered batches from Step 5; each batch = { groups: [ … ] },
each group = { letter, name, sequence, testTask,
changes: [ { num, file, action, section, description, reqs } ] }>
}
The workflow runs one team-implementer agent per group in parallel within a batch; each agent calls board_start({ issue, groupId }) to get its own board worktree (<project>-<issue>-<letter>) on its own branch (<streamBranch>-<letter>, forked from the stream branch) — durable, board-tracked, NOT an ephemeral harness worktree. Parallel groups never collide on path OR branch, and group calls never recreate or reset the stream. Each batch is then gated by a team-reviewer agent in a loop-until-PASS; the workflow re-spawns the affected implementers on ISSUES and only advances to the next batch on PASS.
Migration Hard Rules (passed verbatim as migrationRules; the workflow injects it into implementer prompts for migration groups):
## Database Migration Hard Rules — READ BEFORE TOUCHING ANY MIGRATION FILE
You are modifying database migration files. These rules are non-negotiable. Violating them has previously broken builds and cost hours.
1. DO NOT guess ORM behavior. If this is Prisma, assume every rename is actually a DROP + ADD unless you have verified the generated SQL says otherwise. Same for type changes. Read the generated SQL before applying it.
2. Use the project's migration workflow exactly as documented. For Prisma:
- `prisma migrate dev --create-only --name <name>` to generate migration SQL WITHOUT applying it
- Read the generated `.sql` file. Confirm it matches the intent described in the Change Manifest entry.
- Only then `prisma migrate dev` to apply, or commit the file and let the deploy pipeline apply it — whichever the project's docs specify.
- DO NOT use `prisma db push` for schema changes that will reach production.
3. Before writing or applying the migration, work through the plan's Migration Safety section line by line:
- For each enumerated breaking-change risk (nullability, renames, drops, type changes, index locks, data loss): state in your commit body whether the generated SQL triggers that risk and how it is mitigated. If you cannot confirm, STOP and report.
- Confirm the generated SQL matches the "generated-SQL verification" expectation in the plan. If it diverges, STOP and report — do not "fix" by hand-editing the SQL unless the plan's Migration Safety section authorizes a specific edit with a stated reason.
- Follow the rollout order in the plan. Do not reorder.
4. If you hand-edit generated migration SQL, add a comment in the SQL file explaining the exact reason and what Prisma/the ORM would have done instead. No silent edits.
5. You are NOT authorized to deviate from the Migration Safety section under autoApprove. Migration deviations are the one category where autoApprove does not delegate judgment — STOP and surface a blocked signal on the board per the Autonomous Mode Contract.
6. Triple-check before committing: (a) generated SQL read and matches intent, (b) every breaking-change risk explicitly addressed, (c) rollout order preserved. State each of these in the commit body.
The workflow writes tests as part of each implementer's deliverable and runs the reviewer gate per batch. You do not spawn team-tester, team-implementer, or team-reviewer yourself — the script does, with the correct parallelism, board worktrees, and review loop baked in.
Auto mode (autoApprove: true): call the Workflow tool once with the resolved scriptPath and the full args (all batches). The workflow executes every batch end-to-end — implement → review-until-PASS → next batch — without returning between batches.
Manual mode (autoApprove: false): call the Workflow tool once per batch, passing args with batches sliced to that single batch. After each call returns, present the checkpoint (6c) and use AskUserQuestion (Continue to next batch / Review changes first / Stop here) before invoking the workflow for the next batch. This preserves per-batch human checkpoints, which a single all-batches run cannot.
The workflow returns one of two shapes.
{ status: "complete", completedBatches: [...] } — every batch implemented and reviewed PASS. For each entry in completedBatches, present a checkpoint:
### Checkpoint: Group(s) <groups> Complete
Files changed: <changedFiles>
Commits:
<sha> — <message>
Review: PASS (team-reviewer)
Progress: <completed>/<total> groups
When ALL implementation groups are complete, first integrate the parallel group branches: call board_integrate_groups({ issue }). Each group committed on its own branch in its own worktree; this merges every group branch back into the stream branch (inside the stream worktree), then prunes the group worktrees and branches. Because a well-formed plan partitions groups by disjoint files, the merges are conflict-free.
isError (a merge conflict), the Execution Groups were not actually independent. Do NOT advance: treat it like a blocked result — call board_run with a blocked signal, surface the conflict detail, and stop. The conflicting merge is left in git's conflicted state in the stream worktree for manual resolution.Then call board_run with the issue number to transition the stream to validating. (Per-group completion is recorded in the plan file's Change Manifest by the implementers; the board status advances only when the full set is integrated.)
Skip
board_integrate_groupsonly if the run was never fanned out into parallel groups (single-group plan with no group branches) — the tool is a no-op in that case and reports so.
{ status: "blocked", batchIndex, groups, reason, migrationHalt, completedBatches } — a group failed, the reviewer never reached PASS within its round budget, or a migration deviation forced a halt. Do NOT advance:
board_run with a blocked signal to mark the stream blocked.sendDiscord('blocker', ...) with the failed groups, the issue, and reason — mirroring the epic-mode blocker signal in Step A3 bullet 8 of the /root skill."Execution Group(s)
<groups>(batch<batchIndex>) blocked:<reason>. Halting. Inspect the workflow output and re-run/root:implafter resolving." IfmigrationHaltis true, prepend: "Migration deviation — manual review required."
After all code groups are complete, before final validation:
create actions on source files (not test files)/root:docs Doc Quality Rubric:
project.docsDirnode "$RAG_BIN" --db-path "$DB_PATH" --cache-dir "$CACHE_DIR" ingest <doc-path>
validation.lintCommand across the entire project (not scoped to changed files)validation.testCommand without file pattern restrictionsThis step has four phases: summary, PR creation, CI/review resolution, and merge. In autoApprove mode, all phases run without human intervention.
## Implementation Complete
Plan: <title>
Issue: #<number> — <title>
Groups completed: <N>/<N>
Commits: <list of SHAs and messages>
### Changes
<list all files from Change Manifest with actions>
### Tests Added
<list all test files created>
### Docs Created
<list any docs generated in Step 8>
### Verification
Lint: PASS | Type-check: PASS
Tests: <n> passed, <n> failed
Manual verification: <status>
Coding standards: <n>/<n> checked
If autoApprove: Create the PR automatically — no user prompt. Use squash-ready commit format.
If manual: Use AskUserQuestion:
team-reviewer one more time with the entire plan in scope (cross-group consistency, integration concerns) before creating the PRCreate the PR:
gh pr create --title "<title>" --body "<body with Closes #<issue>>"
After creation, call board_run to transition the stream to pr-ready.
The post-PR flow depends on mode (autoApprove vs manual) and whether CI checks exist.
Auto mode (autoApprove: true):
10c (auto). Wait for CI checks
# Check if any CI checks exist for this PR
CHECKS=$(gh pr checks <pr-number> --json name,state 2>/dev/null || echo "")
If no checks exist: skip to 10e (merge). No CI configured — nothing to wait for.
If checks exist, wait for completion:
gh pr checks <pr-number> --watch --fail-fast
If --watch is unavailable, poll: run gh pr checks <pr-number> --json state every 10 seconds, up to 30 iterations (5 min timeout).
10d (auto). Resolve review findings (3rd set of eyes)
Read PR comments looking for a review:
gh pr view <pr-number> --json comments --jq '.comments[].body'
If no review comments found: skip to 10e. The 1st eyes (team-reviewer during implementation) are sufficient.
If review comments found, resolve each finding using full local context (Implementation Plan, PRD, codebase):
fix(<scope>): address PR review findings), push## Review Resolution
| # | Finding | Severity | Resolution | Reason |
|---|---------|----------|------------|--------|
| 1 | Null check missing on `processPayment()` | 🟠 High | ✅ Fixed | Real defect — input validation was missing |
| 2 | `fetchUser()` doesn't handle 404 | 🟡 Medium | ⏭ Dismissed | Handled by middleware error boundary (REQ-003) |
| 3 | No rate limiting on new endpoint | 🟡 Medium | 📋 Deferred | Valid — tracked as follow-up issue |
10e (auto). Merge
Execute the following as a single chained operation. Do not return to the user between steps:
gh pr checks <pr-number> --watch \
&& gh pr merge <pr-number> --squash --delete-branch \
&& git worktree remove <worktree-path> --force
Then call board_delete({ issue: <issue> }) to remove the stream record. board_delete cascades to worktree cleanup, so any board-tracked worktree paths are also removed. Post a completion comment on the linked issue.
This is one operation. Do not return to the user between the create and merge phases under --auto.
Manual mode (no autoApprove):
10c (manual). Check for CI and hand off to human
CHECKS=$(gh pr checks <pr-number> --json name,state 2>/dev/null || echo "")
If CI checks exist: Wait for them to complete (same polling as auto mode). Then read review comments. If review comments found, resolve findings (same as 10d auto) — push fixes, post the resolution comment. Then present merge options (10e manual below).
If NO CI checks exist:
This block may be entered once (first PR creation) or repeatedly (each time /root #<issue> is re-invoked on a pr-ready stream). Behavior is driven by PR state, not entry mode — the same logic handles both cases.
Read full PR state:
gh pr view <pr-number> --json reviews,comments,author
Find the last Root-posted marker. Scan issue-level comments for the most recent one starting with ## Review Resolution or ## Ready for Review. Record its timestamp as LAST_ROOT_TS (null if no such comment exists — this is first entry).
Identify new reviewer activity since LAST_ROOT_TS:
submittedAt > LAST_ROOT_TS (or all reviews if null)createdAt > LAST_ROOT_TS, excluding any whose body starts with ## Ready for Review or ## Review ResolutionDispatch:
| New activity | Action |
|---|---|
Any review with state: CHANGES_REQUESTED, OR substantive reviewer comments | Fall through to Step 10d's resolution logic: read findings, evaluate against the plan, push fixes in a single fix(<scope>): address PR review findings commit, post a ## Review Resolution comment. Then present merge options (10e manual). |
APPROVED review with no unresolved review comments | Present merge options (10e manual) directly. |
No new activity AND LAST_ROOT_TS is null (first entry) | Post the ## Ready for Review comment (template below). Output: "PR #<number> created and awaiting review. Re-run /root #<issue> when review arrives." Stop. |
No new activity AND LAST_ROOT_TS is not null (re-entry, nothing new) | Output: "Stream #<issue> still awaiting review — no new activity since <LAST_ROOT_TS>. Re-run /root #<issue> when review arrives." Stop. Do NOT re-post the awaiting-review comment. |
Ready for Review comment template (posted once, on first entry):
gh pr comment <pr-number> --body "## Ready for Review
This PR was created by Root. Implementation was validated by the team:
- team-reviewer: PASS (per-group validation)
- Lint/type-check: PASS
- Tests: PASS
**Plan**: <plan-path>
**Issue**: #<issue-number>
### Next Steps
- Review the changes
- Comment \`@root LGTM\` to squash merge
- Comment \`@root fix <feedback>\` to request changes
- Or merge manually"
Stop when no new reviewer activity. The PR stays pr-ready on the board; re-invoking /root #<issue> will re-check for new activity.
10e (manual, after CI/review resolution). Merge options
If CI ran and review was resolved, present options:
Use AskUserQuestion:
gh pr merge --squash --delete-branch, update boardgh pr merge --delete-branch, update boardAfter merge, call board_run to transition the stream. The next board_clean will remove the local worktree.
For Tier 2 plans (no Change Manifest, no Execution Groups):
validation.lintCommand and validation.testCommandgh pr createautoApprove: squash merge automatically. If manual: present merge options.resumePick up from the last incomplete Execution Group.
[ ] or [~]) changesrun flow from Step 5 (identify parallel groups) for remaining workIf all groups are complete: "All groups complete. Run /root:impl finalize to run final validation and create PR."
statusShow current implementation progress.
## Implementation Status
Plan: <title>
Tier: <tier>
Issue: #<number> — <title>
### Execution Groups
| Group | Name | Changes | Tests | Complete | Commit |
|-------|------|---------|-------|----------|--------|
| A | Backend | #1, #2, #3 | 3 scenarios | 3/3 | a1b2c3d |
| B | Frontend | #4 | 2 scenarios | 0/1 | — |
Progress: 1/2 groups (3/4 changes)
Next: Group B: Frontend
Resume: /root:impl resume
For Tier 2: show the numbered step list with checkmarks.
finalizeRun final validation and produce commit/PR without re-executing changes. Use when:
npx claudepluginhub brandcast-signage/root --plugin root/implImplements coding plan from specified plan-file directory using persistent markdown files (task_plan.md, findings.md, progress.md) for state, progress, and rules enforcement.
/implRuns Codex implementation review round on current workflow, auto-writes findings responses (FIX/REJECT/WONTFIX), shows summary, and offers inline next steps (finish/repeat/stop).