Imported from MakingThingsWorkToronto/visual-brainstorm (
.claude/skills/brainstorm-phases/SKILL.md). Install upstream withnpx skills add MakingThingsWorkToronto/visual-brainstorm --skill brainstorm-phases. Copyright stays with the author.
Driving the Phase Funnel
The studio physically re-architects per phase. You choose the phase per board; the funnel
below is the default arc. Don't stay in diverge forever — after 2–3 expanding rounds, force
a narrowing phase. Theories: wiki/Product/phase-funnel.md.
Intake & methodology routing (before the funnel)
Before round 1, the concierge → Living Gallery intake (run-brainstorm step 0,
wiki/Product/intake-methodologies.md) lets the human PICK the methodology to start with. This
intake is MANDATORY and precedes the funnel — every real run does brief → ask_concierge
(≥1) → present_gallery → route BEFORE any present_board; there is no jump-straight-to-boards
shortcut. The roster is a set of PEER methodologies — mind map is one of them, never the
default or the centerpiece. If the seed is an annotated-photo scribble (a .seeds/seed-<stamp>/
folder), run .claude/commands/read-scribble.md FIRST (skill reading-scribbles): VIEW
composite.png + read scribble.json, and let the marks anchor the concierge questions and round 1.
present_gallery returns the pick; route it to a starting mechanic:
| pick | starting mechanic | recommend it when |
|---|---|---|
mindmap |
present_board with a tree (kind mindmap, no options); the user co-edits, edits return in response.editedTree |
the shape is still forming / the user wants to arrange structure directly |
funnel |
the diverge→converge funnel below (start phase:"diverge") |
"show me options to choose among" — the classic path |
wreck |
present_board at phase:"wreck" on the seeded option(s) |
an idea exists and needs pressure-testing |
cluster |
present_board at phase:"cluster" on the seeded options |
many ideas already exist; find structure by grouping |
The recommendation heuristics (which method to mark recommended + a reason quoting the
answers) live HERE and in run-brainstorm — never in harness code (rule 11). "Just give me
options" is not a bypass — it routes to the funnel card, still surfaced through the gallery
and picked there. After a
non-mindmap pick, the funnel below applies as usual; the pick only chose the STARTING mechanic.
A mindmap thread iterates on the tree. READ THE MAP FIRST — run .claude/commands/read-mindmap.md
before generating the next tree, when answering a mind-map artifact-chat, and at plan-closeout.
The map is persisted MODEL-LEGIBLY per round: round-NN/tree.md is a TRAVERSABLE markdown outline
(header counts + indented hierarchy, each node's id + note, — thin flags on branches the
user opened but never grew) — read it FIRST; edited-tree.json (submitted) / draft.json's
editedTree (LIVE, mid-edit) give the exact shape; tree-ops.jsonl is the ordered decision log.
The outline is also folded into brainstorm.md and the feedback digest, so the tree is never a
JSON blob you must parse by hand.
The map IS the user's intention and ANCHORS everything — the next tree, every artifact-chat
answer, and the build plan are organized by it. Read response.editedTree as the user's new
structure AND response.treeOps as the ordered node decisions — editedTree is the final SHAPE,
treeOps the INTENT. Honor them: an explode op (with the node's topic + note) means the
studio ALREADY fanned that node into 5 topic+note-anchored PROMPT children (<topic> · <note> — <facet>); REPLACE/refine each prompt into a genuinely relevant idea in the next tree (reshape
the placeholders, don't append more) — a different note yields a different set; delete means
drop that branch for good (NEVER reintroduce it); add means the user seeded blank child ideas
to help fill; note sets steering for a future explode; — thin branches are gaps — where the
user wants help. Per-node note fields carry the same steering (weight them highest). The user
can also maximize the map → the fullscreen viewer with chat on the right and iteratively
improve it in words (artifact-chat on the mindmap's snapshot; you read the LIVE tree.md/draft
to answer). Then present the next tree (or route into the funnel once the structure is settled).
Phase table
| phase | when to use | studio mechanic | response fields to honor |
|---|---|---|---|
diverge |
opening rounds; after a gap note or remix suggests new territory | airy grid, no ceilings | selectedOptionIds (energy, not verdicts), perOptionNotes, remixPairs, axisValues |
expand |
a direction resonates and the user wants MORE of it | selection grid; gate: ≥1 selection | selectedOptionIds: the pool GROWS — add multiple new syntheses/variants of the picks; remove nothing |
mutate |
user is circling one direction but it isn't landing; creative block | one option at a time + distortion lenses | mutations: for each optionId, the lenses (flip/invert/stretch/compress/tilt/xray) that "revealed something" — next round REGENERATES those options leaning into what the distortion exposed (e.g. stretch kept → explore elongated/banner composition; invert → dark-first or negative-space variant; xray → structure-only skeleton) |
wreck |
perfectionism stall; polite feedback; round 1 felt "fine" | saboteur mode, ≥3 flaws gate | flaws: each flaw becomes a FIX CANDIDATE next round — present the repaired version beside a version that embraces the flaw as a feature. Thank the sabotage; never defend the work |
cluster |
option pool ≥ 8 across rounds; before converging | drag field; distance IS data | positions/clusters: the user's implicit taxonomy — name the clusters back to them; the digest now carries a SPATIAL READ of the raw positions (cluster tightness, closest cross-cluster pair, outliers — see Structured intent channels below); gapNotes: HIGHEST-VALUE SIGNAL — generate the hybrid living between those clusters next round |
converge |
pool is rich enough; time to distill | triage gate (keep/kill/merge + 🏁 Final crown, send locked until complete) | triage: keep → capture_artifact candidates; kill → never regenerate this direction; merge → produce ONE synthesis of all merge-marked options next round. action:"finalize" + finalOptionId: THE answer — capture_artifact it, then compose_poster (the shareable decision poster: winner + lineage + notes, composed deterministically from the cached thread), then run .claude/commands/plan-closeout.md immediately (finality triggers closeout). The studio's ⚔ sudden-death bracket may have crowned it — its duels arrive in duelResults |
Transition heuristics
- diverge → diverge: only if the user's elaboration asks for MORE breadth.
- diverge → expand: selections show a direction resonating — amplify it without dropping the rest.
- diverge → mutate: selections cluster on one option with lukewarm notes.
- any → wreck: notes are polite/empty, or the user says "it's fine" — it isn't.
- diverge/mutate → cluster: total presented options ≥ 8.
- cluster → diverge (one round): a gap note names unexplored territory — go get it.
- cluster/wreck → converge: clusters are stable or flaws are fixed; announce the gate in the prompt.
- converge → done: capture artifacts for every keep; offer
parksummary.
Universal rules
- Narrate the phase shift in the board
prompt("The pool is full — time to triage"). - Execute the
feedbackDigestin the tool result line by line — it is the user's feedback packaged as labeled, imperative instructions. Nothing in it is optional. - Dial deltas are a complete instruction: moved axisValues with nothing else selected
MUST produce a visibly re-tuned next round (say so in the prompt) — never a no-op. It is
also a TWEAK (the digest says so): the re-tuned round is a MUTATION of this round's
captured
round-NN/option-<id>.svgfiles — the liked geometry survives verbatim; only the deltas are paid for — never a from-scratch re-authoring. response.requestedPhaseset (user clicked a phase tab) → the next board uses that phase.axisValuesare taste calibration for ALL future rounds, not one-off data — carry them forward as the next board's axis defaults.- Generation always routes to an EXPLICIT model: the digest's "Model routing" line names
it every round (
response.modelwhen the user picked, else the session's best-SVG default) — delegate to that model by name; never generate on an unnamed fallthrough. response.commandsnon-empty → STOP, run.claude/commands/<command>.md(new-brainstorm → run-brainstorm.md from step 1).- The pool is alive — every gesture eliminates or builds. Maintain a thread-wide KILL LIST: an option killed in triage (or its clear stylistic direction) is NEVER presented again in that thread. Keeps are converged: captured via capture_artifact, and merge verdicts MUST yield exactly one synthesis next round. State the pool changes in the next board's prompt ("killed X for good; bred A×B").
- Judge-deck fields refine the synthesis vector.
ranking(when present) orders the keeps strongest-pull first — weight the top ranks hardest when breeding the next round.deckVerdictskills join the thread kill list exactly like triage kills. EachduelResultsentry is a direct pairwise preference ("winner beat loser head-to-head") — treat it as taste calibration between two directions. - Selections define the SYNTHESIS VECTOR — the iteration law. When the user selects options, the ENTIRE next round is syntheses of those selections: two picks → ~5 distinct offspring all descended from BOTH; one pick → variants spun from it. Unselected directions are dropped, never re-shown. Every round must move measurably along this vector; a next round that ignores the previous selection is the tool failing at its one job.
- SYNTHESIS IS BY MEANING, NEVER BY OVERLAY. Extract what each parent MEANS (state it:
bulb = "the idea", bubble = "the conversation"), combine the meanings, and draw the
offspring FRESH ("an idea that speaks" → a bulb with a speech tail). Graphically
compositing/overlaying the parent SVGs is forbidden — it produces mud, not synthesis.
For
system-mapboards, combining two options = MERGING the two architectures (union of components, reconciled topology, duplicates collapsed), drawn as one clean new diagram. action:"back"is the escape hatch. The user rejected this round: re-present the PREVIOUS round's board unchanged (exact options from brainstorm.md / round-N-1 board.json) and await a fresh answer — but mint a FRESH board id: the bridge dedups responses first-response-wins per boardId, so re-presenting under the old id silently swallows the new answer. Do not advance the funnel; ignore the rest of that response as steering.brainstorm.mdin the thread dir is the append-only text memory — every round's options (labels, descriptions, lineage) and every response digest, auto-written by the store. Read it (or load_discussion) before re-synthesizing so round N+1 provably builds on rounds 1..N; when resuming a thread it is the first thing to read.
Structured intent channels (handoff fidelity)
INTERPRET — new response fields, each folded into the next round:
response.questionAnswers— answers to YOURBoard.questions(mid-round clarifiers), keyed by question id; the digest carries them asAnswer — "<question>": …lines. Fold each answer into the next round's direction like a note — you asked, they answered, the round must show it.response.uncertainties— option ids the user toggled "unsure". UNSURE ≠ KILL (the digest says so explicitly): next round include a clarifying variant of each, or ask aBoard.questionsclarifier probing WHY it's hard to judge. Never silently drop an unsure option.response.remixNotes— remix RECIPES keyed"a×b", riding besideremixPairs; the digest appendsRecipe (what to take from each): …to the remix line. Obey the attribute split literally — "layout from A, palette from B" is an EXECUTABLE instruction, not a vibe: the offspring takes exactly the named attribute from each parent.response.optionAnnotations+annotated-<id>.pngattachments — marks drawn ON an option's SVG (the fullscreen Annotate mode). The digest emitsAnnotated ON "<label>"lines with mark counts, note texts, and aVIEW <savedPath>pointer. VIEW the png (vision — the marks in place) AND traverse the structured field (the saved round response file'soptionAnnotations[id]: coordinates + palette color names): arrows point AT the element to change (tail→head — the HEAD is the target), notes are literal instructions. Same reading vocabulary as thereading-scribblesskill, applied per option.- Positions spatial narrative — the digest now reads the raw
positionsdrag geometry into lines, not just the discrete cluster sets: per-cluster tightness (welded = treat as ONE fused direction; close; loose = related but distinct ideas), the closest CROSS-cluster pair (the user ALMOST joined these — a hybrid of the two is a low-risk bet), spatial outliers (parked far from everything — uniquely valued or unclassifiable; probe with a clarifying variant or question, DON'T drop), and near pairs when the user arranged without forming clusters (treat each pair as an implicit cluster).
AUTHOR — new board-side channels (both optional, never gating):
questionsonpresent_board(0–4, the SurveyQuestion shape) when a signal was ambiguous — rendered as the "Claude asks" box beside the options; answers return inquestionAnswers. Ask about the ambiguity, not the obvious.rationaleon each option, from round 2 on — 1–2 sentences QUOTING the user feedback it responds to; the studio renders it under the option (beside its lineage chips) so the human SEES their feedback driving the round. Brief the artisan to write it.
Changelog
- 2026-07-09 — structured intent channels: interpret questionAnswers / uncertainties (unsure
≠ kill) / remixNotes (executable recipes) / optionAnnotations (+ annotated-.png, VIEW
- traverse) / the digest's positions spatial narrative (welded clusters, cross-cluster bridge pairs, outliers); author mid-round Board.questions + per-option rationale quoting the feedback (from handoff-fidelity-2026-07-09)
- 2026-07-09 — mindmap section: READ THE MAP FIRST via /read-mindmap —
round-NN/tree.mdis the model-legible outline (ids, notes,— thingap flags; draft.json = the LIVE mid-edit tree); the map IS the user's intention and anchors the next tree, artifact-chat answers, and the build plan; maximize→fullscreen chat is the iterative-improvement channel (from mindmap-model-legible-2026-07-09) - 2026-07-07 — intake noted MANDATORY and preceding the funnel; "just give me options" routes to the funnel card via the gallery, not a bypass (orchestration-gated intake honesty)
- 2026-07-07 — intake & methodology-routing section: the concierge→gallery pick routes to a starting mechanic (mindmap→tree board, funnel/wreck/cluster→their phase); mind map is a peer methodology, never the default; recommendation heuristics live here (concierge-living-gallery phase 5)
- 2026-07-05 — created (from phase-funnel-ux-2026-07-05)
- 2026-07-05 — feedbackDigest execution, dial-delta rule, requestedPhase, axis-defaults carry-forward (operator UX-test: dial-only response produced a no-op — never again)
- 2026-07-06 — living-pool rule: thread-wide kill list, selections narrow/build, merges synthesize, pool changes narrated in the next prompt (operator UX-test: selections/kills had no effect)
- 2026-07-06 — SYNTHESIS VECTOR law + brainstorm.md text memory (operator: "disconnect between user action and previous results — select bulb + chat → next 5 options synthesize bulb×bubble; this is how the brainstorm moves forward")
- 2026-07-06 — expand phase (pool grows with syntheses of selections) + finalize contract (🏁 Final crown → capture + plan-closeout) + new-brainstorm seed prompt (operator directives)
- 2026-07-06 — synthesis-by-MEANING law (never overlay parent SVGs; system-map = merge architectures) + back action contract (operator: "expand overlays both images — expand from the meaning in each image")
- 2026-07-06 — back re-present mints a fresh board id (bridge first-response-wins dedup) (from phase-funnel-ux-2026-07-05)
- 2026-07-06 — journey-UX build (studio-journey-ux plan): judge-deck fields (ranking/deckVerdicts/duelResults) interpretation rule; finalize contract now includes compose_poster; sudden-death bracket duels arrive in duelResults
- 2026-07-08 — mindmap iteration: interpret
response.treeOps(explode→≥5 topic+note-relevant children, delete/add/note) + per-nodeeditedTree.notesteering (from mindmap-explode-decision-tree-2026-07-07)