Skills · shaping

Shaping (requirements, shapes and slices on a canvas)

Shape work on a canvas - requirements, shapes, fit check, slices

TerminalCopy
cnotes skills install shaping

Raw markdown: /skills/shaping/skill.md

Shaping settles what to build before anyone builds it. You and the user work two things at once: the requirements (what any acceptable solution must do) and the shapes (rival ways to do it). A fit check plays every shape against every requirement, the user picks one, and the picked shape is cut into vertical slices, each small enough to build and demo on its own.

The method is Shape Up's, as Ryan Singer adapted it for shaping with an agent. This skill keeps the method and moves the output onto CreatorNotes: every requirement, shape, check and slice is a typed, versioned note on one canvas, so the shaping can be read, cited and continued from any session.

Everything runs through the cnotes CLI. The cnotes skill documents every command used here; read it rather than guessing. Use wayfind instead when the work holds several open decisions spread over sessions, and run this skill inside a wayfind ticket that asks "what shape should X take". Use fat-marker-flows to sketch a shape's screens when words stop being enough.

The model

ConceptCreatorNotes shape
Shaping canvasOne canvas named <Effort> · Shaping. Its goal: Decide how we build <effort>. Done when a Decision note selects one shape and a Slice note exists for each slice.
FrameOne Problem note with three headings: ## Source (what was said, verbatim and dated), ## Problem (what hurts, in our words), ## Outcome (what is true when it is solved, with no solution in it)
Current systemObservation notes, dated, on how things work today. In fit checks and prose this is the shape called CURRENT
RequirementOne Requirement note per need, titled R<n> · <the need>. Opens with Status: <status>. and links the frame: [PROBLEM-12: Title](relationship:constrains)
ShapeOne Option note per rival approach, titled <Letter> · <the approach in a few words>, with a parts table
Fit checkOne Shaping note titled Fit check · <what it compares>, <date>: requirements down the side, shapes across the top
SpikeA Question note tagged spike that lists what we need to learn about the mechanics. Answered by an Observation
The choiceA Question note asking the user to pick, with your lean, then a Decision note that selects one shape and rejects the others
BreadboardOne Shaping note titled Breadboard · <shape>: places, what a person can do in each, what the code does, and how they wire together
SliceOne Slice note per slice, titled V<n> · <what someone can do once it ships>, linked [DECISION-9: Title](relationship:implements)

Canvas anatomy

An orientation banner, then numbered sections read top to bottom:

  1. Frame: the Problem note, plus any earlier Decision this revisits.
  2. What happens today: the CURRENT Observations, with the date in the section name.
  3. Requirements: the Requirement notes, R0 first.
  4. Shapes and the fit check: the Option notes side by side, the fit check after them.
  5. What <person> decides: the Question.
  6. The decision and the slices: the Decision, the breadboard, then V1, V2, ...

Section names can say more ("4 · Three Shapes and the Fit Check"). Add a section for spikes when you run any.

Writing each piece

Requirements

  • A requirement names a need, never a mechanism. "State survives a page refresh" is a requirement. "Keep state in the URL" is a part of some shape.
  • It stands alone. Anyone should be able to check it against any shape. If it only makes sense for shape B, it is a part of B.
  • The user owns the status. Propose a status; the user settles it. Use Core goal (R0, exactly one), Must-have, Nice-to-have, Undecided, or Out.
  • Keep the top level short. Past nine requirements, group related ones under a parent (R3, with R3.1 and R3.2 beneath it) so the list stays readable.
  • A fit check can reveal a missing requirement. When a shape passes everything and still feels wrong to the user, ask what it gets wrong, write that as a new requirement, and run the check again.

Shapes

Letters name rival approaches: you pick one of A, B and C. Numbers name the parts inside a shape, which all ship together: A1, A2. When one part has rival ways of being built, name those A2-a and A2-b and pick one of them. Keep the names for good, even after a shape is rejected, so later notes can cite them. A later shape can borrow parts: "D is A1 + A2 + C3".

Each Option note opens with a sentence on the approach, then a parts table:

