Replace the per-bottle Docker sidecar bundle with the shared per-host
orchestrator + gateway, mirroring what the Docker backend already has.
- Add `bot_bottle/backend/firecracker/consolidated_launch.py`:
`_FirecrackerOrchestratorService` (subclasses `OrchestratorService`,
overrides `_gateway()` to return a `DockerGateway` with host port
bindings so Firecracker VMs can reach it via their TAP link);
`launch_consolidated()` registers the bottle by guest IP (attribution
key), provisions git-gate into the shared gateway, and returns the
shared CA + orchestrator URL for teardown; `teardown_consolidated()`
deregisters and cleans up.
- Rewrite `bot_bottle/backend/firecracker/launch.py`: removes the
per-bottle sidecar bundle (`_start_sidecar_bundle`, `_stage_git_gate`,
etc.) and `_mint_certs`; wires `launch_consolidated()` instead. The VM
still sends to `host_tap_ip:PORT` — Docker's PREROUTING DNAT + the nft
`ct status dnat accept` rule in the forward chain route the traffic to
the shared gateway container.
- Extend `DockerGateway` with `host_port_bindings` so the Firecracker
gateway publishes its ports on the host (`0.0.0.0:PORT`).
- Parameterise `OrchestratorService` with `orchestrator_name` /
`orchestrator_label` so Docker and Firecracker orchestrators can
coexist on the same host (`bot-bottle-orchestrator` vs
`bot-bottle-fc-orchestrator`).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>