Gateway
When a stack declares a gateway.<provider> block, stackied does not
spawn a child process. Instead it calls spaceport::build_gateway_router,
binds the returned axum::Router to a TCP listener on the allocated port,
and owns the serving future for the lifetime of the block.
The GatewayRegistry tracks every live gateway by name, holding both the
tokio::task::JoinHandle (so it can be awaited or aborted on shutdown)
and a tokio_util::sync::CancellationToken (so graceful shutdown can be
signalled through axum’s with_graceful_shutdown future).