Skip to content

test(supervisor): honor the REMO_CODE_CONFIG_DIR contract in config-touching tests - #409

Open
finedesignz wants to merge 1 commit into
mainfrom
fix/test-config-isolation-contract
Open

test(supervisor): honor the REMO_CODE_CONFIG_DIR contract in config-touching tests#409
finedesignz wants to merge 1 commit into
mainfrom
fix/test-config-isolation-contract

Conversation

@finedesignz

Copy link
Copy Markdown
Owner

Follow-up to #406, from the post-merge QC of that PR (VERIFICATION-PR406.md).

#406 added the REMO_CODE_CONFIG_DIR override and a guard that hard-throws under NODE_ENV=test when it is unset. QC proved that guard works belt-without-braces: on the fixed code, a full suite run with the override deliberately omitted and APPDATA redirected to a scratch dir writes zero files, where the same run pre-fix wrote supervisor.json with roots=["...\Temp\remo-repoinv-0u7n1b"] — the live corruption signature.

But the contract the guard's own error message states — "tests must set REMO_CODE_CONFIG_DIR before touching config.ts / hub-client.ts" — was not honored by the two tests that actually reach config. They pass only because the throw is swallowed on the save path, so they silently exercise an error path today, and a persistence assertion added to either later would need a real sandboxed config dir rather than a no-op.

Changes

  • repo-inventory-interval.test.ts — the file whose own remo-repoinv-* temp dir is the one that reached the live config — now sets REMO_CODE_CONFIG_DIR to a per-run temp dir, restoring the previous value in afterAll so a leaked override cannot mask a missing one in whatever file runs next in the same process.
  • force-update-marker.test.ts — same, plus a LOCALAPPDATA redirect. Separate bleed found while fixing the first: forceUpdateMarkerPath() resolves through supervisorStateDir(), which keys off LOCALAPPDATA and is covered by neither REMO_CODE_CONFIG_DIR nor fix(supervisor): isolate config-dir resolution from real APPDATA in tests/dev #406's guard. That file was writing force-update.json into the live %LOCALAPPDATA%\remo-code-supervisor, and its afterEach rmSync would delete a real pending force-update marker if one existed. (win32-only by construction; on Linux/macOS the state dir resolves under homedir(), so the override is a no-op on CI runners.)
  • Rust config_cmds::config_path / runtime_cmds::config_dir — comment recording that the Rust half deliberately does not honor the override (the tray app must resolve the real per-user config), and warning that a future Rust test reading or writing through them has none of the TS side's protection. No exposure today: the existing #[test]s are pure-function assertions over a serde_json::Map and touch no filesystem.

Verification

Suite run with the override set:

BEFORE roots=["C:\Users\artic\GitHub"] mtime=1787057273289.4927
       323 pass / 5 fail
AFTER  roots=["C:\Users\artic\GitHub"] mtime=1787057273289.4927
  • Failing set identical to main (the 2 known bridge-permission-returnpath failures + 3 PTY tests that need node-pty).
  • Live %APPDATA%\remo-code\supervisor.json unchanged — same roots, same mtime.
  • The two edited files pass standalone (9 tests), and %LOCALAPPDATA%\remo-code-supervisor\force-update.json is absent both before and after.

No behaviour change — tests and comments only.

🤖 Generated with Claude Code

…ouching tests

PR #406 added a REMO_CODE_CONFIG_DIR override plus a guard that hard-throws
under NODE_ENV=test when it is unset, after supervisor test fixtures wrote
through to the real %APPDATA%\remo-code\supervisor.json -- rewriting `roots`
to a temp scan directory, which made the running supervisor reject genuine
session launches as sandbox_escape (295 denials since May; 7 distinct temp
roots across 5 episodes).

The guard prevents the damage, but the contract its own error message states
("tests must set REMO_CODE_CONFIG_DIR before touching config.ts /
hub-client.ts") was not actually honored by the two tests that reach config.
They passed only because the resulting throw is swallowed on the save path --
so they silently exercise an error path, and any persistence assertion added
to them later would need a real sandboxed config dir rather than a no-op.

- repo-inventory-interval.test.ts (whose own remo-repoinv-* temp dir is the
  one that reached the live config) and force-update-marker.test.ts now set
  REMO_CODE_CONFIG_DIR to a per-run temp dir, and restore the previous value
  in afterAll so a leaked override cannot mask a missing one in whatever file
  runs next in the same process.

- force-update-marker.test.ts also redirects LOCALAPPDATA. Separate bleed,
  found while fixing the first: forceUpdateMarkerPath() resolves through
  supervisorStateDir(), which keys off LOCALAPPDATA and is covered by neither
  REMO_CODE_CONFIG_DIR nor #406's guard -- so that file was writing
  force-update.json into the live %LOCALAPPDATA%\remo-code-supervisor, and its
  afterEach rmSync would delete a real pending marker if one existed.

- Rust config_cmds::config_path / runtime_cmds::config_dir get a comment
  recording that the Rust half deliberately does not honor the override (the
  tray app must resolve the real config) and warning that a future Rust test
  reading or writing through them has none of the TS side's protection. No
  exposure today: the existing #[test]s are pure-function and touch no fs.

No behaviour change. Verified: supervisor suite 323 pass / 5 fail with the
failing set identical to main, and the live supervisor.json unchanged
(same roots, same mtime) before and after the run.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@finedesignz

Copy link
Copy Markdown
Owner Author

AI Review Gate

Gate verdict: FAILURE — blocking finding from Codex
Head SHA: 5ef09a214046

Claude Code (QC): pass

  • no findings

Codex: BLOCK

  • [blocking] supervisor/test/force-update-marker.test.ts — Env isolation is installed too late: The test imports '../src/hub-client' before beforeAll sets REMO_CODE_CONFIG_DIR. The added comments state hub-client/config.ts hard-throw under NODE_ENV=test when the override is unset, so this import order can fail at module evaluation before the hook runs.
  • [blocking] supervisor/test/repo-inventory-interval.test.ts — Env isolation is installed too late: The test imports code from '../src/hub-client' before beforeAll sets REMO_CODE_CONFIG_DIR. Given the stated contract that tests must set the override before touching config.ts / hub-client.ts, this hook runs too late and can break the test at import time.

Policy: both reviewers are blocking — a genuine blocking finding from either fails the gate. An infrastructure failure (quota exhausted, timeout, auth failure, no parseable output) is ADVISORY and never blocks: it means the reviewer never saw the code, which is not a verdict about the code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant