# `Diffo.Provider.Extension.Traversal`
[🔗](https://github.com/diffo-dev/diffo/blob/v0.9.0/lib/diffo/provider/extension/traversal.ex#L5)

Compile-time normalisation of a `via:` hop list into a canonical, validated form.

A traversal is an ordered list of hops, each walking one graph edge in one direction.
Direction is mechanical and mechanism-independent — it names which end of the stored
edge *this* instance is on:

- `:forward` — this instance is the edge `source`; filter `source_id = me`, follow to
  `target_id`.
- `:reverse` — this instance is the edge `target`; filter `target_id = me`, follow to
  `source_id`.

Mechanism is `:assignment` (`AssignmentRelationship`) or `:relationship` (both
`DefinedSimpleRelationship` and the general `Relationship` — a `:relationship` hop spans
either storage, #222). The two axes are independent, so any mechanism × direction
combination is a legal hop and chains of any length compose.

## User hop forms

- `alias` *(bare atom)* — shorthand for `{:reverse, assignment: alias}` (inherit from
  your assigner — the common case, and the zero-config default for an omitted `via:`).
- `{:forward | :reverse, assignment: alias}`
- `{:forward | :reverse, relationship: type}` — relationship filtered by `type` only.
- `{:forward | :reverse, relationship: [type: t, alias: a]}` — by `type` and/or `alias`.

## Canonical form

`normalize/2` returns `{:ok, hops}` where each hop is
`{:forward | :reverse, :assignment | :relationship, selector}` — selector
`%{alias: a}` for assignment, `%{type: t, alias: a}` for relationship (either of `t`/`a`
may be `nil`, but not both). On a malformed hop it returns `{:error, reason}` for the
verifier to surface as a `DslError`.

Used at compile time by `TransformInheritedRefs` (to inject the calc) and
`VerifyCharacteristics` (to validate). The runtime counterpart is
`Diffo.Provider.Calculations.Traversal`.

# `normalize`

Normalises a user `via:` value (or `nil`) into a canonical hop list.

When `via` is `nil`, defaults to a single reverse-assignment hop keyed by `name`
(i.e. `via: [name]`). Returns `{:ok, hops}` or `{:error, reason}`.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
