You've already forked tribes-plugin-trust
40310b26ea
CI / Test (push) Failing after 20s
Introduce the Trust plugin as the federation provider for tribe identity and hello handshakes, with synced Ash resources for remote tribes and tribe relationships plus an admin LiveView for trust management.
91 lines
3.5 KiB
Markdown
91 lines
3.5 KiB
Markdown
# Plugin Contract
|
|
|
|
## Manifest
|
|
|
|
`manifest.json` is the runtime contract consumed by Tribes:
|
|
|
|
- `id` is the canonical reverse-DNS plugin identity; `slug` is the local URL/assets namespace.
|
|
- `otp_app` should be vendor-prefixed and must match the Mix application name.
|
|
- `entry_module` must be a loadable module ending in `.Plugin`.
|
|
- `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.
|
|
|
|
`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.
|
|
|
|
Declare `org.tribe-one.caps.ui@1` in `requires` when rendering through `Tribes.Plugin.Layouts.app`,
|
|
importing `Tribes.UI.Components`, or using `use Tribes.UI`.
|
|
|
|
## Entry Modules
|
|
|
|
The plugin entry module is:
|
|
|
|
```elixir
|
|
defmodule TribeOne.TribesPlugin.Trust.Plugin do
|
|
use Tribes.Plugin.Base, otp_app: :tribe_one_trust
|
|
end
|
|
```
|
|
|
|
Keep plugin implementation code under your own namespace. The default
|
|
generator uses `TribeOne.TribesPlugin.*`; third-party plugins should use their own
|
|
organization or project namespace.
|
|
|
|
## 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.
|
|
|
|
Host services are exposed through public facade modules in
|
|
`Tribes.Plugin.Services`. Use `Tribes.Plugin.Services.Alliance` for local
|
|
tribe metadata and tribe users, `Tribes.Plugin.Services.Metrics` for compact
|
|
metric rollups, and `Tribes.Plugin.Services.Logs` for operational plugin
|
|
logging.
|
|
|
|
## Localization
|
|
|
|
Keep plugin-specific copy in this plugin's own Gettext backend and
|
|
`priv/gettext` catalogs. For shared Tribes UI labels that are documented as
|
|
public plugin API, import `Tribes.Plugin.Gettext` and call `tgettext/2`:
|
|
|
|
```elixir
|
|
import Tribes.Plugin.Gettext
|
|
|
|
tgettext("Cancel")
|
|
tgettext("Save")
|
|
```
|
|
|
|
Do not call arbitrary internal Tribes Gettext domains from plugin code.
|
|
|
|
The generated plugin 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.
|
|
|
|
This plugin owns the tribe-to-tribe trust provider for
|
|
`org.tribes.federation.provider@1` and stores:
|
|
|
|
- `RemoteTribe` — signed or locally observed remote tribe identity metadata.
|
|
- `TribeRelationship` — local relationship state, trust score, notes, requested
|
|
capabilities, and granted capabilities.
|
|
|
|
Both resources are cluster-synced because they are tribe-level governance state.
|
|
They are not internal cluster trust records and must not be used to authorize
|
|
AshNostrSync node writers.
|