clean-room-skill 0.2.2 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.codex-plugin/plugin.json +1 -1
  4. package/README.md +5 -1
  5. package/agents/clean-architect.md +4 -0
  6. package/agents/clean-implementer-verifier-shell.md +4 -0
  7. package/agents/clean-polish-reviewer.md +4 -0
  8. package/agents/clean-qa-editor.md +4 -0
  9. package/agents/contaminated-handoff-sanitizer.md +4 -0
  10. package/agents/contaminated-manager-verifier.md +4 -0
  11. package/agents/contaminated-source-analyst.md +4 -0
  12. package/docs/ARCHITECTURE.md +2 -0
  13. package/docs/REFERENCE.md +28 -1
  14. package/lib/bootstrap.cjs +282 -30
  15. package/lib/fs-utils.cjs +1 -0
  16. package/lib/run-cli.cjs +1 -1
  17. package/lib/run-constants.cjs +7 -0
  18. package/lib/run-controller.cjs +38 -3
  19. package/lib/run-hooks.cjs +44 -11
  20. package/lib/run-results.cjs +23 -0
  21. package/lib/run-roots.cjs +56 -11
  22. package/package.json +1 -1
  23. package/plugin.json +1 -1
  24. package/skills/attended/SKILL.md +2 -1
  25. package/skills/clean-room/SKILL.md +6 -4
  26. package/skills/clean-room/assets/init-config.schema.json +8 -0
  27. package/skills/clean-room/assets/task-manifest.schema.json +16 -0
  28. package/skills/clean-room/references/LEAKAGE-RULES.md +2 -0
  29. package/skills/clean-room/references/PREFLIGHT.md +1 -0
  30. package/skills/clean-room/references/PROCESS.md +4 -1
  31. package/skills/clean-room/references/SPEC-SCHEMA.md +3 -0
  32. package/skills/init/SKILL.md +3 -2
  33. package/skills/preflight/SKILL.md +2 -1
  34. package/skills/resume-cr/SKILL.md +3 -2
  35. package/skills/start-over/SKILL.md +2 -0
  36. package/skills/unattended/SKILL.md +3 -2
@@ -9,7 +9,7 @@
9
9
  "name": "clean-room",
10
10
  "source": "./",
11
11
  "description": "Spec-first clean-room workflow for authorized source analysis without replacement code.",
12
- "version": "0.2.1",
12
+ "version": "0.3.0",
13
13
  "author": {
14
14
  "name": "whit3rabbit"
15
15
  },
@@ -2,7 +2,7 @@
2
2
  "name": "clean-room",
3
3
  "displayName": "Clean Room",
4
4
  "description": "Spec-first clean-room workflow for authorized source analysis without replacement code.",
