Foundry

A brief, end to end

A message lands:

I want a notes app. Something calmer than what exists, my notes are a mess. People should be able to write, but also just talk to it. Nothing complicated.

Three sentences, no flows, no states, no rules, and a promise of "nothing complicated" that always turns out to mean something. This page walks the whole way from there to screens you can click, with the prompt used at each step.

The result is Murmur, one of the examples that ship with Foundry. Every file quoted here is in examples/murmur, so you can compare what you read with what was actually produced.

1. Discovery: turn the brief into an intent

Do not open an editor yet. A brief like that hides three decisions, and an agent will happily invent all three if you let it.

Who is it for, precisely? Not "everyone who takes notes". One person, with a habit.

What is the job? Not the feature list, the thing they hire the product to do.

What does "calm" mean here? It is the only word in the brief carrying any design intent, and it means nothing until you make it concrete.

Ask the client, then hand the answers over rather than the brief:

From these notes on a client conversation, write docs/01-product.md: who it is for as one named person with a habit, the job to be done in their words, the flows we think we need, and the states that matter. No feature list, no roadmap. Say what we are deliberately leaving out and why.

docs/*.md is not decoration: Foundry renders it beside the screens, so the reasoning travels with the prototype. When the client asks in three weeks why there is no folder sharing, the answer is on the canvas.

2. Scope: decide what the MVP is not

The brief said "nothing complicated". Turn that into a list you can hold someone to.

For Murmur that meant four flows and a hard exclusion: no streaks, no counts, no analytics of your own writing. That exclusion is a product decision, so it belongs in the spec, not in a conversation nobody can find later.

spec/project.md carries the identity, the navigation, the flow list, and the global rules:

yaml
spec:
  nav:
    - { flow: notes,       label: Notes,       icon: home }
    - { flow: collections, label: Collections, icon: folder }
    - { flow: settings,    label: Settings,    icon: sliders }
  flows: [welcome, notes, collections, settings]

Above that block, in prose, the rules that every screen must honour. Murmur's, in full:

md
- every screen is reachable from an entry point (no orphans)
- a note can be text, a checklist, a sketch, or a voice memo, and the home grid mixes them
- colour tints a note for mood and never carries meaning on its own
- one ember accent does the pointing (the hand underline, the active switch) and nothing competes with it
- capture is always one tap away: a plus on every tab and a mic inside every note
- an empty notebook leads with one illustration and a single action, never a wall of controls
- the display voice is a reading serif; the body is a plain sans
- no em dash in copy

Write these once. They are what stops the twentieth screen from contradicting the first, and they are the instruction your agent re-reads every time it opens the project.

3. The spec, one flow at a time

One flow per file. Prose for the happy path, then exactly one spec: block for the machine.

Draft spec/flows/notes.md. The home is a grid mixing text notes, a checklist, a sketch and a voice memo. Opening one shows it full screen, where it can be read and edited in the same place. Creating a note and recording a memo both slide up as sheets. Cover the empty notebook. The rule that matters: capture is always one tap away. Keep the prose short and put every machine fact in the spec: block.

Note what the prompt does not say: it never names a file, a component, or a colour. It gives the intent and the one rule that constrains it, and lets the format do the rest.

4. The check disagrees, and it is right

First draft, and the machine answers:

text
$ foundry check
✗ [edge-endpoint-exists] notes: edge "to: entry" is neither a screen here nor a known flow
⚠ [no-orphan-screen] notes/note: screen "note" is not reachable from the flow entry
✗ [overlay-has-exit] notes/record: overlay "record" has no outgoing edge to dismiss it

failed: 2 errors, 1 warning

Read the cascade, because it is the whole argument for this tool. The screen was renamed from entry to note in one place and not the other. That single slip broke the edge, and because the edge broke, the screen it pointed at became unreachable. Meanwhile the recording sheet had no way out: a user who opened it would be stuck, and nobody would have noticed until the demo.

Feed the output back verbatim rather than describing it:

foundry check reports this. Make the smallest change that clears it, and do not restructure the flow.

Then run it again. The exit code is 1 while anything is red, which is what makes the same command usable in CI.

5. The design direction, before any screen

This is the step people skip, and it is the one that decides whether the result looks like every other AI mockup.

design.md is where the visual language lives. Its frontmatter compiles to CSS variables and classes, so a decision made here lands on every screen at once:

yaml
colors:
  ink: '#211f1a'
  paper: '#f4f0e7'
  ember: '#b0502b'
  butter: '#e8d7ab'

Do not ask for "a beautiful modern UI". Give the product a world, and name the choices:

Write design.md for Murmur. It is a notebook for half-formed thoughts, and it should feel like a stack of index cards on a kitchen table, not like software. Warm paper ground, soft pastel note cards, one ember accent that only marks what needs attention. Headings and note titles in a reading serif, because a note should feel like paper rather than a form field; body in a plain system sans. Colour is chosen for mood and rotates freely, it never encodes a category. Under ## Don't, write the tells we refuse.

That last sentence matters. Written into the design system, the refusals apply to every screen the agent writes afterwards, without being repeated in a prompt.

6. The screens

One file per screen and state, content only, styled with the tokens.

Write the screens for the notes flow, mobile. Use the tokens from design.md, never raw hex. The home is a masonry grid mixing a text note, a checklist, a sketch tile and a voice memo, with real titles someone would actually write, never lorem and never "Note 1". Link a card to the note screen with data-wf-to. Respect the rules in spec/project.md.

Two things carry this prompt. Real content, because a layout full of placeholder text hides exactly the density problems you need to see. And the tokens, because a palette change then costs one edit instead of forty.

7. Look at it, starting with the busiest screen

bash
foundry serve

Judge the dense screen first. Craft never shows on an empty state; it shows where six cards of different heights have to sit together. If the grid holds there, it holds everywhere.

What you are looking for is not "is it pretty". It is whether the screens obey the rules you wrote in step 2. If a card uses colour to mean something, the rule was broken and the screen is wrong, however good it looks.

8. Hand it over

bash
foundry build --out handover

A self contained static site: the canvas, the spec beside it, the docs from step 1. Host it anywhere, or send the folder. The client clicks through, and the spec they are implicitly approving sits one tab away from the screens, so the next change starts from it rather than from a new conversation.

Tag the commit while you are at it. The spec is markdown in the repository, so the version the client saw is a git ref, not a separate artifact to keep in sync.

What you end up with

text
spec/project.md               the contract: nav, flows, rules
spec/flows/*.md               one file per flow, prose plus one spec: block
design.md, design.css         the visual language, compiled to tokens
wiresmith.yml                 project name and asset folders
flows/<flow>/*.html           the screens, one file per state
flows/<flow>/meta.yml         the flow's title and its order
flows/<flow>/annotations.yml  the design rationale, beside the screens, never on them
docs/*.md                     why the product is like this
AGENTS.md                     how an agent works on all of the above

All of it is text, in your repository, versioned with the code. The screens are a view of the spec, the docs say why, and foundry check refuses to let the three drift apart.

Read Working with an agent for the prompting detail, or the Spec format for the reference.

Last updated Jul 30, 2026