Prototype
A prototype is throwaway code that answers one question. Write the question down first, in one paragraph at the top of the prototype where the reader sees it. Then build the smallest thing that answers it.
Two modes
Pick by asking: does the prototype need the real app around it to be judged?
- Standalone (default). Plain HTML/CSS/JS, no framework, no bundler, no server. One file per prototype, saved in the task folder per the
aiwork-protocol skill: prototype/index.html, or prototype/{name}.html for several. Everything inline so it opens by double-click and can be sent to anyone. Use for logic and state models, and for UI ideas that can be judged in isolation.
- Integrated. Variants rendered inside the project's framework, on a real route with the real header, data and density, because a variant in a vacuum always looks fine. Work on a dedicated
prototype/{name} branch that is never merged. Follow the project's conventions (Nuxt: pages/, components/, its CSS system) and name files so they are obviously prototypes: components/prototype/, pages/prototype/{name}.vue. Start it with the project's normal dev command.
Rules
- No polish. No tests, no error handling beyond what makes it run, no abstractions, no generalising for later.
- No persistence. State lives in memory. Persistence is something a prototype checks, not something it depends on.
- Surface the state. After every action or variant switch, show the full relevant state and what just changed.
- Read-only against the real app. Integrated variants never call real mutations. Stub them.
Logic prototype
For "does this state machine / data model / API shape hold up". One HTML file a non-developer can drive.
- Keep the logic in one
<script> block as a pure module: a reducer (state, action) => state, an explicit state machine when "which actions are legal now" is part of the question, or a few pure functions over plain data. No DOM inside it. The page calls it, never the reverse.
- Page layout, top to bottom:
- Title and the question.
- Current state as labelled fields, not raw JSON, re-rendered after every click.
- Free-play: one button per action, always available, any order.
- Guided scenarios as tabs. Each has a short plain-language description (the situation and what to watch for) and its steps as real buttons that run in order. Starting a scenario resets to a known initial state.
- Scenarios cover what is hard to reason about on paper: the happy path, an awkward edge case, an attempt at something that should be illegal.
- Domain language everywhere. Buttons and labels read like the business, not like the code.
- Clean and restrained: readable typography, generous spacing, one accent colour, no animation.
UI prototype
For "what should this look like". Several structurally different variants behind one switcher.
- Default to three variants, never more than five. They must disagree about layout, information hierarchy and primary affordance, not just colour or copy. If two come out alike, redo one with an explicit constraint such as "no card grid".
- Share small pieces between variants (a header), never the layout. Each variant is free to throw the layout away.
- Use the project's styling system (in jedlik-nejedlik that is Puleo CSS and the tokens shown on
/style). Standalone HTML inlines the tokens it needs.
- Name variants
A, B, C plus a short label, e.g. B (sidebar layout).
- Integrated: variants on the existing route, selected by
?variant=. Keep the page's data fetching, swap only the rendered subtree. A new throwaway route is the last resort, only when nothing existing can host the variants. An empty route hides problems a populated one exposes.
- Switcher: one shared component, a fixed bar at the bottom centre, visually distinct from the page so it is obviously not part of the design. Previous and next buttons that wrap, the current variant key and label, arrow keys as shortcuts (not while an input, textarea or contenteditable is focused). It updates the URL so a variant is shareable and reload-stable.
- Hand over the URL and the variant keys. The useful feedback is usually "the header from B with the sidebar from C". Add variants or scenarios on request; prototypes evolve.
When it has answered
Record the verdict and why: in the task folder's spec or notes (per the aiwork-protocol skill), or a Verdict section at the top of the prototype file. The prototype itself stays where it is, in the .aiwork/ folder or on its branch, as the primary source. It is never promoted to production code; the real implementation is written separately, using what the prototype taught.
1---2name: prototype3description: Build a throwaway prototype that answers one design question. Plain HTML/CSS/JS in the task's .aiwork/ folder by default, or UI variants inside the app (Nuxt/Vue, ...) on a prototype branch when they must sit against real layout and data. Use for "does this state model feel right" or "what should this look like".4---56# Prototype78A prototype is throwaway code that answers **one question**. Write the question down first, in one paragraph at the top of the prototype where the reader sees it. Then build the smallest thing that answers it.910## Two modes1112Pick by asking: does the prototype need the real app around it to be judged?1314- **Standalone (default).** Plain HTML/CSS/JS, no framework, no bundler, no server. One file per prototype, saved in the task folder per the `aiwork-protocol` skill: `prototype/index.html`, or `prototype/{name}.html` for several. Everything inline so it opens by double-click and can be sent to anyone. Use for logic and state models, and for UI ideas that can be judged in isolation.15- **Integrated.** Variants rendered inside the project's framework, on a real route with the real header, data and density, because a variant in a vacuum always looks fine. Work on a dedicated `prototype/{name}` branch that is never merged. Follow the project's conventions (Nuxt: `pages/`, `components/`, its CSS system) and name files so they are obviously prototypes: `components/prototype/`, `pages/prototype/{name}.vue`. Start it with the project's normal dev command.1617## Rules1819- **No polish.** No tests, no error handling beyond what makes it run, no abstractions, no generalising for later.20- **No persistence.** State lives in memory. Persistence is something a prototype checks, not something it depends on.21- **Surface the state.** After every action or variant switch, show the full relevant state and what just changed.22- **Read-only against the real app.** Integrated variants never call real mutations. Stub them.2324## Logic prototype2526For "does this state machine / data model / API shape hold up". One HTML file a non-developer can drive.2728- Keep the logic in one `<script>` block as a pure module: a reducer `(state, action) => state`, an explicit state machine when "which actions are legal now" is part of the question, or a few pure functions over plain data. No DOM inside it. The page calls it, never the reverse.29- Page layout, top to bottom:30 1. Title and the question.31 2. Current state as labelled fields, not raw JSON, re-rendered after every click.32 3. Free-play: one button per action, always available, any order.33 4. Guided scenarios as tabs. Each has a short plain-language description (the situation and what to watch for) and its steps as real buttons that run in order. Starting a scenario resets to a known initial state.34- Scenarios cover what is hard to reason about on paper: the happy path, an awkward edge case, an attempt at something that should be illegal.35- Domain language everywhere. Buttons and labels read like the business, not like the code.36- Clean and restrained: readable typography, generous spacing, one accent colour, no animation.3738## UI prototype3940For "what should this look like". Several **structurally different** variants behind one switcher.4142- Default to three variants, never more than five. They must disagree about layout, information hierarchy and primary affordance, not just colour or copy. If two come out alike, redo one with an explicit constraint such as "no card grid".43- Share small pieces between variants (a header), never the layout. Each variant is free to throw the layout away.44- Use the project's styling system (in jedlik-nejedlik that is Puleo CSS and the tokens shown on `/style`). Standalone HTML inlines the tokens it needs.45- Name variants `A`, `B`, `C` plus a short label, e.g. `B (sidebar layout)`.46- Integrated: variants on the existing route, selected by `?variant=`. Keep the page's data fetching, swap only the rendered subtree. A new throwaway route is the last resort, only when nothing existing can host the variants. An empty route hides problems a populated one exposes.47- Switcher: one shared component, a fixed bar at the bottom centre, visually distinct from the page so it is obviously not part of the design. Previous and next buttons that wrap, the current variant key and label, arrow keys as shortcuts (not while an input, textarea or contenteditable is focused). It updates the URL so a variant is shareable and reload-stable.48- Hand over the URL and the variant keys. The useful feedback is usually "the header from B with the sidebar from C". Add variants or scenarios on request; prototypes evolve.4950## When it has answered5152Record the verdict and why: in the task folder's spec or notes (per the `aiwork-protocol` skill), or a `Verdict` section at the top of the prototype file. The prototype itself stays where it is, in the `.aiwork/` folder or on its branch, as the primary source. It is never promoted to production code; the real implementation is written separately, using what the prototype taught.