Skip to main content
A Runtime Plugin participates in three lifecycle layers: The plugin manifest must declare every Harnest capability its extension files contribute. Declaration makes ownership inspectable; it does not grant access to undeclared runtime internals. Storage authorities start first. Harnest then calls Plugin.start() in dependency order, followed by contributed @lifecycle.resource factories. Shutdown closes extension resources before calling Plugin.stop() in reverse dependency order, then closes storage. PluginStartContext therefore exposes only already-live named custom storage and declared continuations, not arbitrary lifecycle resources or invocation credentials.

Declare and implement a hook

Plugin and root extensions form one globally validated lifecycle. Lower order values run first. Plugin dependency order and source location break ties. Duplicate singleton authorities or named resources fail compilation rather than shadowing one another.

Choose a declared capability

Declare only the rows the plugin actually uses. Advanced mode still composes Harnest-owned boundaries, but it cannot intercept an opaque native path that bypasses Harnest.

Audit committed mutations

Wrap committed user- or agent-triggered writes with plugin_mutation(...). It emits correlated, payload-free OTEL audit events without recording arguments, credentials, or results:
plugins/warehouse/plugin.py
For external work that must survive a replica stopping, declare context.continuations and follow Durable execution. The plugin persists bounded continuation metadata; it does not resume a suspended Python process.

Use the plugin

Call the bounded public API from an Agent Tool or other trusted invocation code.