Skip to main content
A Plugin adds platform capability — a new channel adapter, a new RAG provider. That is what separates it from a Solution, which adds domain logic such as HR or recruitment.

The service provider

A Plugin is a Composer package whose service provider extends Fapost\Foundation\Lifecycle\AbstractPluginServiceProvider:
onActivate() and onDeactivate() are available to hook enabling and disabling; both are no-ops unless you override them.

The manifest

SolutionManifest is what makes a Plugin checkable at boot rather than at the moment it breaks. requiresPlatform is a version constraint on Core; requiresCapabilities names the platform capabilities the Plugin needs to be present. Core validates the manifest during boot and through the platform update lifecycle.

What you may register

Everything goes through CoreRegistrarInterface. This is the single registration entry point.
An extension declares intent through the registrar. It must not call Route, Schedule, or the migrator directly — the platform decides when and how those are mounted.

Rules

Depend on public contracts, not Core internals. Everything a Plugin needs is in fapost/foundation. A use App\… statement in a Plugin will break on a Core refactor, and nothing in the stability promise covers it. Do not inject Vue components into the running builder. The builder front end is compiled before your Plugin is enabled. Make a node configurable by describing it with a configuration schema — see Builder UI extensions. Follow migration isolation. A Plugin migration is a DDL operation like any other: no app(), no config(), no tenant-aware services, no reads of another module’s tables. See Migration isolation.