# `Selecto.Domain`

Compatibility-safe normalization entry point for Selecto domains.

This module does not participate in `Selecto.configure/3` yet. It provides a
read-only normalization boundary for callers that want a stable, diagnostic
view of authored domain maps while existing runtime behavior remains
unchanged.

# `compose`

```elixir
@spec compose(term(), term()) ::
  {:ok, map(), Selecto.Domain.Diagnostics.t()}
  | {:error, Selecto.Domain.Diagnostics.t()}
```

Composes an authored domain with one or more domain overlays.

This is the Stage 2 composition boundary. It is opt-in and does not participate
in `Selecto.configure/3` yet. Composition uses explicit, deterministic merge
semantics:

- maps deep-merge by section
- `redact_fields`, including `source.redact_fields`, are unioned
- `extensions` are appended uniquely
- other lists and scalar values are replaced by later overlays

After overlays are merged, declared extension `merge_domain/2` callbacks are
applied in declaration order and the result is normalized again.

# `describe`

```elixir
@spec describe(term()) ::
  {:ok, map(), Selecto.Domain.Diagnostics.t()}
  | {:error, Selecto.Domain.Diagnostics.t()}
```

Returns structured inspection output for an authored or normalized domain.

The inspection map is intentionally compact and deterministic so generators,
Studio, docs, and tests can reason about the normalized contract without
walking the whole domain map directly.

# `domain_fingerprint`

# `domain_fingerprint?`

# `domain_version`

# `domain_version?`

# `invalid_schema_version_warning`

# `invalid_section_shape_warning`

# `maybe_put_domain_fingerprint`

# `maybe_put_domain_version`

# `name?`

# `normalize`

```elixir
@spec normalize(term()) ::
  {:ok, map(), Selecto.Domain.Diagnostics.t()}
  | {:error, Selecto.Domain.Diagnostics.t()}
```

Normalizes an authored domain map into a compatibility-safe contract.

The normalizer currently:

- infers `schema_version` as `1` when it is missing
- preserves optional `domain_version` metadata as an opaque authored-domain
  version label
- preserves optional `domain_fingerprint` metadata as an opaque authored-domain
  content identity label
- expands supported field-level choice-source shorthand into canonical
  `source_relationships`, `choice_sources`, and field reference bindings
- classifies authored top-level sections as canonical, projection, proposed,
  or unknown
- exposes current query, write, action, capability, relationship, and choice
  registries without rewriting existing runtime behavior

Returns `{:ok, normalized, diagnostics}` for maps and `{:error, diagnostics}`
for non-map inputs.

# `normalize_schema_version`

# `normalized_domain`

# `parse_schema_version`

# `project`

```elixir
@spec project(map(), :query | :write | :ui | :api | :query_contract) :: map()
```

Projects a normalized domain into a read-only consumer view.

Projection helpers are intentionally conservative in this slice. They reshape
the normalized map for future consumers, but no existing runtime path calls
them yet.

Supported projections:

- `:query` - query/runtime-facing sections
- `:write` - write/action/reference sections
- `:ui` - display defaults, choices, actions, and detail actions
- `:api` - read/write/action contract for API-style consumers
- `:query_contract` - constrained query metadata for tools, Components, and AI

# `query_contract`

```elixir
@spec query_contract(term()) ::
  {:ok, map(), Selecto.Domain.Diagnostics.t()}
  | {:error, Selecto.Domain.Diagnostics.t()}
```

Returns the constrained query contract projection for an authored or normalized
domain.

This is a convenience wrapper around `normalize/1` and
`project(normalized, :query_contract)` for Components, AI tooling, and other
consumers that should not need to walk the normalized domain map directly.

# `schema_version`

# `section_shape_warnings`

# `shape_warnings`

# `unsupported_schema_version_warning`

# `validate`

```elixir
@spec validate(term()) ::
  {:ok, map(), Selecto.Domain.Diagnostics.t()}
  | {:error, Selecto.Domain.Diagnostics.t()}
```

Normalizes an authored domain and validates it against the first-wave
canonical contract.

This is still a compatibility-safe entry point: it does not participate in
`Selecto.configure/3` unless a caller opts in elsewhere.

---

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