feat: run smolmachines sidecar as vm

This commit is contained in:
2026-07-09 16:10:42 +00:00
committed by didericis
parent 46a77aec31
commit ce8e2b3874
12 changed files with 739 additions and 113 deletions
+36 -25
View File
@@ -1,6 +1,6 @@
# PRD prd-new: smolmachines sidecar VM
- **Status:** Draft
- **Status:** Active
- **Author:** codex
- **Created:** 2026-07-09
- **Issue:** #332
@@ -50,15 +50,31 @@ other bottle sidecars if those services share the allowed address.
## Design
The sidecar VM should continue to use the existing sidecar bundle image and
The sidecar VM continues to use the existing sidecar bundle image and
`/app/sidecar_init.py` supervisor. The launch flow builds the sidecar image,
packs it into a `.smolmachine` artifact, creates a per-bottle sidecar VM from
that artifact, passes the same daemon-selection environment the Docker bundle
uses today, mounts or copies the same daemon-private config/state inputs, starts
the sidecar VM, discovers the host-side published ports, then starts the agent
VM with `--allow-cidr <per-bottle-address>/32`.
the sidecar VM, wraps the sidecar VM's raw smolVM-published ports with a local
per-bottle forwarder, then starts the agent VM with
`--allow-cidr <per-bottle-address>/32`.
Agent-facing URLs are stamped from the sidecar VM's published ports:
smolVM currently exposes guest ports as `HOST:GUEST` port pairs bound on host
loopback. It does not expose an address-scoped bind like
`127.0.0.16:<port>:9099`. Because TSI is IP-only, bot-bottle must not advertise
those raw loopback ports directly to the agent. Instead, bot-bottle runs one
small stdlib Python TCP forwarder process per bottle:
```text
agent VM
-> TSI allows only <bottle-address>/32
-> bot-bottle forwarder bound to <bottle-address>:<random-port>
-> raw smolVM-published sidecar port on 127.0.0.1:<raw-port>
-> sidecar VM service
```
Agent-facing URLs are stamped from the forwarder ports, never the raw smolVM
ports:
- `HTTP_PROXY` / `HTTPS_PROXY` point at the published egress proxy port.
- `GIT_GATE_URL` points at the published git HTTP port when git-gate is enabled.
@@ -68,34 +84,29 @@ Agent-facing URLs are stamped from the sidecar VM's published ports:
Internal sidecar-only services stay bound inside the sidecar VM and are not
published.
## Open blocker
### Forwarder constraints
The implementation depends on host-side port publishing that can bind to the
per-bottle address. Current smolVM documentation and upstream source shape show
`-p/--port` accepting `HOST:GUEST`, with `HOST` represented as a port number,
not an IP address plus port. If smolVM cannot bind a guest port to a specific
host address such as `127.0.0.16:<random>`, bot-bottle needs one of these before
implementation can proceed:
1. smolVM support for address-scoped port publishing;
2. a host-side forwarding layer that binds only the per-bottle address and
forwards into the sidecar VM; or
3. a different sidecar VM networking design that preserves the same IP-only TSI
isolation property.
Publishing sidecar ports on generic host localhost is not acceptable because
TSI's allowlist is IP-only and would no longer prove that the agent can reach
only its own sidecar surface.
- Reject wildcard listener binds (`0.0.0.0`, `::`) and generic localhost
listener binds (`127.0.0.1`, `::1`) for agent-facing forwards.
- Accept only fixed loopback targets selected by launch; the client cannot
choose or influence the forwarding target.
- Forward bytes transparently without parsing HTTP, CONNECT, TLS, Git, or MCP.
- Log lifecycle and endpoint metadata only; never log payload bytes.
- Create forwards only for egress, git HTTP when enabled, and supervise when
enabled.
- Fail closed if any listener cannot bind exactly the requested per-bottle
address.
## Implementation chunks
1. Confirm or add an address-scoped sidecar VM port publishing mechanism.
2. Extract the existing image-to-smolmachine pack helper so agent and sidecar
1. Extract the existing image-to-smolmachine pack helper so agent and sidecar
artifacts share the same cache and registry path.
2. Add a strict stdlib host TCP forwarder for per-bottle address-bound
forwarding to raw smolVM-published sidecar ports.
3. Add a sidecar VM launch spec and lifecycle helpers: pack, create, start,
publish/discover ports, stop, delete.
4. Switch smolmachines launch from Docker sidecar bundle lifecycle to sidecar VM
lifecycle.
plus forwarder lifecycle.
5. Update egress apply / reload paths for the sidecar VM supervisor.
6. Add unit tests for argv shape, URL stamping, teardown, and fail-closed
behavior.