24df322c31
First sub-slice of docker launch integration: the foundation the CLI needs to ensure exactly one orchestrator control plane + shared gateway is up before registering/launching bottles. Does NOT touch the real launch path yet — it's the lifecycle primitive the cut-over slices build on. - OrchestratorProcess.ensure_running(): idempotent singleton — returns the control-plane URL if a healthy one already answers /health, else spawns `python -m bot_bottle.orchestrator --broker docker --gateway` detached (start_new_session, output tee'd to <root>/orchestrator.log) and polls /health until healthy or timeout (OrchestratorStartError). - The control-plane port is the singleton key: a second orchestrator can't bind it, so a stray double-start fails fast rather than forking a rival. - Host-process (not container) per the PRD's dev-harness sequencing — it already has the host user's docker access to broker launches; the data-plane gateway it manages is the container. pyright 0 errors; pylint 9.83/10; unit suite green (1714 tests; the 13 test_sidecar_init /bin/sleep errors are pre-existing NixOS-local noise). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WBMWTEtQdJ4W5UrWuLHCck