Problem
aether-agent self uninstall recursively deletes the entire resolved AETHER_AGENT_HOME directory. That environment variable accepts any existing path, and the uninstall path checks only that it exists. If the configured prefix is shared with unrelated files, those files are deleted too.
On main at 67cb640, install_root resolves the override directly. _cmd_uninstall then calls shutil.rmtree(target) without checking ownership or unrelated contents.
The v0.3.2 tag contains the same unbounded removal path; this is not limited to the 0.4.0 source candidate.
Safe reproduction
I set AETHER_AGENT_HOME to an isolated temporary directory containing an unrelated file, mocked shutil.rmtree, and invoked _cmd_uninstall. It returned 0 and would have removed that entire directory. No files were actually deleted in the reproduction.
Expected behavior
Uninstall removes only launcher-owned installation files. A custom prefix with unrelated content is preserved, even if the prefix exists and an aether is installed elsewhere on PATH.
Acceptance criteria
- Establish a verifiable ownership boundary for managed installs (for example, a dedicated child directory or installation marker), and limit recursive removal to that boundary. Resolving a user-supplied path alone is not sufficient evidence of ownership.
- An override pointing to a shared directory, the user's home, a filesystem root, or a directory without trustworthy ownership evidence must refuse or remove only known launcher-owned entries. Preserve unrelated files.
- Handle installs created before the new ownership marker conservatively: offer clear remediation instead of silently deleting an unverified directory.
- Test a normal managed uninstall, a custom shared prefix with unrelated files, a stale/absent managed install, and root/home-like paths. Assert the actual removal target with a mocked filesystem operation; do not run destructive tests against real user directories.
Scope
This concerns the PyPI/pipx launcher self uninstall command. It does not change npm's global uninstall behavior or remove an unrelated aether found on PATH.
Problem
aether-agent self uninstallrecursively deletes the entire resolvedAETHER_AGENT_HOMEdirectory. That environment variable accepts any existing path, and the uninstall path checks only that it exists. If the configured prefix is shared with unrelated files, those files are deleted too.On
mainat67cb640,install_rootresolves the override directly._cmd_uninstallthen callsshutil.rmtree(target)without checking ownership or unrelated contents.The
v0.3.2tag contains the same unbounded removal path; this is not limited to the 0.4.0 source candidate.Safe reproduction
I set
AETHER_AGENT_HOMEto an isolated temporary directory containing an unrelated file, mockedshutil.rmtree, and invoked_cmd_uninstall. It returned0and would have removed that entire directory. No files were actually deleted in the reproduction.Expected behavior
Uninstall removes only launcher-owned installation files. A custom prefix with unrelated content is preserved, even if the prefix exists and an
aetheris installed elsewhere onPATH.Acceptance criteria
Scope
This concerns the PyPI/pipx launcher
self uninstallcommand. It does not change npm's global uninstall behavior or remove an unrelatedaetherfound onPATH.