ADR-0006's two lint findings for a fixture bundle: an expression whose
source text matches no compiled guard, and an expect key naming no
dataset. Both are warnings, never errors - this module has no
{:error, _} return path anywhere in its public API.
Guard matching is byte equality on source text only. A t_index never
appears as a matching key, only as an output pointer for a consumer that
wants to annotate a transition: t_index values are document-order
positions that shift under any edit above the transition (a state
inserted earlier in the document, for example), so matching by index
would silently pin the wrong guard the moment the chart changes shape.
Matching by source text survives exactly that kind of edit, which is why
ADR-0006 fixes it as the identity.
An unmatched expression is a warning, not an error, because a free-standing expression with no corresponding guard is a legal state of the contract - ADR-0006 does not require every expression to mirror a guard. The warning exists for the near-miss case: an expression authored against a guard that has since drifted (reformatted, requoted, or otherwise edited), where matching is exact and a near match does not count. That case is exactly the one a bare "no match" message hides, so the finding's message carries the expression's own source text: a drift of one space or one quote style is invisible until the two strings can be read against each other, and the reader has the chart's guards in front of them already.
Reads a compiled %Statifier.Machine{} only for its transitions' guard
source text (Statifier.Machine.Transition.cond, the {:compiled, _, source} shape Statifier.Machine.expr/0 documents). Nothing here calls
Predicator - it reads source strings, it does not evaluate them - and
nothing here modifies the engine (ADR-0002).
Summary
Functions
A warning per expect key naming no dataset in fixtures.
Expression names matched to the t_index of every transition whose guard
source text is byte-equal to the expression's source.
Every lint finding for fixtures, sorted by path for stable,
byte-comparable output (ADR-0005's canonical-order habit).
A warning per expression whose source text is byte-equal to no guard in
machine.
Functions
@spec dangling_expect_keys(StatifierUI.Fixtures.t()) :: [ StatifierUI.Fixtures.diagnostic() ]
A warning per expect key naming no dataset in fixtures.
Needs no machine: this is a fact about the bundle alone, so it is callable on a bundle by itself.
@spec guard_matches(StatifierUI.Fixtures.t(), Statifier.Machine.t()) :: %{ optional(StatifierUI.Fixtures.expression_name()) => [non_neg_integer()] }
Expression names matched to the t_index of every transition whose guard
source text is byte-equal to the expression's source.
A {:static, _} guard and a transition with no cond at all (nil)
carry no author-written expression text, so both are skipped without
error. An expression can match more than one guard; all matching
t_index values are returned, sorted.
The t_index values in the result are an output - a pointer for a
consumer (a truth table, a guard annotation) that wants to point back at
the transition - never an input to the match. See the moduledoc for why
matching by index would be wrong.
@spec lint(StatifierUI.Fixtures.t(), Statifier.Machine.t() | nil) :: [ StatifierUI.Fixtures.diagnostic() ]
Every lint finding for fixtures, sorted by path for stable,
byte-comparable output (ADR-0005's canonical-order habit).
machine of nil runs only the machine-free check
(dangling_expect_keys/1); given a %Statifier.Machine{}, both checks
run.
@spec unmatched_expressions(StatifierUI.Fixtures.t(), Statifier.Machine.t()) :: [ StatifierUI.Fixtures.diagnostic() ]
A warning per expression whose source text is byte-equal to no guard in
machine.
See the moduledoc for why this is a warning: an unmatched expression is a legal, free-standing fixture, and the finding exists to surface the near-miss case where an author expected a match and a text drift (however small) broke it.