5
- "version": "0.2.1",
5
+ "version": "0.3.0",
6
6
  "author": {
7
7
  "name": "whit3rabbit"
8
8
  },
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clean-room",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "description": "Spec-first clean-room workflow for authorized source analysis without replacement code.",
5
5
  "author": {
6
6
  "name": "whit3rabbit"
package/README.md CHANGED
@@ -109,6 +109,8 @@ npx clean-room-skill@latest init
109
109
 
110
110
  The default task root is `~/Documents/CleanRoom/<task-id>/` with `contaminated/`, `clean/`, `implementation/`, and `quarantine/` children. Keep active contaminated artifacts, clean artifacts, and clean implementation roots separate.
111
111
 
112
+ When multiple tasks target the same destination, group them under a clean-room project with `init --project <name>` (or `--new-project` for a generated name). The project layout is `~/Documents/CleanRoom/<project>/tasks/<task-id>/` with per-task `contaminated/`, `clean/`, and `quarantine/` children plus one shared `~/Documents/CleanRoom/<project>/implementation/` root for every task in the project. Project names must stay neutral, like task IDs: a random word pair such as `amber-meadow` or a generated `proj-xxxxxxxx`, never derived from source folder names. Run at most one active task per project at a time because tasks share the implementation root; `clean-room-skill run` enforces this with an advisory `.clean-room-implementation.lock` in each implementation root.
113
+
112
114
  In Claude Code, invoke skills with the plugin namespace:
113
115
 
114
116
  ```text
@@ -142,12 +144,14 @@ For unattended inner-loop execution from durable artifacts:
142
144
  ```bash
143
145
  npx clean-room-skill@latest run \
144
146
  --task-manifest ~/Documents/CleanRoom/task-1234abcd/contaminated/task-manifest.json \
145
- --agent-commands ./agent-commands.json \
147
+ --agent-runtime claude \
146
148
  --max-iterations 3
147
149
  ```
148
150
 
149
151
  The `run` command executes one bounded inner clean-room loop for an already approved spec slice. It does not replace the outer spec-development workflow.
150
152
 
153
+ Use `--agent-commands ./agent-commands.json` only for a custom non-Claude role-session adapter.
154
+
151
155
  In strict context-management mode, every `agent-commands.json` stage must set `context.fresh_session: true` and `context.brief_path`; see the runner adapter example in `docs/REFERENCE.md`.
152
156
 
153
157
  ## Typical Workflow
@@ -11,6 +11,10 @@ color: blue
11
11
 
12
12
  This role is Agent 2 in the clean-room pipeline.
13
13
 
14
+ ## Claude Code Tool Contract
15
+
16
+ When Claude Code tools are available, use their exact parameter names. `Read` uses `file_path`. `Write` uses `file_path` and `content`. `Bash` uses `command` only; put directory changes inside the command instead of passing `cwd`.
17
+
14
18
  Operate only in the clean domain from `CLEAN_ROOM_CLEAN_ROOTS` as the working directory. Read approved clean artifacts, `CLEAN_ROOM_IMPLEMENTATION_ROOTS`, and explicitly configured public or destination constraint roots. Write only under `CLEAN_ROOM_CLEAN_ROOTS`. Do not write code. Do not read source workspaces, visual roots, raw screenshots, visual indexes, contaminated ledgers, contaminated chat history, or the full `task-manifest.json`.
15
19
 
16
20
  Before tool use, confirm this session has `CLEAN_ROOM_ROLE=clean-architect`, `CLEAN_ROOM_CLEAN_ROOTS`, `CLEAN_ROOM_IMPLEMENTATION_ROOTS`, `CLEAN_ROOM_SOURCE_ROOTS`, `CLEAN_ROOM_CONTAMINATED_ARTIFACT_ROOTS`, `CLEAN_ROOM_ALLOWED_READ_ROOTS`, and `CLEAN_ROOM_SCHEMA_DIR`. Treat missing environment as a stop condition.
@@ -11,6 +11,10 @@ color: cyan
11
11
 
12
12
  This is the explicit shell-capable Agent 3 variant. Use it only in a dedicated clean-room home with strict hooks installed, source roots unmounted where practical, and `CLEAN_ROOM_ALLOW_AGENT3_SHELL=1` set deliberately.
13
13
 
14
+ ## Claude Code Tool Contract
15
+
16
+ When Claude Code tools are available, use their exact parameter names. `Read` uses `file_path`. `Write` uses `file_path` and `content`. `Bash` uses `command` only; put directory changes inside the command instead of passing `cwd`.
17
+
14
18
  Operate only in the clean domain. Read approved clean artifacts, `CLEAN_ROOM_IMPLEMENTATION_ROOTS`, and explicitly configured public or destination constraint roots only. Write clean reports under `CLEAN_ROOM_CLEAN_ROOTS`. Write code, tests, fixtures, and destination project files only under `CLEAN_ROOM_IMPLEMENTATION_ROOTS`. Do not read source workspaces, visual roots, raw screenshots, visual indexes, contaminated ledgers, contaminated chat history, or the full `task-manifest.json`.
15
19
 
16
20
  Before tool use, confirm this session has `CLEAN_ROOM_ROLE=clean-qa-editor`, `CLEAN_ROOM_CLEAN_ROOTS`, `CLEAN_ROOM_IMPLEMENTATION_ROOTS`, `CLEAN_ROOM_SOURCE_ROOTS`, `CLEAN_ROOM_CONTAMINATED_ARTIFACT_ROOTS`, `CLEAN_ROOM_ALLOWED_READ_ROOTS`, `CLEAN_ROOM_SCHEMA_DIR`, and `CLEAN_ROOM_ALLOW_AGENT3_SHELL=1`. Treat missing environment as a stop condition.
@@ -11,6 +11,10 @@ color: pink
11
11
 
12
12
  This role is Agent 4 in the clean-room pipeline.
13
13
 
14
+ ## Claude Code Tool Contract
15
+
16
+ When Claude Code tools are available, use their exact parameter names. `Read` uses `file_path`. `Write` uses `file_path` and `content`. `Bash` uses `command` only; put directory changes inside the command instead of passing `cwd`.
17
+
14
18
  Operate only in the clean domain. Read approved clean artifacts, `CLEAN_ROOM_IMPLEMENTATION_ROOTS`, schemas, and explicitly configured public or destination constraint roots only. Write `polish-report.json` and clean reports under `CLEAN_ROOM_CLEAN_ROOTS`. Write implementation code, tests, docs, `AGENTS.md`, `.gitignore`, and destination project files only under `CLEAN_ROOM_IMPLEMENTATION_ROOTS`. Do not read source workspaces, visual roots, raw screenshots, contaminated ledgers, contaminated chat history, the full `task-manifest.json`, the full `preflight-goal.json`, `source-index.json`, or `visual-index.json`.
15
19
 
16
20
  Before tool use, confirm this session has `CLEAN_ROOM_ROLE=clean-polish-reviewer`, `CLEAN_ROOM_CLEAN_ROOTS`, `CLEAN_ROOM_IMPLEMENTATION_ROOTS`, `CLEAN_ROOM_SOURCE_ROOTS`, `CLEAN_ROOM_CONTAMINATED_ARTIFACT_ROOTS`, `CLEAN_ROOM_ALLOWED_READ_ROOTS`, and `CLEAN_ROOM_SCHEMA_DIR`. Treat missing environment as a stop condition.
@@ -11,6 +11,10 @@ color: green
11
11
 
12
12
  This role is Agent 3 in the clean-room pipeline.
13
13
 
14
+ ## Claude Code Tool Contract
15
+
16
+ When Claude Code tools are available, use their exact parameter names. `Read` uses `file_path`. `Write` uses `file_path` and `content`. `Bash` uses `command` only; put directory changes inside the command instead of passing `cwd`.
17
+
14
18
  Operate only in the clean domain. Read approved clean artifacts, `CLEAN_ROOM_IMPLEMENTATION_ROOTS`, and explicitly configured public or destination constraint roots only. Write clean reports under `CLEAN_ROOM_CLEAN_ROOTS`. Write code, tests, fixtures, and destination project files only under `CLEAN_ROOM_IMPLEMENTATION_ROOTS`. Do not read source workspaces, visual roots, raw screenshots, visual indexes, contaminated ledgers, contaminated chat history, or the full `task-manifest.json`.
15
19
 
16
20
  Before tool use, confirm this session has `CLEAN_ROOM_ROLE=clean-qa-editor`, `CLEAN_ROOM_CLEAN_ROOTS`, `CLEAN_ROOM_IMPLEMENTATION_ROOTS`, `CLEAN_ROOM_SOURCE_ROOTS`, `CLEAN_ROOM_CONTAMINATED_ARTIFACT_ROOTS`, `CLEAN_ROOM_ALLOWED_READ_ROOTS`, and `CLEAN_ROOM_SCHEMA_DIR`. Treat missing environment as a stop condition.
@@ -11,6 +11,10 @@ color: yellow
11
11
 
12
12
  This role is Agent 1.5 in the clean-room pipeline.
13
13
 
14
+ ## Claude Code Tool Contract
15
+
16
+ When Claude Code tools are available, use their exact parameter names. `Read` uses `file_path`. `Write` uses `file_path` and `content`. `Bash` uses `command` only; put directory changes inside the command instead of passing `cwd`.
17
+
14
18
  Operate in the contaminated domain, but with no source access and no Agent 1 source-reading chat history. Read only assigned draft artifacts under `CLEAN_ROOM_CONTAMINATED_ARTIFACT_ROOTS`, the schema directory, and explicitly configured public or destination reference roots. Write only under `CLEAN_ROOM_CONTAMINATED_ARTIFACT_ROOTS`.
15
19
 
16
20
  Before tool use, confirm this session has `CLEAN_ROOM_ROLE=contaminated-handoff-sanitizer`, `CLEAN_ROOM_CONTAMINATED_ARTIFACT_ROOTS`, `CLEAN_ROOM_SOURCE_ROOTS`, `CLEAN_ROOM_CLEAN_ROOTS`, `CLEAN_ROOM_IMPLEMENTATION_ROOTS`, `CLEAN_ROOM_ALLOWED_READ_ROOTS`, and `CLEAN_ROOM_SCHEMA_DIR`. Treat missing environment as a stop condition.
@@ -11,6 +11,10 @@ color: purple
11
11
 
12
12
  This role is Agent 0 in the clean-room pipeline.
13
13
 
14
+ ## Claude Code Tool Contract
15
+
16
+ When Claude Code tools are available, use their exact parameter names. `Read` uses `file_path`. `Write` uses `file_path` and `content`. `Bash` uses `command` only; put directory changes inside the command instead of passing `cwd`.
17
+
14
18
  Operate only in the contaminated domain. Read authorized source and contaminated ledgers as needed. Write only to an explicitly authorized contaminated artifact directory; do not write clean artifacts directly.
15
19
 
16
20
  ## Required Handoff Inputs
@@ -11,6 +11,10 @@ color: orange
11
11
 
12
12
  This role is Agent 1 in the clean-room pipeline.
13
13
 
14
+ ## Claude Code Tool Contract
15
+
16
+ When Claude Code tools are available, use their exact parameter names. `Read` uses `file_path`. `Write` uses `file_path` and `content`. `Bash` uses `command` only; put directory changes inside the command instead of passing `cwd`.
17
+
14
18
  Operate only in the contaminated domain. Treat source access as read-only. Write only under `CLEAN_ROOM_CONTAMINATED_ARTIFACT_ROOTS`.
15
19
 
16
20
  Do not use shell-style tools in this role.
@@ -33,6 +33,8 @@ Optional Docker or Podman support is limited to Agent 3 verification containers.
33
33
 
34
34
  Artifact roots must not disclose private source names. New runs default to `~/Documents/CleanRoom/<task-id>/`; when no explicitly approved neutral task ID is provided, the controller generates `task-` plus 8 lowercase hex characters instead of using the source folder name.
35
35
 
36
+ Multiple tasks targeting the same destination may be grouped under an optional clean-room project: `~/Documents/CleanRoom/<project>/tasks/<task-id>/` with one shared `<project>/implementation/` root. Project names follow the same neutrality rule as task IDs: a random neutral word pair (such as `amber-meadow`) or a generated `proj-` plus 8 lowercase hex characters, matching `[a-z0-9][a-z0-9-]{0,63}` and never derived from source folder names. Because the implementation root is shared, run at most one active task per project at a time; `clean-room-skill run` enforces this with an advisory `.clean-room-implementation.lock` in each implementation root.
37
+
36
38
  ![Artifact Roots](assets/2.png)
37
39
 
38
40
  The initialization wizard and `require-clean-room-env.py` audit clean, implementation, and contaminated artifact root names. They fail closed when a path contains a source root basename or meaningful non-generic tokens from that basename, while filtering generic terms such as `src`, `app`, `test`, `repo`, and `workspace`.
package/docs/REFERENCE.md CHANGED
@@ -164,6 +164,7 @@ Usage:
164
164
  npx clean-room-skill@latest init
165
165
  npx clean-room-skill@latest init --target-dir . --target-profile speckit-feature-folder
166
166
  npx clean-room-skill@latest init --artifact-base ~/Documents/CleanRoom --task-id task-1234abcd
167
+ npx clean-room-skill@latest init --project amber-meadow --task-id task-1234abcd
167
168
  ```
168
169
 
169
170
  Options:
@@ -173,11 +174,13 @@ Options:
173
174
  | `--target-dir <path>` | Repository to initialize; default is current directory. |
174
175
  | `--artifact-base <path>` | External CleanRoom base; default is `~/Documents/CleanRoom`. |
175
176
  | `--task-id <id>` | Neutral task id; default is generated `task-xxxxxxxx`. |
177
+ | `--project <name>` | Group the task under a clean-room project; joins the project when it already exists. Names must be neutral (`[a-z0-9][a-z0-9-]{0,63}`, never derived from source or workspace folder names). |
178
+ | `--new-project` | Create a project with a generated `proj-xxxxxxxx` name. Cannot be combined with `--project`. |
176
179
  | `--target-profile <name>` | `openspec-delta`, `gsd-planning-package`, `speckit-feature-folder`, or `kiro-spec-folder`. |
177
180
  | `--dry-run` | Print actions without writing files. |
178
181
  | `--force` | Overwrite existing bootstrap metadata and repo stub. |
179
182
 
180
- By default, `init` creates:
183
+ By default, `init` creates a single-task layout under `<artifact-base>/<task-id>/`:
181
184
 
182
185
  - `contaminated/`
183
186
  - `clean/`
@@ -186,6 +189,22 @@ By default, `init` creates:
186
189
  - `clean-room-bootstrap.json`
187
190
  - `.clean-room/README.md` in the target repository
188
191
 
192
+ With `--project` or `--new-project`, `init` creates a project layout instead. Tasks live under `<artifact-base>/<project>/tasks/<task-id>/` with per-task `contaminated/`, `clean/`, and `quarantine/`, while every task in the project shares one `<artifact-base>/<project>/implementation/` root:
193
+
194
+ ```text
195
+ <artifact-base>/<project>/
196
+ ├── clean-room-project.json
197
+ ├── implementation/ (shared by all tasks)
198
+ └── tasks/
199
+ └── <task-id>/
200
+ ├── contaminated/
201
+ ├── clean/
202
+ ├── quarantine/
203
+ └── clean-room-bootstrap.json
204
+ ```
205
+
206
+ Re-running `init --project <name>` with a new task id joins the existing project without `--force`: the project metadata and shared `implementation/` are reused, and only the new task folders must not already exist. Because tasks share the implementation root, run at most one active task per project at a time; `clean-room-skill run` enforces this with an advisory `.clean-room-implementation.lock` in each implementation root.
207
+
189
208
  Do not commit source roots, contaminated artifact paths, private identifiers, source-derived names, `preflight-goal.json`, `init-config.json`, `task-manifest.json`, `controller-status.json`, `role-session-brief.json`, or `clean-run-context.json` into the clean implementation repository.
190
209
 
191
210
  ## Preflight CLI
@@ -198,6 +217,7 @@ Usage:
198
217
  npx clean-room-skill@latest preflight --template --output ~/Documents/CleanRoom/task-1234abcd/contaminated/preflight-goal.json
199
218
  npx clean-room-skill@latest preflight --input ./preflight-goal.json --output ~/Documents/CleanRoom/task-1234abcd/contaminated/preflight-goal.json
200
219
  npx clean-room-skill@latest preflight --template --bootstrap ~/Documents/CleanRoom/task-1234abcd
220
+ npx clean-room-skill@latest preflight --template --bootstrap ~/Documents/CleanRoom/amber-meadow/tasks/task-1234abcd
201
221
  ```
202
222
 
203
223
  Options:
@@ -358,9 +378,16 @@ The runner exports `CLEAN_ROOM_SESSION_BRIEF_PATH`, `CLEAN_ROOM_ROLE_SESSION_ID`
358
378
  | `python3 is required to install clean-room hooks` | Python missing or not on `PATH` | Install Python 3 or use `--hooks=copy-only`. |
359
379
  | `safe hooks are installed; clean-room init/onboarding must set role environment variables` | Safe mode default | Start the clean-room init/onboarding flow, or use strict hooks in a dedicated profile. |
360
380
  | `install lock is held` | Another install or uninstall is mutating the same target root | Wait for the other process to finish; stale locks are handled conservatively. |
381
+ | `clean-room run lock is held` | Another run is active for the same task's contaminated root, or a crashed run left a recent lock | Wait for the other run to finish. Locks from dead processes age out and are moved aside automatically; if no run is active, remove `.clean-room-run.lock` from the contaminated root and retry. |
382
+ | `clean-room implementation lock is held` | Another task in the same clean-room project is running against the shared implementation root, or a crashed run left a recent lock | Wait for the other run to finish. Locks from dead processes age out and are moved aside automatically; if no run is active, remove `.clean-room-implementation.lock` from the implementation root and retry. |
361
383
  | Hook config write failed after files copied | Partial installer state | Fix the filesystem error, then re-run the same installer command. |
362
384
  | Install manifest remains `installing` | The previous install did not complete | Re-run the same installer command for that runtime and target root. |
385
+ | `clean-room-skill` is not found | The CLI is not globally installed or the runtime PATH does not include it | Use `npx clean-room-skill@latest ...` immediately; do not search plugin caches for package internals. |
386
+ | `--schema-dir` reports missing schemas | The override points at a stale plugin cache, clean root, or non-directory path | Omit `--schema-dir` to use bundled schemas. Pass it only for a real directory containing `task-manifest.schema.json`. Do not use `/dev/null`. |
387
+ | `task manifest not found` for a task root | The runner needs the contaminated-side manifest file | Pass `~/Documents/CleanRoom/<task-id>/contaminated/task-manifest.json` (or `~/Documents/CleanRoom/<project>/tasks/<task-id>/contaminated/task-manifest.json` in the project layout), not the task root or clean root. |
388
+ | `preflight goal not found` | `task-manifest.json` references a missing or misplaced contaminated-side preflight file | Restore `preflight-goal.json` under the contaminated artifact root, update `preflight_goal_ref` and `preflight_goal_sha256`, then retry `--dry-run`. |
363
389
  | `clean-room run` rejects the manifest | Invalid or incomplete unattended loop metadata | Fix `controller_policy`, `loop_context.foundation_unit_ref`, and `approved_scope_refs`, then retry `--dry-run`. |
390
+ | `clean-room artifact validation failed` lists stale JSON files | Old or hand-written clean-room artifacts are still under contaminated or clean artifact roots | Update those artifacts to current schemas or move stale/legacy JSON to quarantine, then retry `--dry-run`. |
364
391
  | `clean-room run` rejects a covered unit with `discovery_leads` | A high-priority contaminated discovery lead is still unresolved | Analyze the lead in an authorized follow-up unit, mark it resolved, or keep coverage partial/blocked and return an abstract delta. |
365
392
  | `clean-room run` rejects an agent command stage in strict context mode | The stage is missing `context.fresh_session: true`, missing `context.brief_path`, or points the brief outside the allowed artifact root | Fix the stage context and regenerate the role-session brief for the selected unit. |
366
393
  | `clean-room run` reports no progress | Configured stages exited without durable artifact changes | Check role command cwd/argv, selected unit, and artifact write roots. |