Clean-room loop (discussion -> clean-room-loop workflow launch)
Conversational front door to the clean-room-loop dynamic workflow (.claude/workflows/clean-room-loop.js).
The workflow runs in the background with no way to ask anything mid-run, so the discussion happens
HERE; answers pass as args.
Claude Code only. Dynamic workflows are a Claude Code feature. In Pi/Codex/OpenCode the
Workflow() call will not exist - see the Fallback step. Only this workflow shortcut is Claude
Code specific; the underlying clean-room skills (/clean-room:unattended, clean-room-skill run)
work on every supported runtime.
Installed project-local. The workflow script ships to project-local .claude/workflows/
(not global). Workflow({ name }) discovers it from the current project's .claude/workflows/
(or ~/.claude/workflows/ if a personal copy exists). If the current project does not have it,
initialize a project-local install before launching - see Step 3.
What this is (and is NOT)
- It drives the six clean-room roles with the workflow's OWN
agent() subagents (in-session,
subscription, no claude -p), gating every wall crossing with the real
clean-room-skill artifact validate --role leakage + schema hooks.
- It is a cost-free path with context-level separation, NOT the OS-enforced wall. A workflow
cannot set
CLEAN_ROOM_* env or install hooks, so nothing stops a clean subagent from reading
source off disk except the neutral-artifact discipline + the leakage gate. If the user needs the
enforced boundary, use clean-room-skill run --agent-runtime claude instead (that path costs API
tokens by design).
- The workflow READS the authorized source and WRITES clean specs, plans, code, and reports under the
external artifact roots. Confirm authorization and paths before launching.
Steps
Get the brief. Take the end goal from the invocation if present. If missing, ask what they are
reimplementing and why they are authorized to.
Run the discussion. Collect the fields below with AskUserQuestion (batch - max 4 per call,
~3 calls); ask free-text ones plainly. Offer defaults so a terse brief is still runnable. Do NOT
infer the end goal or target stack from source - clean-room forbids it; if unknown, ask.
Batch A (goal + stack):
- endGoal (free-text): what the clean implementation must do; its success definition.
- targetStack: language / runtime / framework / packageManager / testFramework. Pass as a nested object.
- compatibilityPolicy: public-behavior-and-API-names only (default) or public-behavior-only.
Private structure/comments/internal names are NEVER mirrored.
- featurePolicy (skippable): features to preserve / remove / add / non-goals.
Batch B (policy):
- licensePolicy: destination license + any blocked dep licenses.
- dependencyPolicy: allow new deps? prefer stdlib? require approval for native deps.
- codeHygienePolicy (skippable): max lines per code/test file, max files per iteration.
- schemaProfile: speckit-feature-folder (default) / openspec-delta / gsd-planning-package / kiro-spec-folder.
Batch C (roots + bounds - all safety-relevant):
- sourceRoots (REQUIRED): absolute path(s) to the authorized source. No source = cannot run.
- artifactBase: where run artifacts live (default
~/Documents/CleanRoom). Must be OUTSIDE the
source tree and neutral-named.
- project / taskId (skippable): neutral names; the CLI generates neutral ones if omitted.
- maxIterations: finite inner-loop cap (default 3).
Ensure the workflow is installed project-local, preview, STOP for confirmation, then launch.
First confirm this project has the workflow. Dynamic workflows load from project-local
.claude/workflows/. If .claude/workflows/clean-room-loop.js is absent in the current project
(and no ~/.claude/workflows/clean-room-loop.js personal copy exists), initialize a project-local
install before launching:
clean-room-skill --claude --local --yes
# or, without a global CLI:
npx clean-room-skill@latest --claude --local --yes
That writes clean-room-loop.js into the current project's .claude/workflows/ so
Workflow({ name }) can discover it. Then show a compact preview of the args
(at least endGoal, sourceRoots, artifactBase, targetStack, maxIterations) so a wrong
source path or output root is caught BEFORE a filesystem-writing, source-reading run starts. STOP
and wait for an explicit "yes". Do NOT call Workflow in the same turn as the preview. Only after
the user confirms:
Workflow({ name: "clean-room-loop", args: {
endGoal,
targetStack, // { language, runtime, framework, packageManager, testFramework }
compatibilityPolicy, featurePolicy,
licensePolicy, dependencyPolicy, codeHygienePolicy,
sourceRoots, // array of absolute paths (REQUIRED)
artifactBase, project, taskId,
schemaProfile, maxIterations,
specSliceRef, // optional
}})
Pass only what was gathered; omit the rest (the workflow defaults them).
Fallback. If Workflow() errors or is unavailable (non-Claude host, or dynamic workflows
disabled), do NOT hand-run the roles here. Route the user to /clean-room:unattended, which
prefers fresh-context in-harness roles on that harness and drops to the durable runner only as a
last resort: clean-room-skill run --agent-commands <adapter> on Codex/Pi/other runtimes (spawns
the harness CLI, shell: false), or --agent-runtime claude (spawns claude -p, Claude only,
per-token) last. Use the runner only once a runner-ready manifest with loop_context exists.
Hand back the workflow's result (the terminal clean-room-result.json result string, task
root, and clean/implementation roots).
Source: hashgraph-online/awesome-codex-plugins → plugins/whit3rabbit/clean-room-skill/skills/clean-room-loop/SKILL.md
1---2name: clean-room-loop3description: Front door for running the clean-room unattended loop as a Claude Code dynamic WORKFLOW using in-session subagents, so it never spends `claude -p` API tokens. Use when the user wants to run a clean-room / reverse-engineering / source-to-clean-implementation task hands-off but without paying per-token for `clean-room-skill run`, or says "clean-room as a workflow", "unattended clean-room without API cost", "/clean-room-loop". Runs a short discussion (authorization, end goal, target stack, policies, source roots, output roots, iterations) then launches the `clean-room-loop` workflow with the answers. NOT the enforced OS-level wall - that is `clean-room-skill run --agent-runtime claude`.4---567# Clean-room loop (discussion -> clean-room-loop workflow launch)89Conversational front door to the `clean-room-loop` dynamic workflow (`.claude/workflows/clean-room-loop.js`).10The workflow runs in the background with no way to ask anything mid-run, so the discussion happens11HERE; answers pass as `args`.1213**Claude Code only.** Dynamic workflows are a Claude Code feature. In Pi/Codex/OpenCode the14`Workflow()` call will not exist - see the Fallback step. Only this workflow shortcut is Claude15Code specific; the underlying clean-room skills (`/clean-room:unattended`, `clean-room-skill run`)16work on every supported runtime.1718**Installed project-local.** The workflow script ships to project-local `.claude/workflows/`19(not global). `Workflow({ name })` discovers it from the current project's `.claude/workflows/`20(or `~/.claude/workflows/` if a personal copy exists). If the current project does not have it,21initialize a project-local install before launching - see Step 3.2223## What this is (and is NOT)2425- It drives the six clean-room roles with the workflow's OWN `agent()` subagents (in-session,26 subscription, **no `claude -p`**), gating every wall crossing with the real27 `clean-room-skill artifact validate --role` leakage + schema hooks.28- It is a **cost-free path with context-level separation**, NOT the OS-enforced wall. A workflow29 cannot set `CLEAN_ROOM_*` env or install hooks, so nothing stops a clean subagent from reading30 source off disk except the neutral-artifact discipline + the leakage gate. If the user needs the31 enforced boundary, use `clean-room-skill run --agent-runtime claude` instead (that path costs API32 tokens by design).33- The workflow READS the authorized source and WRITES clean specs, plans, code, and reports under the34 external artifact roots. Confirm authorization and paths before launching.3536## Steps37381. **Get the brief.** Take the end goal from the invocation if present. If missing, ask what they are39 reimplementing and why they are authorized to.40412. **Run the discussion.** Collect the fields below with `AskUserQuestion` (batch - max 4 per call,42 ~3 calls); ask free-text ones plainly. Offer defaults so a terse brief is still runnable. Do NOT43 infer the end goal or target stack from source - clean-room forbids it; if unknown, ask.4445 Batch A (goal + stack):46 - **endGoal** (free-text): what the clean implementation must do; its success definition.47 - **targetStack**: language / runtime / framework / packageManager / testFramework. Pass as a nested object.48 - **compatibilityPolicy**: public-behavior-and-API-names only (default) or public-behavior-only.49 Private structure/comments/internal names are NEVER mirrored.50 - **featurePolicy** (skippable): features to preserve / remove / add / non-goals.5152 Batch B (policy):53 - **licensePolicy**: destination license + any blocked dep licenses.54 - **dependencyPolicy**: allow new deps? prefer stdlib? require approval for native deps.55 - **codeHygienePolicy** (skippable): max lines per code/test file, max files per iteration.56 - **schemaProfile**: speckit-feature-folder (default) / openspec-delta / gsd-planning-package / kiro-spec-folder.5758 Batch C (roots + bounds - all safety-relevant):59 - **sourceRoots** (REQUIRED): absolute path(s) to the authorized source. No source = cannot run.60 - **artifactBase**: where run artifacts live (default `~/Documents/CleanRoom`). Must be OUTSIDE the61 source tree and neutral-named.62 - **project / taskId** (skippable): neutral names; the CLI generates neutral ones if omitted.63 - **maxIterations**: finite inner-loop cap (default 3).64653. **Ensure the workflow is installed project-local, preview, STOP for confirmation, then launch.**66 First confirm this project has the workflow. Dynamic workflows load from project-local67 `.claude/workflows/`. If `.claude/workflows/clean-room-loop.js` is absent in the current project68 (and no `~/.claude/workflows/clean-room-loop.js` personal copy exists), initialize a project-local69 install before launching:7071 ```bash72 clean-room-skill --claude --local --yes73 # or, without a global CLI:74 npx clean-room-skill@latest --claude --local --yes75 ```7677 That writes `clean-room-loop.js` into the current project's `.claude/workflows/` so78 `Workflow({ name })` can discover it. Then show a compact preview of the `args`79 (at least `endGoal`, `sourceRoots`, `artifactBase`, `targetStack`, `maxIterations`) so a wrong80 source path or output root is caught BEFORE a filesystem-writing, source-reading run starts. STOP81 and wait for an explicit "yes". Do NOT call `Workflow` in the same turn as the preview. Only after82 the user confirms:8384 ```85 Workflow({ name: "clean-room-loop", args: {86 endGoal,87 targetStack, // { language, runtime, framework, packageManager, testFramework }88 compatibilityPolicy, featurePolicy,89 licensePolicy, dependencyPolicy, codeHygienePolicy,90 sourceRoots, // array of absolute paths (REQUIRED)91 artifactBase, project, taskId,92 schemaProfile, maxIterations,93 specSliceRef, // optional94 }})95 ```9697 Pass only what was gathered; omit the rest (the workflow defaults them).98994. **Fallback.** If `Workflow()` errors or is unavailable (non-Claude host, or dynamic workflows100 disabled), do NOT hand-run the roles here. Route the user to `/clean-room:unattended`, which101 prefers fresh-context in-harness roles on that harness and drops to the durable runner only as a102 last resort: `clean-room-skill run --agent-commands <adapter>` on Codex/Pi/other runtimes (spawns103 the harness CLI, `shell: false`), or `--agent-runtime claude` (spawns `claude -p`, Claude only,104 per-token) last. Use the runner only once a runner-ready manifest with `loop_context` exists.1051065. **Hand back** the workflow's result (the terminal `clean-room-result.json` result string, task107 root, and clean/implementation roots).108109---110111**Source:** [`hashgraph-online/awesome-codex-plugins`](https://github.com/hashgraph-online/awesome-codex-plugins) → `plugins/whit3rabbit/clean-room-skill/skills/clean-room-loop/SKILL.md`