Skip to content
Folio

Diagrams

LifecycleFigure

A state machine: what something can be, and what moves it between states.

Usage

When to reach for it

The one figure that spends colour, and it spends exactly the two tokens the system reserves for state. Every other distinction is shape, so a greyscale print keeps six of the eight.

Ships from@misoto22/design/diagrams

TSX
import { LifecycleFigure } from '@misoto22/design/diagrams'

Notes

A state machine: what something can BE, and what moves it.

The one figure here that spends colour, and it spends exactly the two tokens this system reserves for state: --success on a terminal success, --danger on a terminal failure. Nothing else in the package is allowed those two, and a lifecycle diagram is the case they were reserved for — the whole point of the picture is which end a run came out of.

The other six kinds are carried by shape, so a greyscale print loses the two outcomes' hue and keeps every other distinction: a start is a filled cap, a decision is a diamond, a wait is a dashed frame, an external is a plate with a cut corner.

A RECOVERABLE FAILURE IS A FAILURE WITH A WAY BACK. type: "failure" says how a state is drawn; a transition OUT of it is what says whether the run is over. A retryable error and a terminal one look identical until you follow the arrows, which is correct — the difference between them is a real edge in the machine, not an adjective on a box.

Anatomy

LifecycleFigure anatomy
ElementDescription
Figure shellrequiredThe frame around the picture. What a machine hands it is a transition list with each note folded in after an em dash, so the condition on an arrow — the timeout, the retry count — is in the text copy and not only on the line.
State platerequiredOne shape per kind: a filled cap for a start, a diamond for a decision, a dashed frame for a wait, a cut corner for an external, and the two washes the system reserves for the terminals. The name is centred, step sits in the leading corner and tag along the bottom edge.
Main railThe first lane’s states, sorted by col and joined consecutively at the emphasis weight — one line per neighbouring pair the transitions do not already declare, so a spine written out in full is drawn from the transitions and a spine left implied is drawn anyway. Without it the top row reads as five unconnected boxes, because the spine of a machine is the part nobody writes down.
TransitionA routed line with its label on a mask and its note in a quieter line beneath. A declared transition between two rail neighbours replaces the implicit one rather than doubling it.
LaneA rule with a mono caption above it, drawn only as far as that lane’s own states reach. A lane past the first has its columns shifted along the main rail, which is what keeps a drop out of the spine vertical rather than a dogleg.

Best practices

Do

  • Keep the first lane for the ordered spine and nothing else. Consecutive states there are joined by the implicit rail even when no transition declares the pair, so a state parked in lane 0 for spacing invents an edge the machine does not have. A state whose lane id nothing declares is kept out of that rail and reported as DIAGRAM_LANE_UNKNOWN instead, because a typo should not be able to add an arrow.
  • Count a secondary lane’s columns from the rail. Every col in a lane past the first is shifted two columns along, so col: 0 in the second lane sits under col: 2 in the first — the convention archify’s lifecycle contract already implies, restated here because it is what makes a drop land on the state it came from.
  • Say whether a failure is recoverable with an edge, not with the type. type: "failure" only paints the plate; a retryable error and a terminal one are identical until a reader follows the arrows out, and the one with none is where the run ended.

Don’t

  • yOffset moves the plate and moves nothing out of its way. The lane’s rule is drawn from what that lane holds, so a negative nudge drags the rule up with the state and a large positive one drops the plate into the band below — a state needing that much room wants a column of its own rather than a push.
  • The figure claims a state can be left only the ways its arrows say. A cancel that can happen from anywhere and is drawn from nowhere reads as impossible, which is a reading the picture makes and the specification never wrote — draw it, or say in the subtitle that it is not drawn.

Examples

default

The rail across the top is not in the spec. A lifecycle diagram gives its first lane to the ordered phases, and the arrows between consecutive columns there are drawn for you at the emphasis weight, so an author declares only the edges that leave the spine — here, the three that pass through Blocked. This is also the one figure allowed colour, and it spends exactly two tokens: one on the completed state, one on the failed one. Every other kind is carried by shape, so a greyscale print loses the two outcomes and keeps every other distinction.

A job run

The only figure that spends colour, on the two outcomes.
A job run6 elements and 6 relationships. The only figure that spends colour, on the two outcomes.01Queuedaccepted02Runningtool calls03Reviewquality gate04Completedfinal answerBlockedmissing inputFailedtimed out

6 elements and 6 relationships. The only figure that spends colour, on the two outcomes.

  • Lane: Phases
    • Queued (start) — accepted — step 01
    • Running (active) — tool calls — step 02
    • Review (decision) — quality gate — step 03
    • Completed (success) — final answer — step 04
  • Lane: Interruptions
    • Blocked (waiting) — missing input
  • Lane: Terminal
    • Failed (failure) — timed out
  • QueuedRunning
  • RunningReview
  • ReviewCompleted
  • ReviewBlocked: needs input
  • BlockedFailed: expired — after 24h
  • BlockedRunning: answered
