Two jobs, one root cause

QA and DevOps rarely get grouped together, but many of the bugs each fights are the same bug under different names.

In QA it's the classic flaky test: it passes alone and fails only after some other test. That's a known category. When one test leaves a changed record, a temp file or an open session behind, the next inherits that state and behaves differently than it would from a clean start. The 2026 Flaky Test Benchmark Report puts timing issues, test data problems and runtime errors at over 70% of flaky failures combined, and much of that comes from environment state that wasn't reset the way the suite assumed.

In DevOps it's the install script or Ansible playbook that passes validation and breaks on a truly fresh host. Configuration tools are designed around idempotency (running a script twice should converge on the same state) but that's a property you have to test from many starting states, not assume. If the only place a script runs before production is a staging box with six months of undocumented manual fixes, "it passed staging" says it works on that one machine, not that it's idempotent. A related, increasingly common version is your CI runner's environment changing under you with no code change at all; disposable workspaces for DevOps and CI has a current example.

"Reset" and "disposable" are different guarantees

For the fuller definition, and how it differs from a snapshot or a container, see what is a disposable development environment?

The usual fix for both is a teardown script: a fixture that rolls back the database, a CI step that runs vagrant destroy && vagrant up, a habit of logging in and undoing whatever the last run changed. They work most of the time, and "most of the time" is the problem. A teardown script is code, written by someone (maybe you, months ago) who had to foresee every piece of state a run could leave. Miss one, a cron job that fired mid-test, a package installed as a side effect, a config file an installer half-wrote before failing, and the next run starts probably clean, which is a much weaker guarantee.

A disposable VM removes that category of bug instead of chasing it. There's no cleanup step to get wrong, because nothing about the workspace outlives it. The next run doesn't start from whatever the teardown managed to undo; it starts from the same saved image, bit for bit, every time.

For QA: a base image once, a disposable workspace per run

Save a fully configured environment (OS, browser and test dependencies, the application under test) as a base image once. Each test run clones a new disposable workspace from it in seconds with copy-on-write, runs, and is gone when you close it: no snapshot to remember to delete, and no doubt about leftovers from last time. When a test fails, a whole category of noise is gone. Every run starts from the same state, so a failure that reproduces is real, and one that doesn't is much more likely a race condition than leftovers from three runs ago. That's a far easier bug to triage than "did something about the environment change?"

For DevOps: test against a fresh system, not a machine you half-remember fixing

The same pattern validates a deployment script, an install procedure or a config change before it ships. Since Velo Workspaces 1.2, the vanilla starting point is easy to get: an official Ubuntu, Debian, Fedora or Rocky Linux cloud image, ready about a minute after download, with nothing on it you didn't put there. Test the script against a fresh one every time instead of a box you've patched by hand. If the script only works because an earlier run left a dependency installed, a fresh system is what catches it, before a production host does.

Testing the installer path itself? Fedora Server and Rocky Linux can install unattended from their own ISOs with a kickstart file the app writes, and Ubuntu with autoinstall, so "does a clean install from the vendor's media come up correctly" is a repeatable test too.

One failure mode deserves a mention: an install script that goes wrong early enough that networking or SSH never comes up. That's where SSH-based debugging can't help, because SSH is what's broken. A serial console, a terminal into the guest that doesn't need the network stack, is the difference between staring at a stuck workspace and seeing why. Once a script passes on a fresh system, save that state as a new base image and version it as carefully as the script, so "the golden image" isn't a Slack thread about which server it came from.

Where this sits next to Vagrant, Multipass and Lima

Vagrant, Canonical's Multipass and Lima are good, free tools, and any of them is a reasonable answer to "I want a Linux VM on my Mac for testing". Multipass and Lima work well on Apple silicon and, like Velo Workspaces 1.2, start from cloud images with cloud-init. Plenty of people have moved to Lima after finding Vagrant rougher going on Apple silicon.

The difference is what's built in. Those tools are command-line first and give you a VM; disposability, base-image management and editor setup are workflow you build on top with a Vagrantfile or Lima YAML and your own conventions. Velo Workspaces is a Mac app that treats the disposable shape as the workflow: close a disposable workspace and it's gone, save a base image in one step and clone from it, and the console, SSH details and VS Code Remote config are there without wiring. If you already maintain that scripting and like it, you may not need to switch. If you'd be the one writing it, that's the gap this fills.

What to do

  • Don't rely on a teardown script to undo a run completely. It catches only what its author foresaw; disposability removes the category instead.
  • Test scripts against a provably fresh system, not a machine that's probably been reset.
  • Keep a way into the guest that doesn't need the network, for when the bug is why the network didn't come up.
  • Version your base image as carefully as the script that builds it.

The same disposable-by-default idea shows up in the security deep dive for a different reason: a compromised AI agent's changes not outliving the session is the same property that stops a flaky test's leftovers outliving its run. It's also why some riskier guest performance settings are a fair trade here. If Ubuntu Server is your base, see what's different about it on Apple Silicon, including a cloning gotcha. For versioning the golden image, see base images as versioned infrastructure. For the individual version of this idea, see clean-room bug reproduction, and for why constant create-and-discard gets expensive under metered cloud billing, Velo Workspaces vs. Codespaces vs. Ona. See the QA and DevOps profiles on the home page, or download Velo Workspaces and try it yourself.