| Part | Mechanism | Flag |
|---|---|---|
| A1 | A proposals table holds the handle, owner and asked reviewer | |
| A2 | The read funnel hides rows whose proposal the caller cannot read | ⚠️ |
  • A part is something we build or change. "Types stay the same" is not a part; if it matters, it is a requirement.
  • A part adds how, not what. If a part restates a requirement in other words, it is not saying anything yet. Write the mechanism.
  • Cut parts by feature, not by layer. No "A4 · Data model". Put each table in the part whose feature needs it. When two parts need the same logic, make that logic its own part and have the others say "uses A1".
  • ⚠️ marks a part we can describe but do not know how to build yet. Exploratory shapes carry many. The shape the user picks must carry none, or have a spike open for each one.
  • End with a ## Tradeoffs heading: what the shape costs and risks.

The fit check

| Req | Requirement | Status | CURRENT | A | B |
|---|---|---|---|---|---|
| R0 | A proposal is part of the workspace it would change | Core goal | ❌ | ✅ | ✅ |
| R1 | Only the proposer and the person asked can see it | Must-have | ✅ | ❌ | ✅ |

## Why each fails
- A fails R1: nothing filters rows until every read goes through the funnel.
  • Each cell is ✅ or ❌, nothing else. ✅ means we know which part delivers the requirement. A requirement that rests on a ⚠️ part is ❌ until a spike turns the flag into a mechanism.
  • Write each requirement in full. No shortened versions in the table.
  • Explain failures only, one line each, under the table.
  • Include CURRENT whenever the work changes an existing system. It shows what today already gets right.
  • Link it to the frame with [PROBLEM-12: Title](relationship:checks).
  • To compare rival ways of building one part, run a smaller check with the same columns, A2-a against A2-b.

Spikes

Run a spike when a ⚠️ blocks the fit check. The Question lists numbered questions about mechanics ("Where does the draft filter run today?", "What changes so a reviewer can read without joining?") and ends with Done when we can describe <what we will understand>. A spike gathers facts; it does not decide. Avoid effort questions ("how long?") and yes-or-no questions that reveal nothing about how. Record what it found as an Observation with [QUESTION-30: Title](relationship:answers), then update the shape: clear the flag, or rewrite the part.

The choice

When a shape is ready to pick, write the Question to its rubric: what the user is choosing between, what each option optimizes for, your lean, and what would change it. In a live session, ask it one question at a time. The user picks; you never record a choice they did not make. The Decision note then says [OPTION-4: A · Title](relationship:selects) for the pick, relationship:rejects for each loser, and [QUESTION-8: Title](relationship:answers).

Breadboard

Breadboard the picked shape before slicing it. Write one Shaping note:

  • ## Places: each screen, panel or command a person reaches.
  • One heading per place, with a table of what is there: U1, U2 for what a person sees or does, N1, N2 for what the code does (handlers, queries, tables, jobs), and a Wires to column naming the next U or N.

Name affordances concretely ("Accept button on the review card", not "approval UI"). A part of the shape usually becomes several affordances.

Slices

Cut the breadboard into slices, V1 first. Each slice cuts through every layer it needs (screen, logic, data) and ends in something a person can see work. A slice with nothing to demo is a layer; merge it into the slice that shows it. V1 is the thinnest thing that does. Three to nine slices is typical.

Each Slice note says what changes, which affordances it adds (U3, N4) and a ## Demo heading: the exact steps that show it working. When a slice ships, add a ## Shipped heading in a new version: date, commit, CLI version if any, and how it was verified.

Build from one slice, not the whole shape. When the user says to build, the implementation plan comes from one Slice note, with the Decision and breadboard as context.

Rules every session follows

  1. Rubrics before writing. cnotes types show <Type> for each type you are about to write; read the cnotes skill's humanizer reference before any prose.
  2. The user negotiates; you draft. Propose requirements, statuses and shapes, then let the user accept, edit or strike them. Ask one question at a time. In a session with no human, draft everything, lean in the Question, and stop there.
  3. Show whole tables in chat. When you show requirements, a shape or the fit check, show every row, and mark each row that changed since you last showed it with 🟡. The user is checking for gaps, and summaries hide them.
  4. Change the source, then what rests on it. The order is: frame, then requirements and shapes, then the fit check, then the decision and slices. An edit at one level can break the levels on either side of it. After any edit, list what links to the note you changed (cnotes notes get <id> --expand --incoming --summary) and revise each one that no longer agrees, in the same run. A changed requirement means a new version of the fit check; a slice that finds a new mechanism updates its shape and the fit check, not just itself.
  5. Edit, never duplicate. Revise a requirement, shape or check with cnotes versions create, starting from the current body. Its letter or number stays.
  6. Refer by name. In prose a note is its title; mentions carry both: [REQUIREMENT-14: R2 · Back button restores the view](relationship:constrains).
  7. Bracket writes in a run: cnotes operations begin --prompt "<past-tense headline>" before the first write, cnotes operations end after the last.

