# Plugin Contract ## Manifest `manifest.json` is the runtime contract consumed by Tribes: - `name` and `otp_app` must match the Mix application name. - `entry_module` must be a loadable `Tribes.Plugins.*.Plugin` module. - `provides` declares capabilities exported by the plugin. - `requires` declares hard plugin/API contracts beyond the `host_api` foundation. - `enhances_with` declares optional host capabilities. - `migrations` should be `true` when `priv/repo/migrations` contains plugin migrations. - `children` should be `true` when the plugin starts its own supervision tree. Declare `ui@1` in `requires` when rendering through `Tribes.Plugin.Layouts.app`, importing `Tribes.UI.Components`, or using `use Tribes.UI`. The facade is intentionally provider-backed, so host chrome and UI consumers must make the runtime dependency explicit. `host_api` is the versioned foundation contract. It provides the supported Phoenix, Ash, PubSub, data, and cluster-event APIs for plugins. Do not add separate framework capability requirements for APIs that belong to that foundation. Default LiveView pages should wrap their content in `Tribes.Plugin.Layouts.app` and use `on_mount({Tribes.Plugin.LiveUserAuth, :live_user_optional})`. This keeps plugin pages inside the replaceable Tribes chrome while avoiding a hard compile-time dependency on host web macros. ## Entry Modules The template uses a thin host bridge: ```elixir defmodule Tribes.Plugins.MyPlugin.Plugin do defdelegate register(context), to: MyPlugin.Plugin end ``` Keep plugin implementation code in `MyPlugin.Plugin`. Keep the bridge stable so the host plugin manager can load it from the plugin build output. ## Host Dependencies `tribes_plugin_api` is the release-facing `host_api` foundation. It carries the supported plugin behaviours, helpers, Phoenix/Ash data surface, and sync DSL. Do not add the full `:tribes` app as a production dependency. The template intentionally splits the `:tribes` path dependency by environment: - In `:dev`, `:tribes` is compile-only. This lets `mix compile` create the entry-module beam expected by the host plugin manager without starting a nested Tribes application. - In `:test`, `:tribes` is runtime-enabled. Host-backed tests need the real repository, endpoint pipeline, and plugin contract helpers. ## Ash Resources For cluster-synced plugin data, add Ash resources under the plugin namespace and use `extensions: [AshNostrSync]` only for data that should replicate across the cluster. Prefer one UUID primary key per synced resource. Document any local-only tables, retention policies, or side effects in plugin docs.