Transports
Transport is a deployment choice, not a design constraint.
A transport is the connection between two adjacent zones. The same generated interface runs over an in-process call, a shared-memory queue, TCP, TLS, a WebSocket, or an SGX enclave boundary — choosing which is a matter of how you construct the connection, not how you write the service.
Available transports
i_marshaller calls rather than a stream. Calls within a single zone
need no serialisation at all.
Transports are pluggable: a custom transport implements the same interface, so a link Canopy does not ship can be added without touching service code.
Adjacency, and routing past it
A transport only ever joins two adjacent zones. When the zones a call needs to reach are not directly connected, Canopy routes through the zones in between using passthroughs — automatic multi-hop forwarding that keeps the whole path alive while traffic flows along it. A zone can exist purely to route, with no objects of its own.
This is what lets the topology be whatever the deployment needs: a flat peer mesh where zones connect as equals, or a hierarchical tree with a root zone and child zones for plugins, subprocesses, and enclaves. Either way, an object at any depth in any zone can call an object at any depth in any other — the caller never has to know how many hops, or which transports, lie between them. See Architecture for the zone and service model.