feat: run smolmachines sidecar as vm
This commit is contained in:
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user