一键导入
shaping
Use this methodology when collaboratively shaping a solution with the user - iterating on problem definition (requirements) and solution options (shapes).
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Use this methodology when collaboratively shaping a solution with the user - iterating on problem definition (requirements) and solution options (shapes).
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
| name | shaping |
| description | Use this methodology when collaboratively shaping a solution with the user - iterating on problem definition (requirements) and solution options (shapes). |
A structured approach for collaboratively defining problems and exploring solution options.
Shaping produces documents at different levels of abstraction. Truth must stay consistent across all levels.
Each level summarizes or provides a view into the level(s) below it. Lower levels contain more detail; higher levels are designed views that help acquire context quickly.
Changes ripple in both directions:
Whenever making a change:
The Big Picture isn't a static snapshot — it's a live summary that must stay connected to its source documents. The system only works if the levels are consistent with each other.
When kicking off a new shaping session, offer the user both entry points:
There is no required order. Shaping is iterative — R and S inform each other throughout.
When the shaping doc already has a selected shape:
This gives the user immediate context on where the shaping stands and what needs attention.
A numbered set defining the problem space.
Letters represent mutually exclusive solution approaches.
Give shapes a short descriptive title that characterizes the approach. Display the title when showing the shape:
## E: Modify CUR in place to follow S-CUR
| Part | Mechanism |
|------|-----------|
| E1 | ... |
Good titles capture the essence of the approach in a few words:
| Level | Notation | Meaning | Relationship |
|---|---|---|---|
| Requirements | R0, R1, R2... | Problem constraints | Members of set R |
| Shapes | A, B, C... | Solution options | Pick one from S |
| Components | C1, C2, C3... | Parts of a shape | Combine within shape |
| Alternatives | C3-A, C3-B... | Approaches to a component | Pick one per component |
Keep notation throughout as an audit trail. When finalizing, compose new options by referencing prior components (e.g., "Shape E = C1 + C2 + C3-A").
Shaping moves through two phases:
Shaping → Slicing
| Phase | Purpose | Output |
|---|---|---|
| Shaping | Explore the problem and solution space, select and detail a shape | Shaping doc with R, shapes, fit checks, breadboard |
| Slicing | Break down for implementation | Vertical slices with demo-able UI |
Shaping → Slicing happens when:
You can't slice without a breadboarded shape.
The Big Picture is a living document that reflects the current state of truth at lower levels:
| Stage | Big Picture Contains |
|---|---|
| Exploring shapes | Not needed yet — still comparing options |
| Shape selected | Frame + Shape (fit check, parts, breadboard) |
| Shape breadboarded | Same, with full wiring diagram |
| After slicing | Adds Slices section (sliced breadboard + grid) |
| During implementation | Updated as slices complete (✅/⏳ status) |
The Big Picture always summarizes what exists in the ground truth documents. It evolves as shaping and implementation progress.
THE fit check is the single table comparing all shapes against all requirements. Requirements are rows, shapes are columns. This is how we decide which shape to pursue.
## Fit Check
| Req | Requirement | Status | A | B | C |
|-----|-------------|--------|---|---|---|
| R0 | Make items searchable from index page | Core goal | ✅ | ✅ | ✅ |
| R1 | State survives page refresh | Must-have | ✅ | ❌ | ✅ |
| R2 | Back button restores state | Must-have | ❌ | ✅ | ✅ |
**Notes:**
- A fails R2: [brief explanation]
- B fails R1: [brief explanation]
When comparing alternatives for a specific component (e.g., C3-A vs C3-B), use the same format but scoped to that component:
## C3: Component Name
| Req | Requirement | Status | C3-A | C3-B |
|-----|-------------|--------|------|------|
| R1 | State survives page refresh | Must-have | ✅ | ❌ |
| R2 | Back button restores state | Must-have | ✅ | ✅ |
If a shape passes all checks but still feels wrong, there's a missing requirement. Articulate the implicit constraint as a new R, then re-run the fit check.
These can happen in any order:
When displaying R (requirements) or any S (shapes), always show every row — never summarize or abbreviate. The full table is the artifact; partial views lose information and break the collaborative process.
Shaping is collaborative negotiation. The user needs to see the complete picture to:
Summaries hide detail and shift control away from the user.
A spike is an investigation task to learn how the existing system works and what concrete steps are needed to implement a component. Use spikes when there's uncertainty about mechanics or feasibility.
Always create spikes in their own file (e.g., spike.md or spike-[topic].md). Spikes are standalone investigation documents that may be shared or worked on independently from the shaping doc.
## [Component] Spike: [Title]
### Context
Why we need this investigation. What problem we're solving.
### Goal
What we're trying to learn or identify.
### Questions
| # | Question |
|---|----------|
| **X1-Q1** | Specific question about mechanics |
| **X1-Q2** | Another specific question |
### Acceptance
Spike is complete when all questions are answered and we can describe [the understanding we'll have].
Acceptance describes the information/understanding we'll have, not a conclusion or decision:
The spike gathers information; decisions are made afterward based on that information.
Good spike questions ask about mechanics:
Avoid:
Use the /breadboarding skill to map existing systems or detail a shape into concrete affordances. Breadboarding produces:
Invoke breadboarding when you need to:
The affordance tables (UI and Non-UI) define the breadboard. The Mermaid diagram renders them.
When receiving feedback on a breadboard:
Never treat the diagram as the primary artifact. Changes flow from tables → diagram, not the reverse.
Use CURRENT to describe the existing system. This provides a baseline for understanding where proposed changes fit.
A mechanism can be described at a high level without being concretely understood. The Flag column tracks this:
| Part | Mechanism | Flag |
|---|---|---|
| F1 | Create widget (component, def, register) | |
| F2 | Magic authentication handler | ⚠️ |
Why flagged unknowns fail the fit check:
Fit check is always binary — ✅ or ❌ only. There is no third state. A flagged unknown is a failure until resolved.
This distinguishes "we have a sketch" from "we actually know how to do this." Early shapes (A, B, C) often have many flagged parts — that's fine for exploration. But a selected shape should have no flags (all ❌ resolved), or explicit spikes to resolve them.
Shape parts describe what we BUILD or CHANGE — not intentions or constraints:
childType === 'letter' to typesenseService.rawSearch()" (mechanism)R states the need/constraint (what outcome). S describes the mechanism (how to achieve it). If they say the same thing, the shape part isn't adding information.
The requirement describes the capability needed. The shape part describes the concrete mechanism that provides it. If you find yourself copying text from R into S, stop — the shape part should add specificity about how.
Avoid horizontal layers like "Data model" that group all tables together. Instead, co-locate data models with the features they support:
Each part should be a vertical slice containing the mechanism AND the data it needs.
When the same logic appears in multiple parts, extract it as a standalone part that others reference:
| **B1** | **Signing handler** |
| B1.1 | WaiverSignatures table: memberId, waiverId, signedAt |
| B1.2 | Handler: create WaiverSignature + set member.waiverUpToDate = true |
| **B2** | **Self-serve signing** |
| B2 | Self-serve purchase: click to sign inline → calls B1 |
| **B3** | **POS signing via email** |
| B3.1 | POS purchase: send waiver email |
| B3.2 | Passwordless link to sign → calls B1 |
Start with flat notation (E1, E2, E3...). Only introduce hierarchy (E1.1, E1.2...) when:
| Notation | Meaning |
|---|---|
| E1 | Top-level component of shape E |
| E1.1, E1.2 | Sub-parts of E1 (add later if needed) |
Example of hierarchical grouping (used when shape is mature):
| Part | Mechanism |
|---|---|
| E1 | Swap data source |
| E1.1 | Modify backend indexer |
| E1.2 | Route letters to new service |
| E1.3 | Route posts to new service |
| E2 | Add search input |
| E2.1 | Add input with debounce |
When a shape is selected, you can expand it into concrete affordances. This is called detailing.
Use "Detail X" (not a new letter) to show this is a breakdown of Shape X, not an alternative:
## A: First approach
(shape table)
## B: Second approach
(shape table)
## Detail B: Concrete affordances
(affordance tables + wiring)
Use the /breadboarding skill to produce:
Shape letters (A, B, C...) are mutually exclusive alternatives — you pick one. Detailing is not an alternative; it's a deeper breakdown of the selected shape. Using a new letter would incorrectly suggest it's a sibling option.
A, B, C = alternatives (pick one)
Detail B = expansion of B (not a choice)
Shaping produces up to four documents. Each has a distinct role:
| Document | Contains | Purpose |
|---|---|---|
| Big Picture | Frame summary, Fit Check, Parts, Breadboard, Sliced Breadboard, Slices grid | 10,000-foot view — quick context for driver and developer |
| Frame | Source, Problem, Outcome | The "why" — concise, stakeholder-level |
| Shaping doc | Requirements, Shapes (CURRENT/A/B/...), Affordances, Breadboard, Fit Check | The working document — exploration and iteration happen here |
| Slices doc | Slice details, affordance tables per slice, wiring diagrams | The implementation plan — how to build incrementally |
| Slice plans | V1-plan.md, V2-plan.md, etc. | Individual implementation plans for each slice |
The Big Picture is a one-page summary that shows the entire shaped feature at a glance. It helps:
When to create: After a shape is selected and breadboarded, optionally before slicing is complete. The Big Picture evolves as slicing and implementation progress.
# [Feature Name] — Big Picture
**Selected shape:** [Letter] ([Short description])
---
## Frame
### Problem
- [Pain points as bullet list]
### Outcome
- [Success criteria as bullet list]
---
## Shape
### Fit Check (R × [Selected Shape])
[Fit check table]
### Parts
[Parts table with Flag column]
### Breadboard
[Full Mermaid breadboard]
---
## Slices
[Sliced breadboard — Mermaid diagram with slice boundaries]
[Slices grid — markdown table]
Copy Problem and Outcome from the Frame doc or shaping doc. Use bullet lists.
## Frame
### Problem
- Users cannot search letter content to find what they're looking for
- When users navigate to a letter detail and come back, pagination state is lost
- Page refresh loses any filter state
### Outcome
- Users can search letters by content directly from the index page
- Search and scroll state survives page refresh
- Browser back button restores previous state
Contains three parts: Fit Check, Parts, and Breadboard.
Fit Check (R × [Shape]):
Show only the selected shape column. Full requirement text in every row.
### Fit Check (R × F)
| Req | Requirement | Status | F |
|-----|-------------|--------|---|
| R0 | Make letters searchable from the index page | Core goal | ✅ |
| R2 | Navigate back to pagination state when returning from post detail | Must-have | ✅ |
| R3 | Navigate back to search state when returning from post detail | Must-have | ✅ |
Parts table:
Include the Flag column for flagged unknowns. Use "Flag" as the header, ⚠️ in flagged rows. Center-align with :----:.
### Parts
| Part | Mechanism | Flag |
|------|-----------|:----:|
| **F1** | Create `letter-browser` widget (component, def, register in CMS) | |
| **F2** | URL state & initialization (read `?q=` `?page=`, restore on load) | |
| **F3** | Search input (debounce, min 3 chars, triggers search) | ⚠️ |
Breadboard:
Include the full Mermaid breadboard from the shaping doc. Use flowchart TB (top-to-bottom). Include:
subgraph lettersIndex["PLACE: Letters Index Page"])-->)-.->)Always include a legend after the breadboard:
**Legend:**
- **Pink nodes (U)** = UI affordances (things users see/interact with)
- **Grey nodes (N)** = Code affordances (data stores, handlers, services)
- **Solid lines** = Wires Out (calls, triggers, writes)
- **Dashed lines** = Returns To (return values, data store reads)
Contains two parts: Sliced Breadboard and Slices Grid.
Sliced Breadboard:
A modified version of the main breadboard with slice boundaries shown as colored subgraphs.
Key patterns:
subgraph slice1["V1: SLICE NAME"] — wrap each slice's affordancesslice1 ~~~ slice2 — forces V1 before V2 in layoutfill:transparent to inherit the slice colorflowchart TB
subgraph slice1["V1: WIDGET WITH REAL DATA"]
subgraph letterBrowser1["letter-browser"]
U2["U2: loading spinner"]
U3["U3: no results msg"]
N3["N3: performSearch"]
end
N4["N4: rawSearch"]
end
subgraph slice2["V2: SEARCH WORKS"]
U1["U1: search input"]
N1["N1: activeQuery.next"]
end
%% Force slice ordering (invisible links)
slice1 ~~~ slice2
%% Cross-slice wiring
U1 -->|type| N1
N1 --> N3
N3 --> N4
%% Slice boundary styling (colored fills)
style slice1 fill:#e8f5e9,stroke:#4caf50,stroke-width:2px
style slice2 fill:#e3f2fd,stroke:#2196f3,stroke-width:2px
%% Nested subgraphs transparent (inherit slice color)
style letterBrowser1 fill:transparent,stroke:#888,stroke-width:1px
%% Node styling
classDef ui fill:#ffb6c1,stroke:#d87093,color:#000
classDef nonui fill:#d3d3d3,stroke:#808080,color:#000
class U1,U2,U3 ui
class N1,N3,N4 nonui
Slice color palette (use consistently):
fill:#e8f5e9,stroke:#4caf50 (green)fill:#e3f2fd,stroke:#2196f3 (blue)fill:#fff3e0,stroke:#ff9800 (orange)fill:#f3e5f5,stroke:#9c27b0 (purple)fill:#fff8e1,stroke:#ffc107 (yellow)fill:#fce4ec,stroke:#e91e63 (pink)Slices Grid:
A markdown table with an empty header row. Aim for 2 rows × 3 columns (6 slices) or 3 rows × 3 columns (9 slices).
Each cell contains:
**[V1: SLICE NAME](./feature-v1-plan.md)** (link to slice plan file)✅ COMPLETE or ⏳ PENDING• (bullet + space)<br> for line breaks within cells• as a spacer bullet to equalize cell heights| | | |
|:--|:--|:--|
| **[V1: WIDGET WITH REAL DATA](./letter-search-v1-plan.md)**<br>✅ COMPLETE<br><br>• Create letter-browser widget<br>• Register in CMS system<br>• rawSearch() with parentId<br>• Loading, empty, results UI<br><br>*Demo: Widget shows real letters* | **[V2: SEARCH WORKS](./letter-search-v2-plan.md)**<br>✅ COMPLETE<br><br>• Search input + activeQuery<br>• Debounce 90ms, min 3 chars<br>• Query passed to rawSearch()<br>• <br><br>*Demo: Type "dharma", results filter live* | **[V3: INFINITE SCROLL](./letter-search-v3-plan.md)**<br>✅ COMPLETE<br><br>• Intercom scroll subscription<br>• appendNextPage()<br>• Re-arm scroll detection<br>• <br><br>*Demo: Scroll down, more letters load* |
| **[V4: URL STATE](./letter-search-v4-plan.md)**<br>✅ COMPLETE<br><br>• ?q= and ?page= in URL<br>• initializeState() on load<br>• Router.navigate() on change<br>• Back button restores state<br><br>*Demo: Search, refresh, back all restore state* | **[V5: COMPACT MODE](./letter-search-v5-plan.md)**<br>✅ COMPLETE<br><br>• data.compact config<br>• Conditional scroll subscribe<br>• "See all X results" link<br>• Navigate with ?q=query<br><br>*Demo: compact=true shows fixed items + "See all" link* | **V6: CUTOVER**<br>⏳ PENDING<br><br>a) Local validation + R14<br>b) Deploy code (safe)<br>c) CMS cutover<br>d) Code cleanup<br><br>*TODO: Typesense index job* |
Note: Slices that are pending don't need links yet. Add links when the slice plan is created.
Create the file: [feature]-big-picture.md in the shaping docs folder
Add header: Feature name and selected shape with short description
Frame section: Copy Problem and Outcome from Frame doc or shaping doc
Shape section:
Slices section (after slicing is complete):
Maintain consistency: When lower-level docs change, update the Big Picture to reflect those changes (see Multi-Level Consistency)
Frame (problem/outcome)
↓
Shaping (explore, detail, breadboard)
↓
Slices (plan implementation)
↓
Big Picture (summarizes all of the above)
Frame can be written first — it captures the "why" before any solution work begins. It contains:
When the user provides source material during framing (user requests, quotes, emails, slack messages, etc.), always capture it verbatim in a Source section at the top of the frame document.
## Source
> I'd like to ask again for your thoughts on a user scenario...
>
> Small reminder: at the moment, if I want to keep my country admin rights
> for Russia and Crimea while having Europe Center as my home center...
> [Additional source material added as received]
---
## Problem
...
Why this matters:
When to capture:
Shaping doc is where active work happens. All exploration, requirements gathering, shape comparison, breadboarding, and fit checking happens here. This is the working document and ground truth for R, shapes, parts, and fit checks.
Slices doc is created when the selected shape is breadboarded and ready to build. It contains the slice breakdown, affordance tables per slice, and detailed wiring.
Big Picture is created once a shape is selected. It summarizes the Frame, Shape, and (once slicing is done) Slices. It stays in sync with the ground truth documents throughout implementation.
See Multi-Level Consistency at the top of this document. Changes at any level must ripple to affected levels above and below.
After a shape is breadboarded, slice it into vertical implementation increments. Use the /breadboarding skill for the slicing process — it defines what vertical slices are, the procedure for creating them, and visualization formats.
The flow:
/breadboarding)/breadboarding slicing section)Key principle: Every slice must end in demo-able UI. A slice without visible output is a horizontal layer, not a vertical slice.
Document outputs:
User is shaping a search feature:
## Requirements (R)
| ID | Requirement | Status |
|----|-------------|--------|
| R0 | Make items searchable from index page | Core goal |
| R1 | State survives page refresh | Undecided |
| R2 | Back button restores state | Undecided |
---
## C2: State Persistence
| Req | Requirement | Status | C2-A | C2-B | C2-C |
|-----|-------------|--------|------|------|------|
| R0 | Make items searchable from index page | Core goal | — | — | — |
| R1 | State survives page refresh | Undecided | ✅ | ✅ | ❌ |
| R2 | Back button restores state | Undecided | ✅ | ✅ | ✅ |
**Notes:**
- C2-C fails R1: in-memory state lost on refresh
- C2-B satisfies R2 but requires custom popstate handler