Skip to content

Commit aa5e8b3

Browse files
committed
docs: enforce in-VM execution for all CLI tool tests, ban child_process bridge cheating
1 parent a11d1eb commit aa5e8b3

2 files changed

Lines changed: 81 additions & 65 deletions

File tree

CLAUDE.md

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,19 @@
1818
- NEVER mock external services in tests — use real implementations (Docker containers for databases/services, real HTTP servers for network tests, real binaries for CLI tool tests)
1919
- tests that validate sandbox behavior MUST run code through the secure-exec sandbox (NodeRuntime/proc.exec()), never directly on the host
2020
- NOTHING runs on the host except Docker containers for e2e-docker tests — all CLI tool code executes inside the sandbox VM
21-
- Pi and Claude Code are pure JS — they run in-VM via `import()` or `node -e` through `kernel.openShell()`, NOT via host `child_process.spawn`
21+
- Pi, Claude Code, and OpenCode are ALL pure JavaScript/TypeScript — they ALL run in-VM via `import()` through `kernel.openShell()` or `kernel.spawn()`
2222
- Claude Code is a bundled ESM Node.js script (`@anthropic-ai/claude-code/cli.js`), not a native binary — its `.node` addons (tree-sitter, audio-capture) are optional and gracefully degrade
23-
- OpenCode is a compiled Bun binary — it runs via the sandbox's `child_process.spawn` bridge (the bridge routes to the host, but from the sandbox's perspective it's a normal spawn)
24-
- NEVER use `HostBinaryDriver` or `script -qefc` to bypass the sandbox — if the sandbox can't run something, fix the sandbox
25-
- if a test skips because of a sandbox limitation (module resolution, stdin streaming, isTTY), that is a secure-exec bug to fix, not a test to skip
26-
- NEVER work around sandbox limitations with host-side execution:
23+
- OpenCode is TypeScript (https://github.com/anomalyco/opencode) — the distributed `opencode` command is a Bun-compiled binary but the source is vanilla TS/JS; build the JS bundle from source and run it in-VM
24+
- if the sandbox can't run something, that is a secure-exec bug to fix, not a reason to spawn on the host
25+
- NEVER work around sandbox limitations with host-side execution — this is the #1 rule for CLI tool tests:
26+
- do NOT use `child_process.spawn` or `child_process.spawnSync` from INSIDE sandbox code to run a tool binary on the host (e.g. `spawnSync('claude', [...args])` routing through the child_process bridge) — this is still host execution, the tool's JS runs on the host not in the V8 isolate
27+
- do NOT use `node:child_process.spawn` from TEST code to run tools on the host
2728
- do NOT create `HostBinaryDriver` classes that spawn binaries on the host
28-
- do NOT use `script -qefc` to give host processes a PTY
29-
- do NOT use `node:child_process.spawn` from test code to run tools on the host when the tool should run in-VM
29+
- do NOT use `script -qefc` or `python3 pty.spawn` to give host processes a PTY
3030
- do NOT add `sandboxSkip` / probe-based skip logic that silently skips when the sandbox can't do something
31-
- do NOT mark a story as passing if tests are skipping due to sandbox limitations
32-
- if the sandbox can't run something, the correct action is to FIX the sandbox code in packages/nodejs/src/ or packages/core/src/
31+
- do NOT mark a story as passing if the tool runs on the host instead of in the V8 isolate
32+
- the ONLY correct pattern is: `kernel.spawn('node', ['-e', 'import("tool-entry.js")'])` or equivalent — the tool's JavaScript executes inside the V8 sandbox isolate
33+
- if `import()` hangs, if ESM loading fails, if the TUI crashes — those are secure-exec bugs to fix in packages/nodejs/src/, packages/core/src/, or native/v8-runtime/src/
3334
- e2e-docker fixtures connect to real Docker containers (Postgres, MySQL, Redis, SSH/SFTP) — skip gracefully via `skipUnlessDocker()` when Docker is unavailable
3435
- interactive/PTY tests must use `kernel.openShell()` with `@xterm/headless`, not host PTY via `script -qefc`
3536
- CLI tool tests (Pi, Claude Code, OpenCode) must support both mock and real LLM API tokens:

0 commit comments

Comments
 (0)