Two related changes landed together:
1. /opt/left4me/ becomes a root-owned deploy-artifact root. Only
/opt/left4me/src lives there. Source tree is no longer mutated
by pip at runtime; left4me only needs read access.
2. Runtime mutable state moved to /var/lib/left4me/: the venv (was
/opt/left4me/.venv) and steamcmd (was /opt/left4me/steam).
The non-editable install copies the (root-owned) source to a
left4me-owned tempdir before `pip install --force-reinstall`.
setuptools.build_meta writes <pkg>.egg-info/ into the source dir
during get_requires_for_build_wheel, so a direct `pip install
/opt/left4me/src/l4d2*` fails on a root-owned source. The
temp-copy is what `python -m build` ought to do but doesn't (its
build isolation only sandboxes deps).
Prereq for the deployment-responsibility reshape: target-side
symlinks from /etc/... into /opt/left4me/src/deploy/files/... are
now safe by construction (left4me cannot rewrite its own hardening
profile).
Design + verification record: left4me/docs/superpowers/specs/
2026-05-15-runtime-state-relocation-design.md
Verified on ovh.left4me: bw apply idempotent on second pass (0
fixed, 0 failed); pip show reports site-packages location, no
Editable project location; web + gameserver units run clean;
alembic current returns head.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>