* fix(mcp): report selection after failed target opens
* fix(mcp): retain resource root selection in open failures
* test(session): assert selection during cleanup failures
* test(mcp): delay failed open response across target switch
* test(session): distinguish no selection from pending cleanup
* test(session): assert selections during cleanup and cancellation
* test(mcp): join the failed-open gate before restoring its spy
The snapshot-switch gate waited only on its acknowledgement, so a request
that settled early hung until the runner timeout, and a later assertion
failure restored the spy while that request was still in flight. Race the
acknowledgement and join the launched open in finally before mockRestore.
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>