dc90a75ab4
reconnectSecondary fail-stopped only on "connection removed" and "profile deleted"; every other dial failure fell through to scheduleReconnect with a 15s-capped jitter and no budget. For a tile-pinned owner scope that is forever wantOpen, a pool-slot wait timeout therefore re-issued a background spawn on every backoff tick, for every such tile, indefinitely -- the "waiting for a free local slot ... timed out ... will retry" cycle in #103375's desktop.log, in the same profile order each pass. Count only STALLED dials (a slot-wait timeout or the 20s dial timeout): those are the ones that hold a queue position and re-queue a spawn. After SECONDARY_STALLED_DIAL_BUDGET consecutive stalls the entry parks (wantOpen=false) with a console warning. Fast failures (ECONNREFUSED while a gateway restarts) keep the ordinary unbounded backoff, so a socket that merely dropped still comes back on its own. Parked is not evicted: every explicit open of the scope (requestGatewayForAgent, openGatewayForAgent, ensureGatewayForAgent, and ensureActiveGatewayOpen for the viewed scope -- the Reconnect action and request retries) goes through rearmSecondary, which sets wantOpen and resets the budget. Not changed: resumeTile's non-passive transcript prefetch. It shares the main-process dial claim with the session.resume dial for the same scope, so it never adds a spawn, and a cold tile needs it to paint (resume runs with omit_messages).