Question
Running the e2e suite on a host deletes that host's real devpod workspaces. Make
it impossible.
Graduated from the conflict-scoping ticket,
which found this while enumerating collisions. Three facts compose into a footgun:
dl --purge deletes every workspace devpod list returns
(devlaunch/dl.py:335-339) — it has no notion of "only mine".
- An e2e test exercises exactly that, for real, at
test/e2e/test_full_workflow.py:266.
devpod list reads ~/.devpod, not anything under XDG_*. So the scratch
XDG_CACHE_HOME/XDG_CONFIG_HOME dance that CLAUDE.md prescribes does not
protect you here. devlaunch never sets DEVPOD_HOME (grep -rn DEVPOD_HOME .
is empty).
So pytest -m e2e run on a developer's machine — by habit, by a misconfigured
editor, by an agent that did not read the marker config — destroys their whole
workspace list. The addopts = "-m 'not e2e'" default in pyproject.toml:126 is
the only thing standing between a developer and that, and a default is not a
safeguard.
The same ticket found a second, milder instance: the suite's workspace ids are
hardcoded constants — e2e-test-{create,lifecycle,git,purge} at
test/e2e/test_full_workflow.py:52,86,136,235 — and teardown devpod delete --forces them, so two concurrent e2e runs delete each other's workspaces.
This is a wayfinder:build ticket: go through /tdd.
Test-first, and note the shape of the red test. The failing test cannot be
"run --purge and see what dies" — the red state of that test is the damage.
Write it at a seam instead: the thing under test is that the suite refuses to
touch state it did not create. Candidate seams, pick and justify one — a fixture
that refuses to run destructive e2e unless pointed at a scoped DEVPOD_HOME; a
guard asserting devpod list is empty or contains only this run's ids before any
--force delete; per-run unique ids so the constants stop being shared at all.
Prefer the smallest thing that makes the bad outcome unrepresentable rather than
merely unlikely (principles 2 and 3) — a guard that can be forgotten at the next
new test is weaker than a scoping that applies to the whole suite at once.
Scope note. Whether dl --purge itself should learn a narrower blast radius
in production is a separate question and is not this ticket — this ticket makes
the test suite safe to run. If the work suggests the production behaviour is
also wrong, say so on the ticket and let the map graduate it.
Relation to the daemon. Inside a dind devcontainer each run gets its own
~/.devpod and its own daemon, so the nested daemon fixes this incidentally.
That is not a reason to skip it: the suite must be safe when someone runs it
outside a container, which is precisely the case nobody is protected from today.
Question
Running the e2e suite on a host deletes that host's real devpod workspaces. Make
it impossible.
Graduated from the conflict-scoping ticket,
which found this while enumerating collisions. Three facts compose into a footgun:
dl --purgedeletes every workspacedevpod listreturns(
devlaunch/dl.py:335-339) — it has no notion of "only mine".test/e2e/test_full_workflow.py:266.devpod listreads~/.devpod, not anything underXDG_*. So the scratchXDG_CACHE_HOME/XDG_CONFIG_HOMEdance thatCLAUDE.mdprescribes does notprotect you here. devlaunch never sets
DEVPOD_HOME(grep -rn DEVPOD_HOME .is empty).
So
pytest -m e2erun on a developer's machine — by habit, by a misconfigurededitor, by an agent that did not read the marker config — destroys their whole
workspace list. The
addopts = "-m 'not e2e'"default inpyproject.toml:126isthe only thing standing between a developer and that, and a default is not a
safeguard.
The same ticket found a second, milder instance: the suite's workspace ids are
hardcoded constants —
e2e-test-{create,lifecycle,git,purge}attest/e2e/test_full_workflow.py:52,86,136,235— and teardowndevpod delete --forces them, so two concurrent e2e runs delete each other's workspaces.This is a
wayfinder:buildticket: go through/tdd.Test-first, and note the shape of the red test. The failing test cannot be
"run
--purgeand see what dies" — the red state of that test is the damage.Write it at a seam instead: the thing under test is that the suite refuses to
touch state it did not create. Candidate seams, pick and justify one — a fixture
that refuses to run destructive e2e unless pointed at a scoped
DEVPOD_HOME; aguard asserting
devpod listis empty or contains only this run's ids before any--forcedelete; per-run unique ids so the constants stop being shared at all.Prefer the smallest thing that makes the bad outcome unrepresentable rather than
merely unlikely (principles 2 and 3) — a guard that can be forgotten at the next
new test is weaker than a scoping that applies to the whole suite at once.
Scope note. Whether
dl --purgeitself should learn a narrower blast radiusin production is a separate question and is not this ticket — this ticket makes
the test suite safe to run. If the work suggests the production behaviour is
also wrong, say so on the ticket and let the map graduate it.
Relation to the daemon. Inside a dind devcontainer each run gets its own
~/.devpodand its own daemon, so the nested daemon fixes this incidentally.That is not a reason to skip it: the suite must be safe when someone runs it
outside a container, which is precisely the case nobody is protected from today.