Verified: Sequential Function Chart
Each claim the Sequential Function Chart page makes, with the tests that
prove it in the last green CI run: 44 of 45 verified.
The claims live in docs/claims/sfc.yaml.
Last green CI run 16 Oct 2026, 14:48 UTC on c7618d3 · all runtime claims
SFC-001 verified
An SFC program is a .sfc file: an ST POU whose body is an SFC ... END_SFC block written with INITIAL_STEP, STEP, TRANSITION and ACTION.
SFC-002 verified
A chart has exactly one INITIAL_STEP, active on the first scan; no initial step, or more than one, is an error.
- pass
TestCheckMissingInitialStepinlang/sfc - pass
TestCheckMultipleInitialStepsinlang/sfc - pass
TestConformance/sfc-sim-div-conv/the initial token waits in Idleinlang/conformance - pass
TestConformance/sfc-sim-div-conv/divergence activates every target in the same scan and clears the sourceinlang/conformance
SFC-003 verified
Each step owns a retained BOOL Step.X and an elapsed time Step.T; both are legal in conditions and action bodies.
- pass
TestConformance/sfc-step-tinlang/conformance(6 of 6 passed) - pass
TestCheckKnownStepXTRefIsCleaninlang/sfc - pass
TestStepTimerGatesTransitioninlang/sfc - pass
TestStepXRetainedAndStepTInBodyinlang/sfc
SFC-004 verified
FROM and TO take one step or a parenthesised list, and the transition name is optional.
SFC-005 verified
An association's IEC form XV201A_Cmd(N); or XV201A_Cmd(D, T#3S); is read as the same association as the keyword form; an omitted qualifier is N.
- pass
TestIECAssociationForminlang/sfc
SFC-006 verified
Each scan runs one fixed-order pass: evaluate each transition against the pre-scan activity snapshot, resolve which fire, clear the sources, set the targets, update step timers, compute actions.
SFC-007 verified
Every transition reads the same snapshot, so a token advances at most one step per scan, though several transitions can fire in one scan when several tokens are live.
- pass
TestConformance/sfc-alt-priority/the token advances one step per scan (X to Idle to X again)inlang/conformance - pass
TestConformance/sfc-sim-div-conv/a single token returns and the whole chart is reusableinlang/conformance
SFC-008 verified
Clears run before sets, so a self-loop FROM S TO S leaves S active.
- pass
TestConformance/sfc-jump-back/a self-loop leaves the step active and does not re-fire its entry pulseinlang/conformance - pass
TestSetDominatesClearinlang/sfc
SFC-009 verified
A transition is enabled when all its FROM steps are active and its condition is true.
- pass
TestEnabledNotCondGuardinlang/sfc - pass
TestConformance/sfc-sim-div-conv/convergence does not fire until every source is activeinlang/conformance - pass
TestConformance/sfc-alt-priority/with no condition true the token waits in Idleinlang/conformance
SFC-010 verified
Alternative divergence: transitions sharing a source step are prioritised by declaration order, first highest.
- pass
TestConformance/sfc-alt-priorityinlang/conformance(8 of 8 passed) - pass
TestAltPriorityMutualExclusioninlang/sfc - pass
TestAltDivergenceAbortinlang/sfc - pass
TestConformance/sfc-jump-back/the jump back outranks the exit declared after itinlang/conformance
SFC-011 verified
A lower branch is suppressed only when a higher one sharing a source actually fires, so a convergence waiting on an inactive source cannot deadlock the branch below; overlapping groups resolve to one outcome per scan.
- pass
TestConformance/sfc-alt-priority/a dead convergence declared first does not starve the branches below itinlang/conformance - pass
TestSuppressedOnlyByFiringTransitioninlang/sfc - pass
TestNonTransitiveGroupConvergenceFiresinlang/sfc
SFC-012 verified
Simultaneous divergence (TO (Heat, Mix)) sets both targets in one scan and splits the token; simultaneous convergence (FROM (Heat, Mix)) is enabled only when both sources are active.
- pass
TestConformance/sfc-sim-div-convinlang/conformance(7 of 7 passed)
SFC-013 verified
Every IEC action qualifier compiles: N, S, R, P1, P, P0 and the timed L, D, SD, DS, SL.
- pass
TestTimedQualifiersParseAndCheckCleaninlang/sfc - pass
TestConformance/sfc-qualifiersinlang/conformance(8 of 8 passed) - pass
TestConformance/sfc-timed-qualifiersinlang/conformance(13 of 13 passed)
SFC-014 verified
N is active exactly while the step is.
- pass
TestConformance/sfc-qualifiers/N is high exactly while the step is activeinlang/conformance - pass
TestNDrivesOnlyWhileActiveinlang/sfc
SFC-015 verified
S sets the target and R clears it, each once, on the scan their step activates.
- pass
TestConformance/sfc-qualifiers/S sets once and the chart never clears itinlang/conformance - pass
TestConformance/sfc-qualifiers/R clears once on activationinlang/conformance - pass
TestSetActsOnceThenActionMayClearinlang/sfc - pass
TestResetActsOnceThenActionMaySetinlang/sfc
SFC-016 verified
P1 and P fire once on the rising edge of step activity; P0 fires once on the falling edge.
- pass
TestConformance/sfc-qualifiers/P1 and P are one scan wide on the rising edge, and fire once per entryinlang/conformance - pass
TestConformance/sfc-qualifiers/P0 fires on the falling edge only, once, after the step has been leftinlang/conformance - pass
TestConformance/sfc-qualifiers/every re-entry re-fires P1 and P (P0 counts only its own exits)inlang/conformance - pass
TestP1FiresOncePerActivationinlang/sfc
SFC-017 verified
Timed qualifiers take a duration (a TIME literal or a TIME variable); each association gets its own timer, started when its step activates.
- pass
TestConformance/sfc-timed-qualifiersinlang/conformance(13 of 13 passed) - pass
TestTimedLoweringStableSlotsinlang/sfc - pass
TestTimedQualifierTimeVariableDurationinlang/sfc
SFC-018 verified
L is active from activation for the duration (ending early if the step is left first); D is active once the step has been active for the duration and ends when the step is left.
- pass
TestConformance/sfc-timed-qualifiers/the activation scan — L and SL on, the delayed ones not yetinlang/conformance - pass
TestConformance/sfc-timed-qualifiers/the scan before PT — nothing has changedinlang/conformance - pass
TestConformance/sfc-timed-qualifiers/the scan at PT — L and SL drop, D SD DS rise, the L body runs its final scaninlang/conformance - pass
TestConformance/sfc-timed-qualifiers/leaving before PT — L is cut short, D and DS never come on, SD and SL run on storedinlang/conformance - pass
TestConformance/sfc-timed-qualifiers/after the step leaves — D drops, the stored SD and DS holdinlang/conformance
SFC-019 verified
SD turns on the duration after activation even if the step was left meanwhile; DS turns on once the step has been active for the duration (never, if left sooner); SL runs from activation for the duration, even after the step is left; all three end at an R on the same target.
- pass
TestConformance/sfc-timed-qualifiers/the scan before PT — nothing has changedinlang/conformance - pass
TestConformance/sfc-timed-qualifiers/the scan at PT — L and SL drop, D SD DS rise, the L body runs its final scaninlang/conformance - pass
TestConformance/sfc-timed-qualifiers/leaving before PT — L is cut short, D and DS never come on, SD and SL run on storedinlang/conformance - pass
TestConformance/sfc-timed-qualifiers/R resets the stored qualifiersinlang/conformance - pass
TestConformance/sfc-timed-qualifiers/R before PT cuts SL short and stops SD from ever coming oninlang/conformance
SFC-020 verified
An R acts once, on its step's activation scan, and clears the SD, DS and SL latches on its target as well as an S; an SL that has run its time stays latched and does not run again on re-activation until an R clears it.
- pass
TestConformance/sfc-timed-qualifiers/re-entry restarts L and D; a timed-out SL stays off until an Rinlang/conformance - pass
TestConformance/sfc-timed-qualifiers/after an R, SL arms again on the next activationinlang/conformance - pass
TestConformance/sfc-timed-qualifiers/R resets the stored qualifiersinlang/conformance - pass
TestResetActsOnceThenActionMaySetinlang/sfc - pass
TestConformance/sfc-timed-qualifiers/R acts once on its step's activation, not on every scan the step is activeinlang/conformance
SFC-021 verified
N, pulse and timed associations targeting the same BOOL are OR-combined: the variable is held TRUE while any is active and written FALSE once, on the scan the last one drops.
SFC-022 verified
An association writes its variable only on the scans it acts; an inactive step never touches it, and between those scans the variable belongs to whoever else writes it.
- pass
TestNFreeWhenInactiveinlang/sfc - pass
TestResetOnInactiveStepDoesNotClobberActionWriteinlang/sfc - pass
TestSFCResetOnInactiveStepKeepsActionWriteinacceptance
SFC-023 verified
When an ACTION body assigns the same variable, the association wins while it acts (it is applied after the bodies in the scan); the ACTION owns it the rest of the time, so an R X on an abort step and an ACTION that sets X on a normal step coexist.
- pass
TestSetActsOnceThenActionMayClearinlang/sfc - pass
TestResetActsOnceThenActionMaySetinlang/sfc - pass
TestNDrivesOnlyWhileActiveinlang/sfc - pass
TestSFCResetOnInactiveStepKeepsActionWriteinacceptance - pass
TestAssociationBeatsActionWriteinlang/sfc(5 of 5 passed)
SFC-024 verified
naut check warns on every association/ACTION-body pair that assigns the same variable.
SFC-025 verified
An action body driven by a level qualifier (any but the pulses; a timed window is a level) runs one extra scan on the falling edge of its active signal, so a body written against step activity shuts its outputs down (a TON called with Hold.X resets). A P1 body has no final scan.
- pass
TestConformance/sfc-final-scaninlang/conformance(5 of 5 passed) - pass
TestFinalScanResetsTONinlang/sfc - pass
TestConformance/sfc-timed-qualifiers/the scan at PT — L and SL drop, D SD DS rise, the L body runs its final scaninlang/conformance - pass
TestActionBodyFinalScanEveryLevelQualifierinlang/sfc(6 of 6 passed)
SFC-026 verified
Step.T is the step's elapsed time, how long it has been active, and can be read in an ACTION or a condition (Fill.T >= T#3S).
- pass
TestConformance/sfc-step-tinlang/conformance(6 of 6 passed) - pass
TestStepTimerGatesTransitioninlang/sfc
SFC-027 verified
Step.T compiles to a hidden TON only for steps whose .T is read.
- pass
TestUnreadStepTimerHasNoHiddenTONinlang/sfc
SFC-028 verified
A step supervised with (MAXTIME := T#..) sets its Step.ERR flag one scan after Step.T reaches the limit (active longer than MAXTIME); within the limit nothing is flagged.
- pass
TestConformance/sfc-step-maxtime/within the limit nothing is flaggedinlang/conformance - pass
TestConformance/sfc-step-maxtime/the scan the step overruns sets the flag; the abort fires the scan afterinlang/conformance - pass
TestConformance/sfc-step-maxtime/leaving in time never sets the flaginlang/conformance - pass
TestConformance/sfc-step-maxtime/the step's time does not run while it is inactiveinlang/conformance
SFC-029 verified
Step.ERR stays set after the step is left, so an abort step can read the cause, and clears on the step's next activation; nothing else happens automatically.
- pass
TestConformance/sfc-step-maxtime/the flag holds after the step is left, until Fill runs againinlang/conformance - pass
TestStepOverrunDoesNothingElseinlang/sfc
SFC-030 verified
ERROR := Var names a BOOL variable that mirrors Step.ERR every scan, and an alarm definition bound to that tag annunciates the overrun.
- pass
TestConformance/sfc-step-maxtime/the scan the step overruns sets the flag; the abort fires the scan afterinlang/conformance - pass
TestConformance/sfc-step-maxtime/the flag holds after the step is left, until Fill runs againinlang/conformance - pass
TestConformance/sfc-step-maxtime/leaving in time never sets the flaginlang/conformance
SFC-031 verified
MAXTIME takes a TIME literal; a bad step attribute (non-TIME MAXTIME, ERROR not a declared variable, ERROR without MAXTIME) and Step.ERR on a step with no MAXTIME are errors.
- pass
TestCheckStepAttributesinlang/sfc
SFC-032 verified
naut check structural errors: duplicate step, action or transition names; no or more than one INITIAL_STEP; FROM/TO naming a missing step; an empty condition.
- pass
TestCheckDuplicateStepNameinlang/sfc - pass
TestCheckDuplicateActionNameinlang/sfc - pass
TestCheckDuplicateTransitionNameinlang/sfc - pass
TestCheckMissingInitialStepinlang/sfc - pass
TestCheckMultipleInitialStepsinlang/sfc - pass
TestCheckUnknownFromToinlang/sfc - pass
TestCheckEmptyConditioninlang/sfc - pass
TestCheckSFCDiagnostics/duplicate stepincmd/naut - pass
TestCheckSFCDiagnostics/duplicate actionincmd/naut - pass
TestCheckSFCDiagnostics/duplicate transitionincmd/naut - pass
TestCheckSFCDiagnostics/no initial stepincmd/naut - pass
TestCheckSFCDiagnostics/two initial stepsincmd/naut - pass
TestCheckSFCDiagnostics/FROM missing stepincmd/naut - pass
TestCheckSFCDiagnostics/TO missing stepincmd/naut - pass
TestCheckSFCDiagnostics/empty conditionincmd/naut
SFC-033 verified
naut check structural errors: an association naming neither an ACTION nor a declared variable; a .X/.T reference to an unknown step.
- pass
TestCheckUnresolvedActionAssociationinlang/sfc - pass
TestCheckActionAssociationResolvesToVariableinlang/sfc - pass
TestCheckUnknownStepXTRefinlang/sfc - pass
TestCheckUnknownStepTRefinlang/sfc - pass
TestCheckSFCDiagnostics/association to nothingincmd/naut - pass
TestCheckSFCDiagnostics/unknown step X refincmd/naut - pass
TestCheckSFCDiagnostics/unknown step T refincmd/naut
SFC-034 verified
naut check structural errors: an unknown qualifier (the message lists every supported one and the Step.T recipe); a timed qualifier with no duration, or an untimed one given one.
- pass
TestCheckUnsupportedQualifierinlang/sfc - pass
TestCheckQualifierDiagnosticsinlang/sfc - pass
TestCheckTimeArgumentOnUntimedQualifierIsAnErrorinlang/sfc - pass
TestCheckSFCDiagnostics/unknown qualifierincmd/naut - pass
TestCheckSFCDiagnostics/timed qualifier without durationincmd/naut - pass
TestCheckSFCDiagnostics/untimed qualifier with durationincmd/naut
SFC-035 verified
naut check warns on an unreachable non-initial step and on a dead-end step (a terminal step may be one on purpose).
SFC-036 verified
naut check warns on a simultaneous convergence whose sources are not reachable from a common simultaneous divergence, and not otherwise.
SFC-037 verified
The chart transpiles to ST and compiles like any program; the line map puts a type error in a condition on its TRANSITION line and one in an action body on the offending statement's own line inside the ACTION block.
SFC-038 verified
Step activity, stored flags, pulse edge memories, step timers, timed-qualifier timers and latches, and overrun flags are retained, so an online edit preserves the live token and every timer.
- pass
TestWarmMigrationinlang/sfc(4 of 4 passed)
SFC-039 verified
Renaming a step resets its token (the renamed step's slot is a new name), listed in the swap report.
- pass
TestWarmMigration/renamed-step-resetsinlang/sfc
SFC-040 verified
naut test runs the same *_test.yaml acceptance tests on an SFC program in virtual time.
- pass
TestConformance/sfc-step-tinlang/conformance(6 of 6 passed) - pass
lead pump starts at LeadOn and post-runs after LeadOffinexamples/lift-station
SFC-041 verified
Macro steps and charts nested inside a step are not supported; charts are flat.
SFC-042 verified
Explicit numeric transition priorities are not supported; priority is declaration order.
- pass
TestConformance/sfc-alt-priority/with every condition true the first declared branch wins aloneinlang/conformance - pass
TestCheckSFCNotSupported/numeric priority after TOincmd/naut - pass
TestCheckSFCNotSupported/numeric priority attributeincmd/naut
SFC-043 verified
Instruction List action bodies are not supported; action bodies are ST.
- pass
TestCheckRejects/SFC IL actionincmd/naut
SFC-044 verified
Indicator variables in an association (Valve(N, Ind);) and on transitions are rejected, and naut check names the forms it does take.
SFC-045 partly verified
Import of vendor SFC (Rockwell .L5X routines, Siemens GRAPH, CODESYS) is not supported.
- pass
TestVendorSFCRoutineIsRefusedinlang/l5x