You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
emrg: the suite's config-file write guard omits config.toml, the one host file whose corruption stops the daemon #2435
tests/conftest.py carries an autouse fixture, _guard_real_config_files, whose purpose is to make any test that writes one of the host's real config files fail immediately. It refuses two files:
~/.emrg/config.toml — the third, and the only one of the three that the daemon cannot start without — is not there.
Why the omission is not cosmetic
The fixture patches one writer, atomic_write_yaml, in the two modules that hold it. That is the right seam for projects.yml and tasks.yml, which are YAML. config.toml is not YAML and is not written that way: emrg/config.py::ensure_config creates it with
which atomic_write_yaml never sees. So the file the fixture is named after is covered by neither half of it — not by the file list, and not by the writer it patches.
What that costs
config.toml is the host's live configuration, and a corrupt one is a startup failure rather than a test failure. The recorded shape: a single stray line appended to the end of the file made tomllib raise
TOMLDecodeError: Expected '=' after a key in a key/value pair (at line 48, column 6)
the daemon exited during startup (exit=1), and the traceback landed in ~/.emrg/emrgd-crash.log — a file no startup-failure report reads, so the client's message said only that the daemon had exited and written nothing to its log.
The protection that stands there now is the one a mutation arm removes
Reads are kept off the host file by a separate autouse fixture, _redirect_the_config_path, which repoints config_path() (in emrg.config and in emrg.server.config_reload) at a per-test scratch tree. That redirect is what keeps ensure_config away from the host today.
It is a redirect, not a refusal: it works by making the code resolve a different path. A mutation arm exists precisely to break the code it mutates, so the one thing standing between an arm and the host's config.toml is the thing the arm is designed to disable. Meanwhile the prose rule — a test or an arm must never write this file — is stated in the project's own instructions, and nothing measures it.
Expected
A test that attempts to write the host's ~/.emrg/config.toml fails as loudly, and as immediately, as one that writes projects.yml — and the guard's teeth are demonstrated rather than declared, because a guard that nothing exercises is a claim.
What the fix must satisfy
All three host files are refused, not two.
The seam that actually writes config.toml is covered, not only the YAML one.
Each covered seam has a test that fails when that seam's patch is removed, and passes when it is present.
The guard never makes those files unreadable — a read must pass through untouched.
No test that proves the guard can itself reach a host file: the refusals are driven through paths a test created.
Activity
how2how2how2-arch commentedon Oct 21, 2026
Handled by #2436