Skip to content
Authoring Flows
AutoXXS (320px)XS (375px)SM (640px)MD (768px)LG (1024px)XL (1280px)XXL (1536px)
SketchMaterialiOSTamagui
DataInjectionKeyPatternsServiceTransactionProcessResearchProductQualityPerformanceSpecDomainFunctionTechnologyArchitectureConfigMiddlewareDataDatabaseDrizzleMigrationModelop-sqliteSchemaSQLState ManagementDraftKeystoneMergePatchPatchesPersistenceReactiveRedoStoreUndoTestingDeviceFactoryIsolationTypeScriptZodTopicsCommunicationBidsNVCDesignDesign ImplicationsEducationPedagogyFoundationsPsychologyAttachmentFloodingRelatingAuthentic RelatingUIEditorReact Native

Authoring Flows

Fragment reference Authoring Flows
tags
guideflow

The mental model

A flow is a step-by-step interaction sequence β€” a precise choreography of who does what, in what order, with what outcomes. It answers: β€œWhat actually happens when a user performs this task?”

Flows are the most concrete document type in StarSpec. They compile into interactive Mermaid diagrams that visualize the sequence, branches, and error paths.

When to use flows

Create a flow when:

  • An interaction involves multiple steps with decision points
  • You need to communicate the exact sequence to developers or QA
  • Error handling and branching logic need to be explicit
  • Multiple actors hand off to each other

Do not create a flow for trivial single-step operations. If there is no branching and no meaningful sequence, a feature requirement suffices.

Flows are always standalone files

A flow lives in its own .flow.mdoc file. Never embed flow logic inside a feature or domain document. Features reference flows; they do not contain them.

Anatomy of a flow

Pre/postconditions

State what must be true before the flow begins and what will be true after it completes. Postconditions can be scoped to specific outcomes:

{% postcondition outcome="success" %}Password updated and sessions invalidated.{% /postcondition %}
{% postcondition outcome="expired-token" %}Token expired, user prompted to re-send.{% /postcondition %}

Steps

Each step represents a single discrete action. Steps reference actions or operations by bare name β€” the compiler validates that these exist in a declared API.

{% step action="submit-url" actor="role/user" %}
User pastes a URL and clicks Save.
{% /step %}

Use actor to identify who performs the step. Omit action/operation for purely client-side steps (navigation, viewing).

Branches and paths

A {% branch %} follows a step and models a decision point. Each {% path %} inside it represents one outcome:

  • outcome β€” a unique identifier for this path (e.g., β€œsuccess”, β€œexpired-token”)
  • emit β€” an event broadcast on this path
  • throws β€” an error raised on this path
  • {% join %} β€” an explicit loop-back or skip to a named step

Every path has exactly one exit strategy: it either terminates naturally, throws an error, or joins another step.

Designing good flows

Start with the happy path. Write the straight-line success case first, then add branches for failures and edge cases.

Name steps you need to reference. If a validation failure should loop back to the input step, give that step an id so a {% join %} can target it.

Keep steps atomic. Each step should be one user action or one system response. If you write β€œUser fills in the form and submits it,” that is likely two steps.

Common mistakes

MistakeWhy it hurts
Embedding flows in featuresFlows are standalone documents. Embedding them creates uncompilable content.
Skipping error pathsA flow that only shows the happy path is an incomplete specification. Developers will guess at error handling.
Using flows for CRUDIf there is no branching and one actor, you do not need a flow β€” a feature requirement is sufficient.
Undeclared actionsThe compiler validates that action and operation names exist in an API. Using undeclared names will fail validation.
Missing actorsSteps without actor lose traceability to roles. Always specify who is performing the action.
Overlapping with feature proseA flow describes sequence; a feature describes capability. Do not re-explain requirements in flow steps.

Evolution

Flows change as you discover edge cases. Adding a new branch or error path is non-breaking. Renaming step IDs is breaking if other documents reference them via join. When a flow becomes too complex (more than 10-12 steps), consider splitting into sub-flows linked by events.