- 12pipeline steps on every call, in an order frozen behind sign-off
- 40declarative tools, plus Rust built-ins
- 50golden fixtures; a tool without its fixtures fails the build
An agent that acts on real systems needs validation, authorisation, limits, secret scrubbing, audit and observation on every action. If each tool implements those itself, every new tool is a new hole. In my agent runtime every call, whatever the tool, passes through one frozen, ordered pipeline of twelve steps, and a tool contributes only its core behaviour. Most tools are declared in YAML. No tool enters the catalog without golden fixtures and attack fixtures, and the build fails if one is missing.
The challenge
Tools come in many kinds: shell commands, HTTP calls, compositions of other tools, calls to other agents. Local open-source models make malformed calls. Adding a tool has to stay cheap or the estate stops growing. And every host in the fleet has to run the same approved catalog, which is harder than it sounds when the change notification path can back up under load and a host that misses a change keeps running stale tools.
Constraints
One path, no exceptions: a tool kind that bypassed the pipeline would be the hole. Cheap to add, impossible to add badly. Catalog consistency across hosts without missing changes and without flapping between update modes.
My approach
Freeze the pipeline. Every call passes the same twelve steps in the same order, and that order cannot change without sign-off. Tools are data wherever they can be, declared in YAML with their schema, limits and authorisation. For catalog consistency, each catalog has a deterministic hash, hosts detect drift through database notifications, and when notifications saturate they fall back to polling with measured thresholds and hysteresis so a host does not oscillate.
What I built
A Rust tool harness with the twelve-step pipeline, and four declarative tool kinds that cover almost everything an agent does.
A test runner that fails the build for any tool without golden fixtures, and injection fixtures for the shell template kind.
Hash-pinned catalogs with hot reload, and a drift detector with saturation thresholds and hysteresis.
Least-privilege tool access: an agent cannot call what it was not granted.
Difficult decisions
Freezing the order. A fixed pipeline is less flexible than a configurable one. It is also something you can trust, because there is exactly one way an action happens.
Leaving a kind declared but not runnable. One extension tool kind was designed and not finished. I left it declared and non-runnable instead of releasing it half-done with the pipeline partly bypassed.
Fixtures for trivial tools. A one-line tool still needs its golden and attack fixtures.
Exceptions are where the holes are.
Explicit thresholds over "just poll". Measured saturation thresholds with a fallback and hysteresis keep notification-driven updates fast when they work and stable when they do not.
Results
The frozen pipeline is used by every agent launched in the acceptance runs, including the local-model coding runs.
Technologies used
Rust · Tokio · YAML tool definitions · JSON Schema · PostgreSQL LISTEN/NOTIFY · Redis · Content hashing · Fixture-driven test runners
What this demonstrates
Making the safe path the only path for agent actions, and reliability engineering for distributed configuration: the same catalog on every host, checked by hash, updated without missing a change or flapping.