|
| 1 | +--- |
| 2 | +name: plan |
| 3 | +description: Deliberate a feature or change in three locked rounds — functional requirements, then UI design with wireframes, then extras/quirks/out-of-the-box ideas. Each round asks the user clarifying questions via AskUserQuestion before proceeding. New functional scope at any point cascade-restarts the new piece through all three rounds and merges it into the locked plan. Use when the user invokes `/plan`, when the user is in plan mode and asks for a design/spec/feature breakdown, or when a non-trivial change needs structured deliberation before implementation. |
| 4 | +metadata: |
| 5 | + author: ade |
| 6 | + version: "1.0" |
| 7 | +--- |
| 8 | + |
| 9 | +# /plan — Three-Round Locked Deliberation |
| 10 | + |
| 11 | +A feature plan has three layers: **what it does**, **how it looks**, and **the delightful extras**. Cross-talk between them produces sloppy plans. This skill enforces a strict order: lock functional, then lock UI, then add extras. New functional scope discovered at any point cascades back through all three rounds *for that new piece only*, then merges into the locked plan. |
| 12 | + |
| 13 | +## Activation |
| 14 | + |
| 15 | +Activate when **any** of: |
| 16 | +- The user invokes `/plan` (with or without extra context). |
| 17 | +- The user is in plan mode and asks for a design, spec, breakdown, or feature plan. |
| 18 | +- A non-trivial change request would benefit from structured deliberation (multi-component features, UX-sensitive work, anything spanning >2 files). |
| 19 | + |
| 20 | +## Pre-flight: plan mode gate |
| 21 | + |
| 22 | +Before Round 1, verify plan mode is active. If not: |
| 23 | + |
| 24 | +> This skill is meant to run in plan mode (read-only deliberation). Enter plan mode (Shift+Tab cycles to it) and re-invoke `/plan <your context>`. |
| 25 | +
|
| 26 | +Then stop. Do not proceed in edit/full-auto modes — the deliberation contract assumes no files will be touched mid-plan. |
| 27 | + |
| 28 | +## State you must track |
| 29 | + |
| 30 | +Maintain these in your head (or in scratch) across the whole skill: |
| 31 | + |
| 32 | +- **LockedFunctional** — bullet list of functional requirements confirmed so far. |
| 33 | +- **LockedUI** — bullet list of UI decisions confirmed so far (with wireframe sketches). |
| 34 | +- **LockedExtras** — list of delightful extras confirmed. |
| 35 | +- **CurrentRound** — 1 (Functional), 2 (UI), or 3 (Extras). |
| 36 | +- **PendingNewPieces** — queue of new functional requirements detected mid-flight that need their own cascade. |
| 37 | + |
| 38 | +When a cascade fires, you snapshot CurrentRound, run the cascade for the new piece, merge results back into the Locked* sets, then resume from the snapshotted round. |
| 39 | + |
| 40 | +## Round 1 — Functional Requirements |
| 41 | + |
| 42 | +Silently deliberate on what the user asked for. Pull out: |
| 43 | +- Core capabilities the feature must have. |
| 44 | +- Boundaries (what it does *not* do). |
| 45 | +- Inputs, outputs, edge cases that change behavior. |
| 46 | +- Ambiguities where multiple interpretations exist. |
| 47 | + |
| 48 | +Then call **AskUserQuestion** with 1–4 questions that resolve the meaningful ambiguities. Each option should describe a concrete interpretation with its trade-off. Avoid asking the user to write prose — frame everything as concrete choices. |
| 49 | + |
| 50 | +### Tool reference: AskUserQuestion |
| 51 | + |
| 52 | +Use `AskUserQuestion(questions)` to gather structured choices during Round 1, Round 2, Round 3, and any cascade. `questions` is an array of question objects: |
| 53 | + |
| 54 | +- `id`: stable snake_case identifier. |
| 55 | +- `title`: short user-facing label. |
| 56 | +- `text`: the actual question. |
| 57 | +- `multiSelect`: optional boolean for menus like LockedExtras. |
| 58 | +- `allowOther`: optional boolean that permits an "Other" selection. |
| 59 | +- `allowAnnotation`: optional boolean that permits free-text annotation alongside a selected option. |
| 60 | +- `options`: array of `{ id, label, tradeoffs, description?, preview? }`. |
| 61 | + |
| 62 | +The return value is keyed by question id and contains `selectedOptionIds`, optional `otherText`, and optional `annotations` / `freeText`. Treat selected option ids as the locked choice. Treat `otherText` as a new option authored by the user; if it changes behavior, update **LockedFunctional** and trigger the **Cascade rule**. Treat annotations as refinements to the selected option; if an annotation adds behavior rather than clarifying wording or presentation, it also cascades. |
| 63 | + |
| 64 | +When the user responds: |
| 65 | +- Treat selected options as additions to **LockedFunctional**. |
| 66 | +- If the user's free-text (the "Other" reply or annotation) adds new scope → see **Cascade rule** below. |
| 67 | +- If the user only clarifies an existing item → update **LockedFunctional** and proceed. |
| 68 | + |
| 69 | +Once questions are answered, **do not ask for explicit confirmation**. Silently move to Round 2. |
| 70 | + |
| 71 | +## Round 2 — UI Design |
| 72 | + |
| 73 | +Now deliberate on how the feature presents to the user. Generate 1–3 candidate UI directions. Round 2 candidates may be full-layout wireframes when the whole surface is up for decision, or component-level candidates when only one area is ambiguous. Be explicit which level each candidate represents. |
| 74 | + |
| 75 | +Call **AskUserQuestion** with options that carry **markdown wireframe previews** in the `preview` field. Wireframes are ASCII boxes: |
| 76 | + |
| 77 | +``` |
| 78 | +┌─────────────────────────────────┐ |
| 79 | +│ Header · filter ▾ · +new │ |
| 80 | +├─────────────────────────────────┤ |
| 81 | +│ ▣ item ⋯ │ |
| 82 | +│ ▢ item ⋯ │ |
| 83 | +│ ▢ item ⋯ │ |
| 84 | +└─────────────────────────────────┘ |
| 85 | +``` |
| 86 | + |
| 87 | +Keep each preview readable in a chat-width column (~70 chars). Show real labels, real density, real affordances — not lorem ipsum. |
| 88 | + |
| 89 | +Cover the meaningful axes (layout type, hierarchy of actions, empty/loading/error states, dense vs roomy) in **at most 4 questions total**. Don't waste a question on a decision that has one obvious answer. |
| 90 | + |
| 91 | +When the user responds: |
| 92 | +- Selected wireframes/options → **LockedUI**. |
| 93 | +- If candidates were component-level, merge the selected components into **LockedUI** as integration decisions. The Final output still needs one composed/merged inline wireframe derived from **LockedFunctional**, **LockedUI**, and any selected **LockedExtras**. |
| 94 | +- Free-text that implies new functional behavior (e.g. "add export button" implies an export *flow*) → see **Cascade rule**. |
| 95 | +- Pure UI refinements stay in Round 2. |
| 96 | + |
| 97 | +Silently proceed to Round 3. |
| 98 | + |
| 99 | +## Round 3 — Extras, Quirks, Out-of-the-Box |
| 100 | + |
| 101 | +Now generate 4–8 candidate ideas the user *didn't* ask for but might love: micro-interactions, keyboard shortcuts, empty-state delight, power-user features, animations, accessibility wins, surprise affordances, anti-aesthetics-of-AI touches (favor warmth and specificity over generic monochrome polish). |
| 102 | + |
| 103 | +Call **AskUserQuestion** with `multiSelect: true` for the menu of extras. Each option's `description` should be one sentence explaining the idea and one sentence on the cost/benefit. |
| 104 | + |
| 105 | +Selected items → **LockedExtras**. |
| 106 | + |
| 107 | +If the user adds a new functional idea in free-text → **Cascade rule**. |
| 108 | + |
| 109 | +## Cascade rule (the core contract) |
| 110 | + |
| 111 | +A **new functional requirement** is any input — from the user OR self-detected from your own proposals — that adds, removes, or changes scope of the feature. Not a UI refinement. Not an extras pick. *New behavior the system must perform.* |
| 112 | + |
| 113 | +When detected: |
| 114 | + |
| 115 | +1. **Snapshot** the current round. |
| 116 | +2. **Queue** the new piece in **PendingNewPieces** with a one-line description. |
| 117 | +3. **Announce briefly**: "New functional piece detected: <X>. Cascading it through R1→R2→R3 before resuming Round <snapshot>." |
| 118 | +4. **Run a focused mini-cascade for that piece only**: |
| 119 | + - **R1 for new piece**: AskUserQuestion scoped to just the new piece's functional ambiguities. |
| 120 | + - **R2 for new piece**: AskUserQuestion with wireframes scoped to just how this new piece integrates into the already-locked UI (do NOT redesign locked layouts — show how the new piece slots in). |
| 121 | + - **R3 for new piece**: AskUserQuestion with extras *for this piece only*. |
| 122 | +5. **Merge** the results into the appropriate Locked* sets. |
| 123 | +6. **Resume** from the snapshotted round. |
| 124 | + |
| 125 | +Multiple cascades may stack. Process them depth-first; never lose the snapshot. |
| 126 | + |
| 127 | +### Self-detecting new functional scope |
| 128 | + |
| 129 | +Before sending a UI option or an extra, ask yourself silently: *does this option require behavior that isn't already in LockedFunctional?* If yes, you have a choice: |
| 130 | +- Drop the option (cleanest). |
| 131 | +- Or, if it's genuinely a great idea, **fire the cascade yourself** before sending it. Don't sneak new functional scope into UI/extras questions. |
| 132 | + |
| 133 | +## Final output |
| 134 | + |
| 135 | +After Round 3 completes with no pending cascades: |
| 136 | + |
| 137 | +1. Print a tight consolidated plan in chat with three sections: |
| 138 | + - **Functional** — bulleted LockedFunctional. |
| 139 | + - **UI** — bulleted LockedUI with one inline wireframe of the final composed layout. |
| 140 | + - **Extras** — bulleted LockedExtras. |
| 141 | + Keep total under ~50 lines. No filler. |
| 142 | +2. Call **ExitPlanMode** to formally request approval. |
| 143 | + |
| 144 | +### Tool reference: ExitPlanMode |
| 145 | + |
| 146 | +Use `ExitPlanMode(): void` immediately after the Final output. It has no parameters and returns no value. Calling it signals that **LockedFunctional**, **LockedUI**, and **LockedExtras** are complete, including the final composed wireframe, and asks the user to approve leaving plan mode. Do not call it before all pending cascades are processed. |
| 147 | + |
| 148 | +## Anti-patterns (do not do) |
| 149 | + |
| 150 | +- Asking the user to "describe what they want" in prose. Always frame as concrete options. |
| 151 | +- Sending more than 4 questions in a single AskUserQuestion call (tool max). |
| 152 | +- Slipping new functional behavior into UI or Extras rounds without cascading. |
| 153 | +- Asking explicit "lock in? yes/no" questions between rounds — proceed silently unless interrupted. |
| 154 | +- Re-litigating LockedFunctional during R2 or R3 unless a cascade explicitly opens that piece. |
| 155 | +- Generic AI aesthetics in wireframes — no `font-mono` aesthetic apologies, no centered-everything, no purple gradients in mocked copy. Be specific and warm. |
| 156 | +- Long preamble. The user invoked `/plan`; jump to Round 1. |
| 157 | + |
| 158 | +## Minimal example flow |
| 159 | + |
| 160 | +User: `/plan a markdown note app with tags` |
| 161 | + |
| 162 | +You: silent deliberation → AskUserQuestion (R1): |
| 163 | +- Q1: "How should tags be created?" (inline `#tag` parsing / explicit tag field / both) |
| 164 | +- Q2: "Search scope when filtering by tag?" (notes containing tag / notes tagged-only / both modes) |
| 165 | +- Q3: "Multi-user or single-user?" |
| 166 | + |
| 167 | +User selects + adds "and they sync to iCloud" (new functional scope). |
| 168 | + |
| 169 | +You: "New piece detected: iCloud sync. Cascading." |
| 170 | +→ R1-for-sync: conflict resolution? offline-first? |
| 171 | +→ R2-for-sync: sync-status indicator placement? |
| 172 | +→ R3-for-sync: optimistic UI? merge-conflict modal? |
| 173 | +Merge → resume Round 1. |
| 174 | + |
| 175 | +… and so on through R2 and R3 of the main plan, then ExitPlanMode. |
0 commit comments