self 40310b26ea
CI / Test (push) Failing after 20s
feat: add trust plugin foundation
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.
2026-05-27 22:49:44 +02:00
2026-05-27 22:49:44 +02:00
2026-05-27 22:49:44 +02:00
2026-05-27 22:49:44 +02:00
2026-05-27 22:49:44 +02:00
2026-05-27 22:49:44 +02:00
2026-05-27 22:49:44 +02:00
2026-05-27 22:49:44 +02:00
2026-05-27 22:49:44 +02:00
2026-05-27 22:49:44 +02:00
2026-05-27 22:49:44 +02:00
2026-05-27 22:49:44 +02:00
2026-05-27 22:49:44 +02:00
2026-05-27 22:49:44 +02:00
2026-05-27 22:49:44 +02:00
2026-05-27 22:49:44 +02:00
2026-05-27 22:49:44 +02:00
2026-05-27 22:49:44 +02:00

Trust

Tribe-to-tribe alliances and trust

Getting Started

  1. Edit manifest.json - set description, capabilities, requirements
  2. Implement your plugin in lib/trust/plugin.ex
  3. Run validation, smoke checks, and tests:
mix deps.get
mix tribes.plugin.validate
scripts/plugin smoke
scripts/plugin test

If you are using the shared tribes devenv, run through the local helper instead:

devenv shell -- plugin validate
devenv shell -- plugin smoke
devenv shell -- plugin test
devenv shell -- plugin precommit

Generate AshPostgres resource migrations through the same wrapper so they target the host Tribes.Repo and the plugin migration directory:

plugin ash.codegen update_example_resources

Manual Ecto migrations are the rare exception for schema work not derived from Ash resources:

plugin ecto.migration add_example_table

Development

For local development alongside a Tribes checkout:

# Symlink into the host plugins directory once
cd ../tribes
ln -s ../tribes-plugin-trust plugins/trust

# Start Tribes dev server
iex --sname dev -S mix phx.server

Then edit the plugin in its own repo. In development, the host watches symlinked external plugins and automatically:

  • runs mix compile for Elixir/HEEx or manifest changes
  • runs npm run build --prefix assets when assets/package.json is present and plugin asset files change
  • reloads the plugin in the running Tribes VM
  • triggers a Phoenix browser reload after the rebuild finishes

Browser hooks for external plugins should live in plugin JS assets declared in manifest.json assets.global_js and register themselves through window.TribesPluginHooks. Phoenix colocated hooks are not auto-imported from external plugin OTP apps by the host app.js bundle.

That means the normal edit/compile loop is:

cd /path/to/tribes-plugin-trust
mix deps.get

# in another terminal
cd /path/to/tribes
iex --sname dev -S mix phx.server

Inside the plugin repo's devenv shell, the plugin helper forwards to the host devenv automatically:

plugin validate
plugin smoke
plugin test
plugin precommit

If your plugin does not need a custom frontend pipeline, you can skip assets/package.json and write browser-ready files directly under assets/js and assets/css; the host dev watcher will copy them into priv/static for you in development. The default generator uses TypeScript under assets/ts.

LiveView Hooks

External plugins do not participate in the host asset bundle, so the host cannot statically import arbitrary plugin phoenix-colocated/<otp_app> modules. Register browser hooks from your plugin JS instead:

window.TribesPluginHooks = window.TribesPluginHooks ?? {};
window.TribesPluginHooks.TribeOneTribesPluginTrustExample = {
  mounted() {
    console.info("trust hook mounted");
  }
};

Keep the compiled JS file listed in manifest.json assets.global_js so it loads before the host LiveSocket connects.

Project Structure

trust/
|-- manifest.json           # Plugin metadata (Nix build + runtime)
|-- mix.exs                 # Dependencies
|-- config/                 # Host-backed test config
|-- lib/
|   |-- trust/
|   |   |-- plugin.ex       # Tribes.Plugin entry point
|   |   `-- application.ex  # OTP supervision tree (optional)
|   `-- trust_web/
|       `-- live/           # LiveView pages
|-- assets/                 # TS/CSS (one bundle per plugin)
|   |-- ts/                 # TypeScript browser entry points
|   |-- package.json        # Optional build script used by dev + Guix packaging
|   |-- tsconfig.json       # TypeScript compiler settings
|   `-- package-lock.json   # Optional, recommended for reproducible builds
|-- priv/
|   |-- static/             # Built assets for release
|   `-- repo/migrations/    # Ecto migrations
|-- scripts/
|   `-- plugin              # Shared devenv/non-devenv test wrapper
`-- test/

Manifest

manifest.json declares your plugin's identity and capabilities:

{
  "id": "org.tribe-one.plugins.trust",
  "slug": "trust",
  "display_name": "Trust",
  "entry_module": "TribeOne.TribesPlugin.Trust.Plugin",
  "host_api": "1",
  "otp_app": "tribe_one_trust",
  "provides": ["org.tribe-one.caps.some_capability@1"],
  "requires": ["org.tribe-one.caps.ui@1"],
  "enhances_with": ["org.tribe-one.caps.inference@1"]
}
  • entry_module - must be a valid module ending in .Plugin
  • otp_app - required OTP application name; vendor-prefix it to avoid collisions
  • provides - capabilities this plugin makes available
  • requires - hard plugin/API contracts (build fails without them)
  • enhances_with - optional dependencies (plugin degrades gracefully)

The default generator includes org.tribe-one.caps.ui@1 because the generated LiveView renders inside the host chrome through Tribes.Plugin.Layouts.app. Keep org.tribe-one.caps.ui@1 when a plugin uses host chrome, imports Tribes.UI.Components, or uses use Tribes.UI.

Plugin Data

If your plugin adds Ash resources that should replicate cluster-wide, use extensions: [AshNostrSync] on those resources and assign a sync lane per resource. The host default lane is bulk; latency-sensitive topology or orchestration resources should opt into control. Keep resource-specific side effects explicit in actions.

Testing

The generated plugin starts with two host-backed test layers:

  • Contract tests (test/trust/plugin_contract_test.exs) - manifest and runtime spec stay aligned
  • Page tests (test/trust/home_page_test.exs) - the plugin renders through the real host page pipeline

Run them with:

mix tribes.plugin.validate
scripts/plugin smoke
scripts/plugin test

Use plugin test / plugin precommit for host-backed tests. The helper invokes Mix with the host database/services and host plugin-manager paths, including built-in providers such as tribes_ui. Raw mix test in a plugin checkout is guarded and prints this guidance; mix raw_test / mix raw_precommit are available only for unusual manual debugging when you have set the same host environment yourself.

Building for Release

MIX_ENV=prod mix compile
devenv shell -- npm run build --prefix assets

mkdir -p dist/trust
cp -r _build/prod/lib/tribe_one_trust/ebin dist/trust/
cp -r priv dist/trust/
cp manifest.json dist/trust/

Licence

TODO: Choose a licence.

S
Description
Tribe-to-tribe and user-to-user trust and interop
Readme 140 KiB
Languages
Elixir 95.4%
Shell 2.4%
Nix 1.3%
TypeScript 0.6%
CSS 0.3%