Foundry

Spec format

A spec is a folder of markdown. Each file mixes prose (for humans, and for the agent that composes the screens) with exactly one spec: YAML block that holds the machine read facts.

text
spec/
  project.md          identity, nav shell, global rules, ordered flow list
  flows/<name>.md     one flow per file: prose plus a single spec: block

This page is written for two readers: you, and your coding agent. It is the contract the agent follows when it authors a spec.

project.md

The root file. Prose for the product's intent and its global rules, then one spec: block:

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]
  • flows is the ordered list of flows in the product. A name here with no matching file under flows/ is a planned flow.
  • nav is the top level navigation shell: the sections a user can always reach. Every flow in nav must be a known flow.

flows/<name>.md

One file per flow. Prose describing the happy path and the flow's own rules, then one spec: block:

yaml
spec:
  screens:
    - { id: home,   states: [default, empty] }
    - { id: note,   states: [default] }
    - { id: new,    states: [default], overlay: true }
    - { id: record, states: [default], overlay: true }
  edges:
    - { from: home,   to: note,        on: open }
    - { from: home,   to: new,         on: create }
    - { from: home,   to: collections, on: nav }
    - { from: note,   to: home,        on: back }
    - { from: note,   to: record,      on: dictate }
    - { from: new,    to: home,        on: done }
    - { from: record, to: home,        on: save }

Fields

Field Meaning
screens[].id The screen's identifier, unique within the flow.
screens[].states The states this screen has, for example default, empty, loading.
screens[].overlay true if the screen is a modal or sheet over the current one; it then needs an outgoing edge to dismiss it.
edges[] A transition { from, to, on }. to is a screen in this flow or the name of another flow.

The first screen in screens is the flow's entry.

The checks

foundry check runs a fixed set of coherence checks. An error fails the build; a warning is surfaced but does not fail it. The rule library grows over time; this is what it guarantees today.

Check Level What it enforces
edge-endpoint-exists error Every edge's from is a screen in the flow, and every to is a screen here or a known flow.
overlay-has-exit error A screen marked overlay: true has an outgoing edge that dismisses it.
nav-target-exists error Every nav section in project.md points to a known flow.
no-orphan-screen warning Every screen is reachable from the flow's entry by following edges.
index-lists-flow-files warning Every flow file is listed in project.md's flows.

Reading a finding

Each finding names the check, the flow, and the screen, so a failure points straight at the line to fix. For example:

overlay-has-exit: overlay "record" has no outgoing edge to dismiss it

means a screen marked overlay: true has no edge leaving it, so there is no way back. Add an outgoing edge, and the check passes.

Complete examples

Four reference projects ship with Foundry, spec and screens. Each one opens as a live canvas you can pan around and click through, with its spec beside the screens it produced.

  • murmur, a mobile notes app and the canonical example: a full journey (welcome, notes, collections, settings) with overlays, an empty state, and settings detail pages. The guides follow it.
  • ledger, a freelancer invoicing app.
  • aurora and lueur, larger multi flow specs.

They also live under examples/ in the repository, if you would rather read the raw files.

Last updated Jul 29, 2026