test(supervisor): honor the REMO_CODE_CONFIG_DIR contract in config-touching tests - #409
Open
finedesignz wants to merge 1 commit into
Open
test(supervisor): honor the REMO_CODE_CONFIG_DIR contract in config-touching tests#409finedesignz wants to merge 1 commit into
finedesignz wants to merge 1 commit into
Conversation
…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>
Owner
Author
AI Review GateGate verdict: FAILURE — blocking finding from Codex Claude Code (QC): pass
Codex: BLOCK
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. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #406, from the post-merge QC of that PR (
VERIFICATION-PR406.md).#406 added the
REMO_CODE_CONFIG_DIRoverride and a guard that hard-throws underNODE_ENV=testwhen it is unset. QC proved that guard works belt-without-braces: on the fixed code, a full suite run with the override deliberately omitted andAPPDATAredirected to a scratch dir writes zero files, where the same run pre-fix wrotesupervisor.jsonwithroots=["...\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 ownremo-repoinv-*temp dir is the one that reached the live config — now setsREMO_CODE_CONFIG_DIRto a per-run temp dir, restoring the previous value inafterAllso a leaked override cannot mask a missing one in whatever file runs next in the same process.force-update-marker.test.ts— same, plus aLOCALAPPDATAredirect. Separate bleed found while fixing the first:forceUpdateMarkerPath()resolves throughsupervisorStateDir(), which keys offLOCALAPPDATAand is covered by neitherREMO_CODE_CONFIG_DIRnor fix(supervisor): isolate config-dir resolution from real APPDATA in tests/dev #406's guard. That file was writingforce-update.jsoninto the live%LOCALAPPDATA%\remo-code-supervisor, and itsafterEachrmSyncwould delete a real pending force-update marker if one existed. (win32-only by construction; on Linux/macOS the state dir resolves underhomedir(), so the override is a no-op on CI runners.)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 aserde_json::Mapand touch no filesystem.Verification
Suite run with the override set:
main(the 2 knownbridge-permission-returnpathfailures + 3 PTY tests that neednode-pty).%APPDATA%\remo-code\supervisor.jsonunchanged — same roots, same mtime.%LOCALAPPDATA%\remo-code-supervisor\force-update.jsonis absent both before and after.No behaviour change — tests and comments only.
🤖 Generated with Claude Code