Re-lands the goals of the reverted atomic-publish series (#89483, reverted
in #89785) without the fail-closed decline path that killed profile clicks,
and fixes the underlying pruner race the original series exposed.
Two changes relative to the restored (pre-series) behavior:
- Publication is atomic and mode-safe (#46651): the switch resolves the
target's connection descriptor CONCURRENTLY with the socket work and
publishes $activeGatewayProfile + $connection in one nanostores batch()
frame, so no request or plugin mode-listener observes the new gateway
beside the previous profile's descriptor. Unlike the reverted series, a
failed descriptor lookup fails OPEN — the switch still lands, the previous
descriptor stays, boot/reconnect resyncs it later, and the failure is
logged instead of swallowed.
- The live-work pruner can no longer kill a switch mid-dial (#89622's root
race): ensureGatewayForProfile / ensureGatewayForAgent lease their entry
(activationLeaseUntil, 30s bound) for the duration of the dial and
pruneSecondaryGateways spares leased entries. A switch target is not yet
active, has no live sessions and holds no request lease, so any prune
recompute during a cold pool spawn used to dispose the dialing entry.
Bounded lease: an orphaned one self-expires.
The agent door logs a non-landing activation (target removed mid-dial)
instead of resolving silently, but never fails the switch closed.
Live E2E (Electron over CDP, 3 local profiles, cold + warm): 10 sequential
switches, rapid two-click interleave (last click wins), 6-click stress run —
all land, overlay always clears, fresh pool backends spawn on cold switches.
Tests: gateway-activation-prune-lease suite (mid-dial prune survival on both
doors, lease release, lease expiry); the invalidated-registry-identity pin
updated for the concurrent (read-only) descriptor probe.