Skip to content

Add sandboxed step executor with VFS-backed I/O#25

Merged
mizchi merged 7 commits intomainfrom
feat/sandbox-executor
Mar 31, 2026
Merged

Add sandboxed step executor with VFS-backed I/O#25
mizchi merged 7 commits intomainfrom
feat/sandbox-executor

Conversation

@mizchi
Copy link
Copy Markdown
Owner

@mizchi mizchi commented Mar 31, 2026

Summary

  • Introduce src/sandbox/ — a target-agnostic sandboxed execution layer with trait Fs for DI
  • Add remove/mkdir/is_dir to VirtualFs for directory semantics
  • Update upload/download-artifact v4 → v5 in release.yml (Node 20 deprecation fix)

Design

The sandbox package defines a trait Fs filesystem abstraction. Callers inject any implementation — no dependency on wasi_runner. Ships with MemFs as the default in-memory implementation.

src/sandbox/
├── fs.mbt                 # trait Fs + parse_key_values utility
├── memfs.mbt              # MemFs: in-memory Fs implementation
├── fs_shell_bridge.mbt    # All targets: &Fs → ShellEnv DI bridge
├── step_executor.mbt      # All targets: sandboxed step execution
├── api_js.mbt             # JS only: binding example (globalThis._actrun_sandbox)
└── *_test.mbt             # 31 tests (MemFs, parse_key_values, bridge, executor)

Builds with any target (--target native/js/wasm/wasm-gc).

Test plan

  • moon test src/sandbox — 31/31 pass
  • moon test --target native — 852/852 pass (no regressions)
  • moon check src/sandbox --target js — JS target compiles OK
  • just build-sandbox — build succeeds

🤖 Generated with Claude Code

mizchi and others added 7 commits March 31, 2026 17:38
Update actions/upload-artifact and actions/download-artifact from v4 to v5.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Extend the in-memory VFS with directory semantics needed by the
ShellEnv bridge: remove deletes a key, mkdir creates a directory
marker, is_dir checks for markers or child-key prefixes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Introduce src/browser/ as a target-agnostic sandbox execution layer:

- vfs_shell_bridge: wires VirtualFs into ShellEnv DI callbacks
- step_executor: runs shell steps entirely in-memory, parses
  GITHUB_OUTPUT/GITHUB_ENV from VFS
- api_js: JS binding example that registers plan/executeShellStep/
  executeWasmStep on globalThis._actrun_browser

The core layer (vfs_shell_bridge + step_executor) builds with any
target (native/js/wasm/wasm-gc). The JS binding demonstrates how to
expose it to a browser environment with pre-compiled WebAssembly.Module
support.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The package is a target-agnostic I/O sandbox layer, not browser-specific.
- BrowserStepResult → StepResult
- register_browser_api → register_api
- globalThis._actrun_browser → globalThis._actrun_sandbox
- justfile: build-browser → build-sandbox

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Introduce trait Fs as the filesystem abstraction for sandbox execution.
Callers inject their own implementation instead of depending on VirtualFs.

- Add Fs trait with fs_write/fs_read/fs_exists/fs_is_dir/fs_mkdir/fs_remove
- Add MemFs as the default in-memory implementation
- Rename vfs_shell_bridge → fs_shell_bridge (accepts &Fs)
- step_executor now takes &Fs parameter
- Remove wasi_runner import from sandbox/moon.pkg
- parse_key_values operates on &Fs instead of VirtualFs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Drop fs_ prefix from Fs trait methods (write/read/exists/is_dir/mkdir/remove)
- Fix duplicate dir_key/prefix computation in MemFs.is_dir and VirtualFs.is_dir
- Merge double JSON match blocks in exec_shell_handler and exec_wasm_handler
- Replace manual to_upper with stdlib String::to_upper()
- Add 16 direct unit tests for MemFs and parse_key_values edge cases

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove TOCTOU exists-before-write in step_executor (write is idempotent)
- Simplify MemFs.remove to single map lookup
- Extract extract_string_map/extract_workdir helpers in api_js
- Remove restating doc comments from fs.mbt, memfs.mbt, fs_shell_bridge.mbt

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@mizchi mizchi merged commit e91c05a into main Mar 31, 2026
6 of 7 checks passed
@mizchi mizchi deleted the feat/sandbox-executor branch March 31, 2026 12:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant