Downcity
Plugins

Plugin Hooks and Resolve

Use one overview page to distinguish pipeline, guard, effect, and resolve before going deeper

Plugin Hooks and Resolve

This area is easy to misunderstand because:

  • all four live inside plugin definitions
  • all four look like "register a function"
  • but their runtime semantics are very different

If you only remember one line, start here:

  • pipeline: rewrite a value
  • guard: block a flow
  • effect: run side effects
  • resolve: produce one authoritative answer

Start with the comparison

TypeWho triggers itReturns a valueMultiple handlers allowedWhat failure meansBest fit
pipelinehost code calls ityesyesthrows and stops the current callprogressively transform one value
guardhost code calls itnoyesany thrown error blocks the flowpre-checks and authorization
effecthost code calls itnoyesany thrown error stops the current effect calllogging, analytics, syncing
resolvehost code calls ityesno, exactly onemissing, duplicate, or disabled resolution failsprovide one final answer

The most important thing to remember

Declaring a hook inside a plugin does not make it run automatically.

What actually happens is: host code explicitly calls a named point at a specific time.

For example:

const value = await agent.plugins.pipeline("chat.enrich_message", input);
await agent.plugins.guard("review.require_checked", value);
await agent.plugins.effect("audit.observe", value);
const role = await agent.plugins.resolve("auth.resolve_role", {
  userId: "owner",
});

So the clean mental split is:

  • the plugin defines an extension point handler
  • the host decides when that extension point executes

If the host never calls that point, the hook never runs.

Why resolve deserves separate attention

Many readers naturally treat resolve as just another hook flavor.

But it is really closer to:

  • an authority point
  • a "who gives the final answer?" question

That is why it differs from the other three:

  • the first three allow several plugins to participate
  • resolve allows exactly one plugin to be the final authority

This is also why:

  • duplicate registration for one resolve point throws
  • missing resolvers throw
  • a disabled resolver plugin also causes failure
  1. Mental model overview
  2. Call flow
  3. Pipeline
  4. Guard
  5. Effect
  6. Resolve
  7. How to choose

Jump straight to scenarios