Isolation audit — WP29
Boundaries (what actually separates executors from hidden material)
| Boundary | Mechanism | Verification |
|---|---|---|
| Physical/host | Executors run on cluster nodes (M3U96a, M3U96b, M4M64a, M4M64b); oracles, evaluators, this repository and the series exist only on the laptop (and ~/wp29-oracles/ on the laptop) |
nodes hold no copy (no rsync of oracles ever; tests/isolation/test_bundle_hygiene.py checks every public bundle for forbidden material); node → laptop SSH port 22 unreachable (nc -z from M3U96a, 2026-10-29) |
| Workspace | one fresh directory per run containing exactly the public bundle | isolation.prepare_workspace compares the remote SHA-256 manifest with the local bundle manifest before launch; mismatch ⇒ infrastructure error (this actually fired twice in the first smoke attempt because of an unexpanded ~, and the runs were recorded as error with no inference) |
| Instruction loading | --bare: no CLAUDE.md discovery, no hooks, plugins, MCP, auto-memory, skills; instructions injected only via --append-system-prompt-file; identical flags across arms |
sentinel probes: laptop normal mode loaded 49,077 tokens incl. the user's cluster CLAUDE.md; bare mode 144 tokens and no sentinel; on each node bare mode saw neither the project sentinel nor the node's ~/.claude/CLAUDE.md (reports/sentinel_probes_nodes.jsonl, 175–177 input tokens) |
| Tools | --tools Bash,Read,Write,Edit,Glob,Grep (no WebFetch/WebSearch/Agent/MCP), --permission-prompts none |
the stream's init event lists the tool set; behaviour audit scans every tool_use input for paths outside the workspace (behaviour_audit.json; smoke: 0 outside references in all four arms) |
| Credentials | ~/wp29/.env (mode 600) on nodes, sourced by the launching shell; never written to logs or the repository; --bare never reads keychain/OAuth |
grep of runs/ for the key prefix is part of the release validation |
| Reviewer (arm D) | separate session id, separate system prompt, sees TASK.md + out/ |
residual leak path: the executor transcript exists under ~/.claude/projects on the node and could be read with Bash; not exercised in the smoke run (behaviour audit) — reported as a limitation |
| Nested invocation | no Agent tool; PGAR_DEPTH guard; executors cannot launch controllers |
code review + probe |
Contamination of the task suite
Tasks were authored by Claude Code subagents (fresh contexts, no access to executor transcripts) under a frozen interface; the builder (this session) wrote the smoke task. Executor sessions are fresh (--bare, new session id, new workspace) and cannot access sibling runs, previous attempts or oracles. Pretraining familiarity with textbook methods is expected and reported per task (contamination_risk in each task card). Reference answers were accessible to: the authoring subagent (designer) and the evaluator host. No executor ever had access.
Residual risks
- Same user account on the nodes: an executor could read other runs' workspaces under
~/wp29/runs/(sibling outputs of other runs) via Bash. Behaviour audit flags any such path; none occurred in the smoke. A stricter per-run OS identity was not implemented (documented limitation). - The reviewer can in principle read the executor transcript (see above).
- The gate program is world-readable on the node; arms A/B were not told about it and did not call it (0 invocations in the smoke), which the audit records for every run.