Review: Engines & backends
This review takes engines & backends as described
and asks the three questions: what verifiably holds, what is built but idle, and
what still needs design. The lens is the sovereignty litmus. Verdicts cite code
at xenon-launcher main @56e94575; gap IDs (EB-*) are this beat’s engines
slice and feed Part IV. The app-format half is
reviewed separately.
What verifiably holds
- The d/094 third path is live, not planned. The connector reaches
containers through the engine’s unix socket via
docker exec(backend.rs:827), with no sidecar and no host-published backend port — the two P-141 escalation options are retired in code, not just on paper. This shipped in P-203. - The connector trusts no request input. Project, route, and service are
resolved from launcher-written registry state, never from the HTTP request
(
backend.rs:416); thex-xe-appheader is validated to[a-z0-9-]{1,63}; and the route worker’s grants never cover the backend prefix (a403,route-worker.js:304). A cross-origin grant cannot be turned into backend reach. - The engine is refused if ambiguous.
SmolvmBackendrefuses zero or more-than-onedocker.sockunder the data root (smolvm.rs:276) and verifies a pinned launcher + binary sha256 before exec (smolvm.rs:301). No silent engine substitution. - Failure is told honestly. The lifecycle engine separates slow (503 +
jittered
Retry-After) from failed (502, namingxe doctor), holds only replayable requests, and never holds-then-loses a POST (classify,backend.rs:96;http_error,backend.rs:1110). Singleflight is proven under 200 concurrent first requests (backend.rs:1573). - The compose subset fails closed. Anything that would puncture microVM
isolation is refused at install with a stable code +
source:line:col(compatibility_diagnostics,compose.rs:907).
Built, but idle
- The update engine has no user loop.
crates/apps/src/update.rsis a complete engine — semver-gated discovery, escalation-detecting diff, snapshot → stage → activate → rollback-on-failure, digest-verified volume restore, and anAuto | Notify | Manualpolicy where only patch, non-escalating updates auto-apply and escalations force fresh gate-2 consent. The recon found no CLI or consent-surface wiring driving any of it. The mechanism is correct and idle; there is no proven update loop today (EB-1 below). - Non-default engines are present but partial.
wsl2.rs,firecracker.rs, andmicrosandbox.rsbackends exist alongside smolvm and the ColimaAppEngineBackend— but only smolvm and colima have the connector exec bridge (EB-2 below).
Gap register (this beat, engines slice)
IDs are beat-local; Part IV consolidates.
EB-1 — App updates have no user loop
Exists: a library-complete update engine (above), with the right safety
shape: escalating updates force fresh gate-2 consent (update.rs:239);
non-escalating updates carry prior consent forward (update.rs:242).
The gap: no surfaced command and no consent-surface wiring. The update loop — discover → show the diff at the consent gate → apply or roll back — is unproven end to end.
Options: (a) wire an xe app update command + consent-queue integration and
prove one end-to-end update-with-rollback; (b) leave until an app needs it.
Decides: reversible → orchestrator (surface + one end-to-end proof).
EB-2 — No exec bridge for Windows (WSL2)
Exists: the connector exec bridge is implemented for smolvm and colima only. Linux backend apps work via the smolvm socket.
The gap: WSL2 → “does not yet implement the WSL exec bridge,” ProvisionedVm
→ “no connector exec bridge” (backend.rs:878-889). Windows
backend-carrying apps are unsolved — a genuine hole, not a rough edge.
Options: (a) add a WSL exec bridge; (b) publish a Windows named-pipe socket contract mirroring d/094. Tradeoff: every new engine widens the socket-custody surface the launcher must own. Decides: reversible arch → orchestrator, but whether Windows-with-backend is in scope now is a Luke/Jan placement call (question 3).
EB-3 — Compose validator holes gate the connector (P-174) — sequencing
Exists: the normative refusal list is enforced install-time and fails closed.
The gap: P-174 (open) documents three pre-existing holes in that list —
short-form host ports (ports: ["8080"]), non-UTF-8 corruption in
interpolate_declared, and network_mode: container:. These matter because
P-174 gates running docker compose up on user-supplied manifests. The
guestbook/compose-board proofs used authored manifests; a third-party manifest
is a different trust posture.
Options: (a) dispatch P-174 to close the holes before P-210 (Immich / whole-origin, which runs a third-party compose); (b) accept the holes as known-and-bounded for the near term and sequence P-210 first. This is a sequencing question, not a rendering one. Decides: Fable to dispatch; confirm sequencing with Luke (question 2). Recommendation: P-174 before the connector meets an unauthored manifest.
EB-4 — GPU / ML backend class collides with the isolation subset
Exists: nothing — there is no GPU passthrough in any backend.
The gap: the safe-compose subset forbids exactly what GPU passthrough
needs — raw devices: and privileged are both on the refusal list
(compose.rs:918, 924). Immich dropped its ML service to install at all
(the honest P-207 stop). So a GPU-bearing backend collides head-on with the
isolation validator.
Options: (a) a narrow, separately-consented device-grant carve-out; (b) route ML backends to a dedicated GPU placement outside the container subset. Tradeoff: any device access punctures the compose-subset trust boundary. Decides: Luke — this is litmus / security-touching, not an orchestrator call (question 1).
EB-5 — Resource limits are declared, not enforced
Exists: the XAM ResourceEnvelope (request / minimum / breach) is validated
at install (request ≥ required_minimum).
The gap: the compose adapter sets ResourceEnvelope::default() for every
compose component (compose.rs:1237) and does not map deploy.resources.limits
(which compose-board/compose.yaml declares) into the envelope or into
container cgroups. The envelope is advisory, not runtime-enforced.
Options: map deploy limits → envelope → engine --memory / --cpus.
Decides: orchestrator + a small spec addition.
EB-6 — Documentation staleness (a documentation-program finding)
Exists: docs/serving-and-placement-design.md describes the serving model.
The gap: it is stale. Sections :29, :58-72 still describe
backend-proxy as “dormant / fail-closed end to end … no current launcher
listener owns 127.0.0.1:5199.” That predates P-203; the code at HEAD
contradicts every clause (the connector does bind :5199, the exec bridge
is live). A reader trusting that doc would conclude the opposite of the truth.
Options: (a) refresh the in-repo doc; (b) supersede it with this documentation site as the live truth and mark the old doc historical. Decides: Fable (question 4).
Sovereignty litmus check
| Litmus | Engines/backends verdict |
|---|---|
| Inspect what it sees | Strong. Compose diagnostics name source:line:col; the connector resolves everything from inspectable registry state; failure modes map to honest HTTP status. |
| Fork permissions | Holds. The safe-compose subset is a declared, enforced boundary; device/privilege escalations are refused with stable codes. |
| BYO models + keys | Partial / open. No GPU/ML backend class yet (EB-4) — a BYO local-model backend cannot run inside the current subset without a Luke ruling. |
| Movable memory | Mostly. Named volumes survive stop; update snapshots are digest-verified XAA archives; rollback restores volumes. |
| Auditable actions | Holds. Consent requests are inert-until-decided records; the runtime choke point (runtime.rs:138) leaves no ungated path. |
| Exit without loss | Partial. Volume survival + XAA export are strong; the update user loop that would let you act on an update or roll back is unwired (EB-1). |
The engine layer’s isolation and honesty are its strongest sovereignty assets. The two open edges both touch capability the subset forbids: local ML/GPU (EB-4) and Windows placement (EB-2).
Questions for the Luke + Jan session
- GPU / ML class (EB-4). The isolation subset forbids
devices:+privileged, which GPU passthrough needs. Do we design a narrow, separately-consented device-grant carve-out, or keep ML backends off the container subset entirely? (Luke — litmus) - P-174 before the connector meets real apps (EB-3). The safe-compose validator has three known holes; P-174 gates running compose on user-supplied manifests. Dispatch P-174 before Immich / P-210? (Fable to dispatch; confirm sequencing)
- Windows backend engine (EB-2). No exec bridge for WSL2; backend-carrying apps cannot run on Windows. Is Windows-with-backend in scope now, or explicitly deferred? (Luke / Jan — placement)
- Doc hygiene (EB-6).
serving-and-placement-design.mdis stale (callsbackend-proxy“dormant”; contradicted by shipped P-203). Refresh in-repo, or supersede it with this documentation site as the live truth? (Fable)