Skip to main content
A Harnest Extension participates in three lifecycle layers: List lifecycle files in contributes.lifecycle and declare the capabilities they use. Both are required. Storage authorities start first. Harnest then calls Extension.start() in dependency order, followed by contributed @lifecycle.resource factories. Shutdown closes extension resources before calling Extension.stop() in reverse dependency order, then closes storage. ExtensionStartContext therefore exposes only already-live named custom storage and declared continuations, not arbitrary lifecycle resources or invocation credentials.

Declare and implement a hook

1

Create extensions/warehouse/extension.yaml

extensions/warehouse/extension.yaml
2

Create extensions/warehouse/lifecycle/tool_policy.py

extensions/warehouse/lifecycle/tool_policy.py
Root and extension lifecycle files share one ordering: order, then dependency order, then source location. Duplicate singleton authorities or named resources fail compilation.

Choose a declared capability

Declare only the rows the extension 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 extension_mutation(...). It emits correlated, payload-free OTEL audit events without recording arguments, credentials, or results:
extensions/warehouse/extension.py
For external work that must survive a replica stopping, declare context.continuations and follow Durable execution. The extension persists bounded continuation metadata; it does not resume a suspended Python process.

Use the extension

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