Type-checked wires
Wires between blocks are checked once, at load time, by generating a synthetic TypeScript file that imports every block module in the flow and asserts each wire’s source-output type is assignable to its destination-input type — then running tsc --noEmit --incremental over it.
If the check fails, the old flow keeps running and the error is reported; nothing partially starts. Warm checks take a few hundred milliseconds.
Two-tier trust
Section titled “Two-tier trust”Compile-time checking covers wires between your own blocks. Anything crossing a genuine trust boundary — Home Assistant event payloads, third-party API responses — gets validated at runtime with Zod instead, inside the boundary block. Calling an arbitrary external API with fetch and Zod-parsing the response is meant to be a first-class, pleasant thing to do in a block, not a workaround.
Typechecking as a reload gate
Section titled “Typechecking as a reload gate”The coordinator runs the typecheck gate itself, before ever touching a running flow-host process:
- A
data/blocks/*.tsordata/wiring/*.jsonedit lands (debouncedfs.watch). - Every loaded flow re-typechecks together through the generated assertion file.
- On failure, every existing flow process is left completely alone.
- Only a passing check triggers an actual restart of the affected flow.
This is verified behavior, not aspiration: a deliberately broken edit leaves every flow’s pid unchanged.
