← All craftbooks

Model a Flow as a State Machine

Build: software and codeevalv1.0.0released 2026-06-05workflow: build-loop

Model a stateful flow (checkout, order lifecycle, connection, wizard) as an explicit finite state machine with named states, guarded transitions, and rejected illegal moves — making impossible states impossible. Models the machine FIRST — the full state set, the events, the legal transition table, guards, and entry/exit effects — then implements a transition function that rejects illegal events, then tests every legal path and that illegal transitions are refused. Covers states/events/transitions, transition tables, guards, side-effects on entry, illegal-transition rejection, and exhaustive path testing.

Steps

Entry step: model. Each step names the specialist role it wants; the full working prompt is expandable.

  1. Model the machineplannerentry

    lock states, events, transition table, guards

    Show working prompt
    Model the state machine before coding — making illegal states unrepresentable is the whole value. Step 1: Enumerate the complete, finite set of STATES (including initial and terminal states). Step 2: Enumerate the EVENTS/inputs that can occur. Step 3: Write the full TRANSITION TABLE: for each (state, event) pair, the next state — and explicitly mark the pairs that are ILLEGAL (no transition). Step 4: Note any guards (conditions that must hold for a transition) and entry/exit side-effects per state. Step 5: Write a numbered acceptance-criteria checklist of 5-9 items (e.g. 'the machine starts in the initial state', 'every legal transition produces the table's next state', 'an illegal (state,event) pair is rejected, not silently ignored', 'terminal states accept no further transitions'). `write_task_note` the state diagram/table + checklist and write the same to the produces path.
  2. Build the machinedeveloper

    implement a guarded transition function

    Show working prompt
    Implement the state machine to the model. Step 1: Represent states and events as a closed set (enum/union) so only modeled values are usable. Step 2: Encode the transition table directly and write a `transition(state, event)` function that returns the next state for legal pairs. Step 3: For illegal (state, event) pairs, REJECT explicitly (throw a typed error or return an explicit rejection) — never silently stay or fall through. Step 4: Evaluate guards before transitioning and run entry/exit effects on the relevant transitions. Step 5: Make the current state observable and start in the initial state. Write the machine to the produces path. On a loop-back, fix only the named gaps. `write_task_note` the file path and which criteria now pass.
  3. Test every pathdeveloper

    test legal paths and illegal-transition rejection

    Show working prompt
    Write tests covering the transition table exhaustively. Step 1: Assert the machine starts in the initial state. Step 2: For every LEGAL (state, event) pair in the table, drive the machine to that state and assert the event produces the table's next state. Step 3: For representative ILLEGAL pairs, assert the machine rejects the event (throws/returns rejection) and does NOT change state. Step 4: Assert terminal states reject all further events, and that guarded transitions are blocked when the guard fails. `write_task_note` the test file path and pass/fail count.
  4. Evaluatereviewer

    Grade the deliverable against every acceptance criterion. All pass → finish; any fail → loop back and fix the gap.

    Show working prompt
    Run the tests and exercise the machine. For EACH acceptance criterion: confirm it starts in the initial state, confirm every legal transition matches the table, confirm illegal (state,event) pairs are explicitly rejected without changing state, and confirm terminal states and guards behave. Write PASS/FAIL per criterion; an illegal transition that is silently ignored is a FAIL.
    
    Then route — this is the whole point of the loop:
    
    - **Every criterion PASSES →** call `advance_task_step({ ref, stepId: "evaluate", next: "finish" })`.
    - **Any criterion FAILS →** write the specific gaps to notes, then call `advance_task_step({ ref, stepId: "evaluate", next: "build" })` to loop back. The builder fixes exactly those gaps.
    
    Never route to `finish` while any criterion is unmet. The build phase's completion gate already blocked a grossly-incomplete deliverable; your job is the judgment an automated check cannot make (does it actually work, read well, look right). After ~3 unproductive loops, stop and report DONE_WITH_CONCERNS so the user can step in.
  5. Finishdeveloper

    All acceptance criteria met. Stamp a short summary and report DONE.

    Show working prompt
    Every acceptance criterion passed. Write a one-paragraph DONE summary to task notes via `write_task_note`: what was built, the deliverable path(s), and a one-line confirmation that each criterion is met. Then report DONE.

Triggers

Phrases that suggest this craftbook to a crew.

Source

View this craftbook on GitHub · MIT license