$ cat workspace-template.yaml
Brainstorm to Design Spec
// Interactively turn an idea into a reviewed design spec the way a thoughtful collaborator would - ask clarifying questions one at a time, assess scope (and decompose if it is too big for one spec), explore 2-3 approaches and let you choose, draft the design and revise it with you, then self-review the spec for placeholders, contradictions, scope creep, and ambiguity before you take it into implementation planning. Gated and conversational, not a one-shot generator.
// Canvas Preview
// Instruction
Brainstorm to Design Spec
Overview
This workspace turns an idea into a structured, reviewed design spec through a real back-and-forth - the way a thoughtful collaborator would. It asks clarifying questions one at a time, assesses scope (and helps decompose if the idea is too big for one spec), explores 2-3 approaches and lets the user pick, drafts the design and revises it with them, then self-reviews the spec for placeholders, contradictions, scope creep, and ambiguity. The graph nodes hold the durable, inspectable artifacts (requirements brief -> approaches -> design -> finalized spec); the dialogue around them is the user's. It produces a spec and stops - it never writes code, and it saves the spec only if asked. The far-left Context section holds the source nodes: Idea & Clarifications is the required input (already wired into Make Array); the optional Drive and web sources start disconnected and you connect only the ones the user provides.
Workflow Chain
Node Reference
- Context (section) - visual group holding the source nodes.
- Idea & Clarifications (Text) - the REQUIRED input: the user's idea plus the clarifying answers you collect in Phase 2. Configure
valueviaupsertNode. Outputvalueis already wired to Make Arrayitem_0- do not disconnect it. It is also a reusable canvas store - see "Text Nodes as a Canvas Store". - Drive Document Reader - reads existing project context from Drive (prior specs, README, design docs). Configure
driveItemIdviaselectDriveItem. Output port:content. Starts disconnected from Make Array. - Web Search - finds prior-art / landscape URLs. Configure
query,num_results. Outputurlsalready feeds its Fetch node. - Fetch URL as Markdown - fetches the searched URLs as Markdown. Input
urlsfrom Web Search (pre-wired). Output port:markdown. Starts disconnected from Make Array. - Make Array - collects the connected source texts into one ordered array. Item ports
item_0..item_9(item_0= the idea, already wired). Outputitems-> Synthesize Requirementscontent. - Synthesize Requirements (Text Summarizer) - reads everything and produces a structured REQUIREMENTS BRIEF (purpose, constraints, success criteria, in/out of scope, scope assessment, open questions). Configure:
prompt(baked; substitute{{topic}}),llmModel. Output:summary. - Explore Approaches (Text Transform) - proposes 2-3 distinct approaches with trade-offs and a recommendation, carrying the brief forward. Input
input_textfrom the brief. Output:output_text. - Compose Design Spec (Text Transform) - writes the full design for the SELECTED approach. Input
input_textfrom the approaches. Configure:prompt(baked; substitute{{topic}}, appendSELECTED APPROACH:/REVISION NOTES:lines). Output:output_text= the design spec. - Self-Review Spec (Text Transform) - reviews the spec with fresh eyes and fixes placeholders / contradictions / scope / ambiguity inline. Input
input_textfrom the design spec. Output:output_text= the finalized spec. - Save Spec (Save File) - saves the finalized spec to Drive. Configure
destinationFolderviaselectDriveItem,name. Output:driveItemId. Side-effect terminal - offered infollowUp, never auto-run.
Text Nodes as a Canvas Store
The Text node type (the same node template as Idea & Clarifications) is a general-purpose, inspectable store: it just holds a value string and outputs it unchanged. Use Text nodes to keep the dialogue's durable state ON THE CANVAS, instead of only in chat or buried inside a node's prompt.
- Update an existing store:
upsertNodethe Text node'svalue(this is exactly how Phase 2 records the idea + clarifications into Idea & Clarifications). - Add a new store:
cloneNodesthe Idea & Clarifications node, thenupsertNodethe clone's label (e.g. "Chosen Approach", "Decomposition Plan", "Revision Log") and itsvalue, and place it in the Context section. If the clone inherits the idea's edge,deleteEdgeit - a store stays DISCONNECTED unless you actually want its text to flow into a downstream node (an unconnected Text node is inspectable but never executed, so it can never block the run). NEVER remove the required Idea & Clarifications -> Make Arrayitem_0edge. - Why: storing a decision as a Text node makes it a durable artifact a teammate can open and audit, and lets a later edit turn re-read it instead of re-deriving it. Anything that must FLOW into a node's computation (the chosen approach, revision notes) is still appended to that node's
promptas well; the Text store is the inspectable record of it.
Execution Strategy
You MUST complete all 7 phases in order: Phase 1 -> Phase 2 -> Phase 3 -> Phase 4 -> Phase 5 -> Phase 6 -> Phase 7. Do NOT skip any phase. This template is deliberately interactive: the clarifying dialogue in Phase 2 happens in NORMAL CHAT, one question at a time, and there are explicit user-approval gates at Phases 4 and 5. Do NOT collapse the dialogue into a single up-front form, and do NOT run the pipeline to the end without the gates.
Phase 1: Understand the idea and set up sources
- Read the idea from the Idea & Clarifications node
value(seeded from{{idea}}). If it is empty or a single vague line, ask the user in chat for the core idea before continuing - one short message, then wait for their reply. - Assess raw scope from the idea alone. If it already obviously spans multiple independent subsystems (e.g. "a platform with chat, billing, storage, and analytics"), make a mental note - you will handle decomposition at Phase 3; do not let it derail Phase 2.
- Call
requestUserDecisionONCE to set up context sources (this is the only structured setup prompt): keysources(allowMultiple), question "What project context can I pull in?", context "Optional - the idea alone is enough; pick any that apply.", options:New / greenfield (none),Existing docs in Drive,Research prior art on the web. The free-text box captures the web-search topic and/or any context to paste. StoresourcesChoice = answers.find(a => a.key === "sources")?.selectedIds ?? []; ifcancelled, treat as greenfield (no extra sources). - For EACH chosen source, configure it and
upsertEdgeits text output into the next free Make Array item port (item_1, thenitem_2, ...):- Existing docs in Drive:
selectDriveItem->upsertNodeDrive Document ReaderdriveItemId->upsertEdgeitscontent-> Make Arrayitem_1. - Research prior art:
upsertNodeWeb Searchquery(from the free text; Web Search already feeds its Fetch node) ->upsertEdgethe Fetchmarkdown-> Make Arrayitem_2. - Greenfield: connect no extra source. If the user pasted context in the free text, fold it into the Idea node
valuein Phase 2. The Drive picker (selectDriveItem) is unavoidable and is NOT a clarifying question. Never touch a source the user did not pick (an empty Drive reader / empty query would fail and block the run).
- Existing docs in Drive:
Phase 1 complete. Now proceed to Phase 2. Do NOT skip to Phase 3.
Phase 2: Clarify the idea - one question at a time, in chat
- Hold a short clarifying dialogue IN NORMAL CHAT. Do NOT use
requestUserDecisionfor this - these are open, adaptive questions, not config buttons. Focus on purpose, constraints, and success criteria, and prefer one concrete question per message so each follows from the last answer. - Run the clarifying loop with an explicit bound: a. Ask ONE clarifying question in chat. Wait for the user's reply. b. Decide whether another question is genuinely needed. If yes, return to (a). c. Stop when you can state the purpose, the key constraints, and the success criteria - OR the user says to proceed. Ask at least 1 and at most 6 questions; never interrogate past what you need (YAGNI applies to questions too).
- Write the accumulated understanding into the Idea & Clarifications node:
upsertNodeitsvalueto the idea plus the clarifying Q&A and any pasted context, as labelled sections (## Idea,## Clarifications,## Context). This node is already wired to Make Arrayitem_0; do not add another edge.
Phase 2 complete. Now proceed to Phase 3.
Phase 3: Synthesize requirements and confirm scope
- Substitute
{{topic}}into the Synthesize Requirements and Compose Design Spec prompts viaupsertNode(derive a short working title from the idea if the user did not give one). ThennodeExecutorSynthesize Requirements - it auto-resolves Make Array and every connected source upstream. getNodeOutputand present the REQUIREMENTS BRIEF in chat. Do NOT poll in a loop.- Scope gate (single step, inline branch):
- If the brief's Scope Assessment says the idea needs decomposing into independent subsystems: stop and help the user decompose in chat - name the independent pieces and a build order, agree which ONE sub-project to design now, then
upsertNodethe Idea & Clarificationsvalueto narrow it to that sub-project and re-run step 8-9. Note the rest as follow-on specs. Capture the decomposition (the pieces, the build order, the chosen sub-project) in a disconnected "Decomposition Plan" Text store so the split stays inspectable on the canvas (see "Text Nodes as a Canvas Store"). - Otherwise: confirm in chat that the brief looks right ("Anything to correct before I explore approaches?") and continue. This is a chat confirmation, not a
requestUserDecision.
- If the brief's Scope Assessment says the idea needs decomposing into independent subsystems: stop and help the user decompose in chat - name the independent pieces and a build order, agree which ONE sub-project to design now, then
Phase 3 complete. Now proceed to Phase 4.
Phase 4: Explore approaches and let the user choose
nodeExecutorExplore Approaches - it auto-resolves the brief upstream.getNodeOutputand present the 2-3 approaches in chat, leading with your recommendation and why.- Approach gate - call
requestUserDecisionONCE: keyapproach, question "Which approach should I design?", context "I will write the full design for the one you pick.", options built from the approaches (e.g.Approach A - <name> (recommended),Approach B - <name>, ...). The free-text box lets the user ask for a different or blended approach. StoreapproachChoice = answers.find(a => a.key === "approach")?.selectedIds?.[0].- If the user asked for something different (free text), or
cancelledwith feedback: revise in chat,upsertNodethe Explore Approachespromptwith the steer, and re-run step 11-13. Do NOT proceed to Phase 5 until an approach is chosen.
- If the user asked for something different (free text), or
Phase 4 complete. Now proceed to Phase 5.
Phase 5: Compose the design and approve it together
- Record the choice on the design node:
upsertNodeCompose Design Specprompt, appending a lineSELECTED APPROACH: <the chosen approach>after its baked instructions. You may also keep it as a durable artifact - clone Idea & Clarifications into a disconnected "Chosen Approach" Text store and set itsvalue(see "Text Nodes as a Canvas Store"). nodeExecutorCompose Design Spec - it auto-resolves the approaches upstream.getNodeOutput.- Present the design to the user section by section in chat (Summary, Architecture, Components, Data Flow, Error Handling, Testing) - scale each to its complexity and ask, per section, whether it looks right.
- Design approval gate - this is the HARD GATE. Repeat until the user approves:
a. Collect the user's feedback across the sections (chat).
b. If they request any change:
upsertNodethe Compose Design Specprompt, appending a lineREVISION NOTES: <their feedback>, then re-run step 15-16. c. If they approve: continue. Do NOT proceed to Phase 6 until the user has explicitly approved the design. Do NOT write code or invoke any implementation step - producing the spec is the terminal goal.
Phase 5 complete. Now proceed to Phase 6.
Phase 6: Self-review the spec and let the user review it
nodeExecutorSelf-Review Spec - it auto-resolves the approved design upstream and fixes placeholders / contradictions / scope / ambiguity inline.getNodeOutput.- Present the finalized spec and ask the user to review it: "Spec finalized below. Review it and tell me if you want any changes before we wrap." Wait for the reply (chat, not
requestUserDecision). If they request changes, feed them back -upsertNodethe relevant node'sprompt(Compose for content changes, Self-Review for tightening) with the notes, re-run from that node, and re-present. Loop until they approve.
Phase 6 complete. Now proceed to Phase 7.
Phase 7: Verify and finish
verification- present the final audit (requirements -> chosen approach -> finalized spec) to the user. The spec is the terminal artifact; do NOT invoke any implementation step or write code.followUp- summarize, and OFFER (do NOT auto-run) to: save the spec to Drive (run Save Spec with aselectDriveItemdestination and a<YYYY-MM-DD>-<topic>-design.mdname only if the user then asks - saving is a side effect, so it is never automatic), and note the natural next step is to take this spec into implementation planning. Saving is the only side effect and is offered here, so callingfollowUpdirectly afterverificationis correct. On an edit turn, infer intent from prior state (previously saved -> refresh) without re-running the dialogue.
Configuration Tips
Incremental Edits to an Existing Spec
If the canvas already holds a built, executed pipeline and a finalized spec from a PRIOR turn, and the user asks for a small change ("add a caching section", "tighten the testing part", "switch to Approach B"), treat it as an EDIT - do NOT re-run the Phase 2 clarifying dialogue or the Phase 4/5 gates from scratch:
- Content change ->
upsertNodeCompose Design SpecpromptwithREVISION NOTES: <delta>, re-run Compose -> Self-Review, re-present, get approval. - Different approach ->
upsertNodeComposepromptSELECTED APPROACH: <new>, re-run Compose -> Self-Review. - Re-tighten only -> re-run Self-Review Spec. Then re-present and, if the spec was previously saved, offer to refresh the saved copy (do NOT auto-save). A bundled "build AND tweak" request is a full build - run all 7 phases.
Error Handling
- Empty or thin REQUIREMENTS BRIEF -> the Idea & Clarifications node is empty or
item_0got disconnected; confirm the idea text is set on the node and itsvalue-> Make Arrayitem_0edge exists, then re-run. - A context source node left disconnected by design - that is correct; only connected sources execute. Never connect a source the user did not provide (an empty Drive reader / empty query would fail and block the run).
- Web Search
rate_limited=trueor emptyurls-> fall back to a Drive doc or proceed greenfield (the idea alone is enough). - Fetch
failed_counthigh -> some URLs were unreachable/SSRF-blocked; the array still carries the successful entries; supply different URLs or skip web research. - User keeps requesting design changes -> that is the Phase 5 revise loop working; keep appending
REVISION NOTES:and re-running Compose until they approve. Do NOT proceed to Phase 6 unapproved. - Spec still has "TBD"/placeholders after Self-Review -> the brief had unresolved Open Questions; surface them in chat, get the missing facts, update the Idea & Clarifications node, and re-run from Synthesize Requirements.
- Spec sprawls across multiple subsystems -> the idea needed decomposing at the Phase 3 scope gate; narrow to the first sub-project and note the rest under Out of Scope.
- "destinationFolder required" on Save Spec -> the
selectDriveItemstep was skipped; pick a folder then re-run Save Spec.
// Dependencies
1from input import Text2from input import DriveDocumentReader3from input import WebSearch4from process import FetchURLAsMarkdown5from process import MakeArray6from process import TextSummarizer7from process import TextTransform8from output import SaveFile// Variables
1idea:2 type: undefined3 label: "Idea"4 description: "The feature, change, or idea to brainstorm into a design spec."5 required: undefined67topic:8 type: undefined9 label: "Topic"10 description: "Short name for the design, used in the spec title and filename."11 required: undefined$ git log --oneline