anombyte93/prd-taskmaster
GitHubAtlas引擎的品牌入口,用于将目标转化为验证过的PRD和可执行任务图。本身无逻辑,需立即调用go编排器处理请求。适用于用户输入/prd:atlas、表示想构建或要求基于任务的构建场景。
Install All Skills
npx skills add anombyte93/prd-taskmaster --all -g -y
More Options
List skills in collection
npx skills add anombyte93/prd-taskmaster --list
Skills in Collection (10)
skills/atlas/SKILL.md
npx skills add anombyte93/prd-taskmaster --skill atlas -g -y
SKILL.md
Frontmatter
{
"name": "atlas",
"description": "The Atlas engine — turn any goal into a validated PRD and an executable, verified task graph. Brand-name entrypoint; a thin alias for the `go` orchestrator. Use when the user types \/prd:atlas, says \"I want to build\", or asks for a PRD \/ task-driven build.",
"allowed-tools": [
"Skill"
],
"user-invocable": true
}
atlas (entrypoint alias)
This is the brand-name entrypoint for the Atlas engine. It holds no procedure of its
own — immediately invoke the go orchestrator via the Skill tool (/prd:go).
go reads pipeline state and dispatches to the correct phase
(SETUP → DISCOVER → GENERATE → HANDOFF → EXECUTE). Do not duplicate that routing here.
skills/discover/SKILL.md
npx skills add anombyte93/prd-taskmaster --skill discover -g -y
SKILL.md
Frontmatter
{
"name": "discover",
"description": "Phase 1 of the prd-taskmaster pipeline: brainstorm-driven discovery. Delegates to superpowers:brainstorming in Interactive Mode (one adaptive question at a time), or self-brainstorms in Autonomous Mode when no user is present. Intercepts before the brainstorming chain hands off to writing-plans — this skill owns the exit. Extracts constraints, calibrates scale (Solo \/ Team \/ Enterprise), and advances the pipeline to GENERATE.",
"allowed-tools": [
"Read",
"Skill",
"AskUserQuestion",
"Write",
"ToolSearch",
"mcp__atlas-engine",
"mcp__plugin_prd_go",
"mcp__plugin_prd-taskmaster_go",
"mcp__plugin_atlas-go_go"
],
"user-invocable": false
}
Phase 1: Discover
Declarative phase skill. Invoked by the prd-taskmaster orchestrator when
current_phase is DISCOVER. Never called directly by a user.
The one rule: invoke superpowers:brainstorming for discovery, intercept
before it chains to writing-plans — we control the exit, not the brainstorm
skill.
Entry gate
-
Call
mcp__plugin_prd_go__check_gate(phase="DISCOVER", evidence={})for diagnostics.check_gateis an EXIT gate: it verifies the evidence to advance, not to enter. On first DISCOVER entry you have no evidence yet (the User Approval / Self-Approval Gate below producesuser_approved=trueORauto_classification=CLEAR with assumptions_documented), so agate_passed: falsehere is EXPECTED — the state machine's legal transitions already guarantee only legal entry.- First entry (no evidence yet): note the result and continue with the Procedure.
- Re-entry: if the gate reports violations, report them and stop — it protects against re-running a completed phase or skipping ahead from SETUP.
-
Detect execution context. If any of the following signals are present, switch to Autonomous Mode:
.claude/ralph-loop.local.mdexists in the project root- An
auto-enter/auto-approvedaemon is running against this session - The skill was invoked with an explicit
--autonomousflag - Parent orchestrator is a cron,
/pentest-wtf, or/ralph-loopOtherwise proceed in Interactive Mode (default).
Discovery checklist
Copy into your response before running the procedure:
DISCOVERY CHECKLIST:
- [ ] Mode detected (Interactive vs Autonomous)
- [ ] Goal captured from skill args or soul purpose
- [ ] Adaptive questions completed (one at a time)
- [ ] Constraints extracted and listed
- [ ] Scale classified (Solo / Team / Enterprise)
- [ ] Discovery summary captured for GENERATE phase
- [ ] User approved (Interactive) or summary committed (Autonomous)
Interactive Mode (default — user present)
- Take the user's goal / description from the skill invocation args.
- Invoke
superpowers:brainstormingwith the goal as input. - Brainstorming runs its adaptive question flow — one domain-agnostic question at a time. Let it drive the Q&A rhythm.
- INTERCEPT POINT: when brainstorming signals readiness to chain to
writing-plans, STOP. Do NOT let it invokewriting-plans. Capture the brainstorm output (design, requirements, decisions) into local state instead. The prd-taskmaster orchestrator owns the handoff — notsuperpowers:brainstorming. - Present the summary to the user for approval via
AskUserQuestion(see User Approval Gate below).
Autonomous Mode (no user present)
Do NOT invoke superpowers:brainstorming — it blocks on user input and
will stall an unattended session. Instead, self-brainstorm using this
template:
- Read the goal statement from skill args or
session-context/CLAUDE-soul-purpose.md. - Read
session-context/CLAUDE-activeContext.mdfor project context. - Write discovery notes directly to
session-context/discovery-{timestamp}.mdanswering every question the interactive flow would ask:- Who is this for?
- What problem does it solve?
- What are the success metrics?
- What are the constraints (tech stack, timeline, team, budget, integrations, regulatory)?
- What's explicitly out of scope?
- What's the scale (Solo / Team / Enterprise)?
- Self-approve: the skill acts as both interrogator and approver. Document assumptions explicitly so the user can audit them on wake-up.
- Commit the discovery file. The git history becomes the audit trail — if the user later disagrees, they can reset to that commit and re-run.
Autonomous mode is first-class, not degraded. A well-run autonomous discovery produces a spec the user reads on wake-up and says "yes, that's what I meant" without edits. If you find yourself needing to ask more than two questions the user didn't anticipate, the discovery is under-specified — stop and write a handoff note instead of proceeding.
User Approval Gate (Interactive Mode)
After brainstorming completes, present via AskUserQuestion:
Discovery Complete:
Goal: [one sentence]
Audience: [who it's for]
Approach: [proposed solution]
Key decisions: [list]
Constraints: [known limitations]
Scale: [Solo | Team | Enterprise]
Proceed to generate spec? (or refine further)
- If user says "refine" → ask what to change, update the summary, re-present.
- If user approves → capture as the discovery output and proceed to exit gate.
Self-Approval Gate (Autonomous Mode)
Write the discovery summary to session-context/discovery-{timestamp}.md and
commit it. No interactive approval is required, but assumptions MUST be
explicit in the written summary so the user can audit on wake-up.
Smart Defaults
If brainstorming (or self-brainstorming) produces thin answers, fill gaps with reasonable assumptions instead of forcing extra questions:
- Target audience: small team (< 10 users) unless specified otherwise.
- Timeline: MVP in 4–6 weeks.
- Tech stack: inferred from requirements — do not pick arbitrarily.
- Scale: moderate (hundreds of users, not millions).
Document every assumption in the discovery summary so GENERATE can surface them in the spec.
Constraint Extraction (MANDATORY before advancing)
Before moving to GENERATE, explicitly extract and list all constraints mentioned during discovery. Emit this block:
CONSTRAINTS CAPTURED:
- Tech stack: [e.g., "must use Python", "React frontend", "no new dependencies"]
- Timeline: [e.g., "MVP in 2 weeks", "no deadline"]
- Team: [e.g., "solo developer", "3-person team"]
- Budget: [e.g., "free tier only", "$500/month max"]
- Integration: [e.g., "must work with existing Postgres DB", "connects to Stripe"]
- Regulatory: [e.g., "HIPAA compliant", "GDPR", "none specified"]
- Domain-specific: [e.g., "authorized pentest scope: 10.0.0.0/24 only",
"learning goal: intermediate level"]
Present this list alongside the discovery summary. These constraints MUST be passed to GENERATE — they inform spec content, task decomposition depth, and acceptance criteria. If a constraint is mentioned in discovery but missing from the spec, that's a bug.
Scope Calibration
Infer project scale from discovery answers and set decomposition guidance:
| Scale | Signal | Task Cap | Subtask Depth |
|---|---|---|---|
| Solo | "just me", "side project", "learning" | 8–12 tasks | 2–3 subtasks each |
| Team | "small team", "MVP", "product", "startup" | 12–20 tasks | 3–5 subtasks each |
| Enterprise | "compliance", "multiple teams", "platform" | 20–30 tasks | 5–8 subtasks each |
Pass the scale classification to GENERATE so task count is calibrated, not arbitrary.
Exit gate
After approval (Interactive) or commit (Autonomous), constraints captured, and scale classified:
- Call
mcp__plugin_prd_go__advance_phase(expected_current="DISCOVER", target="GENERATE", evidence={"user_approved": True, "constraints_captured": True, "scale": "<Solo|Team|Enterprise>", "assumptions_documented": True}). The call atomically transitionspipeline.jsonfrom DISCOVER to GENERATE. Theexpected_currentfield is the compare-and-swap guard;evidenceis stored underphase_evidence[GENERATE]for audit. - Return control to the orchestrator (
prd-taskmasterskill). Do NOT invoke GENERATE directly — the orchestrator re-readscurrent_phaseand routes.
Red flags (stop and report, do not paper over)
- "Brainstorming wants to call writing-plans — I'll let it" → NO. Intercept.
The prd-taskmaster pipeline owns the exit, not
superpowers:brainstorming. - "User hasn't answered, I'll pick for them in Interactive Mode" → NO. If stalled, ask one more targeted question or write a handoff note — don't silently self-approve in Interactive Mode.
- "Autonomous mode — I'll invoke superpowers:brainstorming anyway" → NO. It blocks on user input and will stall the session. Self-brainstorm with the template above.
- "Constraints are obvious, I'll skip the CONSTRAINTS CAPTURED block" → NO. GENERATE reads this block — missing constraints become missing spec sections downstream.
- "I can call advance_phase without check_gate" → NO. Gate first, always.
Non-exits
This skill does not use explicit process termination. A hard block reports the reason and returns control to the orchestrator; the orchestrator decides whether to surface to the user.
skills/execute-fleet/SKILL.md
npx skills add anombyte93/prd-taskmaster --skill execute-fleet -g -y
SKILL.md
Frontmatter
{
"name": "execute-fleet",
"description": "Phase execution skill for licensed Atlas Fleet runs. Use when HANDOFF has selected Atlas Fleet and the project should be executed across isolated launcher worktrees with inbox-based result collection, verified CDD cards, sequential integration merges, and one final PR.",
"allowed-tools": [
"Read",
"Bash",
"Skill",
"ToolSearch",
"mcp__atlas-engine",
"mcp__plugin_prd_go",
"mcp__plugin_prd-taskmaster_go",
"mcp__plugin_atlas-go_go"
],
"user-invocable": false
}
execute-fleet
Atlas Fleet is the premium parallel sibling of execute-task. It keeps the
same proof discipline, but the orchestrator owns the scoreboard while workers
only build inside isolated worktrees.
Hard Gates
Before the first wave, all gates must pass. If any gate fails, report the gap and stop; do not fall back to solo execution from inside this skill.
mcp__plugin_prd_go__detect_capabilities()reportstier: "premium"and atlas-launcher MCP registration/aliveness.mcp__atlas-launcher__inbox_readis callable for this session..taskmaster/tasks/tasks.jsonexists..taskmaster/reports/task-complexity-report.jsonexists.git status --shortis empty. Fleet starts only from a committed base.- The integration branch policy is clear: use
fleet-integration; main is never auto-touched.
SOLE-WRITER RULE: only this orchestrator writes
.taskmaster/tasks/tasks.json and .atlas-ai/state/pipeline.json. Workers
must never edit those files. The orchestrator may update task state only
through TaskMaster or the plugin pipeline MCP, and only after verification.
Wave Loop
Repeat until no runnable tasks remain:
- Call
mcp__plugin_prd_go__compute_fleet_waves(concurrency=<N>, tag=<tag>). Use the returned frontier as the only dispatch source. If it reports a deadlock, render status, mark the blocked set, and stop dispatching those tasks. - For each chunk in the current wave, spawn exactly one worker:
mcp__atlas-launcher__session_spawn(isolation="worktree", report_to=<this session>, model=<routing[task_id] model part>, prompt=<worker prompt>). Model is NEVER left default:compute_fleet_wavesreturns aroutingmap (task id -> backend:model) from the capability ladder — Fable for the hardest/longest-running (frontier tier), down the cost-efficiency curve to haiku for trivial tasks. Pass the model part explicitly; non-claude backends require experimental_backends=true and the launcher backend param. The prompt must include the full task JSON inline; never tell workers to read sharedtasks.json. - Inspect the spawn result. If
prompt_injectedis false, re-kick once withmcp__atlas-launcher__session_sendusing the same worker prompt, then confirm injection/readiness. If it is still false, treat that worker as failed and apply the retry policy below. - Render the fleet status view after the wave starts and after each wave transition.
- Poll
mcp__atlas-launcher__inbox_readfor terminal worker messages. The only accepted terminal status vocabulary isDONE,DONE_WITH_CONCERNS,NEEDS_CONTEXT, orBLOCKED; any other terminal word is a protocol failure and counts as a worker failure. - On a completion message, verify the branch, never the narration:
- The worker branch contains
.atlas-ai/cdd/task-<id>.json. - No
.atlas-ai/evidence/file in that branch contains a non-zeroExit status Nline. - The branch changed only its own worktree scope and did not edit
.taskmaster/tasks/tasks.jsonor.atlas-ai/state/pipeline.json.
- The worker branch contains
- Never mark a task done without the CDD card. Missing card means the worker
did not satisfy the contract, regardless of any
DONEmessage. - Merge verified worker branches into
fleet-integrationsequentially, one at a time. After each merge, run the checker/build gate expected for the project before merging the next branch. - Mark the task done only after the merge gate passes:
python3 script.py set-status --id <id> --status done. - Recompute waves after every accepted merge. Do not keep dispatching from a stale frontier.
Worker Prompt Template
Embed this template verbatim for each worker, replacing placeholders before dispatch:
WORKER_CONTRACT_ORCHESTRATOR_REPORT_TO
You are an Atlas Fleet worker. Your orchestrator is <ORCHESTRATOR_ID>. Report every question, blocker, and terminal result to <REPORT_TO_SESSION>.
WORKER_CONTRACT_FULL_TASK_JSON_INLINE
Your assigned task JSON is inline below. Treat this as the source of truth. Do not read shared .taskmaster/tasks/tasks.json.
<FULL_TASK_JSON>
WORKER_CONTRACT_WORKTREE_BRANCH
Work only in this isolated worktree and branch:
worktree: <WORKTREE_PATH>
branch: <WORKER_BRANCH>
WORKER_CONTRACT_CDD_CARD
Before reporting any terminal status, write this CDD card in your worktree: .atlas-ai/cdd/task-<id>.json. The card must list the checks you ran and the evidence paths that prove them. Evidence files under .atlas-ai/evidence/ must contain the FINAL verification run ONLY (one green run, one exit-status line) — intermediate TDD red runs go to .atlas-ai/logs/, never evidence/ (ship-check Gate 5 reads every Exit status line in evidence/ as final-state proof).
WORKER_CONTRACT_TERMINAL_STATUS
End with exactly one terminal status: DONE | DONE_WITH_CONCERNS | NEEDS_CONTEXT | BLOCKED.
Report it via mcp__atlas-launcher__inbox_send(target_session=<REPORT_TO_SESSION>, message_type="task_handoff", payload=<JSON string with at least {"task_id": <id>, "status": "<terminal status>", "branch": "<worktree branch>", "cdd_card": ".atlas-ai/cdd/task-<id>.json"}>, sender_session=<your session name>). The launcher message_type allowlist is task_handoff | notification | data | request | heartbeat — terminal reports use task_handoff; the status lives INSIDE the payload JSON.
WORKER_CONTRACT_HARD_RULES
Hard rules: never edit .taskmaster/tasks/tasks.json or .atlas-ai/state/pipeline.json; never git push; commit only in your own worktree branch.
WORKER_CONTRACT_QUESTIONS_INBOX
Ask questions before building if context is missing: use mcp__atlas-launcher__inbox_send(target_session=<REPORT_TO_SESSION>, message_type="request", payload=<your question as a string>, sender_session=<your session name>). ("question"/"completion"/"blocker" are template intents, not runtime message types — see docs/INTEGRATION-prd-taskmaster.md in the atlas-launcher repo, contract v1.)
Failure Paths
- Silent/dead worker: if there is no inbox message and the session is gone,
re-queue the task ONCE with a fresh worker prompt. On the second failure,
mark the task
BLOCKEDin the orchestrator scoreboard and continue with remaining tasks. NEEDS_CONTEXT: answer throughmcp__atlas-launcher__inbox_send, then let the same worker continue. If it cannot continue, count it under the same retry cap.- Worker
BLOCKED: record the blocker, mark the taskBLOCKED, and continue with independent tasks. - Merge conflict: do not force. Do not resolve by guessing. Create a fix task that captures the conflict and continue with remaining non-conflicting work.
- Evidence failure: do not merge, do not mark done, and do not rewrite the worker's CDD card on their behalf.
Status Rendering
After every wave transition, render the terminal status view with the UX-SPEC
grammar. Use model plus index names such as claude-1, codex-1, and
claude-2. Keep the gate line in plain English every time.
┌─ atlas fleet ── wave 2 of 3 ──────────────── ▶ running 12m ┐
│ wave 1 ✓ merged 3 tasks · 18m · integration green │
│ wave 2 ▶ running │
│ claude-1 task 6 API endpoints ▰▰▰▱ 3/4 │
│ codex-1 task 7 UI components ▰▰▱▱ 2/4 │
│ claude-2 task 9 DB migrations ✓ done — waiting │
│ wave 3 ○ queued 4 tasks · starts when wave 2 merges │
│ │
│ Gate: a wave merges only after the checker approves it │
│ and the integration branch builds green. │
│ │
│ watch: atlas fleet status logs: .atlas-ai/fleet/ │
└────────────────────────────────────────────────────────────┘
Termination
When all waves are done, or all remaining tasks are BLOCKED, switch to
fleet-integration and run:
python3 skel/ship-check.py
If it exits non-zero, report the failing gate and stop. If it exits 0, emit
SHIP_CHECK_OK exactly once, then open one final PR from fleet-integration.
Do not print the token anywhere else. Do not merge the PR yourself.
Non-Exits
This skill never kills the shell and never pushes. Halt conditions are reported to the caller and, when relevant, to the launcher inbox.
skills/execute-task/SKILL.md
npx skills add anombyte93/prd-taskmaster --skill execute-task -g -y
SKILL.md
Frontmatter
{
"name": "execute-task",
"description": "Execute the next TaskMaster task using the implementation plan with CDD verification. Picks the next ready task, matches it to the plan step, implements via a dispatched subagent, verifies subtasks with evidence, marks the task done, and loops until every task is complete.\nWraps the TaskMaster next -> in-progress -> done lifecycle with CDD GREEN \/ RED \/ BLUE verification and the plugin's triple-verification rule. Autonomous by design — no user prompts inside the loop.",
"allowed-tools": [
"Read",
"Write",
"Edit",
"Bash",
"Skill",
"Agent",
"ToolSearch",
"mcp__atlas-engine",
"mcp__plugin_prd_go",
"mcp__plugin_prd-taskmaster_go",
"mcp__plugin_atlas-go_go"
],
"user-invocable": true
}
execute-task
The execution loop. Three sources converge:
- Plan (HOW) —
docs/superpowers/plans/*.mdproduced by GENERATE - TaskMaster (WHAT) —
.taskmaster/tasks/tasks.jsonwith dependencies and complexity scores - CDD (PROOF) — acceptance cards per task, evidence-gated
execute-task is the single skill that runs the full build from "tasks are ready" to SHIP_CHECK_OK. It is autonomous — no AskUserQuestion inside the loop. Any gap that would require user input is surfaced through the recon escalation ladder (step 11) or the inbox (steps 4 and 8), never via a modal prompt.
Entry
This skill is invoked either:
- Directly by the user once HANDOFF has completed and a task-execution mode (A/B/C) has been dispatched, or
- By the
prd-taskmasterorchestrator whencurrent_phaseisEXECUTE.
On entry, confirm that:
.atlas-ai/state/pipeline.jsonexists and recordsphase: EXECUTE.taskmaster/tasks/tasks.jsonexists with at least one ready task.atlas-ai/customizations/system-prompt-template.mdis present (may be empty — absence is a setup bug, empty is fine)
If any of the above are missing, report the gap and halt. Do NOT attempt to bootstrap the missing artifact from inside this loop — that is the orchestrator's job.
Cycle (per iteration)
Each pass through this cycle moves exactly one TaskMaster task from pending
to done. Do the 13 steps in order. Do not skip.
Task-start SHA — at the very beginning of each iteration (before step 2), capture the current git HEAD:
task_start_sha=$(git rev-parse HEAD)Record
$task_start_shain the execute-log row for this iteration. It is the oracle of truth for every reachability sweep in step 9b below: "what modules did THIS task add?" isdiff $task_start_sha..HEAD. The oracle flow already issues per-task start commits; this surfaces the same value in the loop prose.
-
Heartbeat check: verify the execute-task heartbeat timer is running. If missing, register one via
CronCreate("execute-task-heartbeat", "* * * * *", "echo heartbeat"). Abort the iteration if the timer cannot be created — a missing heartbeat means a missing stuck-session detector, and that is load-bearing. -
Inbox reconciliation: read
.atlas-ai/state/pipeline.json,.taskmaster/tasks/tasks.json, and the current TodoWrite list. Diff them. If the three are stale by more than 5 tasks (i.e. TodoWrite says 10 done but tasks.json says 3 done), report the diff and halt — do not paper over bookkeeping drift by silently reconciling. -
Pick next task: run backend op
nextwith the plugin's project-root pointer. Use exactly this invocation:python3 script.py next-taskParse the JSON result.
- If no ready tasks and all tasks are
done, run.atlas-ai/ship-check.py, emit SHIP_CHECK_OK on success, exit the loop. - If no ready tasks but pending tasks exist, the dependency graph is deadlocked — report and halt.
- If no ready tasks and all tasks are
-
Load plan step: search for the matching task ID in this priority order, halting only after all three fail:
docs/superpowers/plans/*.md(the superpowers GENERATE default output).taskmaster/docs/plan.md(the prd-taskmaster HANDOFF default output, whose path is also recorded inpipeline.json:phase_evidence.HANDOFF.plan_file_path)- Any custom path declared in
pipeline.json:phase_evidence.HANDOFF.plan_file_path(in case a future handoff variant writes elsewhere)
If none of the three contains the matching task ID, the task was invented downstream of the plan — mark the task
blocked, inbox the parent orchestrator withmessage_type="blocker", and continue to the next iteration.(Codified 2026-06-04 — yesterday's ai-human-tasker run had its plan at
.taskmaster/docs/plan.mdonly, while this step previously readdocs/superpowers/plans/*.mdexclusively. The controller silently improvised; a cold-start successor would have hit theblockedpath on every task.) -
Generate CDD card: convert the task's
subtasksfield into atesting_plan. Each subtask becomes a verifiable check with a concrete evidence path (file, command output, or test name). Write the card to.atlas-ai/cdd/task-<id>.json. A task without subtasks is treated as a single RED card. -
Set in-progress: run backend op
set-statusfrom the current project root:python3 script.py set-status --id <N> --status in-progressThis flip is observable by watchers and anchors the iteration in TaskMaster itself.
-
Dispatch implementer subagent — NEVER in-session. The controller must:
- Provide the FULL task text to the subagent. Never tell the subagent to "read tasks.json" — per spec §12, the controller serialises the task into the dispatch prompt.
- Inject the plugin customisation block at
.atlas-ai/customizations/system-prompt-template.mdinto the subagent's system prompt. If the file is empty, inject nothing and continue. - Tier the model by TaskMaster complexity score:
1-4 fast— use the fast tier (Haiku-class)5-7 standard— use the standard tier (Sonnet-class)8-10 capable— use the capable tier (Opus-class)
- Wait for the subagent to return a terminal status:
DONE,DONE_WITH_CONCERNS,NEEDS_CONTEXT, orBLOCKED.
Rationale: complexity-tiered dispatch keeps the dollars-per-task curve sensible. A complexity-2 boilerplate task does not need Opus; a complexity-9 architectural task should not be given to Haiku.
-
Route by status: the subagent's return status drives the next move.
- DONE — proceed to the spec gate, then the quality gate. If both pass, advance to step 9.
- DONE_WITH_CONCERNS — the subagent completed but flagged concerns. Address each concern before advancing; re-dispatch if needed.
- NEEDS_CONTEXT — the subagent requested more context. Provide the requested context and re-dispatch. Retry cap at 2 — if the subagent still returns NEEDS_CONTEXT after two re-dispatches, escalate via the recon ladder (step 11).
- BLOCKED — the subagent cannot proceed. Try one model-tier upgrade
first (e.g. standard -> capable). If still blocked, break the task
into smaller subtasks via backend op
expand(python3 script.py expand --id <N>). If still blocked, set status=blocked, inbox parent, halt this iteration.
Do NOT invent new status values. The four above are the only terminal returns. Any other string from the subagent is a protocol violation and should be logged + treated as BLOCKED.
-
Triple verification — the plugin's core quality gate, per spec §11.4. Three independent checks must agree.
Hard exit-code gate (MANDATORY — bypasses agreement count). Before invoking the three checkers, run
.atlas-ai/ship-check.py --dry-run. If it reports any non-zeroExit status Nin evidence files, the task FAILS regardless of how the agent narratives read. SHIP_CHECK_FAIL is NOT a warning. Narrative claiming the exit code is "expected" or "infrastructure noise" does NOT override this gate — write a separatetask-fix-Nto address the underlying failure instead. There is NO override path; Gate 5 is unfakable. (Codified 2026-06-04 after T12 in ai-human-tasker was marked DONE whilepnpm testexited 1 with 11 failing tests.)9b. Reachability sweep (MANDATORY for wired/live tasks). After the hard exit-code gate passes, run the reachability sweep for this task:
python3 script.py reachability-sweep \ --task <task_id> \ --start-commit <task_start_sha>This command:
- Inspects every source module added between
$task_start_shaandHEAD. - Computes a per-task verdict:
WIRED,EXEMPT,ORPHAN, orERROR. - Writes the verdict dict into the task's CDD card
.atlas-ai/cdd/task-<id>.jsonunder the"reachability"key (atomic, additive — existing card keys are preserved).
The sweep exit code encodes the verdict:
exit 0→ WIRED or EXEMPT (pass; proceed to the three checkers).exit 1→ ORPHAN or ERROR (see step 10 for the auto-downgrade path).
For spike/domain-model tasks the sweep returns EXEMPT automatically (no importer search is performed for those tiers).
Why sweep before the triple check? A green test on a module imported by nothing is not "done" — it is scaffolded. The triple check can pass for an ORPHAN module (all tests pass; doubt and validate agree). The reachability gate closes that gap:
donemeans the module is reachable from real production callsites, not just reachable from tests. Wire it or it ships as scaffold.The three checks (run only if the hard gate AND the reachability sweep both pass):
- Plugin-native check: evidence file count vs declared subtask count (from the CDD card in step 5). Missing evidence = fail.
/doubtskill — adversarial doubt sweep on the claimed completion./validateskill — deterministic validation pass (lint / tests / exit codes).- External
Opus subagentsanity pass — asks a fresh subagent "would you merge this?" with the task spec + diff + evidence.
3+ agree pass -> task passes. Disagreement -> halt this iteration, surface to inbox.
- Inspects every source module added between
-
Mark done + propagate state — branch on the sweep verdict from step 9b:
WIRED or EXEMPT (sweep exit 0) → proceed normally:
a. Run backend op
set-statusfor the parent task. Because the sweep already wrote thereachabilityblock into the CDD card, theset-statusCLI auto-reads it — no--reachabilityflag needed:python3 script.py set-status --id <N> --status doneIf you want to be explicit (e.g. for logging), you may pass:
--reachability WIREDor--reachability EXEMPT.b. Subtask writeback: for each subtask
Sintask.subtaskswhose evidence file (per the CDD card from step 5) exists, runpython3 script.py set-status --id <N>.<S> --status done. Subtasks leftpendingwhile the parent isdoneare a data-integrity violation that breaks any tool computing progress from subtask state. (Codified 2026-06-04 — yesterday's run left all 39 subtaskspendingdespite 13/13 parent tasksdone.)c. Update
.atlas-ai/state/pipeline.jsonper-task: callmcp__plugin_prd_go__update_pipeline_task_status(task_id=<N>, status="done")if the MCP tool is available. If not, fall back to atomic read-modify-write using the pattern inmcp-server/pipeline.py:locked_update()— read, append<N>tophase_evidence.EXECUTE.tasks_completed, write to temp, rename. Never leave pipeline.json and tasks.json mutually inconsistent. (Codified 2026-06-04 — yesterday's run promised this write in SKILL.md but never executed it. pipeline.json froze at HANDOFF transition through all 85 minutes of execution.)ORPHAN or ERROR (sweep exit 1) → auto-downgrade to scaffold:
Do NOT mark the task
done. Instead:python3 script.py set-status --id <N> --status scaffoldThen:
- Log to
execute-log.jsonl:"reachability_verdict": "ORPHAN"(or"ERROR"),"auto_downgraded": true, and a plain-English note of which modules are unwired (from the sweep'smoduleslist in the CDD card). - Do NOT halt the loop — continue to the next task (step 1).
An ORPHAN module is scaffolded work, not blocked work. The ship
gate (Gate 6, RA3) will report it honestly as
scaffold, notdone. - If you need to wire the module, create a follow-up task
(
title: "Wire <module> into <entrypoint>") and append it viapython3 script.py expand --id <N>or the MCP equivalent.
Throughline: a green test on a module imported by nothing is not done — wire it or it ships as scaffold. The auto-downgrade ensures the task graph stays honest: Gate 6 will block the ship until every wired/live task's reachability block reads WIRED or EXEMPT. If all wired/live tasks auto-downgraded to scaffold, the ship check will block at Gate 2 ("not every task is done") and the developer must choose: wire the modules, re-tier them (spike/domain-model), or mark them explicitly exempt (
reachableVia: cli:...). There is no silent path to SHIP_CHECK_OK with an unwired module at a wired/live tier. - Log to
-
Check stepback triggers: if 15 minutes have passed with no task moving to done, OR 5 consecutive iterations have failed on the same task class, the recon escalation ladder is MANDATORY. Climb the ladder in this exact order, not out of order:
/stepback->/research-before-coding->/question->pivot/stepback— reassess the architectural assumption. Was the plan wrong?/research-before-coding— feed the blocker into the Perplexity + Context7 + GitHub pipeline for fresh external context./question— batch-research the unresolved unknowns in parallel.pivot— the plan step itself is unsound; kick the task back to the plan author (inbox parent withmessage_type="plan_pivot_requested").
The ladder is append-only — if
/stepbacksurfaces a fix, apply it and return to step 3. Only climb if the prior rung did not yield progress. -
Render progress — show the execute progress panel: MCP
render_status(phase="EXECUTE")→ print itsrenderedfield; CLIpython3 script.py status --phase EXECUTE. Then emit the atlas-gamify one-line score (tasks done / tasks total, complexity-weighted). This is the human-visible progress signal and also feeds the dogfood debrief. -
Loop: back to step 1 until SHIP_CHECK_OK or a halt condition fires.
Termination
The termination sequence is strict — three steps, in order, no shortcuts:
- Run
.atlas-ai/ship-check.py. If it does NOT exit 0, halt. Do NOT emit any completion signal. Investigate the gate failure, fix, retry. - MANDATORY: invoke
Skill(skill: "sync")to refresh the memory bank (session-context/CLAUDE-*.md, MEMORY.md, capability inventory). This MUST happen BEFORE the SHIP_CHECK_OK token is printed. Orchestrators tail-watch the token; if the memory bank is stale when they react, successor sessions inherit a wrong picture of the world. (Codified 2026-06-04 — yesterday's ai-human-tasker run shipped 15.6k LOC whilesession-context/CLAUDE-activeContext.mdstill said "Scaffold complete. No application code yet".) - Print
SHIP_CHECK_OKto stdout. This is the ONLY place in your output where the token may appear — emit it nowhere else, to avoid false-positive matches by log-watchers.
The ship-check script is deterministic. Its gates are documented at the
top of ${CLAUDE_PLUGIN_ROOT}/skel/ship-check.py (copied to .atlas-ai/ship-check.py at setup):
- Gate 1:
pipeline.json current_phase == "EXECUTE" - Gate 2: every
master.tasks[].status == "done" - Gate 3: every task has a CDD card (
task-<id>.jsonor combined variant) - Gate 4: plan file exists at
.taskmaster/docs/plan.mdORdocs/superpowers/plans/*.md - Gate 5 (HARD): no non-zero
Exit status Nline in any evidence file
Gate 5 is the convergent must-do from the 2026-06-04 audit — a "PASS" label on a non-zero-exit test is structurally impossible after this script runs. There is no override path for Gate 5; it is the unfakable oracle.
Do not emit SHIP_CHECK_OK on a mere "DONE" keyword in a subagent reply.
Do not emit on "all tasks marked done" without the explicit ship-check.
Do not emit before /sync has been called.
Red flags
These are the most common pressure points where the loop silently degrades from "verified" to "performative". If you catch yourself thinking any of them, stop and repair the gap.
- "Close enough, mark it done" -> NO. Evidence OR nothing.
- "Let me skip the doubt step this time" -> NO. Triple verification is non-negotiable.
- "I'll retry with same model+prompt" (BLOCKED) -> NO. Escalate.
- "The task says done, don't check evidence files" -> NO. Task status must reflect evidence.
Observability
Every iteration appends a structured row to
.atlas-ai/state/execute-log.jsonl. Field types are strict — text
narrative in a typed field is a logging bug, not compliance. The schema:
iteration(integer, or"FINAL"for the terminal marker)timestamp(ISO 8601 string)task_id(string)complexity(integer or human label)tier(string:"fast"|"standard"|"capable")subagent_status(string:"DONE"|"DONE_WITH_CONCERNS"|"NEEDS_CONTEXT"|"BLOCKED")retry_count(integer)triple_verify(string:"PASS"/"FAIL"plus free-text rationale)stepback_triggered(boolean, REQUIRED — true iff/stepbackwas invoked this iteration). Putting narrative-text in this field is a violation; usestepback_narrativeinstead.stepback_narrative(string, nullable — explanation whenstepback_triggered: true;nullotherwise)ladder_rung(string, nullable — which rung was reached if escalated)gamify(string — atlas-gamify one-line score)
The stepback fields were split (2026-06-04) after a FINAL iteration entry
wrote a paragraph of narrative into the boolean stepback field and was
treated as compliance with the stepback_mandatory rule. Boolean trigger
- nullable narrative is the correct schema.
This log is the dogfood artifact — debrief tools consume it, the orchestrator greps it, and future runs read it for retrospective analysis.
Composition
- Orchestrator handoff: this skill is invoked post-HANDOFF. It does
not call
/handoff— that direction is one-way. - Plan editing: if the plan is unsound, the ladder escalates to
pivot, which inboxes the plan author. This skill does not mutate the plan in place. - Ship-check:
.atlas-ai/ship-check.pyis the terminal gate. This skill calls it; it does not reimplement the checks.
Non-exits
This skill uses no explicit process termination. A halt condition reports the reason in the structured log and returns control to the caller (the user or the orchestrator). Never kill the shell — the caller owns the session lifecycle.
skills/expand-tasks/SKILL.md
npx skills add anombyte93/prd-taskmaster --skill expand-tasks -g -y
SKILL.md
Frontmatter
{
"name": "expand-tasks",
"description": "Expand all TaskMaster tasks with deep research before coding begins. Reads tasks.json, launches parallel research agents per task in waves using the research-expander agent. Writes findings back to tasks.json. Part of the prd-taskmaster toolkit. Use after PRD is parsed and before implementation. Invoke with \/expand-tasks.",
"allowed-tools": [
"Read",
"Write",
"Edit",
"Bash",
"Task",
"Skill",
"Glob",
"Grep",
"AskUserQuestion",
"ToolSearch",
"mcp__atlas-engine",
"mcp__plugin_prd_go",
"mcp__plugin_prd-taskmaster_go",
"mcp__plugin_atlas-go_go"
],
"user-invocable": true
}
Expand Tasks with Research v1.0
Expands TaskMaster tasks with research before coding begins.
Deterministic operations handled by script.py; AI handles judgment.
Script location: skills/expand-tasks/script.py (relative to plugin root)
Part of: prd-taskmaster plugin
Depends on: research-expander agent (parallel research worker), any research
provider configured via task-master models --set-research or registered as an
MCP research tool.
When to Use
Activate when user says: expand tasks, research tasks, research before coding for all, expand subtasks. Do NOT activate for: single task research (use /research-before-coding), PRD generation (use /prd:go).
Native-parallel first (token economy)
Before launching agent waves, check the cheaper path: the native engine expands tasks
in parallel for free. Prefer python3 script.py expand — backend op expand (native api) —
or the expand_tasks MCP tool: it runs structured expand across pending tasks
concurrently (inheriting the engine's ThreadPoolExecutor) on economy-tier models /
keyless host CLIs and merges atomically.
Use THIS skill's agent waves when: no provider/CLI is available, native expand reports
failures for specific tasks (rerun just those here), or the research must be repo-grounded
(agents can read the codebase; native expand cannot).
Prerequisites
- TaskMaster
tasks.jsonmust exist (run/prd:gofirst) - A research provider is configured — either (a)
task-master models --set-research <model> --<provider>for any task-master provider family, or (b) an MCP research tool registered in~/.claude.jsonthat Claude Code can call directly (for examplemcp__plugin_prd_go__*tools or an external search/reason MCP) - At least 1 task in
tasks.json
Workflow (5 Steps)
Step 1: Preflight
python3 skills/expand-tasks/script.py read-tasks
Returns JSON: total, expanded, pending_expansion, tasks[].
If pending_expansion is 0: Report all tasks already expanded. Exit skill.
If research provider is not configured: Check via task-master models and verify a research role is set. If none, tell the user to configure one (task-master models --set-research <model> --<provider>) and exit. The skill does not assume any specific research backend — it uses whatever is configured.
Step 2: Choose Scope
Use AskUserQuestion:
- All tasks (default): Expand every task that hasn't been researched yet
- Specific tasks: User provides task IDs (comma-separated)
- By dependency level: Expand tasks with no dependencies first, then next wave
AI judgment: Recommend "All tasks" for initial expansion, "By dependency level" for incremental work.
Step 3: Generate Research Prompts
For each task to expand:
python3 skills/expand-tasks/script.py gen-prompt --task-id <ID>
Returns JSON with prompt field containing the full research agent prompt.
AI judgment: Review the auto-generated prompt. Customize research questions if the task needs domain-specific queries. Add project context from the PRD or session-context files if relevant.
Step 4: Launch Parallel Research Agents
Launch research agents in parallel waves. Each wave = up to 5 concurrent agents.
For each task, spawn a Task agent using the dedicated research-expander
subagent type (defined in agents/research-expander.md):
Task(
subagent_type: "research-expander",
description: "Research Task <ID>: <title>",
run_in_background: true,
prompt: <prompt from Step 3>
)
Wave strategy:
- Wave 1: Tasks with no dependencies (they inform downstream tasks) — run in parallel
- Wave 2: Tasks depending on Wave 1 — run in parallel
- Wave 3+: Continue until all tasks covered — run in parallel per wave
- Max 5 agents per wave to avoid overwhelming the configured research backend
Wait for each wave to complete before launching the next. Parallel dispatch only happens WITHIN a wave; waves themselves are serial.
Step 5: Collect and Write Results
As each research-expander agent completes, save its research output:
-
Write agent output to a temp file:
cat > /tmp/research-task-<ID>.md <<'EOF' <agent output> EOF -
Write research back to
tasks.json:python3 skills/expand-tasks/script.py write-research --task-id <ID> --research /tmp/research-task-<ID>.md -
After all tasks are written, verify:
python3 skills/expand-tasks/script.py status
AI judgment: Review each research result for quality. If a result is too thin (< 5 lines of useful content) or clearly failed, re-run that specific task's research through a fresh research-expander invocation.
Research Agent Prompt Pattern
The gen-prompt command generates prompts that follow the
research-before-coding pattern:
- Agent receives task context (title, description, dependencies, subtasks)
- Agent runs 3-5 targeted queries against the user's configured research provider. The
research-expanderagent is tool-agnostic: it picks up whichever research tools are available in the current Claude Code session. This may betask-master research, an MCP search/reason tool from~/.claude.json(including anymcp__plugin_prd_go__*tools registered by this plugin), WebSearch as a last resort, or whatever the user has bound. The skill does not hard-code any specific research MCP. - Agent distills results into structured summary
- Summary returns to main context (~25-40 lines per task)
Critical: prefer structured research tools (task-master research, MCP
search/reason tools) over raw WebSearch/WebFetch when available — they produce
cleaner outputs with citations.
Error Handling
| Error | Action |
|---|---|
| Research provider unreachable or rate-limited | Exit skill, tell user to verify task-master models research role is set and reachable |
research-expander agent returns empty/failed |
Re-run that specific task with different queries |
tasks.json not found |
Exit skill, tell user to run /prd:go first |
| Task already expanded | Skip silently unless user forces re-expansion |
| Agent timeout | Mark task as failed, continue with others |
Output
After all tasks are expanded, the skill reports:
- Total tasks expanded
- Any failures that need retry
- Next recommended action (usually: begin implementation)
Integration with prd-taskmaster
This skill fits between Step 8 (Parse & Expand Tasks) and Step 11 (Choose Next Action) of the prd-taskmaster workflow. After PRD is parsed into tasks but before execution begins.
/prd:go → generates PRD → parses into tasks
↓
/expand-tasks → research-expander agents run in Parallel waves → writes findings back to tasks.json
↓
Implementation begins (with research context in each task)
Tips
- Run after PRD generation but before any implementation
- Research results are stored in
research_notesfield of each task intasks.json - Re-running on already-expanded tasks is safe (will skip unless forced)
- For very large task lists (20+), consider expanding in dependency order to save context
- Each
research-expanderagent typically completes in ~30s depending on research backend and query depth; 15 tasks ≈ 3 waves ≈ 2-3 minutes total
skills/generate/SKILL.md
npx skills add anombyte93/prd-taskmaster --skill generate -g -y
SKILL.md
Frontmatter
{
"name": "generate",
"description": "Phase 2 of the prd-taskmaster pipeline: spec generation and task parsing. Loads a template (comprehensive|minimal), fills it with DISCOVER-phase constraints and answers, validates the spec (placeholders_found, grade thresholds), parses the PRD into tasks via task-master, runs TaskMaster's native complexity analysis, and expands every task into verifiable subtasks. Autonomous-safe. Declares GENERATE complete so HANDOFF can follow.",
"allowed-tools": [
"Read",
"Write",
"Edit",
"Bash",
"Skill",
"ToolSearch",
"mcp__atlas-engine",
"mcp__plugin_prd_go",
"mcp__plugin_prd-taskmaster_go",
"mcp__plugin_atlas-go_go"
],
"user-invocable": false
}
Phase 2: Generate
Declarative phase skill. Invoked by the prd-taskmaster orchestrator when
current_phase is GENERATE. Never called directly by a user.
The one rule: generate the spec, validate it catches placeholders, parse it into tasks, expand every task into subtasks. Quality over speed.
Entry gate
-
Call
mcp__plugin_prd_go__check_gate(phase="GENERATE", evidence={})for diagnostics.check_gateis an EXIT gate: it checkstask_count > 0,subtask_coverage >= 1.0, andvalidation_grade in (EXCELLENT, GOOD)— all of which are GENERATE's OWN OUTPUTS, i.e. evidence to advance, not preconditions to enter. On first entry none exist yet, so agate_passed: falsehere is EXPECTED — the state machine's legal transitions already guarantee only legal entry.- First entry (no evidence yet): note the result and continue with the Procedure.
- Re-entry: if the gate reports violations, report them and stop — it protects against re-running a completed phase or skipping ahead from DISCOVER.
-
Read the DISCOVER output (discovery summary +
CONSTRAINTS CAPTUREDblock- scale classification). If any of these are missing, report and stop — the gate should have caught this, but belt-and-braces.
Generate checklist
Copy into your response before running the procedure:
GENERATE CHECKLIST:
- [ ] Template loaded (comprehensive|minimal)
- [ ] Spec written with discovery answers (no bare placeholders remaining)
- [ ] CONSTRAINT CHECK: every DISCOVER constraint appears in the spec
- [ ] SCOPE CHECK: task count matches scale (Solo 8-12, Team 12-20, Enterprise 20-30)
- [ ] Validation score: ___ / ___ (grade: ___)
- [ ] placeholders_found: ___ (bare placeholders = 0 required)
- [ ] Warnings addressed or acknowledged
- [ ] Tasks parsed: ___ tasks created
- [ ] Complexity analyzed via TaskMaster: Y/N
- [ ] All tasks expanded into subtasks: Y/N
Step 1: Choose and load template
Decide based on discovery depth:
- Comprehensive: 4+ detailed answers, complex project, Team / Enterprise scale
- Minimal: thin answers, user wants speed, Solo scale
MCP (preferred): mcp__plugin_prd_go__load_template(type="comprehensive")
CLI fallback: python3 script.py load-template --type comprehensive
The template is the canonical shape — do not invent your own. If the template load fails, report and stop. Do not paper over with a home-rolled skeleton.
Step 2: Generate spec at .taskmaster/docs/prd.md
Fill the template with discovery answers. AI judgment required:
- Replace ALL placeholders with actual content pulled from DISCOVER.
- Expand with project-specific details — do not leave template prose verbatim.
- Add technical depth proportional to what the user provided in discovery.
- Generate domain-appropriate sections (pentest = threat model, app = user stories, business = success metrics, learning = assessment criteria).
- Document assumptions where discovery was thin — explicitly, not silently.
CONSTRAINT CHECK (MANDATORY)
Verify EVERY constraint from the DISCOVER phase CONSTRAINTS CAPTURED block
appears in the spec. If "must use Python" was a constraint, the spec MUST
reference Python. Missing constraints = spec bug.
Emit the check explicitly:
CONSTRAINT CHECK:
- Tech stack (Python): FOUND in spec section "Technical Stack"
- Timeline (MVP in 2 weeks): FOUND in spec section "Milestones"
- ...
Every constraint must be marked FOUND. If any are MISSING, loop back and fix the spec before proceeding.
SCOPE CHECK (MANDATORY)
Use the scale classification from DISCOVER to set task count range:
| Scale | Task Count | Subtask Depth |
|---|---|---|
| Solo | 8–12 | 2–3 subtasks each |
| Team | 12–20 | 3–5 subtasks each |
| Enterprise | 20–30 | 5–8 subtasks each |
If DISCOVER classified the project as Team but the spec implies 30 tasks, that's a scope bug — narrow the spec or re-classify explicitly.
Domain-neutral vocabulary
When the domain is unclear, default to neutral terms:
| Software term | Neutral equivalent | When to use neutral |
|---|---|---|
| tests | verification criteria | pentest, business, learning |
| code | deliverable | business, learning |
| deploy | execute / deliver | business, learning |
| repo | workspace | non-software |
| PR | output / submission | non-software |
If the domain IS software, use software terms. Neutral terms are for non-software goals.
Deferred decisions — the reason: convention
Every [placeholder], {{variable}}, [TBD], [TODO] must be either:
(a) Replaced with real content,
(b) Removed entirely, or
(c) Paired with a reason: explanation on the same line or the next line
documenting why the decision is deferred.
Per the v4 spec: placeholders with reason: attribution are allowed and
surfaced in the validation output as deferred_decisions. A bare placeholder
is a validation failure; an attributed one is a known deferred decision with
accountability.
Examples:
# BAD — bare placeholder, fails validation:
Target latency: {{TBD}}
# GOOD — attributed, appears in deferred_decisions:
Target latency: {{TBD}} reason: awaiting load-test results scheduled 2026-04-20
Write the final spec to .taskmaster/docs/prd.md. This is the canonical
path — downstream tools read from here.
Step 3: Validate spec quality
MCP (preferred): mcp__plugin_prd_go__validate_prd(input_path=".taskmaster/docs/prd.md")
CLI fallback: python3 script.py validate-prd --input .taskmaster/docs/prd.md
Returns: score, grade, checks, warnings, placeholders_found. The
validate call persists its result, so render the GENERATE scorecard and print
it: MCP render_status(phase="GENERATE") → print rendered; CLI
python3 script.py status --phase GENERATE.
Optional AI-augmented review (opt-in): pass --ai (CLI) or ai=True (MCP)
to additionally invoke TaskMaster's configured main model for a holistic
quality review. The deterministic regex checks always run first — AI review
is additive, never a replacement.
Grading thresholds:
- EXCELLENT: 91%+
- GOOD: 83–90%
- ACCEPTABLE: 75–82%
- NEEDS_WORK: <75%
Decision rules:
- If
placeholders_found > 0(bare placeholders, notreason:-attributed): fix before proceeding. No exceptions. - If grade is NEEDS_WORK: offer auto-fix or proceed-with-risk — do not silently advance. Surface the decision.
- If grade is ACCEPTABLE or better AND placeholders_found == 0: proceed to Step 4.
Step 4: Parse tasks via backend
Calculate task count first:
MCP: mcp__plugin_prd_go__calc_tasks(requirements_count=<count>)
CLI: python3 script.py calc-tasks --requirements <count>
Then parse through the normative backend operation:
backend op parse-prd: python3 script.py parse-prd --input .taskmaster/docs/prd.md --num-tasks <recommended>
TaskMaster backend direct methods (only when explicitly operating that backend):
- MCP:
mcp__task-master-ai__parse_prd(input=".taskmaster/docs/prd.md", numTasks=<recommended>) - MCP fallback:
mcp__plugin_prd_go__tm_parse_prd(input_path=".taskmaster/docs/prd.md", num_tasks=<recommended>) - CLI:
task-master parse-prd --input .taskmaster/docs/prd.md --num-tasks <recommended>
The backend operation writes to .taskmaster/tasks/tasks.json. Verify the file exists
and contains the expected number of tasks before continuing.
Step 5: Rate complexity via backend
Use the normative backend operation instead of home-rolled classification:
backend op rate: python3 script.py rate
TaskMaster backend direct methods (only when explicitly operating that backend):
- MCP:
mcp__task-master-ai__analyze_complexity(analyzes all tasks) - MCP fallback:
mcp__plugin_prd_go__tm_analyze_complexity(wraps the CLI) - CLI:
task-master analyze-complexity
Important — output location: the analyze-complexity step does NOT emit
JSON to stdout. It writes structured analysis to
.taskmaster/reports/task-complexity-report.json and prints a human-readable
table to stdout. To read the structured result, read the report file:
cat .taskmaster/reports/task-complexity-report.json | jq .
Do not try to parse the stdout table — it's colour-coded ASCII and will break consumers. TaskMaster's built-in analysis is more accurate than anything hand-rolled because it has full context of the task graph and dependencies.
Step 6: Expand tasks into subtasks (MANDATORY)
Every task MUST be expanded into subtasks before HANDOFF. Subtasks are verifiable checkpoints — without them, tasks are black boxes that either pass or fail with no intermediate proof.
Use backend op expand, NOT bare per-id parallel calls
Per-id parallel calls (e.g. task-master expand --id=1 & task-master expand --id=2 &) hit a non-atomic read-modify-write race on
.taskmaster/tasks/tasks.json: every parallel writer reads the same starting
snapshot, adds its own subtasks, and writes the whole file back. The last
writer wins and earlier writes are silently lost — the AI call reports
success, the subtasks were generated, but they never landed on disk.
Detected in the v4 Shade dogfood 2026-04-13.
backend op expand is the correct path:
python3 script.py expand
The native engine is the sole generator. script.py expand (backend op expand)
expands pending tasks via the native structured path — a keyless host CLI
(claude/codex/gemini) or a provider API key — running in parallel and
applying atomically. When no provider/CLI is available it falls back to
agent-parallel planning + atomic apply (the native/agent floor).
Patience under slow providers
Under claude-code (Claude Max rate-limited) or local ollama, --all
can run for 5–15 minutes on a 12-task project. Do NOT time out aggressively.
Use .taskmaster/tasks/tasks.json mtime as the liveness signal:
- mtime updated within last 60s → work is landing, keep waiting
- mtime stale for 120s+ → investigate (rate limit, provider crash, network)
- Never conclude STUCK from a single capture — always compare two snapshots 30–60s apart
Verify coverage (read tasks.json DIRECTLY, not task-master list)
task-master list --format json has been observed to return a different
top-level schema from tasks.json, causing consumers to report 0/N
coverage even when all tasks have subtasks on disk (v4 dogfood LEARNING
#15). Always read the canonical file directly:
python3 -c "
import json
d = json.load(open('.taskmaster/tasks/tasks.json'))
# tasks.json is tag-grouped (master, defaults, feature branches) — walk all tags
all_tasks = []
if 'master' in d and isinstance(d['master'], dict):
all_tasks = d['master'].get('tasks', [])
elif 'tasks' in d:
all_tasks = d['tasks']
else:
for v in d.values():
if isinstance(v, dict) and 'tasks' in v:
all_tasks.extend(v['tasks'])
counts = [len(t.get('subtasks', [])) for t in all_tasks]
covered = sum(1 for c in counts if c > 0)
total = len(all_tasks)
no_subs = [t['id'] for t in all_tasks if not t.get('subtasks')]
if no_subs:
print(f'WARNING: {covered}/{total} tasks expanded. Missing: {no_subs}. Re-run backend op expand.')
else:
print(f'OK: All {total} tasks expanded ({sum(counts)} subtasks total).')
"
Idempotent recovery
If any task still shows 0 subtasks after --all completes (rate-limit hiccup,
provider timeout, partial run), re-run the same command:
python3 script.py expand
The backend operation only re-expands tasks that are still in pending state
with 0 subtasks, so a second invocation is safe and recovers gracefully. Do NOT
work around it with parallel per-id calls — that is the exact pattern that
causes silent data loss.
Evidence gate
Gate: spec validation grade is ACCEPTABLE+ AND placeholders_found == 0 AND
tasks parsed AND complexity analyzed AND all tasks have subtasks in
.taskmaster/tasks/tasks.json.
Emit a compact one-block status:
Generate:
spec: .taskmaster/docs/prd.md (grade: <grade>, score: <n>/<total>)
placeholders_found: <n> (bare), <m> deferred_decisions
tasks parsed: <n>
complexity report: .taskmaster/reports/task-complexity-report.json
subtask coverage: <n>/<n> tasks expanded (<total> subtasks)
Exit gate
After the evidence gate passes:
- Call
mcp__plugin_prd_go__advance_phase(expected_current="GENERATE", target="HANDOFF", evidence={"validation_grade": "<EXCELLENT|GOOD|ACCEPTABLE>", "task_count": <int>, "subtask_coverage": <float 0-1>, "placeholders_found": <int>}). The call atomically transitionspipeline.jsonfrom GENERATE to HANDOFF. Theexpected_currentfield is the compare-and-swap guard;evidenceis stored underphase_evidence[HANDOFF]for audit. - Return control to the orchestrator (
prd-taskmasterskill). Do NOT invoke HANDOFF directly — the orchestrator re-readscurrent_phaseand routes.
Red flags (stop and report, do not paper over)
- "The validation says placeholders_found=3 but the content reads fine —
I'll advance anyway" → NO. Bare placeholders are a hard fail. Fix or
attribute with
reason:. - "
task-master expand --allis slow, let me runexpand_taskin parallel across IDs to speed it up" → NO. That is the exact race that silently drops subtasks. Serial--allor serial per-id only. - "A constraint from DISCOVER isn't in the spec — I'll add it to the handoff note instead" → NO. Constraints live in the spec. Fix the spec.
- "Complexity analyze output looked odd, I'll skip reading the JSON report"
→ NO. Read
.taskmaster/reports/task-complexity-report.jsondirectly; the stdout table is decoration. - "I can call advance_phase without check_gate" → NO. Gate first, always.
- "The template prose is close enough, I'll ship it verbatim" → NO. The template is a shape, not content. Fill every section with project-specific material.
Non-exits
This skill does not use explicit process termination. A hard block reports the reason and returns control to the orchestrator; the orchestrator decides whether to surface to the user.
skills/go/SKILL.md
npx skills add anombyte93/prd-taskmaster --skill go -g -y
SKILL.md
Frontmatter
{
"name": "go",
"description": "Zero-config goal-to-tasks engine. Takes any goal (software, pentest, business, learning), runs adaptive discovery, generates a validated spec, parses into TaskMaster tasks, creates an implementation plan, and executes with built-in CDD verification. Use when user says \"PRD\", \"product requirements\", \"I want to build\", or any goal-driven phrase.",
"allowed-tools": [
"Read",
"Skill",
"Bash",
"AskUserQuestion",
"ToolSearch",
"mcp__atlas-engine",
"mcp__plugin_prd_go",
"mcp__plugin_prd-taskmaster_go",
"mcp__plugin_atlas-go_go"
],
"user-invocable": true
}
go (orchestrator)
Pure routing. Reads pipeline state, dispatches to the correct phase skill.
Deferred MCP tools: in Claude Code the engine's MCP tools are often deferred — not
callable until loaded. If a tool below is not directly callable, first run
ToolSearch(query="select:mcp__plugin_prd_go__preflight") (keyword fallback
ToolSearch(query="+atlas engine preflight", max_results=10)) and use whichever prefix
matches (mcp__plugin_prd_go__ or mcp__atlas-engine__).
Flow
-
Call
mcp__plugin_prd_go__preflight()— get environment state -
Call
mcp__plugin_prd_go__current_phase()— get pipeline state -
Route via Skill tool:
- current_phase is null or SETUP → invoke
/prd:setup - current_phase is DISCOVER → invoke
/prd:discover - current_phase is GENERATE → invoke
/prd:generate - current_phase is HANDOFF → invoke
/prd:handoff - current_phase is EXECUTE → invoke
/prd:execute-task
- current_phase is null or SETUP → invoke
-
After phase skill returns, re-check current_phase. If it advanced, route to the next phase. If not, report the blocker.
Stateless routing
This skill does NOT hold procedure. Each phase skill owns its own logic. The orchestrator survives context loss because every phase skill reads current_phase() on entry.
Red flags
These thoughts mean STOP, you're rationalising:
- "I know which phase we're in, skip preflight" → NO. Preflight is cheap.
- "The phase skill already ran, I don't need to re-check" → NO. Context might have died.
- "I can just do the work myself" → NO. Dispatch to the phase skill.
skills/setup/SKILL.md
npx skills add anombyte93/prd-taskmaster --skill setup -g -y
SKILL.md
Frontmatter
{
"name": "setup",
"description": "Phase 0 of the prd-taskmaster pipeline. Resolves the active backend, initializes the project, configures the provider stack when the TaskMaster backend is active (DETECT-FIRST — never overwrite a working user config), and verifies the AI pipeline. Autonomous: zero user questions unless a hard block is hit. Declares the Setup phase complete so DISCOVER can follow.",
"allowed-tools": [
"Read",
"Bash",
"Skill",
"ToolSearch",
"mcp__atlas-engine",
"mcp__plugin_prd_go",
"mcp__plugin_prd-taskmaster_go",
"mcp__plugin_atlas-go_go"
],
"user-invocable": false
}
Phase 0: Setup
Declarative phase skill. Invoked by the prd-taskmaster orchestrator when
current_phase is null or SETUP. Never called directly by a user.
Entry gate
-
Call
mcp__plugin_prd_go__check_gate(phase="SETUP", evidence={})for diagnostics.check_gateis an EXIT gate: it verifies you have the evidence to advance, not to enter. On first entry you have no evidence yet (Step 4 below producesvalidate_setup.ready=true), so agate_passed: falseresult here is EXPECTED — the state machine's legal transitions (None → SETUP) already guarantee only legal entry.- First entry (no evidence yet): note the result and continue with the Procedure.
- Re-entry: if the gate reports violations, report them and stop — it protects against re-running a completed phase or skipping ahead.
Enforce the gate when you ADVANCE (after the procedure), not on entry.
Procedure (5 steps, abort on hard failure)
Step 1: Backend detection
Run backend detection:
python3 script.py backend-detect
The native engine is the sole generator and needs no external binary — a
keyless host CLI (claude / codex / gemini) on PATH, or a provider API key,
is sufficient (see Chunk 7's atlas setup wizard). The task-master binary is
no longer required or supported; backend-detect reports its presence purely as
informational. Continue with the resolved (native) backend.
Step 2: Project init
Check whether the current project has a .taskmaster/ directory (the engine
still reads/writes the .taskmaster/ file format for tasks and config).
If missing, run backend op init:
python3 script.py init-project
This initialises the native project state and the .taskmaster/ file format. If
.taskmaster/ is present, continue.
Step 2.5: Customisation bootstrap (REQUIRED — closes execute-task deadlock)
execute-task requires .atlas-ai/customizations/system-prompt-template.md
to exist as a precondition (its Entry gate halts otherwise). It cannot
create the file from inside the loop — the failure mode is a hard halt with
no recovery path.
This step ensures the file exists BEFORE execute-task ever runs:
PLUGIN_SKEL="${CLAUDE_PLUGIN_ROOT}/skel/customizations"
mkdir -p .atlas-ai/customizations
if [ ! -f .atlas-ai/customizations/system-prompt-template.md ]; then
if [ -d "$PLUGIN_SKEL" ]; then
cp -n "$PLUGIN_SKEL"/*.md .atlas-ai/customizations/ # -n: no-clobber, copy starter pack
else
: > .atlas-ai/customizations/system-prompt-template.md # empty is fine per execute-task Entry gate
fi
fi
The starter pack (domain-vocabulary.md, system-prompt-template.md,
task-enrichment-rules.md, verification-preferences.md) is editable —
users tune them to project-specific terminology. Empty is acceptable; the
file simply must exist.
Also scaffold .atlas-ai/ship-check.py if it doesn't already exist:
if [ ! -f .atlas-ai/ship-check.py ] && [ -f "${CLAUDE_PLUGIN_ROOT}/skel/ship-check.py" ]; then
cp "${CLAUDE_PLUGIN_ROOT}/skel/ship-check.py" .atlas-ai/ship-check.py
chmod +x .atlas-ai/ship-check.py
fi
(Codified 2026-06-04 — yesterday's run halted at execute-task Entry
because system-prompt-template.md was missing; the file had to be
manually touch-ed from outside the loop.)
Step 3: Provider configuration — DETECT-FIRST
When the TaskMaster backend is active, read task-master models output BEFORE
setting anything. This is the load-bearing rule. A working user config must
NOT be overwritten silently. When the native backend is active, provider
configuration is handled by the resolved backend and this TaskMaster-specific
step is informational only.
task-master models output |
Action |
|---|---|
| Main / Research / Fallback all populated with a supported provider | SKIP — go to Step 4. |
| Main set, Research/Fallback empty | Partial mutate — fill the empty roles only. |
| All three empty (fresh install) | Full configure — use the default stack below. |
| Provider flagged unsupported / deprecated | Ask the user before mutating. |
Why DETECT-FIRST: v4 dogfood (2026-04-13, LEARNING #9) caught the skill
overwriting a working gemini-cli / gemini-3-pro-preview config because the
procedure wasn't branch-aware. Detect first, mutate only the empty slots.
Default stack (fresh install only):
task-master models --set-main gemini-3-pro-preview --gemini-cli
task-master models --set-research gemini-3-pro-preview --gemini-cli
task-master models --set-fallback gemini-3-flash-preview --gemini-cli
Why Gemini CLI: ~113× more token-efficient than sonnet on parse-prd, free via any Google account, no API key. One provider, three roles, zero cost.
Alternatives: Claude Max (--claude-code sonnet/opus/haiku), any of the
12 task-master provider families, or a registered MCP research tool for the
Research role.
Step 4: Probe test
If tasks already exist, call the MCP tool
mcp__plugin_prd_go__validate_setup or run backend op rate:
python3 script.py rate
If no tasks exist yet (fresh project), skip the probe — Step 3's provider configuration is sufficient evidence the pipeline is wired.
Step 5: Status line
Render the preflight progress panel and print it. MCP-mode: call
render_status(phase="SETUP") and print its rendered field. CLI-mode:
python3 script.py status --phase SETUP. (Fallback if the renderer is
unavailable — emit a compact one-block status:)
Setup:
task-master: installed (<version>)
project: initialized (.taskmaster/)
provider: <main-provider> (main) / <research-provider> (research)
pipeline: verified
Exit gate
After Steps 1–5 report green:
- Call
mcp__plugin_prd_go__advance_phase(expected_current="SETUP", target="DISCOVER", evidence={"validate_setup": <Step 4 result dict>, "provider_configured": True}). The call atomically transitionspipeline.jsonfrom SETUP to DISCOVER. Theexpected_currentfield is the compare-and-swap guard;evidenceis stored underphase_evidence[DISCOVER]for audit. - Return control to the orchestrator (
prd-taskmasterskill). Do NOT invoke DISCOVER directly — the orchestrator re-readscurrent_phaseand routes.
Red flags (stop and report, do not paper over)
- "The config is set but looks wrong — I'll fix it" → NO. Report and ask.
- "No tasks exist so I'll skip backend detection" → NO. Backend detection must run before DISCOVER so later backend ops resolve consistently.
- "I'll auto-install task-master via npm" → NO. Installation is a user action; this skill only reports that installation unlocks the TaskMaster backend.
- "I can call advance_phase without check_gate" → NO. Gate first, always.
Non-exits
This skill does not use explicit process termination. A hard block reports the reason and returns control to the orchestrator; the orchestrator decides whether to surface to the user.
skills/customise-workflow/SKILL.md
npx skills add anombyte93/prd-taskmaster --skill customise-workflow -g -y
SKILL.md
Frontmatter
{
"name": "customise-workflow",
"description": "Customise the prd-taskmaster plugin workflow via curated brainstorm questions. The AI asks, the user answers in plain English, and the skill writes their preferences to .atlas-ai\/config\/atlas.json. Future runs of prd-taskmaster read that file and apply user preferences to phase gates, validation strictness, default provider, preferred execution mode, and template choice. For deeper tweaks beyond the curated questions, users can hand-edit files in .atlas-ai\/customizations\/. Use when the user says \"customise workflow\", \"customize workflow\", \"adjust my PRD settings\", \"tune the skill\", or wants to change how prd-taskmaster behaves.",
"allowed-tools": [
"Read",
"Write",
"Edit",
"Bash",
"AskUserQuestion",
"ToolSearch",
"mcp__atlas-engine",
"mcp__plugin_prd_go",
"mcp__plugin_prd-taskmaster_go",
"mcp__plugin_atlas-go_go"
],
"user-invocable": true
}
customise-workflow
AI-driven workflow customisation for the prd-taskmaster plugin.
Replaces manual JSON editing. Part of the plugin's companion-skills family.
Script: skills/customise-workflow/script.py (all commands output JSON)
Plugin config root: .atlas-ai/ (per-project, lives alongside TaskMaster's
.taskmaster/)
When to Use
Activate when the user says: "customise workflow", "customize workflow", "adjust PRD settings", "tune the skill", "change my defaults", or "personalise prd-taskmaster".
Skip: generating a new PRD (use /prd:go), executing tasks (use
HANDOFF modes), or running research expansion (use /expand-tasks).
The One Rule
The AI asks the questions and writes the config. The user never manually
edits JSON. The config file is the output, not the input. If the user wants
tweaks beyond the curated questions, point them at .atlas-ai/customizations/
(see "Customizations directory" below) — do not hand them raw JSON.
Flow
LOAD → ASK → VALIDATE → WRITE → VERIFY
Phase 1: LOAD current config
Run the script to load existing preferences (or defaults if first run):
python3 skills/customise-workflow/script.py load-config
Returns JSON with current preferences across 6 categories: provider,
validation, execution, template, autonomous, gates. Writes to
.atlas-ai/config/atlas.json if missing, seeding defaults.
Phase 2: ASK curated questions
Read questions/curated-questions.md and ask each one via AskUserQuestion.
The questions are curated so plain-English answers map cleanly to config keys.
Example:
Q1: Which AI provider do you prefer for task generation?
Options: Gemini (free, token-efficient), Claude Code (free, Max only),
OpenAI GPT-4, Anthropic Direct API, OpenRouter, Ollama (local)
Q2: How strict should PRD validation be?
Options: Strict (block on NEEDS_WORK), Normal (warn but allow GOOD+),
Lenient (accept ACCEPTABLE+)
Q3: Which execution mode should prd-taskmaster default to?
Options: A (Plan Mode), B (Ralph loop), C (Atlas Fleet), ...
...
Do NOT ask all questions at once. Ask one curated question at a time and
adapt follow-ups based on answers. (Same pattern as
superpowers:brainstorming.)
Phase 3: VALIDATE answers
Run the script with each user answer as it arrives. The script validates the
answer against allowed values and returns either ok: true or a hint about
what's wrong.
python3 skills/customise-workflow/script.py validate-answer \
--key provider_main --value gemini-cli
If validation fails, re-ask the question with the hint. Never write an invalid value.
Phase 4: WRITE config
After all curated questions are answered, commit the config:
python3 skills/customise-workflow/script.py write-config --input /tmp/answers.json
This writes to .atlas-ai/config/atlas.json in the current project.
Idempotent — re-running customise-workflow reads and updates the existing
file. The script creates the .atlas-ai/config/ directory if missing.
Phase 5: VERIFY
Show the user their final config and confirm it matches their intent:
python3 skills/customise-workflow/script.py show-config
If the user says "that's not what I meant" for any key, re-enter Phase 2 for just that key, re-validate, and re-write.
Script Commands Reference
| Command | Purpose |
|---|---|
load-config |
Load current .atlas-ai/config/atlas.json (or defaults) |
list-questions |
Return the curated question set as JSON |
validate-answer --key K --value V |
Validate a single answer |
write-config --input <file> |
Write validated answers to .atlas-ai/config/atlas.json |
show-config |
Display current config |
reset-config |
Delete .atlas-ai/config/atlas.json (back to defaults) |
Config Schema
.atlas-ai/config/atlas.json has 7 top-level keys:
{
"token_economy": "conservative|balanced|performance",
"provider": {
"main": "gemini-cli|claude-code|anthropic|openai|openrouter|ollama|...",
"model_main": "gemini-3-pro-preview|sonnet|gpt-4o|...",
"research": "gemini-cli|perplexity|...",
"model_research": "sonar-pro|gemini-3-pro-preview|...",
"fallback": "gemini-cli|claude-code|...",
"model_fallback": "gemini-3-flash-preview|haiku|..."
},
"validation": {
"strictness": "strict|normal|lenient",
"ai_review_default": true,
"min_passing_grade": "EXCELLENT|GOOD|ACCEPTABLE|NEEDS_WORK"
},
"execution": {
"preferred_mode": "A|B|C|D|E|F|G|H|I|J",
"auto_handoff": true,
"external_tool": "cursor|codex-cli|gemini-cli|..."
},
"template": {
"default": "comprehensive|minimal",
"custom_template_path": null
},
"autonomous": {
"allow_self_brainstorm": true,
"ralph_loop_auto_approve": true
},
"gates": {
"skip_phase_0_if_validated": false,
"skip_user_approval_in_discovery": false,
"require_research_expansion": true
}
}
Phase files (skills/setup, skills/discover, skills/generate,
skills/handoff, skills/execute-task) read this config at runtime and apply
user preferences before falling back to documented defaults.
token_economy here is honored by the engine itself: load_fleet_config reads it
from this file when .atlas-ai/fleet.json does not set one (fleet.json wins if it
does), so the economy you pick via this skill actually drives model-tier routing.
Customizations directory
For tweaks that go beyond the curated questions — custom template overrides,
provider-model mapping tables, gate hooks, per-phase overrides — users can
drop files into .atlas-ai/customizations/. This is the escape hatch for
power users. The curated questions cover the 80% case; the customization
directory covers everything else.
Expected layout:
.atlas-ai/
config/
atlas.json # written by this skill
customizations/ # user-editable, never overwritten by this skill
templates/ # custom PRD templates
prompts/ # provider prompt overrides
gates/ # custom gate predicates
README.md # user-authored notes
Rules:
- This skill NEVER writes into
.atlas-ai/customizations/— that's user territory. - Phase skills read
.atlas-ai/customizations/as a fallback after the curatedatlas.jsonbut before documented defaults. - When a user asks for a setting not covered by curated questions, the AI proposes a customization file shape, the user edits, and the AI verifies the file parses.
Critical Rules
- Never ask the user to edit JSON directly — the skill asks curated questions and writes the file.
- Questions are curated and AI-adapted, not a fixed form — adapt follow-ups to earlier answers.
- Every answer is validated before being written (
validate-answer). - Config is idempotent — re-running updates cleanly.
- Config is per-project (lives in
.atlas-ai/config/), not global. - Customization files live in
.atlas-ai/customizations/and are user-authored — this skill never overwrites them. - Phase skills must GRACEFULLY FALL BACK to documented defaults when config keys are missing.
skills/handoff/SKILL.md
npx skills add anombyte93/prd-taskmaster --skill handoff -g -y
SKILL.md
Frontmatter
{
"name": "handoff",
"description": "Phase 3 of the prd-taskmaster pipeline: smart mode selection and user handoff. Detects installed capabilities (superpowers, ralph-loop, task-master-ai, playwright, research providers), recommends ONE execution mode (A\/B\/C) with reasoned justification, appends the task-execution workflow to CLAUDE.md, surfaces a structured AskUserQuestion multi-option picker for user agency, and dispatches the chosen mode. Mode D (Atlas Fleet) is selectable only when detect_capabilities returns tier=premium (licensed atlas-launcher detected); otherwise it is a locked Atlas Pro teaser. Plan Mode is NOT used (spec section 13.5): AskUserQuestion is the sole user-agency mechanism. Declares HANDOFF complete so EXECUTE can follow.",
"allowed-tools": [
"Read",
"Skill",
"AskUserQuestion",
"ToolSearch",
"mcp__atlas-engine",
"mcp__plugin_prd_go",
"mcp__plugin_prd-taskmaster_go",
"mcp__plugin_atlas-go_go"
],
"user-invocable": false
}
Phase 3: Handoff
Declarative phase skill. Invoked by the prd-taskmaster orchestrator when
current_phase is HANDOFF. Never called directly by a user.
The one rule: detect what the user has, recommend ONE mode, give the user a structured choice, dispatch the chosen mode. Mode D executes only on tier=premium; otherwise it is a locked teaser.
Entry gate
-
Call
mcp__plugin_prd_go__check_gate(phase="HANDOFF", evidence={})for diagnostics.check_gateis an EXIT gate: it requiresuser_mode_choiceandplan_file_exists— both produced by HANDOFF itself, i.e. evidence to advance, not to enter. On first entry neither exists yet, so agate_passed: falsehere is EXPECTED — the state machine's legal transitions already guarantee only legal entry.- First entry (no evidence yet): note the result and continue with the Procedure.
- Re-entry: if the gate reports violations, report them and stop — it protects against re-running a completed phase or skipping ahead from GENERATE.
-
Read the GENERATE outputs —
.taskmaster/docs/prd.md,.taskmaster/tasks/tasks.json,.taskmaster/reports/task-complexity-report.json. If any are missing, report and stop. The gate should have caught this, but belt-and-braces.
Handoff checklist
Copy into your response before running the procedure:
HANDOFF CHECKLIST:
- [ ] Capabilities detected (tier + per-capability flags)
- [ ] Recommended mode: ___ (reason: ___)
- [ ] Summary displayed (spec location, task count, capabilities)
- [ ] CLAUDE.md task workflow appended (idempotent)
- [ ] AskUserQuestion mode picker surfaced (or prose fallback if hook-blocked)
- [ ] User choice dispatched (Mode A / B / C, or D when tier=premium)
- [ ] Debrief scaffold emitted (optional, silently tolerated)
- [ ] Handoff complete
Step 1: Detect capabilities
MCP (preferred): mcp__plugin_prd_go__detect_capabilities()
CLI fallback: python3 script.py detect-capabilities
Returns a tier field ("free" or "premium") plus per-capability flags.
Key signals:
| Capability | What It Enables |
|---|---|
| superpowers plugin | Modes A, C (brainstorm, plans, subagents) |
| task-master-ai (CLI or MCP) | Mode B (native auto-execute loop) |
| ralph-loop plugin | Mode C (iterative execution loop) |
| atlas-launcher MCP (licensed) | Mode D — Atlas Fleet (tier=premium) |
| atlas-loop / atlas-cdd skills | legacy Mode-D seeds — superseded by atlas-launcher detection |
| Research model (task-master or MCP) | Deep research per task |
| Playwright MCP | Tier S browser verification |
Mode D (Atlas Fleet) unlocks on tier: "premium" only — i.e. a licensed
atlas-launcher MCP registration detected by detect_atlas_launcher(). Local
atlas-loop/atlas-cdd skills do NOT unlock it. See Step 2 and the Mode D
section below.
Step 2: Recommend ONE mode
Decision logic (first match wins):
superpowers+ralph-looppresent → Mode C (recommended free)superpowersonly → Mode A (plan-only, manual drive)task-master-aionly → Mode B (native auto-execute)- Fallback → Mode A
External-tool modes (E–J: Cursor, RooCode, Codex, Gemini, CodeRabbit, Aider)
are offered as alternatives via the alternative_modes field, not primary
recommendations. Mode D is recommended iff tier == "premium" AND the task
graph parallelizes (>= 2 independent dependency chains — check fleet-waves
output: any wave with >= 2 chunks). Premium + serial graph: recommend the best
free mode and say why ("your tasks form a single dependency chain — Verified
Loop is the right tool here"); Fleet stays selectable but not default. Free
tier: Mode D is a locked Atlas Pro teaser, never selectable, regardless of
which local plugins are installed.
Mode A: Plan Only (Manual)
Recommended: Plan Only
superpowers:writing-plans creates your implementation plan
Plan references TaskMaster task IDs from tasks.json
You drive execution manually
Mode B: TaskMaster Auto-Execute (Mode B — TaskMaster backend only)
Recommended: TaskMaster Auto-Execute
MCP: mcp__task-master-ai__next_task -> implement -> set_task_status(id, "done") (Mode B — TaskMaster backend only)
CLI: task-master next -> implement -> task-master set-status --id N --status done (Mode B — TaskMaster backend only)
Native TaskMaster execution loop (no external orchestrator required)
Mode C: Plan + Ralph Loop (Recommended Free)
Recommended: Plan + Ralph Loop
superpowers:writing-plans → implementation plan referencing tasks.json IDs
ralph-loop wraps each task:
next_task → set_task_status("in-progress") → research if <80% confident
→ subagent-driven-development → execution gate (Tier A+ evidence)
→ post-doubt check → log to .claude/verification-log.md
→ set_task_status("done") → TodoWrite → repeat
Completion: doubt agent reviews verification log before promise satisfied.
Mode D: Atlas Fleet (selectable on tier=premium; 🔒 locked teaser on free)
🔒 Atlas Fleet Atlas Pro · $29/mo
Parallel multi-session execution across Claude, Codex, and Gemini:
your task graph split into dependency waves of isolated git worktrees
checker-gated merges into one integration branch, one final PR
durable inbox result collection (verified, not narrated)
CDD evidence card per task; one SHIP_CHECK_OK at the end
Walk away, come back to proof.
Unlock: https://atlas-ai.au/pro (the free modes above stay free forever)
When tier == "premium" (licensed atlas-launcher detected): Mode D is a
real, selectable mode — dispatching it invokes /prd:execute-fleet
(the wave orchestrator skill). Show the unlocked card:
▸ Atlas Fleet ★ Pro · license active
<N> waves · est. from your dependency graph · walk-away
When tier == "free": Mode D is a locked teaser — not selectable, never
executed. If the user selects it while locked, respond with:
"Atlas Fleet is part of Atlas Pro ($29/mo). On this project it would split your tasks into parallel waves across isolated worktrees with checker-gated merges and one final PR. Unlock at https://atlas-ai.au/pro — your spec and tasks are saved. Meanwhile, everything else is free forever: please pick one of the free modes below."
Then re-invoke the mode picker (AskUserQuestion) with Mode D removed from the options.
Alternative modes E–J (external AI tools)
detect_capabilities returns alternative_modes when these tools are
installed. Users can pick any of them instead of Modes A–D. All are
tool-agnostic wrappers around the same .taskmaster/tasks/tasks.json.
| Mode | Tool | Invocation |
|---|---|---|
| E | Cursor Composer | cursor --open .taskmaster/tasks/tasks.json, @-ref in Composer |
| F | RooCode | VS Code command palette → RooCode: Run tasks.json |
| G | Codex CLI | python3 script.py next-task | codex implement (free via ChatGPT) |
| H | Gemini CLI | gemini --file .taskmaster/tasks/tasks.json implement next (free via Google) |
| I | CodeRabbit | Implement via A–H, open PR, CodeRabbit reviews per task. Combines with other modes. |
| J | Aider | aider --read .taskmaster/tasks/tasks.json — pair-programming style |
Step 3: Append task workflow to CLAUDE.md
Use the deterministic subcommand — do not do raw Read+Edit. This path is idempotent, takes a timestamped backup when modifying an existing file, and uses HTML-comment sentinels so re-runs are no-ops.
-
The workflow content is the same every run — write it to a tempfile:
## Task Execution Workflow (prd-taskmaster) When implementing tasks, prefer backend operations: 1. `python3 script.py next-task` — get next ready task 2. `python3 script.py set-status --id <id> --status in-progress` — note hyphen; underscore is rejected 3. Implement the task (follow the plan step linked to this task) 4. `python3 script.py set-status --id <id> --status done` — mark complete 5. Update TodoWrite with progress 6. Repeat from step 1 Valid statuses: `pending`, `in-progress`, `done`, `review`, `blocked`, `deferred`, `cancelled`. ### Progress Tracking - Update TodoWrite BEFORE and AFTER each task - Cannot proceed to next task without updating TodoWrite - TodoWrite = user visibility. TaskMaster = source of truth. -
Run the append command. No Plan Mode preview — the subcommand itself is idempotent (HTML-comment sentinels gate the write), so the information is surfaced to the user via the Step-4 summary and the AskUserQuestion options (Step 5) before dispatch, not via a plan dialog:
python3 $SKILL_DIR/script.py append-workflow \ --target ./CLAUDE.md \ --content-file /tmp/pdtm-workflow-section.mdThe JSON response reports one of:
action: "created"— no prior CLAUDE.md, fresh file with markersaction: "skipped"(reason:markers_present) — already wired, no-opaction: "appended"— existing CLAUDE.md untouched except for the appended marker block;backup_pathpoints atCLAUDE.md.prd-taskmaster-backup-<ts>
If the user wants a preview before the write, surface the planned content inside the AskUserQuestion options or as an informational paragraph in the Step 4 summary — describe what would be written without invoking any plan-dialog tool.
Step 4: Display summary
Render the handoff panel and print it: MCP render_status(phase="HANDOFF") →
print rendered; CLI python3 script.py status --phase HANDOFF. (Fallback —
emit a compact block before the mode picker so the user has full context:)
Spec Generated: .taskmaster/docs/prd.md
Validation: <GRADE> (<score>/<max>)
Tasks: <count> tasks parsed with dependencies (see .taskmaster/tasks/tasks.json)
Complexity: analyzed via TaskMaster (.taskmaster/reports/task-complexity-report.json)
Research: <expanded|skipped>
Capabilities:
[check] TaskMaster (MCP|CLI)
[check|circle] Playwright (browser verification)
[check|circle] Research provider
[check|circle] Ralph-loop plugin
[check|circle] Atlas Fleet (premium: selectable · free: locked)
Step 5: Mandatory AskUserQuestion for mode selection
HANDOFF is the moment of user agency. Prose recommendations are skippable;
tool calls are not. You MUST invoke AskUserQuestion in this step. This
is hard-enforced — prose-only fallback is a bug, not a shortcut.
AskUserQuestion gives the user an explicit, structured, machine-readable choice. That's the durable handoff record. The user's selection is logged programmatically and downstream steps dispatch on it directly — no parsing natural-language affirmatives, no ambiguity.
Sequence
-
Emit a handoff summary covering:
- PRD path + validation grade
- Task count + complexity breakdown
- Recommended mode (A/B/C) + one-line reason
- Alternative modes available (E–J when detected, collapsed under "Use another tool…")
- Mode D 🔒 Atlas Fleet teaser with the Atlas Pro price and /pro URL
- A "next step" description scoped to the recommended mode (e.g. for Mode
B: "run
task-master next" with the first ready task ID (Mode B — TaskMaster backend only))
-
Call
AskUserQuestionwith a multi-option question listing each available execution mode. Use the user-facing names (internal IDs in parentheses are for this skill only — never shown to the user):- Plan & Drive (Mode A) — get the plan, implement it yourself
- Auto-Execute (Mode B) — TaskMaster's native loop, lighter verification
- Verified Loop (Mode C) — evidence-gated single-session loop (recommended when superpowers + a loop runner are present)
- 🔒 Atlas Fleet (Mode D) — Atlas Pro $29/mo, parallel multi-session
- "Use another tool…" — expands the applicable alternatives from E–J
- "Show me more detail before I decide" — loops back to Step 4 summary
Mark the recommended mode as the default (Atlas Fleet may be the default only when tier=premium AND the graph parallelizes). Selecting Atlas Fleet while locked (free tier) returns the upgrade response (see the Mode D block in Step 2) and re-prompts with only the free modes (plus any applicable alternatives).
-
Dispatch the chosen mode:
-
Mode A handoff: invoke
superpowers:writing-planswith spec path.taskmaster/docs/prd.md -
Mode B handoff (Mode B — TaskMaster backend only): show the
task-master nextcommand + the first ready task ID surfaced from.taskmaster/tasks/tasks.json -
Mode C handoff: write
.claude/atlas-loop-prompt.mddescribing the task-execution contract, then invoke/goalwith the condition:"SHIP_CHECK_OK has been emitted by .atlas-ai/ship-check.py AND all tasks in .taskmaster/tasks/tasks.json show status=done AND /sync has been invoked this session"The
/goalsession continues until the Haiku evaluator verifies the condition. Each iteration runs the execute-task 13-step cycle and checks the condition after step 13./syncMUST be the last action before SHIP_CHECK_OK is emitted (per execute-task Termination). (Migrated from/ralph-loop:ralph-loop2026-06-04 — Claude Code's built-in/goalevaluator structurally solves the controller-wears- different-hats triple-verify rot caught in the 2026-06-03 audit.) -
Mode D handoff (tier=premium): invoke
/prd:execute-fleet— it owns the wave loop, worker dispatch, verification, merges, and SHIP_CHECK_OK termination. (free tier: upgrade response only, re-prompt)
-
Hook-blocked fallback (graceful degradation)
If PreToolUse:AskUserQuestion is hook-blocked (automated / orchestrator /
fleet session), fall back to a prose option table preserving the same
semantics — labels, descriptions, Mode D locked Atlas Pro teaser, recommended
mode marked. Surface the hook block as an [AI] insight block so the
parent orchestrator can detect the fallback:
[AI] Hook blocked AskUserQuestion — a PreToolUse hook disables interactive questions for this session (automated mode). Surfacing the mode picker in prose instead. A parent orchestrator should either lift the hook for skills with requires_user_agency:true or supply the mode selection as part of the spawn directive.
The prose fallback MUST NOT invoke any plan-mode dialog. AskUserQuestion is the sole user-agency mechanism in this skill — when it is unavailable, the prose table is the documented fallback.
Hard-coded programmatic path (for tests and fleet orchestrators)
The skill's deterministic layer exposes
python3 script.py handoff-gate --recommended <A|B|C> (when implemented).
This emits the full mode option set as structured JSON on stdout, enabling
tests and external orchestrators to drive the handoff without the LLM layer.
Use this when you need deterministic, LLM-skippable handoff enforcement.
Anti-pattern: prose-only prompt
DO NOT say "Ready to proceed with Mode X? (or type 'options')" as your
only gate. That is a prose prompt the model can skip or satisfy with a fake
affirmative. The v4 dogfood (LEARNING #16 → #20) surfaced this exact pattern
as a user-agency hole. AskUserQuestion is the fix.
Step 6: Auto-scaffold dogfood debrief
Every successful HANDOFF calls the deterministic debrief scaffolder as its final act, so the run does not leave only artifacts (PRD, tasks.json, complexity report) with no record of what actually happened:
SLUG="$(basename "$PWD")"
python3 "$SKILL_DIR/script.py" debrief \
--slug "$SLUG" \
--grade "$VALIDATION_GRADE" \
--output-dir docs/v4-release 2>/dev/null || true
- Uses the project's directory name as slug (stable, matches human convention).
- Embeds the validation grade captured in Step 4's summary (
EXCELLENT 56/57, etc.). - Defaults to
.taskmaster/{tasks/tasks.json, reports/task-complexity-report.json, docs/prd.md}— no path flags needed in the common case. - Silently tolerates failure (
|| true) — a missing complexity report or gitignoreddocs/v4-release/must never block a handoff that otherwise succeeded. - Output path is returned as
output_pathin the JSON response; surface it to the user as "Debrief scaffolded at:. Judgment sections (worked / broke / meta) left as TODO — fill them in before the memory fades."
If docs/v4-release/ doesn't exist in the target project (most projects
won't — this is a prd-taskmaster convention), skip the call or let it fail
silently. The scaffold is only useful for projects that retain it.
Evidence Gate
Gate: capabilities detected AND a mode recommended AND CLAUDE.md workflow
appended AND AskUserQuestion surfaced (or prose fallback with [AI] insight
if hook-blocked) AND the user's choice dispatched.
Emit a compact one-block status:
Handoff:
capabilities tier: <free|premium>
recommended mode: <A|B|C>
CLAUDE.md: <created|appended|skipped>
picker: <AskUserQuestion|prose-fallback>
user choice: <A|B|C|D-teased>
dispatched: <skill/command invoked, or "waitlist re-prompt">
debrief: <path or "skipped">
Exit gate
After the evidence gate passes:
- Call
mcp__plugin_prd_go__advance_phase(expected_current="HANDOFF", target="EXECUTE", evidence={"user_mode_choice": "<A|B|C>", "plan_file_exists": True, "capabilities_tier": "<free|premium>"}). The call atomically transitionspipeline.jsonfrom HANDOFF to EXECUTE. Theexpected_currentfield is the compare-and-swap guard;evidenceis stored underphase_evidence[EXECUTE]for audit. - Return control to the orchestrator (
prd-taskmasterskill). Do NOT invoke EXECUTE directly — the orchestrator re-readscurrent_phaseand routes.
Red flags (stop and report, do not paper over)
- "The user typed 'yeah sure' so I'll treat that as Mode C approval" → NO.
Use
AskUserQuestion. A structured choice is the durable record; prose affirmatives are skippable. - "AskUserQuestion is hook-blocked so I'll just pick Mode C myself" → NO.
Fall back to the prose option table +
[AI]insight block. The user still picks; you just surface the choice in a different shape. - "Mode D (Atlas Fleet) is available locally because atlas-loop is installed,
so I'll execute it" → NO. Mode D is always a teaser. Detection returns
atlas_auto: falseuntil the feature ships. - "The CLAUDE.md append had markers already, so I'll skip Step 3 entirely"
→ NO.
action: "skipped"is the expected idempotent outcome; emit it and proceed. Skipping the call means you don't know the state. - "I can call advance_phase without the evidence gate passing" → NO. Gate first, always.
- "The debrief scaffolder failed so I'll abort the whole handoff" → NO. The
scaffolder is silently tolerant (
|| true) — a missingdocs/v4-release/is not a handoff failure.
Non-exits
This skill does not use explicit process termination. A hard block reports the reason and returns control to the orchestrator; the orchestrator decides whether to surface to the user.


