From root
Start or continue a Root development session for a GitHub issue. On first invocation classifies tier, loads docs via RAG, and plans. On re-invocation drives the stream through implementation, review, and merge. Also handles orchestration verbs (list, status, approve, run, sync, delete, clean, reset).
How this skill is triggered — by the user, by Claude, or both
Slash command
/root:root #<issue> [description] [--auto] | #<epic> --auto | #<x> #<y> #<z> --auto --batch | list | status #<issue> | approve #<issue> | run | sync | delete #<issue> | clean | reset#<issue> [description] [--auto] | #<epic> --auto | #<x> #<y> #<z> --auto --batch | list | status #<issue> | approve #<issue> | run | sync | delete #<issue> | clean | resetThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Entry point for the Root development workflow framework. Provides tier-based planning, doc-aware context gathering, and session tracking.
Entry point for the Root development workflow framework. Provides tier-based planning, doc-aware context gathering, and session tracking.
Root reads project-specific settings from root.config.json in the project root. If the config file doesn't exist, use sensible defaults:
docsDir: "docs"plansDir: "docs/plans"prdsDir: "docs/prds"Execute all steps in order. Steps 1-7 run autonomously. Step 8 drives planning (tier-dependent). Step 9 generates tasks after plan approval.
CARDINAL UNDER
--auto: when CI on a PR you opened goes green, the next action isgh pr merge --squash --delete-branch— NOT a status report and NOT a confirmation prompt. Asking the user to type "merge" or "yes" is a protocol violation. The full--autocontract is defined in Step 0's "--auto flag behavior" table below; this is the one-line summary you must internalize before reading anything else.
The training distribution's default template is "report status, wait for human." Under --auto that template is wrong. Three concrete failure modes:
(a) PR merge after green CI BAD: "PR #164 opened with the docs cleanup. All CI checks pass. Let me know when you'd like to merge." GOOD: "Merged #164 at abc123. Main current."
(b) Follow-on fix folded into the active PR BAD: "I noticed a small type error in the adjacent file. I've included the fix in this PR — let me know if you'd prefer it as a separate issue." GOOD: "Opened #165 for the type error in foo.ts. Keeping it out of this PR."
(c) End-of-run status report BAD: "All three PRs are open and CI is green on each. Ready to merge when you give the word." GOOD: "Merged #159, #160, #164. All squash-merged and branches deleted. Main is current."
Under --auto, the user authorized merge and forward decisions at session start. The model is not asking — it is reporting outcomes.
/root is both the task entry point AND the orchestration driver. Re-running /root #<issue> is the universal "continue" gesture — every invocation inspects stream state and advances to the next actionable phase.
Parse the first token of the argument.
Flag extraction. Before matching verbs or issue numbers, scan the argument for these flags and remove them from the token stream:
--auto — set the autoApprove flag. Effect depends on entry path (see below).--batch — explicit batch-mode signal. Required when the argument contains 2+ issue numbers; rejected with one issue. Forces --auto (batch without auto is meaningless).--groups A,B — limit execution to specific groups (passed through to /root:impl).Multi-issue invocation. Count issue numbers in the argument. If 2+:
--batch: reject — "Multiple issue numbers require --batch. Did you mean /root #x #y #z --auto --batch?"--batch but without --auto: implicitly add --auto, surface a one-line note ("--batch implies --auto").Single-issue + --auto. Single issue with --auto runs the readiness gate (below) before falling through to phase-aware dispatch. This is the existing single-issue autonomous path with the new gate in front.
Reserved orchestration verbs — if the first token matches one of these, dispatch and stop (no session init):
| Verb | Action |
|---|---|
reset | Call board_clean. Output "Root streams cleared." Stop. Ignore any issue number in the argument. |
list | Call board_list. Output result. Stop. |
status [#issue] | If issue given, call board_status; else board_list. Stop. |
sync | Call board_sync. Output result. Stop. Ignore any issue number. |
delete <#issue> | Requires an issue. Call board_delete with issue. Output result. Stop. If no issue is present, reject: "delete requires an issue number." |
clean | Call board_clean. Output result. Stop. Ignore any issue number. |
approve <#issue> | Requires an issue. Call board_approve with issue. Then fall through to phase-aware dispatch below for that issue (approval means "go"). If no issue is present, reject: "approve requires an issue number." |
run [#issue] [--groups A,B] | If no issue and exactly one active stream exists, use it. If multiple, call board_list and ask which. Call board_sync first. Then fall through to phase-aware dispatch below. |
Verb + issue normalization. When a verb is matched AND an issue number also appears anywhere in the argument, use the issue as the verb's target — regardless of position. This handles natural-language variants like /root list #1234 (treat as status #1234 — the user clearly meant that one stream, not the whole list), /root approve 1234, /root delete #42. If the verb is one that ignores issues (reset, sync, clean), discard the issue with no error.
Otherwise — extract an issue number from the argument (formats: #1234, 1234, issue 1234, GH-1234, github.com/.../issues/1234).
If no issue number is found, reject:
"Root work is issue-anchored. Either pass an issue number (
/root #1234 <description>) or file one first withgh issue create."
Stop.
Phase-aware dispatch (we now have an issue number):
board_status with the issue number.board_reconcile with the issue number before routing. If board_reconcile returns { "reconciled": true }, the stream was in a terminal GitHub state (PR merged or issue closed out-of-band). Output: "Stream # reconciled — . Record removed." Stop. Do not proceed to any planning or implementation steps.| Stream status | Action |
|---|---|
| no stream | Proceed to Step 1 (fresh session init). |
queued / planning | Proceed to Step 1 (resume planning). |
plan-ready | Read planPath from the stream record. Output: "Plan at <planPath> awaiting approval. Re-run /root #<issue> after approving, or /root approve #<issue> to green-light now." Stop. |
approved / implementing / validating / pr-ready | Dispatch /root:impl #<issue> (no subcommand — /root:impl phase-detects from board_status and starts at the correct step: Step 1 for approved/implementing, Step 8 for validating, Step 10c for pr-ready). Pass --groups if specified. After it returns, call board_run to advance state. If the new state is actionable (not plan-ready or terminal), re-evaluate this step. |
terminal (merged, etc.) | Output: "Stream # is complete (<status>)." Stop. |
Only the "no stream" and "planning" branches fall through to Steps 1-8 below. All other actionable branches dispatch to /root:impl and loop on re-evaluation until the stream reaches a human gate (plan-ready) or terminal state (merged).
pr-ready is not terminal. A stream reaches pr-ready when the PR exists but CI may still be pending, review comments may be unresolved, and the merge hasn't happened. Re-invoking /root #<issue> drives the stream through Step 10c (CI poll), Step 10d (review resolution), and Step 10e (merge) until it reaches merged.
--auto flag behavior (when extracted above):
| Entry path | Effect |
|---|---|
| No stream exists (fresh creation) | Pass autoApprove: true to board_start in Step 6. All gates (including Tier 1 plan_approval) auto-advance for this stream. |
Stream exists, status plan-ready | Treat as equivalent to approve — call board_approve with the issue, then fall through to phase-aware dispatch. |
| Stream exists, any other status | --auto is a no-op and a warning: "Stream # already exists with autoApprove: <value>. --auto only takes effect at stream creation. To green-light a specific gate, use /root approve #<issue>." Continue with phase-aware dispatch regardless. |
| Orchestrator behavior throughout the run | Under --auto, the orchestrator MUST NOT call AskUserQuestion and MUST NOT park the run for human approval at any step Root controls (plan_approval, draft-PR review, post-CI review, run-completion confirmation). The only stops permitted are: (a) readiness-gate interview where context cannot resolve a concern, (b) genuinely irrecoverable failure, (c) external gates Root does not control (branch protection, required reviews, red CI). --auto is permission to make defensible defaults and ship. |
The MCP enforces this honestly: board_run at mcp/mcp-root-board/src/index.ts:337 skips gate evaluation entirely when stream.autoApprove === true, including Tier 1 plan_approval. There is no "--auto does not override plan_approval" rule — if you see a message claiming that, the stream's autoApprove is false.
The issue number was already extracted in Step 0 (this branch is only reached when an issue number is present). Now extract:
Run:
gh issue view <number> --json number,title,body,labels,state,assignees
Store the result. The issue title, body, and labels inform tier classification and doc matching.
Only runs on fresh stream creation (Step 0 routed via the "no stream" branch). Skip if the stream already exists.
If the issue's labels include status:roadmap or status:backlog, stop and confirm before continuing:
status:roadmap — on the immediate roadmap but not necessarily the next thing to pull.status:backlog — has merit but is not prioritized for work.Both are signals that picking this up now may not be intentional. Use AskUserQuestion to confirm:
"Issue # is labeled
<status:roadmap|status:backlog>. Do you want to start work on it now?"
board_start.--auto was extracted in Step 0, skip this gate — passing --auto on a roadmap/backlog issue is explicit pre-approval.Tier classification is owned by the MCP. board_start inspects the issue's labels, title, and body via classifyTier (mcp/mcp-root-board/src/classify.ts) and writes a definite tier to the stream record. You do not classify tier yourself here.
| Tier | Criteria (used by classifyTier) |
|---|---|
| Tier 1 (Full Process) | type:refactor/type:epic/type:security labels, or Tier 1 keywords (refactor, migration, rewrite, schema change, architecture) in title/body. (type:feature is not a Tier 1 signal — triage over-applies it; feature issues classify by keywords.) |
| Tier 2 (Light Process) | type:bug/type:chore/type:docs/type:dependencies labels, or Tier 2 keywords (fix, typo, bump, patch, hotfix, update dep). Also the policy for ambiguous cases. |
Scope-signal downgrade (automatic). After the classifier resolves Tier 1, classifyTier runs a secondary scopeSignal check. When ALL THREE of the following hold simultaneously, the result is quietly downgraded to Tier 2:
## Files affected section if present, otherwise the full body).## Acceptance criteria, ## Acceptance, or ## Done when heading with ≥2 bullet lines beneath it.## heading) contains a mechanical keyword (rename, signature, single-file, one-line, typo, bump, extract, inline, move, split, merge), OR a ## Fix: / ## Fix path: section names a specific function or code location.When the downgrade fires, board_start's Tier: response line reads:
Tier: tier2 (classifier: Tier downgraded by scope signal (small (N files) + locked (AC/done-when) + mechanical (keyword: X)); original label/keyword classification was tier1)
Surface this reason to the user in the Step 7 summary so the downgrade is visible.
User-supplied tier overrides short-circuit before classifyTier is called, so this downgrade never fires when the user explicitly passes a tier.
Your job in this step: extract an explicit user override from the argument, if one was given.
tier: "tier1" AND tierJustification: "<exact phrase the user used>" to board_start in Step 6.tier: "tier2" AND tierJustification: "<exact phrase the user used>".tier argument and let classifyTier decide. Do not invent a justification just to override the classifier — board_start will reject blank/whitespace tierJustification values, and the failure mode (a Tier 1 stream you mentally treat as Tier 2) is worse than letting the classifier decide.board_start's response line (Tier: tierX (reason)) reports the classification and why. Surface the reason to the user in the Step 7 summary.
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"
node "$RAG_BIN" --db-path "$DB_PATH" --cache-dir "$CACHE_DIR" query "<query from task description + issue title/body>"
limit: 10 to get a broad set of resultsRead root.config.json and match against all three mapping types:
For each doc loaded in Step 4, check its path against docMappings[].pattern (regex match). Collect matching agents and skills.
For each label on the issue, check against labelMappings[].label. Collect matching agents.
For each entry in keywordMappings, check if any keywords appear in the task description or issue title/body. Collect matching agents.
Call board_start MCP tool with the issue number. If --auto was extracted in Step 0 AND this is a fresh stream (no prior stream existed), pass autoApprove: true as well — this sets the stream to fully autonomous so all gates (including Tier 1 plan_approval) auto-advance. If a tier override was extracted in Step 3, pass tier: "tier1" or tier: "tier2" accordingly and pass tierJustification quoting the user's actual words; otherwise omit both and the MCP will classify from issue data. board_start rejects an override with a blank tierJustification.
Warning:
board_startwithout agroupIdis destructive on existing streams — it callscreateStreamwhich overwrites. Step 0's phase-aware dispatch ensures we only reach Step 6 when no stream exists (the "no stream" branch), so this is safe in practice. (Aboard_startcall with agroupIdon an existing stream is the non-destructive group-worktree path used by the Tier 1 workflow — it never recreates the stream.)
Then call board_run to advance the status from queued to planning.
The board stream at .root/board/<issue>.json is the sole source of truth for session state. Do NOT write /tmp/root-session.json.
Print a structured summary. Example for Tier 2:
## Root Session Initialized
**Tier**: 2 (Light Process) — [brief reason]
**Issue**: #1132 — Fix auth token refresh loop
**Stream**: #1132 (planning)
**Labels**: area:backend, type:bug
**State**: OPEN
### Docs Loaded
- `docs/AUTH_SYSTEM.md` — Authentication System
### Recommended Agents
- **Agent**: `specialist-backend` — area:backend label, auth-related docs
### Workflow (Tier 2)
1. Understand → Read the relevant code, trace the issue
2. Fix → Make the change
3. Validate → lint + type-check + relevant tests
4. Commit → Conventional commit format
### Next Step
- **Autonomous**: Re-run `/root #1132` — it will pick up from the current phase and drive through to PR-ready.
- **Manual**: Make the change, validate, and commit.
Example for Tier 1:
## Root Session Initialized
**Tier**: 1 (Full Process) — [brief reason]
**Issue**: #1200 — New weather integration
**Stream**: #1200 (planning)
**Labels**: area:backend, type:feature
### Docs Loaded
- `docs/INTEGRATIONS.md` — Integration Architecture
### Recommended Agents
- **Agent**: `specialist-backend` — area:backend, integration-related docs
### Workflow (Tier 1)
1. PRD → Write in <prdsDir>
2. Implementation Plan → Delegated to `team-architect` (writes plan, traces code)
3. Review → Plan mode for human approval
4. Implement → Delegated to `team-implementer` per Execution Group (parallel worktrees)
5. Test → Delegated to `team-tester` (per group)
6. Review → Delegated to `team-reviewer` before commit
7. Validate → Full quality gate
8. Document → Update relevant docs
9. Commit → Zero errors, conventional format
### Next Step — MANDATORY
Tier 1 work MUST run through the agent team. Your next action is:
- **Autonomous**: Re-run `/root #<issue>` after plan approval — it will auto-progress through all remaining phases.
- **Manual**: Run `/root:prd new` then spawn `team-architect`, then `/root:impl`.
After outputting the summary, proceed to Step 8.
Planning is tier-dependent. Execute the appropriate path below.
Read root.config.json to get project.plansDir and project.prdsDir.
Delegation is mandatory. The main thread does not write the Implementation Plan or trace code paths — it coordinates the team. Follow this sequence exactly.
Check for PRD: Look for a PRD in <prdsDir> that matches the issue or task slug. Three branches:
Branch A — PRD file exists: Use that file as the PRD input for step 2. Continue.
Branch B — No PRD file; issue body qualifies (isIssueBodyPRDEquivalent → true):
isIssueBodyPRDEquivalent returns true when the issue body contains ALL THREE of:
## Acceptance criteria heading, or a clearly-marked equivalent such as a bulleted "Acceptance", "Done when", or "Definition of done" sectionIf all three are present, skip /root:prd new entirely. Tell the user one line:
"Issue body satisfies PRD requirements (problem + approach + acceptance criteria). Skipping
/root:prd new; passing issue body toteam-architect."
Use the issue body verbatim as the PRD input for step 2. No interview. No file written.
Branch C — No PRD file; issue body does NOT qualify (isIssueBodyPRDEquivalent → false):
--auto is NOT set: tell the user:
"Tier 1 requires a PRD before the implementation plan. Starting guided PRD authoring." Run
/root:prd new <task description or issue number>to guide the user through PRD creation. After the PRD is written, continue to step 2. Do not stop or ask the user to re-run/root.
--auto IS set: do NOT call /root:prd new — it invokes AskUserQuestion during its Phase 2 interview, which is a protocol violation under --auto. Instead, tell the user one line:
"Under
--auto, the issue body is incomplete but Root must not interview. Passing issue body toteam-architectwith instruction to scope independently." Use the issue body as the PRD input for step 2, and include in the architect prompt an explicit note that the issue body is underspecified and the architect should produce its own scoping in the Implementation Plan.
Spawn team-architect: Use the Agent tool with subagent_type: "team-architect" and a prompt that:
<plansDir>/TEMPLATE.md as the required formatroot.config.json for coding standards and validation commands<plansDir>/<slug>.md, and call ExitPlanMode when ready for approvalDo NOT trace code paths or draft the plan in the main thread. The architect owns this work end-to-end. Wait for it to return before proceeding.
Update session state: After the architect returns with the plan file path, call board_run with the issue number to evaluate the plan gate:
board_run returns { "status": "ready" } (auto gate), the stream advances automatically toward approved.board_run returns { "status": "blocked" } (human gate), the stream pauses at plan-ready awaiting human approval via board_approve or the root:approved GitHub label.Ingest the plan into RAG:
node "$RAG_BIN" --db-path "$DB_PATH" --cache-dir "$CACHE_DIR" ingest <plan-path>
Relay plan mode to user: The architect already called ExitPlanMode. Surface the plan to the user for review:
"Implementation plan written to
<plansDir>/<slug>.mdbyteam-architect. Review and approve to proceed to/root:impl."
Enter plan mode: Use EnterPlanMode to create an ephemeral plan in .claude/plans/ (or .gemini/plans/ if using Gemini CLI).
Write a lightweight plan covering:
root.config.json → validationRecord the plan path — MANDATORY verification before proceeding: After EnterPlanMode returns, the harness provides the plan file path (e.g. .claude/plans/<slug>.md).
a. Verify the path exists on disk. Use the Read tool or test -f <path> to confirm the file is present and readable. If the path is missing, empty, or unreadable, halt with:
"Tier 2 plan path could not be resolved (EnterPlanMode returned no usable path). The stream will stay at
planninguntil this is fixed. Investigate the harness return value before continuing." Do NOT callboard_set_plan_path.
b. Call board_set_plan_path with the issue number and the verified path. If board_set_plan_path returns an error, halt with:
"
board_set_plan_pathreturned an error:<error>. The plan path was not persisted. The stream will stay atplanning. Resolve the MCP error before continuing." Do NOT callboard_run.
c. Check resulting stream status. Call board_status with the issue number. If the status is not plan-ready, halt with:
"
board_set_plan_pathdid not advance the stream toplan-ready. Current status:<status>. Halting." Do NOT callboard_run.
Update session state (only reached if step 3's checks all passed): Call board_run with the issue number. For Tier 2 the plan_approval gate defaults to auto, so the stream will advance automatically.
The plan is ready when the user approves it via plan mode. GitHub issue/PR linkage provides traceability.
After the user approves the plan (exits plan mode), hand off to /root:impl:
"Implementation Plan approved.
- Autonomous: Re-run
/root #<issue>— it will dispatch/root:impland drive the stream to PR-ready.- Manual: Run
/root:implto execute step by step, or/root:impl statusto review the plan."
The plan file is the source of truth — /root:impl reads the Change Manifest and Execution Groups directly. No intermediate task list is needed.
Triggered by /root #<epic> --auto (epic mode) or /root #x #y #z --auto --batch (batch mode). Both share the same orchestration spine; they differ only in how children are resolved.
The orchestrator runs in this main harness conversation. Each child issue is dispatched as a Agent tool subagent with isolation: worktree so per-child execution does NOT consume the orchestrator's context. The orchestrator's only jobs are: readiness gating, sequencing, shared-context curation, PR assembly, and notification.
Critical context-window discipline. Everything load-bearing for resuming the run after auto-compaction must be on disk in the shared-context file, not in the conversation. This includes: which children have completed, which is currently running, the running child's worktree path, the partial PR URL once opened, and any architectural decisions a future child needs. Treat the conversation as scratch space; treat shared-context as the durable state.
Before creating any stream:
gh api graphql sub-issues query, same shape as getSubIssues).
For batch mode: the explicit list from the argument.issue-readiness-grader agent. Pass the issue number; the agent reads the body via gh issue view and returns strict JSON.needs-clarification, enter the interview loop (next step). Do NOT skip, do NOT offer a --force flag, do NOT bypass.ready does the orchestrator proceed to Step A1.needs-clarification)Round budget: 3 grading rounds total. Round 4 is a hard stop.
Per round:
#<n>: <title>
Concerns: <list of short concern identifiers>
Questions:
1. <question>
2. <question>
AskUserQuestion for the answers — one block per issue, with a free-form text input. Allow the user to type abort at any prompt to cancel the run; allow skip <n> to drop a specific child from the run (epic mode only — batch members are explicit, dropping one is the user's call to re-invoke).## Clarifications (added by /root readiness gate, <ISO-timestamp>) section to the issue body via gh issue edit <n> --body "<full new body>". Quote each question and the user's answer underneath.ready, exit the loop and proceed to Step A2.needs-clarification, hard-stop with: "After 3 rounds the readiness gate is still failing. Either the rubric is wrong or the issue needs hand-revision before Root can take it. Concerns remaining: ." Do not create any stream.Call board_epic_start({ epicIssue, mode, children }):
mode: "epic" — children argument omitted; the MCP resolves via sub-issues.mode: "batch" — children array is the explicit list from the argument.The parent stream's branch is feat/epic-<n>-<slug> or chore/batch-<n>-<slug>. Create the worktree at this branch (use the same createWorktree machinery board_start uses; reuse via the parent's recorded branch).
Append a kickoff note to shared-context:
board_shared_append({
epicIssue: <n>,
note: "Run started. Mode: <epic|batch>. Children in order: <list>. Branch: <epicBranch>."
})
For each child in declared order:
Tier check. Call board_status on the child if a stream already exists; otherwise pre-classify via gh issue view + the same heuristics classifyTier uses. In batch mode, any tier-1 child triggers a hard stop (sendDiscord('blocker', ...)) — batch is for tier-2 sweeps only. In epic mode, tier-1 children are allowed but their plan_approval gate will pause the run; the parent's autoApprove does NOT cascade to children automatically (per-child autoApprove is set in the next step).
Read shared-context. Call board_shared_get({ epicIssue: <parent> }). Pass the contents into the subagent prompt so the child has the same orientation as everyone before it.
Spawn subagent. Use the Agent tool with isolation: worktree, subagent_type: team-implementer (or a more specific specialist if root.config.json mappings suggest one), and a prompt that:
#<n>)epicBranch (not a per-child branch) and to stop after committing — no PR creation per childautoApprove: true for the child stream so its own gates don't pause the runCollect result. Wait for subagent return. Parse the Result block.
Append summary to shared-context. One concise entry per child: issue number, commit SHAs, files touched, deviations, target metrics. This is what protects against auto-compact — the orchestrator may forget what the child did, but the file remembers.
Update / open PR. On first completed child: open the PR — as ready-for-review when --auto is set, or as draft otherwise. On every subsequent child: gh pr edit to refresh the body, adding the new Closes #<n> line and the new check entry. PR title:
<epic-title> (epic #<epic-num>)chore: batch fixes (#x, #y, #z)
PR body sketch:Autonomous <epic|batch> run.
- [x] #101 — <title> (sha: abc123)
- [x] #102 — <title> (sha: def456)
- [ ] #103 — pending
Closes #101
Closes #102
Under --auto, the create → watch → merge sequence for a single child is one atomic step from the orchestrator's perspective:
gh pr create --base main --head <epicBranch> --title "<title>" --body "<body>" \
&& gh pr checks <pr-num> --watch \
&& gh pr merge <pr-num> --squash --delete-branch
Do not surface CI status updates to the user between gh pr create and gh pr merge — those are internal progress states, not user-facing checkpoints. Under --draft (non---auto), skip the watch and merge commands; the PR stays draft until the user flips it.
Project sync per child. board_start already sets the child's Project Status to In Progress (issue #8). The native PR-linked workflow will move each Closes #<n> issue to Review once the PR is opened.
On child failure or hard-stop. Stop dispatching further children. Fire sendDiscord('blocker', ...) with the failed issue number and reason. Update the PR body with a ⚠ Partial completion callout above the checklist. PR stays draft. Update parent stream status to epic-blocked or epic-partial. Append a concluding note to shared-context.
When all children complete successfully:
epic-complete.sendDiscord('epic_complete', ...) with the PR URL.If --auto is set (autonomous completion path):
Execute the following as a single chained operation. Do not return to the user between steps:
gh pr checks <pr-num> --watch \
&& gh pr merge <pr-num> --squash --delete-branch \
&& git worktree remove <worktree-path> --force
Then call board_delete({ issue: <epic-or-batch-num> }) to remove the parent stream, and print a concise summary: which children landed (issue numbers + titles), the merge SHA, and a one-line note on what shipped.
This is one operation. Do not return to the user between gh pr create and gh pr merge — CI status updates are not user-facing checkpoints. Returning to the user after opening the PR but before merging it is a protocol violation under --auto.
If CI is red, branch protection blocks the merge, or a merge conflict exists (regardless of --auto): park at pr-ready, fire sendDiscord('blocker', ...) describing the external gate, and surface the blocker to the user. --auto does not bypass branch-protection rules or required reviews — it removes only the human gates Root itself imposes.
If --auto is NOT set (non-autonomous path):
gh pr ready <pr-num> when satisfied."Re-invoking /root #<epic> --auto on a partially-completed epic should pick up where it left off:
board_status on the epic returns kind: 'epic', status: 'epic-running' | 'epic-blocked' | 'epic-partial'.This means: never destroy shared-context mid-run. The 32KB overflow trigger is intentional — silent truncation would defeat resumability.
npx claudepluginhub brandcast-signage/root --plugin rootCreates bite-sized, testable implementation plans from specs or requirements, with file structure and task decomposition. Activates before coding multi-step tasks.