Key
  • Entry
  • Working
  • Decision
  • Succeeded
  • Waiting
  • Failed

a decision with both ends

A decision with both of its ends drawn. Approved sits on the rail, so its arrow is implied; Declined sits in a second lane, which is the only way to fan out of a decision here — a fourth state added to the first lane would be joined to its neighbour by the implied rail whether that transition exists or not. The two terminal states are the only marks in the package allowed colour, and this is the figure the tokens were reserved for: the question a reader brings to a state machine is which end a run came out of.

Card authorisation

One decision, and the two ends a run can come out of.
Card authorisation4 elements and 3 relationships. One decision, and the two ends a run can come out of.01Submittedcard token02Risk scoremodel and rules03Approvedfunds heldDeclinedno retry

4 elements and 3 relationships. One decision, and the two ends a run can come out of.

  • Lane: Authorisation
    • Submitted (start) — card token — step 01
    • Risk score (decision) — model and rules — step 02
    • Approved (success) — funds held — step 03
  • Lane: Refusals
    • Declined (failure) — no retry
  • SubmittedRisk score
  • Risk scoreApproved
  • Risk scoreDeclined: score above 90
Key
  • Entry
  • Decision
  • Succeeded
  • Failed
Two ends
  • A run leaves through Approved or through Declined and nowhere else.
The rail
  • Submitted to Risk score to Approved is drawn without being declared.

a failure with a way back

Two states of type failure, drawn identically, and only one of them ends the run. Nothing on a plate says whether a failure is terminal — the difference is a real edge in the machine, so Timed out has an arrow back to Sending and Rejected has none, and a reader tells them apart by following arrows rather than by reading an adjective. The retry edge carries a note under its wording, which is where a count or a condition goes when folding it into the label would make the label too long to sit in the gap it has.

A delivery attempt

Two failures on the same plate; one of them is not the end.
A delivery attempt5 elements and 5 relationships. Two failures on the same plate; one of them is not the end.01Queuedaccepted02Sendingattempt n03Delivered2xxTimed outno responseRejectedno retry

5 elements and 5 relationships. Two failures on the same plate; one of them is not the end.

  • Lane: Delivery
    • Queued (start) — accepted — step 01
    • Sending (active) — attempt n — step 02
    • Delivered (success) — 2xx — step 03
  • Lane: Faults
    • Timed out (failure) — no response
    • Rejected (failure) — no retry
  • QueuedSending
  • SendingDelivered
  • SendingTimed out: no reply in 10s
  • Timed outSending: retry — up to 5 times
  • SendingRejected: 400 invalid body
Key
  • Entry
  • Working
  • Succeeded
  • Failed
Same plate, different run
  • Timed out and Rejected are drawn identically.
  • Only the arrow leaving Timed out says the run continues.

the implicit rail

Three facts about placement that only bite once. Declaring one of the spine's own pairs is not a duplicate — it replaces the implied edge and takes your label — so the way to name a step is to write that transition, not to hope the rail carries it. A secondary lane's column N sits under the main lane's column N + 2, which is why Withdrawn at column 0 lands beneath Accept rather than beneath In review. And yOffset is accepted on a state and deliberately ignored: the nudge is measured in archify's lane depth, not this one, so honouring it would drop a plate onto the lane below.

An article, from draft to live

The spine is drawn; only the departures are written.
An article, from draft to live6 elements and 6 relationships. The spine is drawn; only the departures are written.01Draftauthor only02In reviewtwo readers03Accept?editor04Publishedon the siteWithdrawnby the authorHeldawaiting legal

6 elements and 6 relationships. The spine is drawn; only the departures are written.

  • Lane: Review
    • Draft (start) — author only — step 01
    • In review (active) — two readers — step 02
    • Accept? (decision) — editor — step 03
    • Published (success) — on the site — step 04
  • Lane: Off the rail
    • Withdrawn (neutral) — by the author
    • Held (waiting) — awaiting legal
  • DraftIn review
  • In reviewAccept?
  • Accept?Published
  • In reviewWithdrawn: author pulled it
  • Accept?Held: legal question — blocks publication
  • HeldAccept?: cleared
Key
  • Entry
  • Working
  • Decision
  • Succeeded
  • Idle
  • Waiting

Accessibility

  • success and failure are the only coloured marks in the package’s diagrams, and each is also a distinct plate shape — colour is never the only carrier.
  • The main rail is drawn between consecutive states in the first lane even when the specification does not list those transitions, because they are the diagram’s spine rather than its exceptions.