Removed in 5d740a6.
Stale pointer comments removed in 5d740a6.
Removed in 5d740a6.
Removed in 5d740a6.
Done in 3b41858 — moved enumerate_active + parser + query helpers into a new backend/docker/enumerate.py, mirroring backend/smolmachines/enumerate.py. cleanup.py is now purely prepare/cleanup.
Done in 3b41858 — added abstract BottleBackend.is_available() (docker → shutil.which('docker'), smolmachines → smolvm.is_available()) and a top-level has_backend(name) on the backend package. Cross-backend enumerate_active_agents() gates on it, so neither inline shutil.which check exists anymore.
Done in 3b41858 — same has_backend('docker') gate replaces the inline shutil.which. (Late-imported inside _query_bundle_services() to sidestep the cycle, since backend/__init__.py imports this module transitively.)
Done in 3b41858 — ActiveBottle renamed to ActiveAgent everywhere (backend package, both backends, CLI, dashboard, tests). The ActiveAgent = ActiveBottle alias is gone; enumerate_active_bottles is now enumerate_active_agents.
Review feedback addressed in 3b41858.
Resolved by #76. Each bottle now reserves a unique 127.0.0.16 .. 127.0.0.31 loopback alias, the bundle's port-forwards bind there, and the agent's TSI allowlist is the alias's /32. Smolvm…