plan
PM planning trigger on decision-weight work: multi-file, cross-system, reversed prior. Size first if unsized.
SKILL.mdskills/plan/SKILL.md
GitHubcoordinator:plan
<!-- Purpose: Decision-tree router for plan-writing. Predicate classification and evidence: state/audits/2026-08-08-plan-skill-predicate-classification.md. A plan-router may never auto-resolve a triage exit classified untrusted-gate. -->Trigger: EM is about to plan implementation work carrying decision weight (multi-file, new abstraction, cross-system, scaffolds new agents/skills, reverses a prior decision) OR the PM typed "write a plan", "break this down", "plan the implementation".
When NOT to use: Trivial work → coordinator:sizing submits it, no plan doc. Implementation-only ambiguity mid-coding → harness Plan tool inline. Architectural-tier (four criteria below) → surface to PM first. Exploration mode or unconverged problem-shape → coordinator:shape. Vague or multi-subsystem spec → coordinator:brainstorming. SKILL.md authoring → plugin-dev:skill-development. Plan needs review → coordinator:review. Stuck → Branch E.
A new skill/agent scaffold is Branch B, not architectural-tier. Architectural-tier requires one of four positive criteria: cross-system-irreversible, multi-stakeholder, security/privacy boundary, naming-collision-with-product-policy. If none can be named, it is not architectural.
Route is resolved by the caller/engine before this skill loads (Branch A). Route-specific detail (Branches B-E, Exit terminals) is retrieved by the plan-assemble brief op, scoped to the resolved route. Segments: coordinator/skills/plan/residue/.
Dispatch authorization — invoking this skill IS the request. The dispatches named below are constitutive steps of this skill, not a separate thing to get cleared: invoking a skill requests the actions that skill performs. A harness line permitting dispatch "unless the user requested it" is therefore satisfied here, not overridden — no precedence claim is needed and none is made. Re-asking spends the very context the dispatch exists to protect. The rule attaches to skill entry and dissolves no PM-authored gate: keyword-gated skills gate entry, and every gate a skill names for itself still binds — per-session cross-repo-commit assent, ask-before-external-action, and any other this skill's own body names. Tripwire: UNATTRIBUTED-HARNESS-LINE-IS-NOT-PM.
Branch A — Triage: should I plan, and at what altitude?
Condition: a planning trigger has arrived; decide whether a plan doc is the right artifact.
- An incoming sizing-object is present? (
coordinator:sizingresolved this ask and handed astate/sizings/<id>.yaml, or the EM is picking up a sizing-routed baton citing one) → Conform, don't gate — skip the rest of triage — but conform per the object's actualroute. The D5 shape-entry gate still wins — wiki § Shape-is-a-conditional-room. → Arrival split. Fresh inbound, accepted sizing, any route the engine carries (dispatch,spec-dispatch,plan) → submitWorkflow({name: "coordinator:engine-ask", args: {sizing: "<path>"}}), the single submission; the run plans, executes, reviews and commits — not Branch B/C, no/review --surface plan. Engine refusal → the relay fallback: cite the object'sintent(verbatim),estimate, andappetitewhen present (never block or backfill on it) in B.0's restatement, then Branch B. Via the return edge (verified-scope collapse re-invoked sizing) → conform identically but resume at Branch C; the submission fires only fresh. →route: spec-dispatchis the S lane: setscope_mode: spec-dispatch; the Exit resolves its light terminal. OWES full Branch B substrate verification, B.0's doubt-check, the concurrent-session pre-flight, the cross-plan conflict scan, the pre-dispatchplan-reviewerpass (after the scan, before emit-and-dispatch), and bothscaffold-planinvocation points. SKIPS Branch C's four-lens composition (an S-lane body: problem sentence, file scope, acceptance criteria, test surface) and the Opus plan review. NEVER skips scoped-commit discipline or ask-before-external-action. →route: shape/roadmap/pm-decision→ plan is not the room. Do not enter Branch B; route tocoordinator:shapeorcoordinator:roadmap-planning, or surface the choice. The engine setspm_decision_pendingand never auto-selects — the pick (PM, or APM in ceo) lands inxl_exit; a nullxl_exitnever means accept.split: independent initiatives;roadmap: one initiative, several workstreams. Preconditions:shape— JTBD unstated or not falsifiably restatable in the PM's vocabulary;roadmap— spans ≥2 workstreams, or carries/needs an initiative/goal FK;accept_multi_session— neither holds and the PM explicitly assented (xl_exit: accept_multi_session). → plan requires a sizing-object and trampolines back without one. Lifted forplanalone. → Enforcement is EM behaviour: the tools check a cited path or frontmatter; only the trampoline catches ABSENCE. - No sizing-object, and this ask has not been through the lobby — whatever its provenance?
→ STOP. Do not enter Branch B. Invoke
coordinator:sizingdirectly — never ask permission to size. On return, re-enter Branch A; this row fires at most once per invocation. All six routes:plan→ conform, Branch B as fresh inbound;spec-dispatch→ conform, Branch B at S-lane weight;dispatch→ abandon the pass and submitWorkflow({name: "coordinator:engine-ask", args: {sizing: "<path>"}});shape/roadmap→ the named room;pm-decision→ surface the offered exits.- Anti-gaming clause. Satisfied only by an artifact on disk in
state/sizings/citing this ask — not by holding file:line substrate, not by concluding the work is plan-tier, not by asking "want me to plan that?". - Provenance-blind: a picked-up cross-repo memo's
askneeds the lobby too. - Carve-outs — exactly two, no more. (1) A continuation is exempt only if its baton cites work already routed: a resolving
sizing_object, or a plan (viaorigin_plan_id/plan_ids, or adeliverable_idsome plan on disk carries). Every citation must resolve; never re-litigate a resolved citation. A baton citing none is unsized whatever its provenance. Tripwire:A-BATON-IS-NOT-A-SIZING-ARTIFACT. (2) The express lane never reachesplan.
- Anti-gaming clause. Satisfied only by an artifact on disk in
- Trivial? (single-file change, no new abstraction, scope obvious) → Submit it (
Workflow({name: "coordinator:engine-ask", args: {sizing: "<path>"}})). No plan doc. - Implementation-only ambiguity? (choosing between two valid shapes mid-typing) → Harness Plan tool inline. No plan doc.
- PM has set a session axiom? ("we are going to do X" / "build Z this session" — a directive naming the work, not a question about it) → Disposition flips to plan: plan the named work, do not re-litigate it. Continue to Branch B. The architectural-tier check still fires. This row disposes; it does not admit: with no sizing object on disk the trampoline row above fires first.
- Trigger arrived via a PM-handed pickup whose handoff prescribes a plan? → Already authorized — do NOT ask "want me to plan?". A T3 spinoff fork stays separately PM-gated (surface it as a one-line candidate). Continue to Branch B.
- PM in exploration mode, OR problem-shape unconverged, OR the EM detects it is guessing at the problem?
→ Propose
coordinator:shapebefore committing to plan; its exit gate chains back here. A PM session axiom and the architectural-tier check both win. The PM HAS a problem →shape; the PM does not know what to build →brainstorming. - Cross-repo work whose shared contract is itself the unknown, even when a handoff says "ready to execute" / "XS"? (negotiated co-design — the contract/hookspec/shared fixture takes round-trips to converge)
→ Invoke
coordinator:plananyway — do NOT execute off the handoff's t-shirt. Continue to Branch B.- Negotiated co-design is the trigger, not a sibling's existence: a memo (one ask) does not escalate; no nameable coordinating party and contested shared contract → this row has not fired.
- A multi-wave plan that sends a memo carries a wave-boundary re-read of it, written into the spine: at each wave close, enumerate the memos sent and ask whether the wave just landed contradicts any; the correction memo is part of that wave's deliverable. Tripwire:
A-MULTI-WAVE-PLAN-NEVER-RE-READS-ITS-OWN-SENT-MEMOS.
- Non-trivial (default for everything else)? (multi-file, new abstraction, cross-system, scaffolds an agent/skill, reverses prior teardown, touches shared schema)
→ Continue to Branch B, and scope the task list to the COMPLETE problem set; ADR, lineage and docs chunks are not execution-wave rows: list them under a non-empty
## Distill passheading, referenced from the closing handoff or the/workstream-completestep, which hands them to/distill. - Architectural-tier? (the four positive criteria above)
→ Surface to PM: "this looks architectural — propose
/staff-session, want me to draft the brief?" Wait for PM.
Exit — Route-Selected Terminal
Condition: body drafted and saved to docs/plans/YYYY-MM-DD-<slug>.md. The inbound sizing route selects which terminal fires. shape/roadmap/pm-decision never reach here — Branch A diverted them before Branch B.
The plan file MUST be produced and committed via scaffold-plan, not hand-authored. It owns frontmatter-skeleton emission and the write-time commit across two invocation points either side of body authoring. Every terminal holds this.
Invocation point 1 — scaffold. The generator is the single emission point for frontmatter — never hand-author field lists against schemas/plan.schema.json; hand-authored frontmatter is conformed through the same invocation.
Invoke the .exe launcher by absolute path via the PowerShell call operator (Shape W) —
ladder: ${CLAUDE_PLUGIN_ROOT}/snippets/resolve-coordinator-bin.md.
`& "$env:COORDINATOR_SETTINGS_HOME\bin\coordinator-doc-new.exe" --type plan --title "<title>" --sizing-object state/sizings/<the-object-that-routed-you-here>.yaml --out docs/plans/YYYY-MM-DD-<slug>.md`
Pass --sizing-object. coordinator-doc-new --type plan hard-refuses without an explicit --sizing-object/--no-sizing-object, exit 1, nothing written. The flag also writes the reverse edge onto the cited sizing (plan FK plus status flip).
Read the scaffolded file before authoring the body.
Invocation point 2 — commit. Commit the moment the body is saved, then proceed to review, per
snippets/scoped-commit-route.md — pathspec exactly docs/plans/<slug>.md, subject
plan(<slug>): draft; never a sweep commit.
Test Surface
No runtime test for this skill body — prose-doctrine. The grep-asserts below stand in, one count per token against the named file.
| # | token | file | expect | threshold reason |
|---|---|---|---|---|
| 1 | Eighth dimension |
core + shared segment |
≥2 | table self-citation |
| 1 | trampoline: true |
core + shared segment |
≥2 | same |
| 2 | plan⇄spike |
core + shared segment |
≥2 | same |
| 2 | plan⇄spike |
skills/spike/SKILL.md |
≥1 | both sides |
| 3 | coordinator:plan |
skills/spike/SKILL.md |
≥1 | viable exit |
| 3 | coordinator:shape |
skills/spike/SKILL.md |
≥1 | not-viable exit |
| 4 | "viable" |
schemas/spike-result.schema.json |
≥1 | schema-backed enum |
| 4 | "not-viable" |
schemas/spike-result.schema.json |
≥1 | same enum |
| 5 | plan⇄sizing |
core + plan-route + shared segments |
≥3 | split across segments |
| 6 | plan requires a sizing-object and trampolines back without one |
this file | ≥2 | 1 = gate is gone |