Skip to content

Run the lobster agent 🦞 #2

Merged
tad-20 merged 8 commits into
mainfrom
aniket/picoclaw
Feb 15, 2026
Merged

Run the lobster agent 🦞 #2
tad-20 merged 8 commits into
mainfrom
aniket/picoclaw

Conversation

@aniketmaurya
Copy link
Copy Markdown
Collaborator

@aniketmaurya aniketmaurya commented Feb 15, 2026

This PR enables SmolVM to expose the microVM port to the host and adds example to run OpenClaw

@aniketmaurya aniketmaurya assigned aniketmaurya and unassigned tad-20 Feb 15, 2026
@aniketmaurya aniketmaurya added the enhancement New feature or request label Feb 15, 2026
@aniketmaurya
Copy link
Copy Markdown
Collaborator Author

@codex please review the PR

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 26ee427cfb

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/smolvm/facade.py
Comment thread src/smolvm/network.py Outdated
@tad-20 tad-20 merged commit bd1b3a6 into main Feb 15, 2026
@tad-20 tad-20 deleted the aniket/picoclaw branch February 15, 2026 11:41
aniketmaurya added a commit that referenced this pull request May 5, 2026
…validation fix (#259)

* feat: published-image flow as the default + libkrun stub rows + cache-invalidation fix

Bundles three pending items from the rollout plan:

## 1. Flip ``SMOLVM_USE_PUBLISHED`` default to ON

The published-image fast path (~5–10 s first boot) was opt-in behind
``SMOLVM_USE_PUBLISHED=1`` for the alpha release while we exercised it.
Now that macOS QEMU + Linux Firecracker + Linux QEMU all boot it
end-to-end (PR #258), make it the default. Opt out with
``SMOLVM_USE_PUBLISHED=0`` (or ``false``/``no``).

## 2. Graceful fallback when no manifest entry exists

Only ``openclaw`` has a CI-built rootfs today — codex / claude-code /
hermes don't. With the default flipped on, those presets would fail at
``ensure_published_image`` lookup. New ``is_preset_published(...)`` in
``published.py``; ``_run_start`` checks it before taking the published
path. If the (preset, arch, vmm) tuple isn't in MANIFEST, fall through
to the existing install-at-boot flow. So users of unpublished presets
see the same behavior they had before; only openclaw users get the
fast path automatically.

Also handles the ``_vmm_for_host`` RuntimeError on unsupported hosts:
fall through rather than raising at dispatch time (the install-at-boot
flow has its own platform errors).

## 3. Decompressed-rootfs cache invalidation

The published-image manager downloads the compressed ``.zst`` and
decompresses to a sibling ``.ext4``. The decompression was guarded by
``if not decompressed_path.is_file()`` only — so when the ``.zst``
SHA changed (via a manifest version bump or in-place rootfs republish)
the manager re-downloaded the ``.zst`` but kept serving the stale
``.ext4`` from the previous SHA. Real bug we hit while diagnosing the
openclaw uid bake regression.

Fix: stamp the source ``.zst`` SHA into a sidecar
``rootfs.ext4.from-sha256`` file. Re-decompress whenever the sidecar
is missing or doesn't match the manifest's expected SHA. New regression
test (``test_decompression_reruns_when_zst_sha_changes``) pins this.

## 4. libkrun stub manifest rows

Schema-only addition: two MANIFEST entries for ``(openclaw, amd64,
libkrun)`` and ``(openclaw, arm64, libkrun)``. Reuse the ELF kernel
(libkrun is Firecracker-API-compatible) and the same rootfs as the
firecracker rows on the same arch. The CLI's ``_vmm_for_host()``
doesn't return ``"libkrun"`` until the libkrun runtime spike succeeds,
so the rows are unreachable today — they exist so that spike can be a
one-line plumbing change rather than a manifest migration.

## Test plan

- ``uv run pytest`` — 882 pass (+4 new), 13 skipped
- E2E #1: ``smolvm openclaw start`` (no env) — published path, openclaw
  rootfs from GH Releases, sshd ready
- E2E #2: dispatch test — codex/non-published preset doesn't take the
  published path even when default-on
- E2E #3: ``SMOLVM_USE_PUBLISHED=0 smolvm openclaw start`` — explicitly
  forces install-at-boot path even though manifest has openclaw rows

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* fix(workspace): short-circuit 9p probe via /proc/filesystems for built-in kernel

User hit ``Cannot mount workspaces: guest is missing 9p or overlay
kernel support`` running ``smolvm claude start --mount ./`` on macOS.
Root cause: the SmolVM-built universal kernel has 9p, 9pnet_virtio, and
overlay all =y (no modules), and ships without /lib/modules/$(uname -r).
The facade's probe used ``modprobe`` which always fails ("module not
found") on a kernel with no module-loading machinery, even though the
filesystems are registered and ready to use.

Fix: read /proc/filesystems FIRST. Built-in filesystems show up there
regardless of /lib/modules. If 9p (and overlay if needed) are listed,
short-circuit successfully; otherwise fall through to the existing
modprobe + Ubuntu apt-install repair path.

E2E re-validated: ``smolvm claude start --mount ./`` boots, 9p +
overlay mount cleanly, host files appear at /workspace inside the
guest:

  workspace0 on /mnt/.smolvm-ws-workspace0 type 9p (ro,...)
  overlay on /workspace type overlay (rw,lowerdir=...,upperdir=...)

Tests:
- 3 existing workspace tests updated to mock /proc/filesystems
  WITHOUT 9p so the fall-through path still gets tested.
- 1 new test (test_mount_workspaces_skips_probe_when_filesystems_register_builtin)
  pins the short-circuit: when /proc/filesystems lists 9p+overlay,
  modprobe is NOT called.

Also adds a kernel-runtime compatibility matrix to kernel/qemu/README.md
covering: ELF vs Image format per runtime, what each Kconfig actually
provides for which runtime, and what's deliberately NOT enabled.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* chore: rename kernel/qemu → kernel/microvm

The folder name was a holdover from when this directory housed the
QEMU-specific kernel. Since #258 the build produces ONE artifact pair
that boots all three runtimes (Firecracker, QEMU, libkrun) — "qemu" in
the name is now misleading.

"microvm" is more accurate: this is the in-house microvm kernel,
distinct from a desktop-class kernel we may ship in some future
``kernel/desktop/`` if the need arises.

All seven files moved via ``git mv`` so blame is preserved. Ref
updates:

- ``.github/workflows/build-qemu-kernel.yml`` → ``build-microvm-kernel.yml``
  (workflow name string + path triggers + cache key + step summary)
- ``.github/workflows/smoke-published-images.yml`` ``workflow_run`` trigger
  references the workflow's display name "Build microvm Kernel"
- ``kernel/microvm/build.sh`` self-reference and README
- ``src/smolvm/images/published.py`` BaseKernel docstring + comments
- ``src/smolvm/runtime/boot_profiles.py`` module docstring link

Artifact filenames (``vmlinux-<arch>.elf``, ``vmlinux-<arch>.image``,
``vmlinux-<arch>.config``) are unchanged — they were already
runtime-neutral after #258.

Tests still 883/883. ``SMOLVM_VERIFY_ONLY=1 bash kernel/microvm/build.sh``
passes both archs in the Docker recipe.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* chore: gitignore .claude/ (agent-local state, leaked in 6a3dbd9)

The previous rename commit picked up ``.claude/scheduled_tasks.lock``
via ``git add -A`` — that file is local Claude Code agent state and
shouldn't be in the repo. Remove it from tracking and add ``.claude/``
to ``.gitignore`` so this can't happen again. Other entries under
``.claude/`` (settings.local.json, skills/, worktrees/) are also local.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* review: fix stale README comment, document workflow_run brittleness, test is_preset_published

- kernel/microvm/README.md: build.sh produces .elf + .image, not -qemu.bin
- smoke-published-images.yml: comment that workflows[] matches display name
- tests/test_published_images.py: TestIsPresetPublished covers happy path,
  missing dimensions, unknown presets, empty manifest, and default MANIFEST

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* review-r2: don't ignore explicit --backend; finish stale -qemu.bin sweep

CodeRabbit r2 on PR #259:
- main.py: published path now respects an explicit --backend. Previously,
  `smolvm openclaw start --backend qemu` on Linux silently picked the
  Firecracker published row (since _vmm_for_host()=firecracker on Linux).
  Now falls through to install-at-boot when the requested backend doesn't
  match what the published row would use.
- main.py: en dashes -> hyphens in _published_path_enabled docstring
  (RUF002 — not in our select list, but consistency is cheap).
- microvm/README.md: finish the .elf/.image rename — the smoke-test
  invocation, the `.config` reference, and the naming convention block
  still said `vmlinux-<arch>-qemu.bin`.
- microvm/build.sh: header comment — same rename.
- smoke-published-images.yml: kernel pattern + boot path were still
  `vmlinux-${ARCH}-qemu.bin`; build now ships `.elf`/`.image`. Smoke gate
  would have 404'd. Switch to `.image` (smoke job runs qemu-system-*).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants