Node
Node: the typed remote send (distributed actors, last piece of 1/4).
Node.send(peer, to, msg) is what a user writes; everything under it exists already (NodeSend carries bytes, PeerReader reads them, the control/data split, GlobalPid). What this layer adds is the codec contract, and the compiler enforces it:
msg's type mustderive Json. A missing codec is a TYPECHECK error
at the call site, naming the type -- not the runtime panic a generic
`to_json` gives.
* The wire `type_tag` is the message type's name as the compiler resolves
it (module-qualified where the type is declared inside a module), the
same name `derive Json for T` registers its codec under, so a sender and
a receiver agree on the tag by construction. No string to keep in step.
* A `Pid` anywhere in the type is refused by `derive Json` itself: a local
pid means nothing on another node. Carry a `GlobalPid.Pid`.Mechanism. send below is an ordinary stdlib function whose BODY is never reached: the typechecker records, per Node.send call site, the resolved message type (Typecheck_caps.check_node_send_sites, after the whole module is solved -- the argument's type is usually pinned later than the call), and both backends rewrite the call to send_tagged(peer, to, "<tag>", JsonTo$T.to_json(msg)) -- the interpreter in Eval's EApp arm, the compiler in Lower_expr, both off the March_ast.Json_dispatch table that from_json already uses. An UNCHECKED interpreter run (the stdlib March test harness never typechecks) has no table; there the interpreter names the type from the value itself, the way the generic to_json does, and the tag is that runtime name. The body below is reached only by a value no table and no runtime shape can name; it says so loudly.
Node.enqueue(q, to, msg, policy) is the same contract through a peer's NodeQueue (credit-based flow control): same codec check, same minted tag, rewritten to enqueue_tagged(q, to, "<tag>", JsonTo$T.to_json(msg), policy).
Receiving is the caller's: read the ACTOR_MSG (NodeSend.serve_one or a PeerReader), compare d.type_tag with the tag the sender's compiler minted (a receiver hosting T in the same module tree writes the same qualified name), and decode with Node.payload(d) pinned to T by the result type -- from_json dispatch is the typechecker's already. Design: specs/progress/2026-09-14-remote-send-to-a-global-pid.md.