Skip to content
Runner · Write your pluginStep 4 of 6

Run & observe

The CLI safety ramp from dry-run to live, and how to know it's healthy.

The CLI is a ramp from safe to live. Walk up it in order; each step gives you more confidence before the next.

pnpm dry-run my-strategy    # simulate decide() + the tx, print the decision. No gas, nothing submitted.
pnpm inspect my-strategy    # show wallet balance, vault state, permissions, persisted ctx.state
pnpm trigger my-strategy    # run decide() ONCE, for real. One tick, then stop.
pnpm start                  # start the daemon: every plugin, on its triggers, forever.

(With npm the same scripts are npm run dry-run my-strategynpm start.)

  • dry-run is your inner loop (you met it in the last step).
  • inspect answers "why isn't my plugin acting?" *before* you run it. It shows the live vault state and the permissions the contract will check your actions against.
  • trigger fires a single real tick. Use it to confirm one live execution before committing to the daemon.
  • start is production: the scheduler ticks each plugin on its triggers, isolates failures, and serves health.

Watch it

The daemon serves a health endpoint (HEALTH_PORT, default 3030, bound to 127.0.0.1 — set HEALTH_HOST=0.0.0.0 when the probe comes from outside the host):

curl -s http://localhost:3030/health | jq
# → { "ok": true, "plugins": [{ "name": "my-strategy", "state": "healthy", "metrics": {…} }] }

/health returns 200 when every plugin is healthy and 503 if any is unhealthy. A plugin that throws is marked unhealthy, skipped for a few ticks, then auto-retried, while the others keep running. The full playbook is Deploy & observability.

The rules that already protect you

You don't have to get everything right before going live, because the floor holds:

  • One operator per vault. A discretionary vault has exactly one operator_address. Don't run the bot *and* drive the same vault by hand; both sign with the same key.
  • The contract is the hard floor. Position size, exposure, the function whitelist, pause state: all enforced on-chain. A bad Action[] reverts; it can't exceed the caps.
  • A crash is contained. A plugin that throws can't bring down the runtime or the others.

That's the loop: write a plugin, dry-run it, walk it up the ramp, watch it. From here, the Build ladder takes you from this read-only rung all the way to a multi-trigger agent.