Second half of layer B: an `@acm` yielding a `trio` receive-chan
of `TIPCNameEvent` fed by a nursery-spawned reader on a
`SOCK_SEQPACKET` conn to `TIPC_TOP_SRV`.
This is the bit that makes #378's "end game cluster proto" claim
real — the kernel *tells* us when any actor anywhere in the
cluster publishes or withdraws a service name, so a registrar
never has to poll `find_actor()`. Groundwork for the push
registry in `discovery/_registry.py` (gh #184, #216).
Deats,
- `filt` selects granularity; `TIPC_SUB_SERVICE` is one event
per *name*, `TIPC_SUB_PORTS` one per *publisher* — the latter
makes the §2.3 duplicate-name/round-robin crosstalk case
externally observable, which is how a push-registry could
ever detect it.
- a full event buf **drops** w/ a loud warning rather than
blocking the reader; stalling it just backs up the kernel's
own queue and loses the event less visibly.
- `SOCK_SEQPACKET` is fine here bc this sock never goes through
`MsgpackTransport` — the contract's "`SOCK_STREAM` only" rule
is about `MsgTransport` streams, not this.
XXX teardown order is load-bearing: cancel the nursery BEFORE
closing the fd. `.close()`ing out from under a pending
`.recv()` races — trio's retry can land on an already-freed fd
and raise a bare `OSError(EBADF)` instead of the
`ClosedResourceError` the reader guards for, which then escapes
the nursery as an eg.
(this patch was generated in some part by `claude-code` using `claude-opus-5` (`anthropic`))