Tests and agents run apps against a scratch root, never a person's real data
State: open/published
Summary
Section titled “Summary”- Tests and agents run apps against a scratch root and never touch a person’s real data.
- One override moves every state root, and a harness that cannot prove isolation refuses to run.
- S-0011-application-state-locations defines the override. S-0020-desktop-apps-tested-web-first-in-scratch-root applies it to app testing.
Statement
Section titled “Statement”Tests and agents run apps against a scratch root and never touch a person’s real data. One override moves every state root, and a harness that cannot prove isolation refuses to run.
An app keeps state in several places: a vault, settings, a registry, caches, a backup store, models. A test that moves only some of them still writes to the rest under the real home. The damage is silent. A backup test that prunes snapshots, or an agent that registers a fixture vault, changes a person’s machine and nobody notices until data is missing.
Partial isolation is worse than none, because it looks safe. So isolation is all or nothing. It is proved after the app boots, not assumed from the flags passed.
How it applies
Section titled “How it applies”- Every state root resolves through fleet, so one override (
FLEET_ROOT) moves them all. See S-0011-application-state-locations. - A launcher creates a scratch root, points the app at it, and checks the resolved paths after boot. Every path must lie inside a root the harness made or was given. A path outside them, or under the real home, aborts the run. See S-0020-desktop-apps-tested-web-first-in-scratch-root.
- A test names its vault explicitly. It never relies on a checkout fallback or the last-active vault.
- An agent exploring an app by hand uses the same launcher as the tests.
Implications
Section titled “Implications”- A state path that bypasses fleet is a defect, because the override cannot reach it. Lint rules enforce this.
- An app-specific path knob (
VAULT_BACKUP_STORE,--state-dir) is not isolation. It moves one root and leaves the others. - CI can run e2e with
HOMEpointed at an empty directory. Any path that escapes shows up as a failure. - A test that needs real data copies a fixture into the scratch root. It never reads the person’s data in place.