The merge-time items from the #381 review. navigator.sendBeacon is not fetch,
so the base-aware wrapper never saw the two crash-diag beacons and a sub-path
install posted them to the origin root every two seconds. The test suite now
strips CODEMAN_BASE_URL like CODEMAN_GESTURE, since the constructor reads it
as a fallback and an operator who exports it would see the root-install
byte-identity assertions fail. test/base-path-server.test.ts boots a real
WebServer under /codeman and checks the ingress strip, the base injection,
the rebased redirects, the 404 envelope and a prefixed WebSocket upgrade.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
`test/setup.ts` gives every test file a temp HOME so the suite cannot touch the
real Codeman tree, and strips the env vars that would leak past it — but the
list only covered auth and the gesture flag. The three vars
`src/config/instance.ts` derives the data dir and tmux socket from were missing,
and they reach past the temp HOME:
- **`CODEMAN_DATA_DIR` is the one that matters.** It is an ABSOLUTE override
read in `getDataDir()`, so it bypasses HOME entirely: a developer who exports
it — or a shell left over from `codeman web -d` — has the suite reading and
WRITING their real `state.json`, `users.json`, `intents.json` and
`hook-secret`.
- **`CODEMAN_INSTANCE`** moves the data dir to `~/.codeman-<name>` and the
socket to `codeman-<name>`. Inside the temp HOME that is not data loss, but it
silently changes the paths tests assert on — and `scripts/run-beta.sh` exports
it, so any shell that has run a beta carries it.
- **`CODEMAN_TMUX_SOCKET`** renames the socket `resolveTmuxSocketName()`
returns. `TmuxManager` no-ops its shell commands under vitest, so this is
assertion drift rather than a stray `tmux -L` against prod — same class of
leak, same one-line fix.
They are deleted in the setup file rather than in a hook because
`CODEMAN_INSTANCE` is captured into a module-level const the first time
`config/instance.ts` is imported; a `beforeEach` would already be too late.
`test/test-env-isolation.test.ts` pins the whole list in two halves, because the
obvious half is not enough: asserting the vars are unset passes trivially on a
machine that never set them, so a removed `delete` line would sail through on
almost every box and on CI. The static half reads `setup.ts` and asserts each
name is deleted there, which fails everywhere. An anti-drift check catches the
other direction — a var stripped in `setup.ts` but never given a reason in the
list — and is scoped to the strip section so the teardown's restores are not
mistaken for strips.
Verified by demonstrating the leak: with the `CODEMAN_DATA_DIR` line removed and
the var exported, the runtime assertion fails; with the line restored it passes.
Full suite: no new failures against an upstream/master baseline.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WQkoi1cNegqVwZHgzx5SbJ