Root cause: server wraps QConnectMessage inside an inner envelope with
fields 1 (correlation_id), 2 (sequence), 3 (actual message bytes).
We were passing the envelope directly to QConnectMessage::decode(),
which silently skipped the unknown wrapper fields and found nothing.
Also restructure bootstrap: controller join first (works without
session_uuid), renderer join deferred until SESSION_STATE (type 81)
arrives with the session_uuid the server requires.