setup.py now generates a P-256 console keypair: the public half compiles into config.h, the private half persists to .misery_key (gitignored, chmod 600) and is loaded by the console at runtime. Agent and console agree a per-connection AES-256-GCM session key from an ECDH handshake (plaintext KEY_EXCHANGE frame on TCP, ephemeral-pubkey prefix on beacon polls), so no secret key material ships in a binary. KEY= option removed; --rotate-key rotates the keypair.
setup.py saves and reuses the master key in .misery_key (gitignored, chmod 600) so rebuilds keep one key and deployed agents stay reachable; --rotate-key forces a fresh one. Ghost sessions now use unique per-process profile dirs and clean up leftovers from crashed sessions, including a partial-start cleanup when the browser fails to launch.