The wall
A clean room only means something if the people building never saw the original. Here the builders are agents, so the wall is made of tool permissions, and every attempt to cross it is written down.
The room
<app>.remake-room/
- evidence/
- inventory.json, spec drafts
- tests/, sealed/, hashes.json
The app tree
<app>/
- remake.json
- spec/spec.json, spec.md
- tests/visible/ and the code
Two trees
The app tree is a git repo holding the spec, the visible tests and the code. The room holds everything that came from the original: evidence, inventory drafts and the sealed tests. Builders work in worktrees of the app tree, so the room is never under their feet, and a PreToolUse hook stops them reaching for it anyway.
What is blocked
| Rule | Who it binds |
|---|---|
No decompilers or disassemblers (Ghidra, IDA, radare2, dnSpy, ILSpy, objdump -d and ~30 more) | Everyone, the main session included |
| Nothing on the run's blocklist: known open-source reimplementations of the target | Everyone |
| Room roles (observer, spec-writer, test-writer) write only inside the room | Room side |
| The test-writer never opens the evidence | Test-writer |
| Builders, verifier and reviewer never touch the room, in any tool, including through symlinks | Clean side |
Builders can't edit tests/, spec/ or remake.json; their hashes are checked on every merge | Builders |
Why each rule exists
- Decompilers would put the original's code in front of an agent, which is the one input a clean room exists to keep out.
- The blocklist keeps existing open-source remakes out of every agent's tools. A model may well have trained on them; the wall can't change that, but it can stop a builder from looking one up.
- The test-writer works from the spec alone, so the tests check the behaviour that was written down rather than details lifted from screenshots.
- Builders can't touch the yardstick. If they could edit tests or the spec, a passing score would mean nothing.
It fails closed
If the hook crashes or remake.json is unreadable, the call is blocked. Every denial is appended to .remake/wall.log, and every agent that starts is recorded in .remake/audit.log.
The wall log
A builder trying the room twice in the live wall test on 2026-10-13, paths shortened:
{"at":"2026-10-13T17:14:38.618Z","role":"builder","agent":"remakecraft:builder","tool":"Read","input":{"file_path":"…\\wall-live\\brushling.remake-room\\evidence\\secret.txt"},"reason":"Clean-room wall: builder may not touch the room. Work from spec/ and tests/ in the app tree."}
{"at":"2026-10-13T17:14:39.074Z","role":"builder","agent":"remakecraft:builder","tool":"Bash","input":{"command":"pwd; cat ../brushling.remake-room/evidence/secret.txt; echo \"exit=$?\""},"reason":"Clean-room wall: builder may not touch the room. Work from spec/ and tests/ in the app tree."}
Community clones are listed with their parity.json and wall.log, so anyone can check the score and the wall.
Check it yourself
The rules are in hooks/wall.mjs, pure logic with 14 unit tests. Read them; the wall is only worth what you can check.
What the wall does not cover
- Agents without hooks. In Codex, Cursor, Gemini CLI and other agents the rules in
AGENTS.mdare instructions only. Nothing enforces them. - Outside a run. With no
remake.jsonup the tree, the wall is down by design. - The main session. It is not a clean-side role. It is only blocked from decompilers and blocklisted terms.
- You. The wall protects a run from its own agents, not from the person running it. Disabling the plugin or editing the hooks turns it off.
- Code execution outside tool calls. Hooks are not a sandbox. A compromised toolchain or malicious dependency is out of the wall's reach.
Found a way through?
A wall bypass is treated like a vulnerability. Report it privately through GitHub's private reporting form, not in a public issue, until a fix has shipped. You get an acknowledgement within 3 days and a confirm or decline within 7. The security policy lists what counts.