feat(smolmachines): run backend on Linux #284

Open
didericis-claude wants to merge 2 commits from prd-smolmachines-linux into main
Collaborator

Closes #283.

PRD: prd-new-smolmachines-linux.md

Summary

Makes the smolmachines backend runnable on Linux (KVM), not just macOS. smolvm/libkrun already support Linux via /dev/kvm; the gap was entirely in bot-bottle's host-side glue, which hard-coded macOS assumptions. Three fixes:

  • KVM preflight. On Linux, smolmachines_preflight now checks /dev/kvm is present and accessible, distinguishing "KVM not enabled" (load kvm-intel/kvm-amd) from "no permission" (join the kvm group). macOS is unaffected.
  • Fail-closed TSI enforcement. force_allowlist previously no-oped on Linux, failing open — the agent VM's egress allowlist was never enforced. It now runs on both platforms, derives the smolvm state-DB path per-OS (XDG on Linux), only patches when the persisted allowlist doesn't already match, and dies rather than booting a VM whose /32 confinement it can't confirm (DB missing, row missing, or patch didn't take). This is a strict improvement on macOS too (the old code wrote unconditionally and never verified).
  • Per-bottle loopback scoping on Linux. allocate returned the shared 127.0.0.1 on Linux (no isolation between bottles/host services). It now does the same per-bottle 127.0.0.<N>/32 allocation as macOS — and since all of 127.0.0.0/8 is already loopback on Linux, this needs no ifconfig/sudo step. Only ensure_pool's lo0 aliasing stays macOS-only.

README gains a Linux + NixOS host-setup section.

Testing

  • Unit suite green (1263 tests), including new coverage for the KVM preflight branches, fail-closed force_allowlist (DB/row missing, patch-doesn't-take, skip-when-matching), per-bottle Linux allocation + locking, and the platform-derived DB path. pyright clean; pylint 9.69/10.

Pending verification (cannot run on the macOS dev box)

The author worked on macOS (darwin, no /dev/kvm), so the Linux/KVM acceptance gate could not be executed here. Before merge, the following need to run on a NixOS/Linux host with /dev/kvm:

  • PRD 0022's tests/integration/test_sandbox_escape.py against BOT_BOTTLE_BACKEND=smolmachines (the security acceptance gate).
  • Confirm the Linux smolvm state-DB path/schema matches the inferred ~/.local/share/smolvm/server/smolvm.db (if not, the fail-closed check turns it into a clear launch-time error, not a silent escape).
  • Confirm whether the current Linux smolvm build still drops --allow-cidr with --from (the fail-closed design handles either answer).

See the PRD's "Open questions / verification pending" section for detail.

Closes #283. PRD: [prd-new-smolmachines-linux.md](https://gitea.dideric.is/didericis/bot-bottle/src/branch/prd-smolmachines-linux/docs/prds/prd-new-smolmachines-linux.md) ## Summary Makes the `smolmachines` backend runnable on Linux (KVM), not just macOS. `smolvm`/libkrun already support Linux via `/dev/kvm`; the gap was entirely in bot-bottle's host-side glue, which hard-coded macOS assumptions. Three fixes: - **KVM preflight.** On Linux, `smolmachines_preflight` now checks `/dev/kvm` is present and accessible, distinguishing "KVM not enabled" (load `kvm-intel`/`kvm-amd`) from "no permission" (join the `kvm` group). macOS is unaffected. - **Fail-closed TSI enforcement.** `force_allowlist` previously **no-oped on Linux, failing _open_** — the agent VM's egress allowlist was never enforced. It now runs on both platforms, derives the smolvm state-DB path per-OS (XDG on Linux), only patches when the persisted allowlist doesn't already match, and **dies rather than booting a VM whose `/32` confinement it can't confirm** (DB missing, row missing, or patch didn't take). This is a strict improvement on macOS too (the old code wrote unconditionally and never verified). - **Per-bottle loopback scoping on Linux.** `allocate` returned the shared `127.0.0.1` on Linux (no isolation between bottles/host services). It now does the same per-bottle `127.0.0.<N>/32` allocation as macOS — and since all of `127.0.0.0/8` is already loopback on Linux, this needs **no `ifconfig`/sudo step**. Only `ensure_pool`'s `lo0` aliasing stays macOS-only. README gains a Linux + NixOS host-setup section. ## Testing - Unit suite green (1263 tests), including new coverage for the KVM preflight branches, fail-closed `force_allowlist` (DB/row missing, patch-doesn't-take, skip-when-matching), per-bottle Linux allocation + locking, and the platform-derived DB path. `pyright` clean; `pylint` 9.69/10. ## Pending verification (cannot run on the macOS dev box) The author worked on macOS (`darwin`, no `/dev/kvm`), so the Linux/KVM **acceptance gate could not be executed here**. Before merge, the following need to run on a NixOS/Linux host with `/dev/kvm`: - PRD 0022's `tests/integration/test_sandbox_escape.py` against `BOT_BOTTLE_BACKEND=smolmachines` (the security acceptance gate). - Confirm the **Linux smolvm state-DB path/schema** matches the inferred `~/.local/share/smolvm/server/smolvm.db` (if not, the fail-closed check turns it into a clear launch-time error, not a silent escape). - Confirm whether the current Linux `smolvm` build still drops `--allow-cidr` with `--from` (the fail-closed design handles either answer). See the PRD's "Open questions / verification pending" section for detail.
didericis added 2 commits 2026-06-25 17:08:26 -04:00
Design for porting the smolmachines backend off macOS-only: KVM
preflight, platform-aware smolvm state-DB path, fail-closed TSI
allowlist enforcement, and per-bottle loopback scoping on Linux.
NixOS is the primary validation target.

Issue: #283

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NkwFXLFff9PYPy4wgVBJp9
feat(smolmachines): run backend on Linux
lint / lint (push) Failing after 1m52s
test / unit (pull_request) Successful in 45s
test / integration (pull_request) Successful in 17s
49c2ed0b93
Port the smolmachines backend so BOT_BOTTLE_BACKEND=smolmachines
works on Linux (KVM), not just macOS:

- Preflight gates /dev/kvm presence + accessibility on Linux with
  actionable remediation (kvm module, kvm group).
- smolvm state-DB path is platform-derived (XDG on Linux).
- force_allowlist runs on both platforms and is fail-closed: it
  verifies the persisted TSI allowlist and dies rather than booting
  a VM whose egress confinement it can't confirm. Previously it
  no-oped on Linux, failing OPEN.
- allocate() does per-bottle 127.0.0.<N> scoping on Linux too (no
  ifconfig needed — all of 127/8 is already loopback); only
  ensure_pool's lo0 aliasing stays macOS-only.
- README documents Linux + NixOS host setup.

Linux/KVM integration (the sandbox-escape acceptance gate) is
pending verification on a NixOS host; unit tests cover the new
platform branches.

Issue: #283

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NkwFXLFff9PYPy4wgVBJp9
didericis force-pushed prd-smolmachines-linux from a4413406df to 49c2ed0b93 2026-06-25 17:08:26 -04:00 Compare
Some checks are pending
lint / lint (push) Failing after 1m52s
test / unit (pull_request) Successful in 45s
test / integration (pull_request) Successful in 17s
This pull request can be merged automatically.
You are not authorized to merge this pull request.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin prd-smolmachines-linux:prd-smolmachines-linux
git checkout prd-smolmachines-linux
Sign in to join this conversation.