Skip to content

feat(driver): microsandbox microVM backend#761

Merged
skevetter merged 5 commits into
mainfrom
feat/microsandbox
Jul 27, 2026
Merged

feat(driver): microsandbox microVM backend#761
skevetter merged 5 commits into
mainfrom
feat/microsandbox

Conversation

@skevetter

@skevetter skevetter commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Adds a microsandbox driver that runs the devcontainer OCI image as a hardware-isolated microVM (libkrun), alongside the docker/podman/kubernetes/apple backends.

Summary

  • New driver under pkg/driver/microsandbox/ behind a narrow sandboxClient port, with the SDK isolated in an adapter so the lifecycle logic is unit tested against a fake.
  • Full up lifecycle: build (docker → load into runtime for feature/Dockerfile/compose devcontainers), run, exec, ssh, stop/start/restart, delete, --recreate.
  • Image acquisition: local docker images loaded via docker save | msb load; registry images pulled directly, falling back to an in-process authenticated pull (go-containerregistry with Devsy's keychain) that needs no docker CLI.
  • Agent delivery streams the binary into the guest over the SDK exec (kubernetes-style), with offline support via DEVSY_AGENT_BINARY.
  • Named-volume and tmpfs mounts, idle auto-shutdown, resource ceilings, and egress hardening are wired; unsupported container-runtime options are warned and ignored.
  • Provider (providers/microsandbox/provider.yaml), driver registration, unit tests, a build-tagged integration test, and an up-provider-microsandbox e2e label + CI matrix entry.

Scope / notes

  • Verified on macOS/arm64; CI covers Linux/KVM. Windows/WHP is out of scope.
  • Draft: private-registry auth uses Devsy's existing keychain (mechanism verified end to end; a specific credentialed registry check is environment-bound).

Summary by CodeRabbit

  • New Features
    • Added the Microsandbox provider for hardware-isolated microVM development environments, including new provider preset and icon recognition.
    • Added Microsandbox configuration for resource sizing, ephemeral storage, and optional network egress blocking.
    • Added support for executing in Microsandbox environments and streaming command output.
    • Added an environment option to use a locally provided agent binary instead of downloading.
  • Testing
    • Added new e2e and integration coverage for Microsandbox lifecycle and connectivity, plus CI provider setup for Linux Microsandbox runs.

@netlify

netlify Bot commented Jul 26, 2026

Copy link
Copy Markdown

Deploy Preview for devsydev canceled.

Name Link
🔨 Latest commit f29aa41
🔍 Latest deploy log https://app.netlify.com/projects/devsydev/deploys/6a66ca619ea6aa00085b0c0f

@coderabbitai

coderabbitai Bot commented Jul 26, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@skevetter, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 30 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 1430b09c-7906-4c5d-9653-9335ffddb89f

📥 Commits

Reviewing files that changed from the base of the PR and between d20691e and f29aa41.

⛔ Files ignored due to path filters (1)
  • desktop/src/renderer/public/icons/providers/microsandbox.svg is excluded by !**/*.svg
📒 Files selected for processing (27)
  • .github/workflows/pr-ci.yml
  • desktop/src/renderer/src/lib/components/provider/ProviderIcon.svelte
  • desktop/src/renderer/src/lib/components/provider/ProviderWizard.svelte
  • e2e/tests/up/provider_microsandbox.go
  • e2e/tests/up/testdata/microsandbox/.devcontainer.json
  • e2e/tests/up/up_behaviors.go
  • pkg/agent/binary.go
  • pkg/agent/binary_env_test.go
  • pkg/agent/delivery/factory.go
  • pkg/agent/delivery/factory_test.go
  • pkg/config/env.go
  • pkg/credentials/server.go
  • pkg/driver/drivercreate/create.go
  • pkg/driver/microsandbox/cliclient.go
  • pkg/driver/microsandbox/cliclient_test.go
  • pkg/driver/microsandbox/client.go
  • pkg/driver/microsandbox/integration_test.go
  • pkg/driver/microsandbox/microsandbox.go
  • pkg/driver/microsandbox/microsandbox_test.go
  • pkg/gitsshsigning/helper.go
  • pkg/options/resolve.go
  • pkg/options/resolve_test.go
  • pkg/provider/parse.go
  • pkg/provider/provider.go
  • providers/microsandbox/provider.yaml
  • providers/providers.go
  • providers/providers_test.go
📝 Walkthrough

Walkthrough

Adds microsandbox as a provider with configuration, a CLI-backed microVM driver, agent delivery and binary overrides, desktop provider entries, CI installation, credentials readiness, and unit, integration, and end-to-end tests.

Changes

Microsandbox provider

Layer / File(s) Summary
Provider contracts and registration
pkg/provider/*, providers/microsandbox/provider.yaml, providers/providers.go, pkg/options/*, pkg/driver/drivercreate/create.go
Defines microsandbox configuration, resolves and validates its options, embeds the provider definition, and selects the driver.
Microsandbox CLI runtime
pkg/driver/microsandbox/client.go, pkg/driver/microsandbox/cliclient.go
Adds sandbox contracts and msb operations for images, lifecycle, volumes, execution, logging, and resources.
Microsandbox driver orchestration
pkg/driver/microsandbox/microsandbox.go, pkg/driver/microsandbox/microsandbox_test.go
Maps workspace options into microVM specs and implements execution, lifecycle, image, architecture, GPU, mount, and cleanup behavior with unit coverage.
Agent delivery and validation integration
pkg/agent/*, pkg/config/env.go, pkg/credentials/server.go, .github/workflows/pr-ci.yml, desktop/src/renderer/src/lib/components/provider/*, e2e/tests/up/*, pkg/driver/microsandbox/integration_test.go
Adds local agent binary sourcing, microsandbox delivery routing, provider UI entries, CI installation, readiness handling, and runtime lifecycle tests.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 5.63% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: adding a microsandbox microVM driver backend.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@netlify

netlify Bot commented Jul 26, 2026

Copy link
Copy Markdown

Deploy Preview for images-devsy-sh canceled.

Name Link
🔨 Latest commit f29aa41
🔍 Latest deploy log https://app.netlify.com/projects/images-devsy-sh/deploys/6a66ca61053bd200074e7d38

@skevetter
skevetter force-pushed the feat/microsandbox branch 5 times, most recently from 43f56a4 to 1375ea9 Compare July 26, 2026 18:45
@skevetter
skevetter marked this pull request as ready for review July 27, 2026 01:18

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 7

🧹 Nitpick comments (1)
pkg/agent/delivery/factory_test.go (1)

172-182: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Missing coverage for the microsandbox stream-delivery (PodExec set) branch.

The new test only covers the opts.PodExec == nil fallback to LegacyShellDelivery. The new provider.MicrosandboxDriver branch in factory.go also has a stream-delivery path (return &KubernetesDelivery{Exec: opts.PodExec} when PodExec is set) that isn't directly exercised by a test in the shown range.

func TestNewAgentDelivery_MicrosandboxUsesStreamDelivery(t *testing.T) {
	opts := FactoryOptions{
		WorkspaceConfig: &provider.AgentWorkspaceInfo{
			Agent: provider.ProviderAgentConfig{Driver: provider.MicrosandboxDriver},
		},
		PodExec: func(context.Context, string, []string, driver.Streams) error { return nil },
	}
	d := NewAgentDelivery(opts)
	if _, ok := d.(*KubernetesDelivery); !ok {
		t.Fatalf("microsandbox driver with PodExec set must use stream delivery, got %T", d)
	}
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/agent/delivery/factory_test.go` around lines 172 - 182, Add a test
covering the PodExec-configured branch of NewAgentDelivery for
provider.MicrosandboxDriver. Create FactoryOptions with a non-nil PodExec
callback, invoke NewAgentDelivery, and assert the result is a
*KubernetesDelivery, while preserving the existing nil-PodExec
LegacyShellDelivery test.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/pr-ci.yml:
- Around line 583-589: Update the Linux microsandbox installation step in the
“Install microsandbox (Linux)” workflow block to download a specific versioned
installer artifact instead of piping mutable remote content directly to sh, then
verify its published SHA-256 checksum or signature before executing it. Keep the
existing PATH setup and msb doctor invocation unchanged.

In `@e2e/tests/up/provider_microsandbox.go`:
- Around line 23-26: Update the Linux KVM guard in the runtime OS check to
validate usable access rather than only /dev/kvm existence: attempt to open
/dev/kvm with read/write access, skip with the existing microsandbox message
when opening fails, and close the handle on success before continuing.

In `@pkg/driver/microsandbox/cliclient.go`:
- Around line 208-217: Update msbRun to stop including raw runtime arguments in
returned errors, since createArgs may contain secret values in --env options.
Report the operation while redacting option values, preserving the command
output and underlying error details; use the existing msbRun and createArgs flow
without exposing joined args.
- Around line 250-254: Update the error path in the save/load flow around
save.Run and load.Wait: when save.Run fails, terminate the already-started load
process and call load.Wait() before returning the docker save error. Preserve
the existing error message and normal load.Wait handling for successful saves.
- Around line 61-67: Update cliClient.Find so only an inspect result that
clearly indicates the sandbox is absent returns nil, nil. For cancellation,
permission, execution, or other CommandContext/Output failures, return a wrapped
error instead, preserving the original error for diagnostics and preventing
callers such as DeleteDevContainer and RunDevContainer from treating the sandbox
as absent.

In `@pkg/driver/microsandbox/microsandbox.go`:
- Around line 360-396: Update warnUnsupportedOptions to detect configured
MountTypeBind entries and include a bind-mount warning alongside the existing
ignored options. Preserve volumeMounts behavior and ensure the warning is
emitted only when at least one bind mount is actually present.

In `@providers/microsandbox/provider.yaml`:
- Around line 18-25: Validate microsandbox resource-limit environment values
before buildSpec applies runtime defaults. Update the parsing/configuration flow
for MICROSANDBOX_MEMORY, MICROSANDBOX_MAX_MEMORY, MICROSANDBOX_CPUS, and
MICROSANDBOX_MAX_CPUS so invalid, overflowing, or non-positive values are
rejected rather than converted to 0; preserve empty values as the
runtime-default case, especially ensuring CPU options never treat 0 as valid.

---

Nitpick comments:
In `@pkg/agent/delivery/factory_test.go`:
- Around line 172-182: Add a test covering the PodExec-configured branch of
NewAgentDelivery for provider.MicrosandboxDriver. Create FactoryOptions with a
non-nil PodExec callback, invoke NewAgentDelivery, and assert the result is a
*KubernetesDelivery, while preserving the existing nil-PodExec
LegacyShellDelivery test.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 7840688b-ff67-460d-b51c-78d32a2e0901

📥 Commits

Reviewing files that changed from the base of the PR and between 40594c0 and 1375ea9.

⛔ Files ignored due to path filters (1)
  • desktop/src/renderer/public/icons/providers/microsandbox.svg is excluded by !**/*.svg
📒 Files selected for processing (24)
  • .github/workflows/pr-ci.yml
  • desktop/src/renderer/src/lib/components/provider/ProviderIcon.svelte
  • desktop/src/renderer/src/lib/components/provider/ProviderWizard.svelte
  • e2e/tests/up/provider_microsandbox.go
  • e2e/tests/up/testdata/microsandbox/.devcontainer.json
  • e2e/tests/up/up_behaviors.go
  • pkg/agent/binary.go
  • pkg/agent/binary_env_test.go
  • pkg/agent/delivery/factory.go
  • pkg/agent/delivery/factory_test.go
  • pkg/config/env.go
  • pkg/driver/drivercreate/create.go
  • pkg/driver/microsandbox/cliclient.go
  • pkg/driver/microsandbox/client.go
  • pkg/driver/microsandbox/integration_test.go
  • pkg/driver/microsandbox/microsandbox.go
  • pkg/driver/microsandbox/microsandbox_test.go
  • pkg/options/resolve.go
  • pkg/options/resolve_test.go
  • pkg/provider/parse.go
  • pkg/provider/provider.go
  • providers/microsandbox/provider.yaml
  • providers/providers.go
  • providers/providers_test.go

Comment thread e2e/tests/up/provider_microsandbox.go
Comment thread pkg/driver/microsandbox/cliclient.go
Comment thread pkg/driver/microsandbox/cliclient.go
Comment thread pkg/driver/microsandbox/cliclient.go
Comment thread pkg/driver/microsandbox/microsandbox.go
Comment on lines +18 to +25
MICROSANDBOX_MEMORY:
description: "Guest memory limit in MiB. Empty uses the runtime default."
MICROSANDBOX_CPUS:
description: "Number of virtual CPUs. Empty uses the runtime default."
MICROSANDBOX_MAX_MEMORY:
description: "Hotplug memory ceiling in MiB. Empty uses the runtime default."
MICROSANDBOX_MAX_CPUS:
description: "Hotplug CPU ceiling. Empty uses the runtime default."

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

ast-grep outline pkg/driver/microsandbox/microsandbox.go --items all
rg -n -C3 'func parseUint(32|8)|parseUint(32|8)\(' pkg/driver/microsandbox
rg -n -C3 'type: (number|integer)|MICROSANDBOX_(MEMORY|CPUS|MAX_MEMORY|MAX_CPUS)' providers pkg

Repository: devsy-org/devsy

Length of output: 10133


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '--- microsandbox.go relevant sections ---\n'
sed -n '260,380p' pkg/driver/microsandbox/microsandbox.go
printf '\n--- parse functions implementation ---\n'
sed -n '430,476p' pkg/driver/microsandbox/microsandbox.go
printf '\n--- provider schema relevant section ---\n'
sed -n '1,60p' providers/microsandbox/provider.yaml
printf '\n--- option declarations in package files ---\n'
rg -n -C2 'type (Number|Integer|Integer64|Bool|String|Float) option|Type: (Number|Integer|Integer64|Bool|String|Float)|MICROSANDBOX_(MEMORY|CPUS|MAX_MEMORY|MAX_CPUS)' pkg providers -g '*.go' -g '*.yaml' -g '*.yml'
printf '\n--- parser behavioral probe via Go source text (for overflow cases only) ---\n'
python3 - <<'PY'
from pathlib import Path
src = Path('pkg/driver/microsandbox/microsandbox.go').read_text()
print('parseUint32 returns 0 on strconv.ParseUint error:', 'if err != nil {\n\t\treturn 0\n\t}' in src)
print(src.split('func parseUint32(s string) uint32 {')[1].split('\n}')[0])
print('parseUint8 returns 0 on strconv.ParseUint error:', 'if err != nil {\n\t\treturn 0\n\t}' in src)
print(src.split('func parseUint8(s string) uint8 {')[1].split('\n}')[0])
PY

Repository: devsy-org/devsy

Length of output: 244


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- microsandbox.go relevant sections ---'
sed -n '260,380p' pkg/driver/microsandbox/microsandbox.go
printf '%s\n' ''
printf '%s\n' '--- parse functions implementation ---'
sed -n '430,476p' pkg/driver/microsandbox/microsandbox.go
printf '%s\n' ''
printf '%s\n' '--- runner option values if any ---'
rg -n -C2 'Micropsandbox|Microsandbox|memory:|cpus:|maxMemory:|maxCpus:' pkg/driver/microsandbox pkg/devcontainer pkg/provider pkg/config providers/microsandbox/provider.yaml

printf '%s\n' ''
printf '%s\n' '--- schema options declarations ---'
rg -n -C2 'type (Number|Integer|Integer64|Uint|Bool|String|Float) option|Type: (Number|Integer|Integer64|Bool|String|Float)|MICROSANDBOX_(MEMORY|CPUS|MAX_MEMORY|MAX_CPUS)' pkg providers -g '*.go' -g '*.yaml' -g '*.yml'

printf '%s\n' ''
python3 - <<'PY'
from pathlib import Path
src = Path('pkg/driver/microsandbox/microsandbox.go').read_text()
print(src[src.index('func parseUint32(s string) uint32 {'):src.index(')', src.index('func parseUint32(s string) uint32 {'))+1])
print('\ncontains parseUint32 overflow/error-zero branch:', 'if err != nil {' in src[src.index('func parseUint32(s string) uint32 {'):src.index('func parseUint8(s string) uint8 {')])
PY

Repository: devsy-org/devsy

Length of output: 19017


Validate microsandbox resource limits before creating the microVM.

MICROSANDBOX_MEMORY, MAX_MEMORY are parsed by parseUint32, while MICROSANDBOX_CPUS and MAX_CPUS are parsed by parseUint8; any invalid or overflowing value logs a warning and falls back to 0, so buildSpec then uses the runtime default. Add positive numeric validation before applying these defaults, at least for CPU options where 0 is not semantic.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@providers/microsandbox/provider.yaml` around lines 18 - 25, Validate
microsandbox resource-limit environment values before buildSpec applies runtime
defaults. Update the parsing/configuration flow for MICROSANDBOX_MEMORY,
MICROSANDBOX_MAX_MEMORY, MICROSANDBOX_CPUS, and MICROSANDBOX_MAX_CPUS so
invalid, overflowing, or non-positive values are rejected rather than converted
to 0; preserve empty values as the runtime-default case, especially ensuring CPU
options never treat 0 as valid.

@skevetter
skevetter marked this pull request as draft July 27, 2026 01:27
@skevetter
skevetter force-pushed the feat/microsandbox branch from 1375ea9 to 9dfe844 Compare July 27, 2026 01:33
@skevetter
skevetter marked this pull request as ready for review July 27, 2026 02:07

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (1)
pkg/driver/microsandbox/cliclient.go (1)

61-91: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Still masks non-“absent” inspect failures as “not found.”

The added ctx.Err() check only carves out cancellation; every other Output() failure (permission errors, msb crashes, malformed invocations, transient runtime faults) still falls through to return nil, nil. DeleteDevContainer/RunDevContainer will treat these as "sandbox absent" and proceed incorrectly. exec.Cmd.Output() populates *exec.ExitError.Stderr, which isn't being inspected — only a specific, verified "not found" signal from msb inspect should map to nil, nil; everything else should be wrapped.

🐛 Proposed fix
+	"errors"
 	...
 func (cliClient) Find(ctx context.Context, sandbox string) (*sandboxInfo, error) {
 	// `#nosec` G204 -- args are a resolved binary path and a derived sandbox name
 	out, err := exec.CommandContext(ctx, msbBinary(), "inspect", sandbox, "--format", "json").
 		Output()
 	if err != nil {
-		// inspect fails when the sandbox is absent, which is not an error here.
-		// A cancelled/timed-out context is, so do not mask it as "not found".
 		if ctx.Err() != nil {
 			return nil, fmt.Errorf("inspect microsandbox VM %q: %w", sandbox, ctx.Err())
 		}
-		return nil, nil
+		var exitErr *exec.ExitError
+		if errors.As(err, &exitErr) && looksLikeSandboxAbsent(string(exitErr.Stderr)) {
+			return nil, nil
+		}
+		return nil, fmt.Errorf("inspect microsandbox VM %q: %s: %w", sandbox, exitErr.Stderr, err)
 	}

Needs verification of the actual msb inspect "not found" wording before implementing looksLikeSandboxAbsent.

#!/bin/bash
# Look for any documented/tested msb inspect "not found" wording in-repo.
rg -n "not found|no such sandbox|does not exist|no sandbox" pkg/driver/microsandbox -S
rg -n "msb inspect|inspect.*--format" pkg/driver/microsandbox -S
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/driver/microsandbox/cliclient.go` around lines 61 - 91, Update
cliClient.Find so only a verified microsandbox “not found” inspect result
returns nil, nil; inspect failures such as permission errors, crashes, invalid
invocations, and transient faults must be wrapped and returned. Inspect
exec.ExitError.Stderr (alongside the exit result) via a
looksLikeSandboxAbsent-style check, first confirming the exact not-found wording
from repository documentation or tests, while preserving the existing
context-cancellation handling and successful JSON parsing.
🧹 Nitpick comments (1)
pkg/driver/microsandbox/cliclient.go (1)

145-241: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add unit tests for the pure arg-building helpers.

createArgs, runtimeArgs, resourceArgs, mountArgs, namedVolumes, and redactArgs are pure functions with no CLI dependency, but this package's tests (per microsandbox_test.go) exercise the driver through a fake sandboxClient, bypassing cliclient.go entirely. Direct unit tests here would cheaply cover the argument construction and the env-redaction logic without needing the msb binary.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/driver/microsandbox/cliclient.go` around lines 145 - 241, Add direct unit
tests for the pure helpers createArgs, runtimeArgs, resourceArgs, mountArgs,
namedVolumes, and redactArgs in cliclient.go. Cover representative populated and
empty specs, mount and named-volume handling, resource/runtime flags, argument
ordering, and redactArgs masking --env values while preserving non-secret
arguments; avoid routing tests through the fake sandboxClient or requiring the
msb binary.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/pr-ci.yml:
- Around line 609-615: Update the “Install microsandbox (Linux)” workflow step
to make msb available on the root sudo execution path by installing or
symlinking the downloaded binary into /usr/local/bin after the existing
installer runs. Keep the current GITHUB_PATH update and doctor check unchanged.

In `@pkg/driver/microsandbox/cliclient.go`:
- Around line 134-143: Tighten the existing-volume handling in ensureVolumes so
only a confirmed msb “volume already exists” condition is ignored. Replace the
broad lowercase output substring check with msb-specific wording, exit-code, or
error-type matching, or verify presence via msb volume list before creation;
return errors for all other create failures.

---

Duplicate comments:
In `@pkg/driver/microsandbox/cliclient.go`:
- Around line 61-91: Update cliClient.Find so only a verified microsandbox “not
found” inspect result returns nil, nil; inspect failures such as permission
errors, crashes, invalid invocations, and transient faults must be wrapped and
returned. Inspect exec.ExitError.Stderr (alongside the exit result) via a
looksLikeSandboxAbsent-style check, first confirming the exact not-found wording
from repository documentation or tests, while preserving the existing
context-cancellation handling and successful JSON parsing.

---

Nitpick comments:
In `@pkg/driver/microsandbox/cliclient.go`:
- Around line 145-241: Add direct unit tests for the pure helpers createArgs,
runtimeArgs, resourceArgs, mountArgs, namedVolumes, and redactArgs in
cliclient.go. Cover representative populated and empty specs, mount and
named-volume handling, resource/runtime flags, argument ordering, and redactArgs
masking --env values while preserving non-secret arguments; avoid routing tests
through the fake sandboxClient or requiring the msb binary.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: d88db097-f10f-4299-a79a-17173ff3c578

📥 Commits

Reviewing files that changed from the base of the PR and between 1375ea9 and d20691e.

⛔ Files ignored due to path filters (1)
  • desktop/src/renderer/public/icons/providers/microsandbox.svg is excluded by !**/*.svg
📒 Files selected for processing (25)
  • .github/workflows/pr-ci.yml
  • desktop/src/renderer/src/lib/components/provider/ProviderIcon.svelte
  • desktop/src/renderer/src/lib/components/provider/ProviderWizard.svelte
  • e2e/tests/up/provider_microsandbox.go
  • e2e/tests/up/testdata/microsandbox/.devcontainer.json
  • e2e/tests/up/up_behaviors.go
  • pkg/agent/binary.go
  • pkg/agent/binary_env_test.go
  • pkg/agent/delivery/factory.go
  • pkg/agent/delivery/factory_test.go
  • pkg/config/env.go
  • pkg/credentials/server.go
  • pkg/driver/drivercreate/create.go
  • pkg/driver/microsandbox/cliclient.go
  • pkg/driver/microsandbox/client.go
  • pkg/driver/microsandbox/integration_test.go
  • pkg/driver/microsandbox/microsandbox.go
  • pkg/driver/microsandbox/microsandbox_test.go
  • pkg/options/resolve.go
  • pkg/options/resolve_test.go
  • pkg/provider/parse.go
  • pkg/provider/provider.go
  • providers/microsandbox/provider.yaml
  • providers/providers.go
  • providers/providers_test.go
🚧 Files skipped from review as they are similar to previous changes (20)
  • providers/providers_test.go
  • providers/microsandbox/provider.yaml
  • providers/providers.go
  • pkg/driver/microsandbox/client.go
  • e2e/tests/up/testdata/microsandbox/.devcontainer.json
  • desktop/src/renderer/src/lib/components/provider/ProviderIcon.svelte
  • pkg/agent/delivery/factory.go
  • pkg/driver/drivercreate/create.go
  • pkg/agent/binary_env_test.go
  • e2e/tests/up/up_behaviors.go
  • pkg/options/resolve_test.go
  • pkg/config/env.go
  • pkg/options/resolve.go
  • desktop/src/renderer/src/lib/components/provider/ProviderWizard.svelte
  • e2e/tests/up/provider_microsandbox.go
  • pkg/provider/parse.go
  • pkg/driver/microsandbox/integration_test.go
  • pkg/provider/provider.go
  • pkg/agent/binary.go
  • pkg/driver/microsandbox/microsandbox_test.go

Comment on lines +609 to +615
- name: Install microsandbox (Linux)
if: matrix.install-microsandbox == true && runner.os == 'Linux'
run: |
curl -fsSL https://install.microsandbox.dev | sh
echo "$HOME/.local/bin" >> "$GITHUB_PATH"
# The e2e test skips gracefully if KVM is unavailable on the runner.
"$HOME/.local/bin/msb" doctor || true

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Install msb on the root execution path.

The Linux tests run through sudo (Line 644), whose secure PATH excludes $HOME/.local/bin; the microsandbox driver in the root-run e2e process will therefore fail to locate msb. Install or symlink it into /usr/local/bin after installation.

Proposed fix
           curl -fsSL https://install.microsandbox.dev | sh
-          echo "$HOME/.local/bin" >> "$GITHUB_PATH"
+          sudo ln -sf "$HOME/.local/bin/msb" /usr/local/bin/msb
           # The e2e test skips gracefully if KVM is unavailable on the runner.
-          "$HOME/.local/bin/msb" doctor || true
+          /usr/local/bin/msb doctor || true
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- name: Install microsandbox (Linux)
if: matrix.install-microsandbox == true && runner.os == 'Linux'
run: |
curl -fsSL https://install.microsandbox.dev | sh
echo "$HOME/.local/bin" >> "$GITHUB_PATH"
# The e2e test skips gracefully if KVM is unavailable on the runner.
"$HOME/.local/bin/msb" doctor || true
- name: Install microsandbox (Linux)
if: matrix.install-microsandbox == true && runner.os == 'Linux'
run: |
curl -fsSL https://install.microsandbox.dev | sh
sudo ln -sf "$HOME/.local/bin/msb" /usr/local/bin/msb
# The e2e test skips gracefully if KVM is unavailable on the runner.
/usr/local/bin/msb doctor || true
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/pr-ci.yml around lines 609 - 615, Update the “Install
microsandbox (Linux)” workflow step to make msb available on the root sudo
execution path by installing or symlinking the downloaded binary into
/usr/local/bin after the existing installer runs. Keep the current GITHUB_PATH
update and doctor check unchanged.

Comment thread pkg/driver/microsandbox/cliclient.go
Add a "microsandbox" backend that boots the devcontainer OCI image as a
hardware-isolated microVM (libkrun) via the microsandbox runtime, wired
through Devsy's driver/provider system.

- New pkg/driver/microsandbox driver behind a narrow sandboxClient port
  (SDK isolated in one adapter; lifecycle logic unit tested with a fake).
- Full up/exec/ssh/stop/restart/delete lifecycle; image-only devcontainers
  boot directly, built devcontainers build with docker then load into the
  runtime; authenticated registry pulls via go-containerregistry.
- Named-volume/tmpfs mounts, idle-shutdown, resource ceilings, egress
  hardening, GPU host-requirement handling, cross-arch/name-length guards.
- Offline agent delivery via DEVSY_AGENT_BINARY; provider.yaml + provider
  registration; desktop UI provider entry with a VM icon; e2e test and CI
  matrix entry (Linux/KVM, macOS Apple silicon).
The #765 handler refactor switched unmatched paths from an implicit 200
(the old switch had no default) to http.NotFound. The readiness probe in
waitForServer hits the root path, so startup detection began failing with
404 and git/docker credential forwarding was silently skipped for every
driver ("credentials server did not start in time"). Add an explicit root
route that returns 200 while keeping 404 for unknown credential endpoints.
Address review feedback:
- Find now surfaces real inspect failures (permission, crash, bad
  invocation) instead of masking every error as "sandbox absent"; only a
  verified "sandbox not found" from msb inspect maps to (nil, nil).
- ensureVolumes matches the specific "already exists" wording rather than a
  broad "exist" substring, so genuine volume-create failures are not
  swallowed.
- Add direct unit tests for the pure arg-building and env-redaction helpers.
Reference the shared names package (names.Create, names.Flag(names.Name/
Env/Label/User)) instead of ad-hoc local flag constants; the
microsandbox-specific flags without a shared name stay as literals.
#765's refactor widened the per-line trim from "\n" to "\r\n", so removing
the SSH-signing section from a CRLF-authored gitconfig rewrote every line to
LF. Trim only the LF to leave untouched lines' endings intact.
@skevetter
skevetter force-pushed the feat/microsandbox branch from 5650eb8 to f29aa41 Compare July 27, 2026 03:02
@skevetter
skevetter enabled auto-merge (squash) July 27, 2026 03:44
@skevetter
skevetter merged commit fca71ca into main Jul 27, 2026
68 checks passed
@skevetter
skevetter deleted the feat/microsandbox branch July 27, 2026 03:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant