883b57cbd8
Phase 2 of the multi-connection campaign (#86679 shipped the registry). The Electron backend pool can now serve agents from ANY registered connection concurrently, keyed by composite (connection, profile) scopes. - connection-registry.ts: backendScopeKey(connectionId, profile) — the single home of the composite-key rule. Local/empty connection ids keep the BARE profile key, so every legacy pool entry, reaper log line, and touch call is byte-identical for single-source users; non-local connections get `conn:<id>::<profile>`, which cannot collide with a plain profile name. backendScopePrefix() matches the keys a connection owns (teardown on remove). - main.ts ensureRegistryBackend(connectionId, profile): resolves a backend against the v2 registry. local kind delegates to ensureBackend() untouched; remote/cloud dial the entry's own URL/auth (descriptor carries profile + connectionId + sharedRemote for per-request ?profile= scoping); ssh bootstraps a tunnel scoped to the composite key, with the served dashboard token persisted back onto the REGISTRY entry (not v1 connection.json). Pool entries reuse the existing LRU/idle-reaper/touch lifecycle. - hermes:connections:remove now stops every pooled backend + ssh scope the removed connection owns. - New IPC hermes:connection:for + preload getConnectionFor + renderer types (connectionId/sharedRemote on HermesConnection). No renderer behavior change yet — the multi-source roster/socket switchover is PR 3. Tests: +2 backendScopeKey contract cases (28 total in the registry suite); electron + settings projects 1357 passed; both tsc configs and eslint clean.