The daemon is not a bag of goroutines sharing locks. Each domain owns its state behind an actor, and the tree that supervises them is named after the business, not the transport.
A daemon that handles inbound streams, retries deliveries, commits consensus entries, and serves local gRPC has plenty of ways to race. The usual answer is mutexes around shared structures, which spreads the invariants of one concept across every function that touches it.
The actor model inverts that. Each piece of mutable state has exactly one owner, and the only way to change it is to send that owner a message. Concurrency stops being something every call site has to remember and becomes a property of the structure.
The packages are named after the domain rather than the machinery: thread, tasks, inbox, outbox, registry, names, deliver. Each is a bounded context that owns its own vocabulary and its own persistence, and none reaches into another's tables.
Those contexts map one to one onto the supervision tree. Every domain package exposes the same EnableActor shape, which spawns that domain's actor under a shared hierarchy. The result is that the runtime topology is a picture of the domain model, not of the framework.
Threads are the clearest case. A thread's log must stay hash-linked and correctly ordered, which is an invariant that only holds if writes to that thread are serialised. Giving each thread an actor means that serialisation is structural: there is no code path that can append to a thread except by going through the one actor that owns it.
Actors are spawned under a single root supervisor with domain containers beneath it, and children are registered by logical name so the same domain actor is never started twice. Stopping the root stops the whole application tree rather than leaving orphaned workers behind, which makes shutdown and inspection a single operation instead of a checklist.