- 14function crates on the substrate
- 7of them produced by the generator
- 2registrations in every slice entry
- 3actions per tool in the gateway
Registration as a property of the build
FAFO Core and Function Forge: a tool can be half-registered. I had seen hand-written registration routines drift that way. When agents started generating functions, I decided registration would be a property of the build, so discovery happens at link time and nothing can drift between what is built and what is registered.
In the gateway, missing from the result path: the call hangs.
Callable, not controllable: the job cannot be paused or drained.
Wired: executes and takes commands.
Not wired: the build fails, so nothing half-wired runs.
Execution and control in one entry
Each function crate contributes an entry to a link-time distributed slice through the Rust linkme crate, a third-party crate I use. At startup the control plane walks that slice. Execution and control register in the same entry, which keeps every function operable by agents as well as executable.
Generated lists that nobody edits
The control plane's composition root is generated too. It is the list of compiled-in functions plus the control-plane service, produced from registration files by a generated macro, so adding a function never means editing a startup routine. On the gateway side, the tool surface is generated at build time from per-function YAML and loaded at startup. This replaced an earlier design in which each function called a hand-written registration routine at startup.
tools/list: execute, status, controlDeleting a function reverses every edit the generator made.
A human gate before a tool is callable
Function Forge depends on this. A new function needs a rebuild and a restart, and I chose that deliberately.
It puts a human gate at the moment a tool becomes callable, and I wanted the gate there.
Moving checks earlier, here from runtime into the linker, removes a class of failure, and the gate sits where it matters most for AI-generated code. The governance around that path is in Tools that build tools, under governance, and the build-time generation it rests on is on the Schema-driven build-time code generation page.