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

Reads + writes the `config :mob, :trusted_plugins, %{...}` entry in `mob.exs`.

Trust is per-host: each host project records which plugin fingerprints
it trusts in its own `mob.exs`. There is no central registry; the
initial trust is established once via `mix mob.plugin.trust <name>`.

The on-disk shape is:

    config :mob, :trusted_plugins, %{
      mob_foo: "ed25519:abc...=",
      mob_bar: "ed25519:def...="
    }

Mutations (`add_trust/2`, `remove_trust/1`) work line-by-line over
the existing `mob.exs` so unrelated config and user comments are
preserved. `mob.exs` is the source of truth — `load_trusted_plugins/0`
reads it via `Config.Reader.read!` exactly like the activation
reader in `MobDev.Plugin.activated_names/0`.

# `trust_map`

```elixir
@type trust_map() :: %{required(atom()) =&gt; String.t()}
```

Map of plugin name to `"ed25519:<base64>"` fingerprint.

# `add_trust`

```elixir
@spec add_trust(atom(), MobDev.Plugin.Crypto.pub_key()) :: :ok | {:error, term()}
```

Writes `name => Crypto.fingerprint(pub_bin)` into `mob.exs`.

Preserves unrelated config and user comments by editing the file
line-by-line rather than regenerating it. Idempotent: writing the
same fingerprint a second time is a no-op. Replaces an existing
entry on key rotation. Adds the `config :mob, :trusted_plugins, …`
line at the end of the file when no entry exists yet.

# `add_trust`

```elixir
@spec add_trust(atom(), MobDev.Plugin.Crypto.pub_key(), Path.t()) ::
  :ok | {:error, term()}
```

Variant of `add_trust/2` that targets `project_dir`.

# `load_trusted_plugins`

```elixir
@spec load_trusted_plugins() :: trust_map()
```

Reads `config :mob, :trusted_plugins` from `mob.exs` in the cwd.

Returns an empty map when the key is unset or the file is missing.
Pure: this function uses `Config.Reader.read!`, the same approach
used to read `config :mob, :plugins` (the activation list).

# `load_trusted_plugins`

```elixir
@spec load_trusted_plugins(Path.t()) :: trust_map()
```

Variant of `load_trusted_plugins/0` that reads from `project_dir`.

# `remove_trust`

```elixir
@spec remove_trust(atom()) :: :ok
```

Removes the trust entry for `name` from `mob.exs`.

# `remove_trust`

```elixir
@spec remove_trust(atom(), Path.t()) :: :ok
```

Variant of `remove_trust/1` that targets `project_dir`.

# `trusted?`

```elixir
@spec trusted?(atom(), MobDev.Plugin.Crypto.pub_key()) :: boolean()
```

Returns `true` if the stored fingerprint for `name` matches `pub_bin`.

A plugin with no trust entry is not trusted. A plugin with a stored
fingerprint different from `Crypto.fingerprint(pub_bin)` is not
trusted (key rotation event — caller is expected to surface this
separately).

# `trusted?`

```elixir
@spec trusted?(atom(), MobDev.Plugin.Crypto.pub_key(), trust_map()) :: boolean()
```

Variant of `trusted?/2` that takes the trust map as input (pure).

---

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