`ClientLifecycleMode::Auto` only fell back from `server/discover` on
`-32601`, so legacy servers that reject the probe with other codes
(`-32600`, `-32602`, implementation-defined errors) failed to connect
even though `initialize` would have succeeded.
The previous attempt (indicates_legacy_server) classified the failure
after the fact by reverse-engineering the error type. This rewrite moves
the classification into `discover_startup` itself, where the full context
(request id, response correlation, transport state) is still available.
`discover_startup` now returns `DiscoverOutcome`: `Modern` on success,
`Legacy(error)` when the probe received a complete, correlated JSON-RPC
error whose code is not a modern-era rejection. Every other failure
becomes `Err`, so `Auto` simply matches the outcome — no methods on
`ClientInitializeError`, no downcast, no transport-specific types
leaking into the generic lifecycle layer.
Additional fixes that fall out naturally:
- Response correlation is now checked in `expect_response` for both
success and error branches. Previously error responses skipped id
correlation entirely. A new `UncorrelatedErrorResponse` variant
surfaces responses that cannot be tied to the request.
- When both discover and the legacy fallback fail, a
`LegacyFallbackFailed` compound error preserves both phases instead
of discarding the discover error.
Fixes#1040.