Start shaping (first invocation)

  1. Make sure the types exist. cnotes types list -q. Create any of Problem, Requirement, Option, Shaping and Slice that are missing, and give each a rubric (setting a rubric needs a workspace admin; if it is refused, carry on and tell the user):

    cnotes types create Problem --display-name "Problem" --description "A problem worth solving: source, problem, outcome"
    cnotes types update Problem --validation-prompt "Open with one sentence naming who hurts and when. Then three headings: Source (what was said or seen, quoted verbatim with who and when), Problem (what is broken, in our words), Outcome (what is true once it is solved, naming no solution)." --enable-validation
    cnotes types create Requirement --display-name "Requirement" --description "A need any acceptable solution must meet, tied to no one shape"
    cnotes types update Requirement --validation-prompt "Title is 'R<n> · <the need>'. The body opens with 'Status: <Core goal|Must-have|Nice-to-have|Undecided|Out>.' and links the Problem it constrains. State what must be true, never how to build it. It must be checkable against any shape." --enable-validation
    cnotes types create Option --display-name "Option" --description "One rival approach, with its parts and tradeoffs"
    cnotes types create Shaping --display-name "Shaping" --description "A shaping working note: a fit check or a breadboard"
    cnotes types create Slice --display-name "Slice" --description "A vertical slice: a demo-able increment through UI, logic and data"
    cnotes types update Slice --validation-prompt "Title is 'V<n> · <what someone can do once it ships>'. Links the Decision it implements. Says what changes and which affordances it adds, then a Demo heading with the exact steps that show it working. Once shipped, a Shipped heading gives the date, commit and how it was verified." --enable-validation
    
  2. Look for prior work. cnotes brief "<effort>" and cnotes canvas search "<effort> shaping". An existing shaping canvas means you continue it (next section). An earlier Decision on the same question is linked from the frame with relationship:revisits.

  3. Ask where to start. The user can start from the problem (requirements first, shapes come out of them) or from a solution they already have in mind (capture it as shape A and pull requirements out of it). Either is fine; the two inform each other the whole way.

  4. Frame it. Quote the source verbatim, with who said it and when. Agree the Problem and Outcome with the user before writing any shape.

  5. Map today when the work changes something that exists: read the code or the product, and record what you found as dated Observations. That is CURRENT.

  6. Open the run and create the canvas: cnotes canvas create "<Effort> · Shaping" --goal "<goal from the model table>" --audience "<who decides, who builds>". Create the notes in one batch (cnotes notes create --notes "$(cat batch.json)"), cross-linked with @key placeholders, then lay out the sections with one cnotes canvas place spec. Banner first, in the cnotes skill's banner order: what happened and who asked, what this board decides, who decides it, how to read it.

  7. Iterate with the user on requirements and shapes until the fit check shows one shape the user wants. Every change is a new version of its note.

  8. Close the run and give the canvas link.

Continue shaping (every later invocation)

  1. Load: cnotes canvas read <canvasId>. Find the fit check and the Decision, if there is one.
  2. Orient the user. If a shape is selected, show the fit check for that shape alone, CURRENT included if present, and list what is still open: Undecided requirements, ❌ cells, ⚠️ parts, slices not yet shipped. If none is selected yet, show the whole fit check and say what blocks a choice.
  3. Do the next step with the user: resolve an Undecided requirement, run a spike, add or detail a shape, take the choice, breadboard, slice, or mark a slice shipped. Follow rule 4 for every edit.
  4. Read it back with cnotes canvas read, close the run, and report by name what changed and what is next.

Finishing

Shaping is finished when the Decision selects a shape with no ⚠️ parts and every slice has a Slice note with a demo. Say so, name V1 as the place to start building, and leave the canvas as the record. As slices ship, their Shipped headings keep the canvas current.