Completion is an ordinary semantic consequence of state geometry or mounted work, but it is not an ordinary external event. Completion is generated by the system, selected through checked listeners, and committed in the macrostep that produces it. Final geometry, an accepted mounted-work settlement, or the arming of an empty closed family may produce completion. Root completion then crosses a separate boundary into terminal lifecycle.
Complete states through final geometry
Entering a non-root final state completes its compound parent. The interpreter raises that parent's state-completion event onto the macrostep's internal queue. If the completed parent is one region of a parallel grandparent, and every region has reached final geometry, the parallel grandparent also completes.
Completion therefore follows topology:
- a compound state completes when its active direct child is final; and
- a parallel state completes when every direct region has completed.
An atomic state does not complete merely because it has no outgoing transition. Being unable to move and being complete are different claims.
State-completion events are raised by the interpreter and carry typed payloads.
A compound state's completion payload is the union of its direct final
instances. A parallel state's completion payload is a record keyed by region
tag. If a parallel region has no reachable final, that parallel completion is
never. Authors name these events through the state that can complete rather
than by hand-writing a reserved event string. The listener still participates
in ordinary selection, guarding, conflict resolution, exit, and entry.
Because completion is queued internally, eventless transitions enabled by the final entry run before the completion event is dequeued. The completion event remains inside the macrostep and may itself cause further transitions before the chart stabilizes.
Send Finish to reach the final child and watch the completion listener move the
chart to CompletionObserved in the same live result.
Starting the completion chart…
Consume root completion at the chart boundary
The configured root is itself the chart, so root completion has no parent state
inside that chart. The chart boundary consumes the completion directly. It
does not enqueue a done.state event for the empty root path.
A compound root completes when its active direct child is final. A parallel root completes when every direct region completes. A raw atomic root does not complete on its own.
After root completion, the snapshot status becomes Done and the interpreter
runs terminal exit. The final configuration remains in the terminal snapshot
as a record, but its states are no longer live. No later internal work or
external event can treat that retained configuration as active.
Give every singular completion a disposition
A mounted singular activity has checked completion channels. Success is always possible. A declared typed error adds a failure channel. Retry adds an exhaustion channel for the singular mount. Every channel that the mount can produce must have an ancestor-or-self listener that is provably active while the mount is active.
The law is total disposition, not mandatory state movement. A listener may transition, perform actions without changing configuration, or explicitly ignore the completion. What is forbidden is an armed completion channel with no authored decision.
The check also runs in the other direction. A completion listener must correspond to matching mounted work that can actually produce that channel. This prevents both silent completion and dead listeners.
Timers and singular child sites follow the same structural principle: a mounted source must have a co-active completion listener. Their exact channel sets remain owned by their declarations rather than by strings in the event alphabet.
Commit completion with its producing decision
Completion-commit atomicity states that completion and the chart response to it belong to one macrostep, whether completion follows final geometry, an accepted settlement, or vacuous closed-family arming.
For state completion, entry into final geometry, generation of the completion event, any transition selected for that event, and the eventual stabilized snapshot commit together. There is no observable committed snapshot in which the parent is complete but its selected completion behavior has not run.
For mounted work, admission first proves that the settlement belongs to the current slot and arming. Releasing that slot, generating its completion event, selecting the authored disposition, and updating resulting geometry commit as one decision. A stale settlement from an exited site or superseded arming is refused before it can claim completion.
A closed family captures its membership once per arming and reports aggregate
Done after every captured member succeeds. Empty membership completes
vacuously in the arming fold, without a settlement. Membership models beyond
closed capture are outside the scope of this page.
Atomicity does not imply that post-commit effects have finished. It means the settlement and the chart's semantic response cannot be split across committed snapshots.
Distinguish chart lifecycle statuses
The snapshot lifecycle has four statuses:
| Status | Authority | Retained configuration | Later external events |
| ----------- | -------------------------------------------------------- | ----------------------------------------------------------------------- | ------------------------------ |
| Running | The instance may admit more macrosteps. | Current active paths. | Selected or refused normally. |
| Done | The compound or parallel root completed. | Final configuration after terminal exit updates. | Fail with StatechartDone. |
| Stopped | External instance authority admitted a chart-level stop. | Configuration at termination after exit updates; born-stopped is empty. | Fail with StatechartStopped. |
| Cancelled | Parent geometry ended a child arming. | Configuration at cancellation after exit updates. | Fail with StatechartStopped. |
There is no error terminal chart status. At the kernel tier, a rejected
activity does not become chart death merely because its failure event has no
selected transition: the slot is released, the event is consumed, and the
chart remains Running. The checked authoring surface prevents that omission
by requiring the activity's possible completion channels to have dispositions.
Authors who require a failure state must model one through an explicit
completion disposition.
Run terminal exit exactly once
Done, stop, and cancellation all leave entered states through terminal exit. The interpreter records history, runs exit actions in exit order, applies exit updates, plans exit emits, cancels timers and children, stops activities, and drops raises produced during terminal exit. Nothing enters afterward.
The terminal snapshot retains the configuration and post-exit facet values as historical record. Done exit actions have no current event; the terminal trace marker is not an event value. Stop exit actions observe the reserved stop stimulus. Cancellation remains geometric child authority and has no public kill operation.
Stopping an already terminal instance is idempotent and does not advance its sequence. Stopping before start creates a born-stopped snapshot without running root entry or mounting work. These cases preserve the invariant that each state that actually entered exits exactly once before terminal.
Keep operational failure outside chart status
Durable engines may also describe an instance as faulted or parked. Those are operational conditions, not additional snapshot lifecycle literals.
A faulted instance has a trustworthy current snapshot but machine-scheduled future work has been dammed after bounded redelivery. External sends and reads may still operate against the valid snapshot. A parked instance has an untrustworthy stored past, so author-facing reads and mails are rejected until an operator resolves that condition.
Neither condition generates a chart event or selects an authored transition. Chart lifecycle states what the chart has semantically reached. Operational status states whether the engine can safely trust the past and process the future.