Interprets a normalized keyword route against one concrete argument, without walking it.
A literal keyword list becomes ordered pairs of {node, treatment} entries plus a
shape-preserving rebuilder. A non-keyword argument gets its whole-argument fallback:
the leading treatment for a keyed refinement, or :raw for positional keyword routing.
Positional routing requires exactly one treatment per pair, and never pads or truncates:
decode!/2 raises on a mismatch, and is what Resolve applies to the written call the
route was stamped on; decode/2 reads a mismatch as the :raw fallback, since the only
argument that can present one is a mutator's rebuild whose pairs a static positional
route no longer fits (a rebuilt call is routed again before it is read,
Mutare.Transform.Resolve.reroute/1; a classifier answers for the rebuilt pairs, a static
list keeps its count) — a stamp that does not fit says nothing about the argument.
Keyed refinements choose each value's final treatment before any descent. Unnamed values
and data keys inherit the leading treatment, except that :interior becomes :expression
below the container. Block keys are always raw. Positional keyword routes leave all keys
raw and assign treatments to values by order, including duplicate keys.
Resolve, body analysis, guard tagging, self-call rewriting and binding analysis share this interpretation, not a traversal. Each pass still decides what a treatment means for its task; the container's own offer and nested syntax scopes also remain with that pass. In particular, withholding mutation does not establish whether an expression executes.
Summary
Types
Functions
decode/2, raising where a positional keyword route names a treatment count other than
the argument's pair count — the route and the written call disagree about the argument's
shape, which is the route's error to fix, loud and at transform time.