docs(test): a bare vitest is isolated now, and the guards need the sandbox HOME

Merge-time fix for #660. CLAUDE.md and architecture-invariants still said a
raw npx vitest skips setup.ts, contradicting the updated Testing note: both
now say it resolves the root vitest.config.ts (and why that file must stay).
The architecture-invariants entry for safeRmHomeTree adds the sandbox-HOME
requirement (isSandboxedHome, TEST_HOME_PREFIX), the same rule for
isUnderTestHome, the route-harness assert and the 2026-10-10 incident.
CLAUDE.md's repo-root preamble lists vitest.config.ts with its reason, so a
tidy-up does not move it into config/ and reopen #640. The
assertSandboxedHome JSDoc no longer claims every route test is covered: only
the ones built on createRouteTestHarness are.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Codeman maintainer committed 2026-10-22 19:25:52 +02:00
1 parent 6310868696
commit 6d2763d50b
3 files changed
+6 -5

No files matched your search

+2 -2
View File
@@ -1170,9 +1170,9 @@ The repair is a **chmod, not a rebuild**: the prebuilt binary is fine. `scripts/
⚠️ `CODEMAN_DATA_DIR` is the one that matters: `getDataDir()` reads it as an ABSOLUTE override before it ever looks at `homedir()`, so one inherited from the shell (a second instance, a beta run, a shell left over from `codeman web -d`) bypasses the temp HOME entirely, and a bare suite run once overwrote the real `remote-hosts.json` with a route test's fixture. `os.homedir()` itself DOES follow `$HOME`, so the temp HOME is what redirects everything else; `CODEMAN_INSTANCE` must be stripped in the setup file and never in a hook, because `config/instance.ts` captures it into a module-level const on first import.
Tests that delete case trees go through `safeRmHomeTree()` (`test/mocks`), which refuses any path outside the temp HOME, so a wrong anchor leaves a temp dir behind instead of deleting `~/codeman-cases`.
Tests that delete case trees go through `safeRmHomeTree()` (`test/mocks`), which refuses any path outside the temp HOME, so a wrong anchor leaves a temp dir behind instead of deleting `~/codeman-cases`. ⚠️ It also refuses everything unless HOME IS the throwaway dir `test/setup.ts` made (`isSandboxedHome()`: its basename starts with `TEST_HOME_PREFIX`, `codeman-vitest-`, the one thing a real home cannot have). "Under HOME" alone is vacuous when setup never ran: on 2026-10-10 a bare `vitest` run had the developer's real home as HOME, every real file was "under the test HOME", and the guard written to prevent exactly that deleted the real linked-cases registry. `isUnderTestHome()` (for single-file deletes such as `linked-cases.json`) carries the same requirement, and the shared route harness `createRouteTestHarness()` calls `assertSandboxedHome()`, so a route test built on it refuses to start against a real `~/.codeman` (a route test that builds its own app from `createMockRouteContext()` is not covered by that).
⚠️ Raw `npx vitest` without `--config` skips `setup.ts` and with it the temp-HOME isolation.
⚠️ A bare `npx vitest` (no `--config`) resolves the root `vitest.config.ts`, which re-exports `config/vitest.ci.config.ts`, so it runs `setup.ts` and gets the temp HOME like `npm test`. Vitest looks for its config by walking up from cwd, so this holds from `test/` as well, while `packages/xterm-zerolag-input` keeps its own config. Before that file existed a bare run found no config, ran without the setup file, and wrote fixtures into the real `~/.codeman` (#640: a `clis.json` with a test entry, `users.json`, `webhook.json`, `.env`, settings values). `test/test-env-isolation.test.ts` pins it; a `--config` pointing at a config without `setupFiles` would still skip the isolation.
### install.sh: the public installer