Changelog
All notable changes to the quicksand project will be documented in this file.
The format is based on Keep a Changelog.
[v0.9.4] - 2026-04-01
Changed
- quicksand-cua: Reduced overlay image size from ~604 MB to ~445 MB by removing unused Playwright headless shell, Vulkan GPU drivers, and system Node.js
Fixed
- quicksand-core: Virtio-serial agent client now keeps connection open across auth retries. Disconnecting caused QEMU to stop accepting new chardev connections
- quicksand-core: Pin httpx<1.0 to prevent breaking API change
- quicksand-core: Fix
MountSpec→Mountin README exports - ARM64 image wheels built on macOS are now retagged for Linux via uvr post_build hook
- quicksand-alpine, quicksand-ubuntu: Restore editable install guard in build hooks
- quicksand-alpine-desktop, quicksand-ubuntu-desktop: Break up large package install commands to avoid build timeouts
[v0.9.3] - 2026-03-30
Added
- quicksand-cua: noVNC web client (port 6080), websockify, socat, and rsync in the overlay image
Fixed
quicksand run -p HOST:GUESTport forward parsing now works correctly
[v0.9.2] - 2026-03-29
Added
quicksand cleanCLI command to remove local.quicksand/and optionally global~/.quicksand/data directories
[v0.9.0] - 2026-03-26
Added
- Virtio-serial guest agent transport with 25x boot speedup (Alpine p50: 11.5s → 0.45s)
Sandbox.qemu_commandproperty to inspect the QEMU command lineSandbox.boot_timingproperty with phase-level profiling (kernel, init, agent breakdown)BootTimingdataclass with__str__for human-readable boot phase displayquicksand benchmarkCLI command with percentile stats, progress bar, and--jsonoutputquicksand uninstallCLI command to remove installed extras-v/--mountoption on benchmark command for measuring boot with mounts
Changed
- Guest images now use static IP (10.0.2.15/24) instead of DHCP. This eliminates ~8s dhcpcd overhead
- Alpine: enabled
rc_parallel="YES"for parallel OpenRC service startup - Alpine: guest agent moved to
bootrunlevel (fromdefault) - Ubuntu: guest agent moved to
After=sysinit.target(fromAfter=basic.target) - Rust guest agent supports dual transport: virtio-serial first, HTTP fallback
[v0.7.1] - 2026-03-24
Changed
quicksand-alpine-desktopandquicksand-ubuntu-desktopconverted from standalone base images to overlay images built on top of their respective base packages- Desktop image wheels are significantly smaller (Alpine: 359MB → 286MB, Ubuntu: 575MB → 254MB) since they only contain the overlay delta
- Desktop packages now depend on
quicksand-alpine/quicksand-ubunturespectively - Docker is no longer required to build desktop image packages
Removed
- Dockerfiles for desktop image packages (build now uses overlay mechanism)
[v0.7.0] - 2026-03-24
Changed
- Breaking:
ResolvedImage.baseandResolvedImage.overlaysreplaced with unifiedchain: list[Path].chain[0]is the root base qcow2, andchain[1:]are overlay layers in bottom-to-top order - Breaking: Save format bumped to v6. Only session-local overlays are stored. Installed package overlays are resolved by name at load time
ImageProviderprotocol now requires animages_dir: Pathattributeqemu-img convert -cpreserves backing file references (-B) instead of flattening the full chain
Added
quicksand-cuaoverlay package (first release)_verify_overlay_from_package()validates that non-session overlays belong to installed packages at save time
[v0.6.1] - 2026-03-24
Added
SandboxConfig.archparameter for cross-architecture VM builds via TCG emulationquicksand run --archflag for cross-arch boot from the CLIquicksand install --archflag to download cross-platform wheelsquicksand run IMAGEnow takes image as a required positional argument (was-b/--base)- Overlay build phase in release pipeline (
build-overlayjob, runs after base images) --reuse-base-buildand--reuse-overlay-buildflags for independent build reusequicksand-base-scaffoldpackage for scaffolding new base image packagesquicksand-overlay-scaffold --baseflag to choose which base image to overlay on
Changed
- Release pipeline
buildjob renamed tobuild-basefor clarity quicksand installremoved legacy save-download path. All names are package installs- Scaffold packages output to fixed directories (
packages/for base,packages/contrib/for overlay) - Workflow conditions use
fromJSONnull checks instead ofcontainsstring matching
Fixed
- Release artifacts from multiple runs now merge correctly (tri-source downloads)
- KVM setup is best-effort in overlay builds (falls back to TCG gracefully)
_to_titleno longer uppercases short words. This avoidsSandboxSandboxin scaffold output
[v0.6.0] - 2026-03-23
Changed
- Breaking:
SandboxConfig.imageis nowstronly (wasstr | Path | ImagePaths) - Breaking:
save()returnsSaveManifestinstead ofSaveInfo - Breaking: Removed
loadparameter fromSandbox.__init__(). UseSandboxConfig(image="save-name")instead - Breaking: Save format bumped to v5 (directory-based, no tar support)
- Breaking: Removed legacy
quicksand.basesentry point group. Onlyquicksand.imagesis supported ImageProvideris now atyping.Protocolinstead of an abstract class- Sandbox internal state uses flat fields instead of wrapper dataclasses
build_qemu_command()takes individual path arguments instead ofImagePaths/DiskPaths
Removed
SavedConfig,SaveInfo,ImagePaths,DiskPaths,_BootState,_VMConfig,SandboxSnapshottypes_WorkspaceOptions,_QuicksandGuestAgentState,_QMPState,_VNCStatestate wrappersSavedConfig.from_sandbox_config()andSavedConfig.resolve()methodsget_image_path()andget_image_artifacts()legacy functions from image packagessandbox/_state.pymodule- Legacy tar-based save format support (v3/v4 manifests)
Fixed
SandboxConfigis now truly frozen and never mutated after construction- Config mutation bug where
config.accelwas overwritten during cross-arch save loading - Hardcoded
quicksand_version: "0.1.0"in save manifests
[v0.5.0] - 2026-03-20
Changed
- Breaking: Entire Sandbox public API is now async/await
Sandboxusesasync with(__aenter__/__aexit__) andawait start()/stop()- All mixins are async:
execute,save,checkpoint,revert,mount,unmount,type_text,press_key,mouse_move,mouse_click,screenshot, etc. QMPClientuses asyncio streams instead of blocking socketsQuicksandGuestAgentClientuseshttpx.AsyncClient- Examples updated with
asyncio.run()wrappers - Tests updated to pytest-asyncio + AsyncMock
[v0.3.3] - 2026-03-18
Added
python -m quicksandentrypoint (equivalent toquicksandCLI)
Fixed
- Bumped GitHub Actions to latest versions (Node.js 24 support)
[v0.3.2] - 2026-03-17
Fixed
quicksand installfailing to resolve third-party dependencies (httpx) due to--no-indexflag blocking PyPI access
[v0.3.0] - 2026-03-17
Added
- CIFS hot-mount API:
sb.mount()/sb.unmount()withMountHandle quicksand-smbpackage: pure-Python SMB3 server spawned via QEMU guestfwd (no TCP port, no Samba, zero dependencies)NetworkMode.MOUNTS_ONLYfor mounts without internet access via guestfwd tunnelsNetworkModeenum now has three modes:NONE,MOUNTS_ONLY(default),FULL- QEMU block layer flush before snapshot pivot to prevent data loss on large writes
- Path traversal protection in SMB server (symlink +
..escape checks) examples/mounts.pydemonstrating boot-time, dynamic, and readonly mount patterns
Changed
- Replaced
quicksand-smbd(bundled Samba binary, 50MB+) withquicksand-smb(pure Python, ~2K LOC) - Default network mode is now
MOUNTS_ONLY(wasHOST_ONLY) - Mounts use CIFS over guestfwd in all network modes (no TCP port opened on host)
Removed
quicksand-smbdpackage (replaced byquicksand-smb)- 9p as default mount protocol (replaced by CIFS). 9p remains available via
type="9p"
Fixed
- macOS SIP
PermissionErrorwhen copying binaries NetworkModeenum definition to properly support three modes
[v0.2.3] - 2026-03-12
Added
quicksand-ubuntu-desktoppackage with full Ubuntu 24.04 desktop sandbox supportquicksand-alpine-desktoppackageKeyenum for keyboard input- Image install CLI (
quicksand images install <name>) query_display_size()API for display introspection- Double-click support in input API
- Overlay chain support in core snapshot/checkpoint system
Changed
- Refactored core to use
NetworkModeenum, overlay chains, and display/input subsystem - Updated Alpine and Ubuntu base packages for
NetworkModeAPI - Renamed
quicksand-agenttoquicksand-guest-agent - Updated guest agent and dev tools for new core API
- Improved desktop images with browser support, software cursor, and DNS fixes
Fixed
- Checkpoint integration tests for overlay chain format
- Typecheck issues with
overlay_chaininSandboxSnapshot - CI version bump to push from latest main instead of tag HEAD
[v0.2.2] - 2026-02-27
Changed
- Renamed
quicksand-agenttoquicksand-guest-agentand added package init scaffold
Fixed
- Integration test compatibility with renamed package
[v0.2.1] - 2026-02-26
Changed
- Refactored core internals
installcommand now supports multi-argument package installation
[v0.2.0] - 2026-02-26
Added
- Streaming
execute()API for real-time command output - README install instructions using
quicksandCLI installer
Changed
- Refactored core internals and removed
write_file/read_filein favor ofexecute() - Updated integration tests to use
execute()API
Fixed
- Missing
readlineimport error on Windows - Binary file tests to use POSIX-compatible tools (
odinstead ofxxd)
[v0.1.27] - 2026-02-24
Fixed
- Mount hangs when
restrict_network=True
[v0.1.26] - 2026-02-24
Fixed
- DNS resolution in Ubuntu sandbox (enabled
systemd-resolved) - Reverted DNS changes that broke mount tests
[v0.1.25] - 2026-02-24
Changed
- QEMU bundling is now optional
[v0.1.24] - 2026-02-24
Added
- CLI to
quicksandpackage quicksand-qemuCI build jobs
[v0.1.23] - 2026-02-23
Added
- Rust guest agent, replacing the Python agent for smaller images and faster startup
curladded to Alpine image for network tests
[v0.1.22] - 2026-02-20
Fixed
- microvm + Ubuntu compatibility: match
eth*interfaces insystemd-networkd
[v0.1.21] - 2026-02-20
Changed
- Disabled microvm temporarily due to Ubuntu compatibility issues
[v0.1.20] - 2026-02-20
Fixed
- microvm networking by using explicit
-netdev/-deviceQEMU args
[v0.1.19] - 2026-02-20
Added
- GPL license files for QEMU binary distribution (Section 3(c) compliance)
- QEMU version tracking
Removed
- Redundant
bundle_qemu.pyscript (inlined intohatch_build.py)
[v0.1.18] - 2026-02-20
Added
- microvm support: bundle
bios-microvm.binfor ~4x faster boot on Linux x86_64 - QEMU performance optimizations
Fixed
- microvm
bios-microvm.binexistence check before enabling _build_mount_argssignature change in tests
[v0.1.16] - 2026-02-19
Added
- Serial console output for boot debugging
Changed
- Renamed
install.pytoinstaller.py
Fixed
- Docker build: remove
/etc/resolv.confbefore symlinking - Ubuntu DNS by enabling
systemd-resolved - Installer tests
[v0.1.15] - 2026-02-17
Added
- SMB-based mounting for Windows hosts, replacing
FileSyncAgent
Fixed
- Windows SMB mount (standard port 445, explicit CIFS options)
- Build hooks importing from package being built
- Checkpoint tests with mounts on Windows
[v0.1.14] - 2026-02-15
Changed
- Use pyproject entry points for optional package discovery
[v0.1.13] - 2026-02-14
Changed
- Refactored host module naming.
Platformenum renamed toOSand merged runtime module
[v0.1.12] - 2026-02-12
Added
ARCHITECTURE.mddocumenting codebase structure and QEMU glossary- Comprehensive tests for
quicksand-image-toolsCLI - Per-package tags with bundled releases
- Python-based wheel merge script (
merge_wheels.py)
Changed
- CI release flow: single tag with incremental builds
- Separated build tasks for core and image packages
Removed
- Committed
agent.pyfromquicksand-alpine(now generated)
[v0.1.11] - 2026-02-12
Changed
- Refactored
sandbox.pyinto modular VM components - Refactored platform config to subclass-based architecture
Fixed
filesyncimport error on Windows guest
[v0.1.10] - 2026-02-11
Changed
- Redesigned
image_wrapperto properly subclassSandbox
[v0.1.9] - 2026-02-11
Changed
- Optimized QEMU boot time
[v0.1.8] - 2026-02-11
Added
install.pyhelper script for GitHub releases with download progress bars- Interactive
testsubcommand with--mount,--network, and sandbox type options - DNS resolution and curl HTTPS integration tests
- Cross-platform CI: unit tests on Linux, macOS, and Windows
- Matrix test-installer workflow across OS and image type
Fixed
- Platform matching in
install.pyfor wheel selection - Progress bar Unicode error on Windows
- Network integration tests
[v0.1.7] - 2026-02-11
Changed
- Switched to tag-based releases
- Consolidated CI into single workflow (check, build, test)
[v0.1.6] - 2026-02-11
Changed
- Redesigned CI workflows: separate check/build/test stages with proper release flow
- Cross-workflow artifact handling via
gh run download
Removed
- Debug KVM ARM64 workflow
[v0.1.5] - 2026-02-11
Changed
- Split CI into separate workflows
[v0.1.4] - 2026-02-11
Added
sync_file()API for explicit file sync- Bidirectional filesync with
use_filesyncconfig option - Standalone release workflow
- WHPX kernel arg (
noapic) for Windows
Fixed
- Windows filesync: path handling, port initialization, atomic rename, bidirectional sync
- Filesync initial sync race condition
- WHPX kernel panic by correcting QEMU arg order
[v0.1.3] - 2026-02-10
Fixed
- CI: removed
continue-on-errorfrom build and test jobs
[v0.1.2] - 2026-02-10
Changed
- CI workflow now triggers on version tags
[v0.1.1] - 2026-02-10
Added
- Initial release of quicksand: pip-installable Linux sandboxes powered by QEMU
- Core sandbox API with
SandboxandUbuntuSandboxclasses - Monorepo packages:
quicksand-core,quicksand-ubuntu,quicksand-alpine,quicksand-qemu - QEMU binary bundling for macOS, Linux, and Windows
- Direct kernel boot with virtio networking and 9p mounts
- FastAPI-based HTTP guest agent
- P2P file sync for Windows hosts (virtio-9p alternative)
- Docker-based VM image building
- CI/CD pipeline with per-platform wheel builds and integration tests
- MIT License