Skip to content

How-to guides

Each guide solves one task with numbered steps and working code. They assume you already know the basics — if you're starting from scratch, the tutorial comes first.

Capabilities

Start here — the kernel's core wiring mechanism, where plugins declare what they provide and require.

  • Work with capabilities — Declare provides/requires, resolve providers with get_capability(), tag providers, and handle missing capabilities.
  • Use tags for provider selection — Pick one provider by tag when several plugins offer the same capability — swap a backend without touching policy.
  • Use capability policies — Configure capability_collision, capability_selection, and capability_missing on Core for different deployment environments.
  • Lock down capability access — Set capability_access to restrict each plugin to its declared grant; handle CapabilityAccessError and StalePluginError.
  • Resolve a live plugin instance — Use the kernel.lifecycle grant to act on a discovered plugin instance directly.
  • Probe a plugin before admission — Call check_plugin() to validate a candidate against the live graph before committing to register_plugin().

Core lifecycle

  • Manage core lifecycle — Start, stop, restart, and observe state transitions through INITIALIZED → RUNNING → STOPPING → STOPPED.
  • Boot a plugin graph in order — Boot a batch of sources with core.load_plugins() (atomic) or core.try_load_plugins() (best-effort, with a skip report), or fall back to manual ordering, build_host() factoring, and polling for capabilities that arrive asynchronously.
  • Shut down gracefully — Build a ShutdownHandler that traps OS signals and the system.shutdown event, and blocks main() until shutdown is requested.
  • Use hot reload — Load or swap plugins at runtime without restarting the core, using core.load_plugin().

Plugin development

Events

  • Publish events — Emit events with plugin.emit(), inspect event.source, and schedule delivery to a future tick with at_tick=.
  • Subscribe to events — Register handlers with @event() using exact names or glob patterns.

Hooks

  • Register hook handlers — Use @hook() to provide extension points with a name and optional priority.
  • Execute hooks — Call plugin.hook() to invoke handlers in priority order, collect results, or defer to a future tick.

Error handling

  • Use error handler decorator — Apply @handle_errors() for automatic exception logging, fallback return values, and optional core.plugin_error event emission.

Plugin management

  • Register and manage plugins — Register, unregister, and query plugins by ID, name, or capability using core.register_plugin() and core.list().
  • Manage plugin dependencies — Declare hard plugin-to-plugin dependencies by UUID, validate load order, and detect circular dependency errors.
  • Use plugin collections — Query the live plugin graph by capability, hook, or event using PluginCollection and chained filters.

Scheduling