# `StatifierUI.DatamodelExplorer.Scope`
[🔗](https://github.com/riddler/statifier-ui/blob/v0.11.0/lib/statifier_ui/datamodel_explorer/scope.ex#L1)

The three ADR-0003 tiers that do not switch source between authoring and
live mode: document `<data id>` declarations (tier 1), the SCXML 5.10.1
system variables (tier 2a), and the predicator provider functions in
scope (tier 2b). All three come from a compiled `%Statifier.Machine{}`
and two engine constants - no session, no fixtures, no wire messages.

## Tier 1 - `<data>` declarations

Enumerated with `machine.data_elements |> Tuple.to_list()`, the idiom
`StatifierUI.Trace.Manifest` already uses for the same field
(`trace/manifest.ex:193-201`), in `d_index` order - never re-sorted by
id (ADR-0011's rule applied to an engine-ordered sequence). A tier-1
entry has no runtime value here: predicator is non-evaluative
(ADR-0004 upstream, adopted by ADR-0002), so `value` is always
`:undefined` and `declared_source` carries the declared expression
*text*, sliced from the `:source` option, only when one was given and
`value_location` differs from `location`
(`docs/wire-format.md:420-432`'s guard: when the two are equal there is
no value span and the slice would be the whole element).

## Tier 2a - system variables

`Statifier.Evaluator.SystemVariables.initial/2` is the single source of
the name list: exactly `_sessionid`, `_name`, `_event`, `_ioprocessors`.
**`_x` is deliberately absent** - the evaluator seeds it nowhere
(`deps/statifier/lib/statifier/evaluator.ex:359-361`) - and `In(stateId)`
is a tier-2b *function*, not a tier-2a datamodel key, even though both
are things a reader of spec 5.10/5.9.1 will look for here. `_event`
additionally gets `children`: one entry per key of
`SystemVariables.event/1`'s schema (spec 5.10.1's six fields plus
`data`), so the key list cannot drift from the engine's own. The
session id comes from the `:session_id` option, defaulting to the
documented placeholder `"(authoring)"` - there is no session in
authoring mode, and the placeholder says so honestly rather than
hiding it.

## Tier 2b - provider functions

Read from `Statifier.Evaluator.Functions.base_context().functions`, the
fully *resolved* `%{name => {arity, {module, atom}}}` map, rather than a
walk over `Predicator.FunctionProvider.builtin_providers/0`. The
resolved context is the only source that reflects predicator's
builtins-then-providers-then-`:functions` shadowing order
(`deps/predicator/lib/predicator/context.ex:216-237`); a provider-module
walk can report a shadowed function as live. ADR-0003's `functions/0`
phrasing is satisfied transitively, since that callback is what the
resolution already consumed. Provider metadata is name and arity only -
no return type, no parameter names - so a function entry's `label` is
`"name/arity"` (or `"name/2|3"` for the multi-arity form) and nothing
richer; ADR-0003:110-116 names richer metadata as upstream `px-`/`st-`
work, not something to synthesize here.

## Diagnostics, not failures

A tier-1 element whose `value_location` offsets fall outside the given
`:source` string yields an entry with `declared_source: nil` plus one
`StatifierUI.Fixtures.diagnostic()` (`kind: :unsliceable_declared_source`)
- one bad span takes down one label, not the pane, following
`StatifierUI.EventInjection.Palette`'s precedent
(`event_injection/palette.ex:97-126`).

# `opt`

```elixir
@type opt() :: {:source, String.t() | nil} | {:session_id, String.t()}
```

# `t`

```elixir
@type t() :: %StatifierUI.DatamodelExplorer.Scope{
  data: [StatifierUI.DatamodelExplorer.Entry.t()],
  diagnostics: [StatifierUI.Fixtures.diagnostic()],
  functions: [StatifierUI.DatamodelExplorer.Entry.t()],
  system: [StatifierUI.DatamodelExplorer.Entry.t()]
}
```

# `build`

```elixir
@spec build(Statifier.Machine.t(), [opt()]) :: {:ok, t()} | {:error, term()}
```

Builds the mode-independent tiers from a compiled `machine`.

`:source` (default `nil`) is the chart's raw SCXML text, used only to
slice tier-1 declared-value spans for display; `:session_id` (default
`"(authoring)"`) seeds tier 2a's `_sessionid` and `_ioprocessors`.
Returns `{:error, {:invalid_machine, other}}` for anything that is not
a `%Statifier.Machine{}`.

---

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