39bf984765
ensureGatewayForAgent (the SDK ensureAgent door) skipped the two invariants the profile path provides: - $connection / $activeGatewayProfile were only updated when a socket was freshly dialed (setConnection inside openSecondary), so activating an ALREADY-OPEN registry agent left both describing the previous backend — /api/fs, /api/media and image.attach routed to the wrong machine (same class as #46651) and newSessionInProfile targeted the stale profile. - Activations bypassed the gatewaySwitch mutex, so a rapid agent/profile interleave could complete out of order with the earlier setActive() landing last. Add profile.ts ensureGatewayAgent: the (connectionId, profile) analogue of ensureGatewayProfile that shares the same gatewaySwitch mutex, moves $activeGatewayProfile on every activation, and resyncs $connection from getConnectionFor (best-effort, like the profile path). The SDK ensureAgent now routes through it; local/null connectionId falls through to the profile path unchanged.