# `MobDev.Plugin.Manifest`
[🔗](https://github.com/genericjam/mob_dev/blob/master/lib/mob_dev/plugin/manifest.ex#L1)

Reads, validates, and classifies a plugin's `priv/mob_plugin.exs` manifest.

The manifest is data, not code (see `MOB_PLUGINS.md`): a plain Elixir map
describing what a plugin contributes. This module is the single place that
turns that map into a validated, classified description — tier, hot-push
status, activation — that `mix mob.plugins` reports and the compile-time
merge will later consume.

A tier-0 plugin has no manifest at all; `load/1` returns `{:ok, nil}` for
that case, and `tier(nil)` is `0`.

# `hot_pushable`

```elixir
@spec hot_pushable(map() | nil) :: true | false | :partial
```

Whether the plugin's contributions can be hot-pushed without a native rebuild.

Computed from populated sections, not from tier: `true` for pure-Elixir
plugins, `false` for native-only ones (NIFs / components), and `:partial`
when a plugin mixes native code with hot-pushable Elixir (screens, lifecycle).

# `load`

```elixir
@spec load(Path.t()) :: {:ok, map() | nil} | {:error, String.t()}
```

Loads the manifest for a plugin checked out at `plugin_dir`.

Returns `{:ok, nil}` when there is no `priv/mob_plugin.exs` (a tier-0
plugin), `{:ok, map}` when one is present and evaluates to a map, or
`{:error, reason}` when the file is unreadable or doesn't yield a map.
Does not validate field contents — call `validate/1` for that.

# `tier`

```elixir
@spec tier(map() | nil) :: 0..4
```

Classifies the plugin tier (0–4) from which capability sections are present.

Highest matching section wins. `nil` (no manifest) is tier 0. A manifest
with required fields but no capability sections is the tier-1 floor (the
"minimum viable manifest").

# `validate`

```elixir
@spec validate(map() | nil) :: {:ok, map() | nil} | {:error, [String.t()]}
```

Validates a manifest map against the spec's required top-level fields.

Returns `{:ok, manifest}` or `{:error, reasons}` with a list of every
problem found (validation never stops at the first error). `nil` (no
manifest) is valid — a tier-0 plugin has nothing to validate.

---

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