Skip to main content

breadboarding

Transform a workflow description into affordance tables showing UI and Code affordances with their wiring. Use to map existing systems or design new ones from shaped parts.

Datos de origen

Repositorio
rjs/shaping-skills
Última actividad en el origen
11 de febrero de 2026 a las 11:58
Idioma detectado de SKILL.md
inglés
Estrellas
1442
Forks
94

Opciones de instalación

De forma predeterminada está seleccionado el prompt que primero revisa el origen. Puedes cambiar a un comando directo o descargar una copia local.

Revisa los archivos de origen

Lee SKILL.md y los archivos complementarios que muestra SkillsMP antes de decidir si quieres instalarlo.

Mostrando SKILL.md

SKILL.md
Instrucciones de origen · Vista previa de solo lectura
name
breadboarding
description
Transform a workflow description into affordance tables showing UI and Code affordances with their wiring. Use to map existing systems or design new ones from shaped parts.
# Breadboarding Breadboarding transforms a workflow description into a complete map of affordances and their relationships. The output is always a set of tables showing numbered UI and Code affordances with their Wires Out and Returns To relationships. The tables are the truth. Mermaid diagrams are optional visualizations for humans. --- ## Use Cases Breadboarding serves two functions: ### 1. Mapping an Existing System You don't understand how an existing system works in its concrete details. You have a workflow you're trying to understand — explaining how something happens or why something doesn't happen. **Input:** - Code repo(s) to analyze - Workflow description (always from the perspective of an operator trying to make an effect happen — through UI or as a caller) **Output:** - UI Affordances table - Code Affordances table - (Optional) Mermaid visualization **Note:** If the workflow spans multiple applications (frontend + backend), create ONE breadboard that tells the full story. Label places to show which system they belong to. ### 2. Designing from Shaped Parts You have a new system sketched as an assembly of parts (mechanisms) per shaping. You need to detail out the concrete mechanism and show how those parts interact as a system. **Input:** - Parts list (mechanisms from shaping) - The R (requirement/outcome) the parts are meant to achieve - Existing system (optional) — if the new parts must interoperate with existing code **Output:** - UI Affordances table - Code Affordances table - (Optional) Mermaid visualization ### Mixtures Often you have both: an existing system that must remain as-is, plus new pieces or changes defined in a shape. In this case, breadboard both together — the existing affordances and the new ones — showing how they connect. ### 3. Reading a Whiteboard Breadboard Hand-drawn or whiteboard breadboards use a visual stacking format rather than tables. The same concepts apply (Places, affordances, wiring) but the layout conventions differ. **Visual conventions:** | Element | How it appears | |---------|---------------| | **Place** | Colored block (often pink/purple) at the **top** of a vertical stack | | **Affordances in a place** | Blocks stacked **underneath** the place block — containment is shown by vertical position in the stack | | **Code affordances** | Typically float **between** place stacks, not inside them | | **Place loader** | A code affordance positioned at the **top-left** of the place block — describes the data/inputs needed to render that place | | **Wires Out** | Solid arrows between blocks | | **Returns To** | Dashed arrows between blocks | | **Conditionals** | Indented blocks within a stack, often a different color (e.g., green), showing if/else branches | | **Place references** | `_` prefix on a place name within a stack (same as `_PlaceName` convention) | | **Uncertain/tentative** | `?` prefix or `~` prefix on an affordance name, or dashed borders — indicates the affordance is speculative | | **Containing box** | A large boundary drawn around multiple stacks — groups affordances by system or responsibility boundary (e.g., "HireEZ" box) | | **Notes/annotations** | Freeform text near elements — context, open questions, or rationale | **How to read a whiteboard breadboard:** 1. **Identify places** — Find the colored header blocks at the top of each stack 2. **Read each stack top-to-bottom** — Everything stacked under a place belongs to that place 3. **Find loaders** — Code affordances at the top-left of a place block describe what data is needed to render 4. **Trace wiring** — Follow arrows between stacks for control flow (solid) and data flow (dashed) 5. **Note conditionals** — Indented blocks with different colors show branching logic within a place 6. **Check containing boxes** — Large boundaries indicate system/responsibility boundaries 7. **Flag speculative items** — `?` and `~` prefixed items are uncertain and may not survive shaping **Translating to tables:** When converting a whiteboard breadboard to standard affordance tables, map each stack to its Place, enumerate the affordances top-to-bottom, and capture the arrows as Wires Out / Returns To relationships. Loaders become code affordances with Returns To pointing at the UI affordances they feed. --- ## Core Concepts ### Places A Place is a **bounded context of interaction**. While you're in a Place: - You have a specific set of affordances available to you - You **cannot** interact with affordances outside that boundary - You must take an action to leave **Place is perceptual, not technical.** It's not about URLs or components — it's about what the user experiences as their current context. A Place is "where you are" in terms of what you can do right now. #### The Blocking Test The simplest test for whether something is a different Place: **Can you interact with what's behind?** | Answer | Meaning | |--------|---------| | **No** | You're in a different Place | | **Yes** | Same Place, with local state changes | #### Examples | UI Element | Blocking? | Place? | Why | |------------|-----------|--------|-----| | Modal | Yes | Yes | Can't interact with page behind | | Confirmation popover | Yes | Yes | Must respond before returning (limit case of modal) | | Edit mode (whole screen transforms) | Yes | Yes | All affordances changed | | Checkbox reveals extra fields | No | No | Surroundings unchanged | | Dropdown menu | No | No | Can click away, non-blocking | | Tooltip | No | No | Informational, non-blocking | #### Local State vs Place Navigation When a control changes state, ask: did *everything* change, or just a subset while the surroundings stayed the same? | Type | What happens | How to model | |------|--------------|--------------| | **Local state** | Subset of UI changes, surroundings unchanged | Same Place, conditional N → dependent Us | | **Place navigation** | Entire screen transforms, or blocking overlay | Different Places | #### Mode-Based Places When a mode (like "edit mode") transforms the entire screen — different buttons, different affordances everywhere — model as separate Places: ``` PLACE: CMS Page (Read Mode) PLACE: CMS Page (Edit Mode) ``` The state flag (e.g., `editMode$`) that switches between them is a **navigation mechanism**, not a data store. Don't include it as an S in either Place. #### Three Questions for Any Control For any UI affordance, ask: 1. Where did I come from to see this? 2. Where am I now? 3. Where do I go if I act on it? If the answer to #3 is "everything changes" or "I can't interact with what's behind until I respond," that's navigation to a different Place. #### Labeling Conventions | Pattern | Use | |---------|-----| | `PLACE: Page Name` | Standard page/route | | `PLACE: Page Name (Mode)` | Mode-based variant of a page | | `PLACE: Modal Name` | Modal dialog | | `PLACE: Backend` | API/database boundary | When spanning multiple systems, label with the system: `PLACE: Checkout Page (frontend)`, `PLACE: Payment API (backend)`. ### Place IDs Places are first-class elements in the data model. Each Place gets an ID: | # | Place | Description | |---|-------|-------------| | P1 | CMS Page (Read Mode) | View-only state | | P2 | CMS Page (Edit Mode) | Editing state with page-level controls | | P2.1 | widget-grid (letters) | Subplace: letter editing widget within P2 | | P3 | Letter Form Modal | Form for adding/editing letters | | P4 | Backend | API resolvers and database | Place IDs enable: - **Explicit navigation wiring** — wire `→ P2` instead of to an affordance inside - **Containment tracking** — each affordance declares which Place it belongs to - **Consistent Mermaid subgraphs** — subgraph ID matches Place ID ### Place References When a nested place has lots of internal affordances and would clutter the parent, you can **detach** it: 1. Put a **reference node** in the parent place using underscore prefix: `_letter-browser` 2. Define the full place separately with all its internals 3. Wire from the reference to the place: `_letter-browser --> letter-browser` The reference is a **UI affordance** — it represents "this widget/component renders here" in the parent context. ```mermaid flowchart TB subgraph P1["P1: CMS Page (Read Mode)"] U1["U1: Edit button"] U_LB["_letter-browser"] end subgraph letterBrowser["letter-browser"] U10["U10: Search input"] U11["U11: Letter list"] N40["N40: performSearch()"] end U_LB --> letterBrowser ``` In affordance tables, list the reference as a UI affordance: | # | Affordance | Control | Wires Out | |---|------------|---------|-----------| | U1 | Edit button | click | → N1 | | _letter-browser | Widget reference | — | → P3 | Style place references with a dashed border to distinguish them: ``` classDef placeRef fill:#ffb6c1,stroke:#d87093,stroke-width:2px,stroke-dasharray:5 5 class U_LB placeRef ``` ### Modes as Places When a component has distinct modes (read vs edit, viewing vs editing, collapsed vs expanded), model them as **separate places** — they're different perceptual states for the user. If one mode includes everything from another plus more, show this with a **place reference** inside the extended place: ``` P3: letter-browser (Read) — base state P4: letter-browser (Edit) — contains _letter-browser (Read) + new affordances ``` The reference shows composition: "everything in P3 appears here, plus these additions." ```mermaid flowchart TB subgraph P3["P3: letter-browser (Read)"] U10["U10: Search input"] U11["U11: Letter list"] end subgraph P4["P4: letter-browser (Edit)"] U_P3["_letter-browser (Read)"] U3["U3: Add button"] U4["U4: Edit button"] end U_P3 --> P3 ``` In affordance tables for P4, the reference shows inheritance: | # | Affordance | Control | Wires Out | Notes | |---|------------|---------|-----------|-------| | _letter-browser (Read) | Inherits all of P3 | — | → P3 | | | U3 | Add button | click | → N3 | NEW | | U4 | Edit button | click | → N4 | NEW | ### Subplaces A **subplace** is a defined subset of a Place — a contained area that groups related affordances. Use subplaces when: - A Place contains multiple distinct widgets or sections - You're detailing one part of a larger Place - You want to show what's in scope vs out of scope **Notation:** Use hierarchical IDs — `P2.1`, `P2.2`, etc. for subplaces of P2. ``` | # | Place | Description | |---|-------|-------------| | P2 | Dashboard | Main dashboard page | | P2.1 | Sales widget | Subplace: sales metrics | | P2.2 | Activity feed | Subplace: recent activity | ``` In affordance tables, use the subplace ID to show containment: ``` | U3 | P2.1 | sales-widget | "Refresh" button | click | → N4 | — | | U7 | P2.2 | activity-feed | activity list | render | — | — | ``` **In Mermaid:** Nest the subplace subgraph inside the parent. Use the same background color (no distinct fill) — the subplace is part of the parent, not a separate Place: ```mermaid flowchart TB subgraph P2["P2: Dashboard"] subgraph P2_1["P2.1: Sales widget"] U3["U3: Refresh button"] end subgraph P2_2["P2.2: Activity feed"] U7["U7: activity list"] end otherContent[["... other dashboard content ..."]] end ``` **Placeholder for out-of-scope content:** When detailing one subplace, add a placeholder sibling to show there's more on the page: ``` otherContent[["... other page content ..."]] ``` This tells readers: "we're zooming in on P2.1, but P2 contains more that we're not detailing." ### Containment vs Wiring These are two different relationships in the data model: | Relationship | Meaning | Where Captured | |--------------|---------|----------------| | **Containment** | Affordance belongs to / lives in a Place | **Place column** (set membership) | | **Wiring** | Affordance triggers / calls something | **Wires Out column** (control flow) | **Containment** is set membership: `U1 ∈ P1` means U1 is a member of Place P1. Every affordance belongs to exactly one Place. **Wiring** is control flow: `U1 → N1` means U1 triggers N1. An affordance can wire to anything — other affordances or Places. The Place column answers: "Where does this affordance live?" The Wires Out column answers: "What does this affordance trigger?" ### Navigation Wiring When an affordance causes navigation (user "goes" somewhere), wire to the **Place itself**, not to an affordance inside: ``` ✅ N1 Wires Out: → P2 (navigate to Edit Mode) ❌ N1 Wires Out: → U3 (wiring to affordance inside P2) ``` This makes navigation explicit in the tables. The Place is the destination; specific affordances inside become available once you arrive. In Mermaid, this becomes: ``` N1 --> P2 ``` The subgraph ID matches the Place ID, so the wire connects to the Place boundary. ### Affordances Things you can act upon: - **UI affordances (U)**: inputs, buttons, displayed elements, scroll regions - **Code affordances (N)**: methods, subscriptions, data stores, framework mechanisms ### Wiring How affordances connect to each other: **Wires Out** — What an affordance triggers or calls (control flow): - Call wires: one affordance calls another - Write wires: code writes to a data store - Navigation wires: routing to a different place **Returns To** — Where an affordance's output flows (data flow): - Return wires: function returns value to its caller - Read wires: data store is read by another affordance This separation makes data flow explicit. Wires Out show control flow (what triggers what). Returns To show data flow (where output goes). --- ## The Output: Affordance Tables The tables are the truth. Every breadboard produces these: ### Places Table | # | Place | Description | |---|-------|-------------| | P1 | Search Page | Main search interface | | P2 | Detail Page | Individual result view | ### UI Affordances Table | # | Place | Component | Affordance | Control | Wires Out | Returns To |
Ver en GitHub
Este SKILL.md es muy grande, por eso SkillsMP muestra aqui solo la primera seccion. Ver en GitHub