Plugins
Source:
docs/plugins/README.md· Status: current.
Plugins
Section titled “Plugins”How to ship packs for the Inhuman harness — surfaces, install, commands, and reference sketches.
Target design: plugins/hooks-notify-vs-transform-2026-09-20.md,
revised 2026-09-22, is authoritative for the proposed API. Interception comes in two kinds:
guards stand on the critical path, see raw values, may narrow or replace, fail closed,
and are content-addressed and bound to a host-owned consent store — so a change to a guard
is reviewed at install or update; hooks declare :pre / :post / :post-fail, run in
parallel, receive filtered values only, fail open, and never block. It uses guard/turn and
guard/round for chain position at lifecycle boundaries with self/notify contributed by
parallel hook/turn / hook/round, single-use invoke, and per-lineage re-entrancy
limits. Tool-argument schema repair and read caching are host machinery, not plugin
surfaces. There is no react or producer registration.
Behavior is selected per bot: a definition chooses plugin.scm, optional environment,
configuration, and receiver bindings; each running agent pins the revision and owns
its registrations, private state, and notifications. plugin.json additionally
declares session/project/global Scheme state modules with define/method APIs.
Bots use call/method or injected callables without needing a target bot or exposing
model tools. State scope owns the log and rollback semantics; packages supply trusted
code and optional shared resources.
Follow the plugins/plugin-surface-implementation-2026-09-21.md for
migration and acceptance scenarios.
polish.md, lifecycle.md, and plugins/reference/ describe the
behavior capability in packages/harness-server/src/plugin-surface. It is an Arrival
EnvCapability: author-facing forms are symbol.macro, and handler lambdas cross with
toJS. A callback passed into one of those lambdas is reverse Rosetta. The session loop
stores the pin and joins behavior notes with loopEnd. It does not call loadProgram or
dispatchBoundary.
plugins/tldr.md documents InhumanPlugin. Host builtins (shell, toolkit, scheme-repl,
and the JS tasks projection) still construct that class and compile it with
applyPackPlugins. The pack loader does not import plugins[]. loopEnd still joins
until a later removal. The
plugins/plugin-shape-2026-09-20.md and
plugins/hooks-design-review-2026-09-20.md are historical context.
Author guides:
- polish.md — behavior selection, guards, hooks, state methods, consent
- lifecycle.md — register vs callback, turn/round, tool chain, replay
plugins/reference/—plugin.jsonandhooks.scm. Shipped slash-commands stay inpackages/harness-server/src/defaults/commands/plugins/tldr.md— module bag the host builtins still load- install.md — npm into the kernel folder +
config.json - commands.md — Client Scheme sandbox vs JSON-RPC commit
Extension plugins are not driver providers. Drivers are not the behavior
surface. drivers[] is still parsed and projected onto DriverSpec. That merge is
unsupported; no exemplar pack declares a driver. A driver provider is a runtime
package registered by product composition — not a pack loaded through plugin
manifests or the plugin loader. Exterior for a behavior pack is connections on
existing drivers (/connect, MCP servers), pack tools, and commands. Internal doc:
../runtime/drivers.md.
Product nouns (locked — link, do not re-host):
| Noun home | Path |
|---|---|
| Grain / regions / catalog | ../canon/grain.md |
| Proposals | ../canon/proposals.md |
| Permission / LICENSE WHEN | ../runtime/approval.md |
| Always-on FS toolkit | ../canon/standard-toolkit.md |
Not this tree: operator day-to-day → ../client/operate.md.
Exemplar packs: ../plugins/.
Tool constructor: ../packages/harness-plugin-sdk/README.md.