Develop-side planning orchestrator for an OpenSpec change: artifact creation → doubt-driven-review → scenario-design → fold of automated scenarios into tasks.md, then STOPS at the git-worktree boundary. Main interactive session only; never a subagent. Triggers: "plan this change", "draft the proposal and plan", "scaffold + review + fold", "prep a change for building".
npx skills add https://github.com/BlackBeltTechnology/pi-agent-dashboard --skill plan-proposal
Orchestrates the planning phase of an OpenSpec change on develop. Composes
existing skills — it does not reimplement them. Twin of ship-it, which owns
the implementation phase inside the worktree. The two split at the **git-worktree
boundary, which is also the interactive/headless line**.
flowchart LR
subgraph Planning ["PLANNING — develop, human present"]
A["new/ff/continue"] --> B["doubt-review"]
B --> C["scenario-design + category-fold + manifest"]
C --> D["plan-proposal (this skill)"]
end
D -->|"boundary: commit + spawn worktree"| E["ship-it"]
subgraph Implementation ["IMPLEMENTATION — worktree"]
E
end
plan-proposal MUST run in the main interactive session. It invokes
doubt-driven-review (which spawns a fresh-context reviewer, and interactively a
second cross-model reviewer — nested subagent spawn is blocked) and
scenario-design (whose proposal/design-stage HARD gate calls ask_user). Both
need a live main session.
Guard: if you detect you are running inside a subagent context (nested
reviewer spawn would be blocked, or ask_user is unavailable), STOP and
surface: *"plan-proposal must run in the main session — doubt-review and the
scenario-design gate cannot run nested. Re-invoke from the main session on
develop."* Do not degrade the doubt-review to a self-questioning fallback.
develop branch (planning happens on develop; the worktree is spawnedfrom the planning commit).
openspec CLI available; resolve the change name from --change <name>, theconversation, or openspec list --json (ask if ambiguous).
<change> (override with /plan-proposal <other>)."*Bring the change to a drafted state using the existing generated skills — do not
hand-roll the directory:
openspec-new-change (or -ff for the fast path).openspec-continue-change.Artifacts live at openspec/changes/<change>/: proposal.md, design.md (when
the change warrants one), specs/**/spec.md, tasks.md.
Whenever proposal.md or design.md is created or changed in this session,
invoke doubt-driven-review on the changed artifact:
deltas, the non-goals, the invariants it asserts).
offer is mandatory (doubt-review Step 3 "always offer, never silently skip").
precedence (contract-misread → actionable → trade-off → noise). When a finding
is valid + actionable, PAUSE: the artifact is corrected before proceeding.
Do not fold scenarios until the doubt cycle reaches a stop condition (trivial
findings, 3 cycles, or explicit "ship it").
scenario-design is a required step, not an option. A change never reaches
the worktree boundary without a test-plan.md manifest and its automated rows
folded into tasks.md. Do not hand-author test tasks, infer scenarios from
the proposal, or skip straight to the commit — always drive the tasks from the
scenario-design output. Smoke-test-only tasks.md is a planning failure.
Run scenario-design for the change (proposal/design stage → HARD gate; it may
ask_user and STOP on a spec gap — that is expected, answer and continue). It
writes openspec/changes/<change>/test-plan.md — the manifest, carrying a
level + disposition (automated | manual-only) per scenario row. If
test-plan.md does not exist after this step, scenario-design did not run —
re-invoke it before folding.
Then fold each row into tasks.md:
automated rows → one vanilla - [ ] task each, routed to its category:| manifest level | home | check-first (reuse infra) |
|---|---|---|
| L1 | packages/*/**/__tests__/*.test.ts (vitest) | sibling *.test.ts |
| L2 | qa/tests/*.sh \| *.ps1 | existing qa test for that OS |
| L3 | tests/e2e/*.spec.ts (docker harness) | existing spec for that surface |
| electron | ci-electron.yml / _electron-build.yml | existing electron job |
| ci | ci.yml / workflow-level | existing workflow assertion |
Before tasking new infra, scan for an existing test of that type to extend.
Each folded test task MUST carry:
category to copy harness glue from (e.g. see tests/e2e/reconnect.spec.ts).
Bare "author X.spec.ts" tasks are forbidden — ship-it resolves the
exemplar path into the task context it hands apply.
input · trigger · observable) as plain text.(test-plan #<id>) or aninline (test-plan: automated) — so ship-it/ship-change can map it back.
manual-only rows → a plain manual task tagged (test-plan: manual-only);no test is folded. ship-change defers these post-merge (its manifest-aware
defer rule).
Fold-completeness gate (before Step 4): every automated row in
test-plan.md MUST map to exactly one folded test task in tasks.md, and every
manual-only row MUST map to one tagged manual task. Verify the count matches
the manifest — if any scenario row has no corresponding task, the fold is
incomplete; finish it before committing. Do not proceed to the boundary with an
unfolded manifest.
Parser-safety (load-bearing): tasks.md MUST stay vanilla checkbox format.
No custom token, no bracketed tag, no non-standard syntax on a task line — only
- [ ] <text> where the manifest reference is ordinary prose. `openspec status
--json and the generated apply` skill parse this file; a stray token could
break them. Verify openspec status --change <change> --json reports the same
task counts after folding as the plain checkboxes imply.
Precondition: test-plan.md exists and the fold-completeness gate passed.
Never commit without the manifest — a missing test-plan.md means Step 3 was
skipped; go back and run scenario-design.
Commit proposal.md, design.md, specs/**, tasks.md, and test-plan.md to
develop. The worktree is spawned from that commit via the existing worktree
flow (dashboard "start work" / git worktree add).
Then STOP. plan-proposal does not enter the implementation phase. Report:
> *Planning complete for <change>. Artifacts committed to develop; worktree
> ready. Automated scenarios folded to tasks (manifest dispositions in
> test-plan.md). Next: run ship-it inside the worktree to build + ship.
> If a design issue surfaces during build, ship-it writes SHIP_IT_BLOCKED.md
> and hands back here.*
tasks.md stays vanilla — the manifest (test-plan.md), not a task tag,is the automated-vs-manual source of truth.
scenario-design is mandatory — no test-plan.md, no commit. Neverhand-author test tasks or skip scenario design; the manifest is the sole
source of the folded test tasks.
automatedand manual-only row maps to a task.
ship-it authorsthe tests. This skill plans; it does not implement.
openspec-new-change / -ff / -continue · doubt-driven-review ·
scenario-design (+ its test-plan.md manifest) · handoff to ship-it.
Take blackbelttechnology/plan-proposal from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.