create-harness-vibe-coding 0.8.4 → 0.8.6

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.
package/README.md CHANGED
@@ -18,7 +18,7 @@ npx create-harness-vibe-coding@latest my-project
18
18
 
19
19
  ## Your Agent Knows What to Do
20
20
 
21
- Already have a project? **Don't read the docs**. Paste this sentence. Your agent handles the rest.
21
+ Already have a project? Paste this sentence. Your agent should use the script-first fast path: dry-run JSON first, read only files named in `agent.aiMergeRequired`, then run the structural validator.
22
22
 
23
23
  ```text
24
24
  Read and follow https://github.com/zingspark/create-harness-vibe-coding exactly to configure this project with create-harness-vibe-coding.
@@ -41,7 +41,7 @@ Chinese README: [README-CN.md](README-CN.md)
41
41
  | `subagent-orchestrator` | Runs parallel agents without collision |
42
42
  | `memory-master` + `context-master` | Learns from failures, compresses when full |
43
43
  | PRD + Research templates | Asks "what" and "why" before coding |
44
- | 11 built-in agents | Research, plan, architect, test, build, review, debug, verify |
44
+ | 16 built-in agents | Research, plan, architecture, TDD, build, review, debug, verify, memory/context, WF-MAX managers |
45
45
  | Architecture docs | Knows where boundaries live |
46
46
  | Context-loading protocol | Loads only the docs each agent needs |
47
47
  | `.claude/` + `.agents/skills/` | Claude Code and Codex skill adapters over the same Harness docs |
@@ -125,10 +125,15 @@ npx create-harness-vibe-coding@latest my-app . -y --dry-run --json
125
125
 
126
126
  # Add only what's missing. Never overwrite.
127
127
  npx create-harness-vibe-coding@latest my-app . -y --on-conflict skip --json
128
+
129
+ # Install-complete structural gate.
130
+ node Harness/scripts/validate-harness.mjs
128
131
  ```
129
132
 
130
133
  The JSON output is the agent's install report: `scan` replaces hand-written root probes, `plan.create` is script-owned, and `agent.aiMergeRequired` is the only list that needs semantic AI review. Do not read package source or templates unless `agent.aiMergeRequired` names a conflicting file.
131
134
 
135
+ For existing projects, a passing non-strict validator is the install-complete gate. `--strict` is the bootstrap/release gate and may fail until PRD, research, and architecture placeholders have been resolved from real project facts.
136
+
132
137
  `npx` is an install and safe-merge entry, not an update engine for an already installed Harness. Once `Harness/` exists, use `/wf-update` in Claude Code, `$wf-update` in Codex, or `node Harness/scripts/wf-update-check.mjs`; root entry conflicts such as `CLAUDE.md`, `AGENTS.md`, `.claude/`, `.agents/`, `.codex/`, and local Harness docs need agent-mediated merge decisions.
133
138
 
134
139
  | Flag | Does |
@@ -182,6 +187,14 @@ npx create-harness-vibe-coding@latest my-app . -y --dry-run --json
182
187
 
183
188
  Use `scan.markers` instead of manual top-level probes. Ask **at most 3 blocking questions** before touching files. Files in `plan.create` are handled by the script; only files in `agent.aiMergeRequired` need AI comparison and user-supervised merge decisions.
184
189
 
190
+ Fast path for an existing project with no installed `Harness/`:
191
+
192
+ 1. Run the dry-run JSON command.
193
+ 2. Run the JSON `agent.safeMergeCommand` to create only missing files.
194
+ 3. Patch only files listed in `agent.aiMergeRequired`; preserve project-owned content.
195
+ 4. Run `node Harness/scripts/validate-harness.mjs`.
196
+ 5. Stop and report install status. Defer `--strict` until bootstrap fills project-fact placeholders.
197
+
185
198
  Ask these only when they affect writes:
186
199
 
187
200
  - If `CLAUDE.md` or `AGENTS.md` already exists, should missing Harness guidance be merged, kept separate, or skipped?
@@ -205,7 +218,10 @@ Harness docs always live in root `Harness/`; do not route Harness files through
205
218
  # In this package repo
206
219
  npm test
207
220
 
208
- # In a generated project after bootstrap
221
+ # In an existing project immediately after safe-merge install
222
+ node Harness/scripts/validate-harness.mjs
223
+
224
+ # In a generated project after bootstrap, or before release
209
225
  node Harness/scripts/validate-harness.mjs --strict
210
226
  ```
211
227
 
@@ -229,7 +245,7 @@ my-project/
229
245
  │ ├── memory/ ← Durable self-learning
230
246
  │ └── scripts/ ← Validator
231
247
  ├── .claude/
232
- │ ├── agents/ ← 11 common agents
248
+ │ ├── agents/ ← 16 built-in agents
233
249
  │ ├── skills/ ← Claude Code skill commands
234
250
  │ └── rules/ ← Universal coding rules
235
251
  ├── .agents/
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-harness-vibe-coding",
3
- "version": "0.8.4",
3
+ "version": "0.8.6",
4
4
  "description": "Scaffold a 0-1 product harness for AI-assisted research, PRD, planning, architecture, build, test, and feedback loops",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,14 +1,17 @@
1
- ---
2
- name: wf-remove
3
- description: Use for /wf-remove in Claude Code, $wf-remove or /skills wf-remove in Codex, or any request to uninstall Harness safely.
4
- ---
5
-
6
- # WF Remove Adapter
7
-
1
+ ---
2
+ name: wf-remove
3
+ description: Use for /wf-remove in Claude Code, $wf-remove or /skills wf-remove in Codex, or any request to uninstall Harness safely.
4
+ ---
5
+
6
+ # WF Remove Adapter
7
+
8
8
  ## Invocation
9
9
 
10
10
  - Claude Code: use `/wf-remove` or select the `wf-remove` skill.
11
11
  - Codex CLI or IDE: use `$wf-remove` or `/skills` then choose `wf-remove`.
12
+ - User-facing removal is the slash/skill command. The Node commands below are
13
+ agent-internal execution steps; do not ask the user to copy/paste them unless
14
+ the agent has no shell/tool access.
12
15
 
13
16
  ## Load
14
17
 
@@ -17,21 +20,31 @@ description: Use for /wf-remove in Claude Code, $wf-remove or /skills wf-remove
17
20
 
18
21
  ## Flow
19
22
 
20
- 1. Run `node Harness/scripts/wf-remove.mjs --json` for the machine-readable
21
- plan.
22
- 2. Auto-remove only SAFE files that still match stored checksums.
23
+ 1. On plain `/wf-remove`, run `node Harness/scripts/wf-remove.mjs --json` for
24
+ the machine-readable plan, then run the safe default apply command yourself.
25
+ 2. Auto-remove only SAFE files that still match stored checksums or exact
26
+ built-in Harness discovery files recognized by the script.
23
27
  3. Ask the user before every MODIFIED or uncertain file.
24
28
  4. Preserve USER DATA by default. For an explicit thorough uninstall, use
25
29
  `--purge-user-data` (alias `--purge`); add `--keep-tasks` when the user wants task records
26
30
  retained while project-fact Harness docs are removed.
27
- 5. Run the script, not manual deletes:
31
+ 5. Run the script yourself, not manual deletes and not user-side command copy:
28
32
  - safe default: `node Harness/scripts/wf-remove.mjs --apply --yes`
29
33
  - thorough but keep tasks: `node Harness/scripts/wf-remove.mjs --apply --yes --purge-user-data --keep-tasks`
30
34
  - exact modified decisions: add `--delete-modified <path>` for each
31
35
  user-approved MODIFIED file.
36
+ 6. After apply, verify residual discovery folders:
37
+ - `.claude/agents`
38
+ - `.claude/skills`
39
+ - `.claude/commands`
40
+ - `.claude/rules`
41
+ - `.agents/skills`
42
+ - `.codex`
43
+ Built-in Harness files in these locations should be gone. Custom user skills
44
+ or user-owned files may remain and must be reported, not blindly deleted.
32
45
 
33
46
  ## Return
34
47
 
35
48
  Report SAFE removals, MODIFIED keep/delete decisions, preserved USER DATA,
36
- PURGE removals, directory cleanup, CLAUDE/AGENTS status, `.harness-version`
37
- status, and `git status` guidance.
49
+ PURGE removals, directory cleanup, `.claude` / `.agents` / `.codex` residual
50
+ status, `.harness-version` status, and `git status` guidance.
@@ -1,6 +1,6 @@
1
1
  {
2
- "generator": "0.8.4",
3
- "generated": "2026-07-02T09:50:07.142Z",
2
+ "generator": "0.8.6",
3
+ "generated": "2026-07-02T10:59:32.891Z",
4
4
  "options": [],
5
5
  "autoCheck": true,
6
6
  "source": "https://raw.githubusercontent.com/zingspark/create-harness-vibe-coding/main/templates/common/",
@@ -12,7 +12,7 @@
12
12
  ".agents/skills/wf-learn/SKILL.md": "sha256-7f3e1ee0aa83cbb76707698d0c26b703ad5c74b2df95a7dc4d751939a4ba05b2",
13
13
  ".agents/skills/wf-max/SKILL.md": "sha256-9b37cc3385f6d1a285b617169e91fbf71ffec76135b7b46ec1de2fe94ca220da",
14
14
  ".agents/skills/wf-readme/SKILL.md": "sha256-4d34ee3b6b305fa2581f5d8cb31e9152759f3df8bf8fa08efbb43782f128bdcd",
15
- ".agents/skills/wf-remove/SKILL.md": "sha256-f27aee81d4d6988186f468ccc5dfd02c7605967636a5aea93d92443e030dbcc2",
15
+ ".agents/skills/wf-remove/SKILL.md": "sha256-21ebef1a1fa8645d094c8ceeca78b33f036b6c42cda6db8be425d38d9e91af75",
16
16
  ".agents/skills/wf-review/SKILL.md": "sha256-cc6d536ec6de25546a0ba96e686f195da50ed11bc03763a76ef46d77243d3537",
17
17
  ".agents/skills/wf-update/SKILL.md": "sha256-d57cd89e271b2af63b6a1264af552a30f8d44959cf4782b42f0ab082a90be9cf",
18
18
  ".agents/skills/wf/SKILL.md": "sha256-70766bd2cb02bc489b5cc021797af62596a005d444a026abb511054a1a820a67",
@@ -42,7 +42,7 @@
42
42
  ".claude/skills/wf-learn/SKILL.md": "sha256-7f3e1ee0aa83cbb76707698d0c26b703ad5c74b2df95a7dc4d751939a4ba05b2",
43
43
  ".claude/skills/wf-max/SKILL.md": "sha256-9b37cc3385f6d1a285b617169e91fbf71ffec76135b7b46ec1de2fe94ca220da",
44
44
  ".claude/skills/wf-readme/SKILL.md": "sha256-4d34ee3b6b305fa2581f5d8cb31e9152759f3df8bf8fa08efbb43782f128bdcd",
45
- ".claude/skills/wf-remove/SKILL.md": "sha256-f27aee81d4d6988186f468ccc5dfd02c7605967636a5aea93d92443e030dbcc2",
45
+ ".claude/skills/wf-remove/SKILL.md": "sha256-21ebef1a1fa8645d094c8ceeca78b33f036b6c42cda6db8be425d38d9e91af75",
46
46
  ".claude/skills/wf-review/SKILL.md": "sha256-cc6d536ec6de25546a0ba96e686f195da50ed11bc03763a76ef46d77243d3537",
47
47
  ".claude/skills/wf-update/SKILL.md": "sha256-d57cd89e271b2af63b6a1264af552a30f8d44959cf4782b42f0ab082a90be9cf",
48
48
  ".claude/skills/wf/SKILL.md": "sha256-70766bd2cb02bc489b5cc021797af62596a005d444a026abb511054a1a820a67",
@@ -56,8 +56,8 @@
56
56
  "Harness/HARNESS_BRIDGE.md": "sha256-681dbeca9a590bbeb3a0c01b044e40e642e6d640632d8611064eb897ada8a48d",
57
57
  "Harness/MEMORY.md": "sha256-038217c5407a526dca3bd186ec4880f266fa6a8a31d52ebcd27d55aa11f32bb0",
58
58
  "Harness/MEMORY_PROTOCOL.md": "sha256-c24c232442a50f1dc7183480fc3b51c6171e32d3ba6648c056797ccd69fea717",
59
- "Harness/README.md": "sha256-f646e1b02cd3344e4b379aa150af914758376fc576f6ed6e648d00b87a837405",
60
- "Harness/SETUP.md": "sha256-33e05d9bc99449b7942db3a8c70160dab1c3ecfec0510afccd459790088118e8",
59
+ "Harness/README.md": "sha256-95f5d0bd9e250669845c9c5e0724fdb474b1d84ec90d97588501b15f5ef183e9",
60
+ "Harness/SETUP.md": "sha256-490fdac08d5cff4e3b3de4c2155aac18a67f305aa659187923d8a54a4a759873",
61
61
  "Harness/TDD-GUIDE.md": "sha256-602084530fd0dea7499a023ce75738351e5d97a0c222b64d405f36da6b59a162",
62
62
  "Harness/WF-AUTO-SPARK.md": "sha256-48cc08e1a78cd4abb2ae9c2807ef1ac9a09544eb954220b9087b2032fabbd690",
63
63
  "Harness/WF-AUTO.md": "sha256-d31b545249588a69c73e5e0ad8b1286ece1a53d9cd0e93b8ba0ae6dac6fdd119",
@@ -70,8 +70,8 @@
70
70
  "Harness/lifecycle.md": "sha256-a2d025e52f3b4412d8439083aca0d2cf7a4458ad0e30de4fc6465f990379190f",
71
71
  "Harness/research/README.md": "sha256-956c154df01cb9376972eb8b88bb3be0fe4e2dda802a72457c0126e3476fa755",
72
72
  "Harness/scripts/scan-clean.mjs": "sha256-7f693faf762c9c8e7657143d651f7c8369ed4823f18babe21daec58a55025593",
73
- "Harness/scripts/validate-harness.mjs": "sha256-e584959476265d53408484ec3653dd652a0f64922c785db97f0638c26f19e04c",
74
- "Harness/scripts/wf-remove.mjs": "sha256-4eb136ab26a9e20a949835e8cc6ff716b4beb3496c81ae3a4c03c049db60895c",
73
+ "Harness/scripts/validate-harness.mjs": "sha256-31dc33729034656d24ec163ff310164e2fc77289212b2278ab4a2f3d4b9294dc",
74
+ "Harness/scripts/wf-remove.mjs": "sha256-944e5da9dc1abcfb8f410bca743c3f5fbee2bc74d09b97e04ceaaf53da0cb9f1",
75
75
  "Harness/scripts/wf-update-check.mjs": "sha256-d14ce08f4c05ba118362a56a4b7d5965b114bc2b15a023c08e21d57f32b2cf93",
76
76
  "Harness/subagents.md": "sha256-16255092bab9011bb67359b4399d27ab292c14a717e67123e8a76e40e8669661",
77
77
  "Harness/templates/ACCEPTANCE.template.md": "sha256-394a6c08b155b1d121f1d51da774f7988bdb891224c6d5f2ca2c131e8c95ffb3",
@@ -77,7 +77,7 @@ Routing priority: if a request explicitly says `/wf <task>`, `$wf`, `wf mode`, `
77
77
  | Need subagents | subagent, role pack, context, inject, return format, orchestrator, isolation | [subagents.md](subagents.md), [context-loading.md](context-loading.md), [dispatch.md](dispatch.md), [AGENT_ISOLATION.md](AGENT_ISOLATION.md) | controller plan, role-specific context pack, isolation-aware dispatch pack |
78
78
  | Need feature work | feature, implementation, TDD, test, review, closeout | [tasks/_template/PLAN.md](tasks/_template/PLAN.md), [agent-workflow.md](agent-workflow.md), [TDD-GUIDE.md](TDD-GUIDE.md), [ACCEPTANCE_PROTOCOL.md](ACCEPTANCE_PROTOCOL.md) | task plan, AC-linked RED tests, implementation loop |
79
79
  | Review or release check | review, release, finding, risk, evidence, verification | [agent-workflow.md](agent-workflow.md), current feature doc | findings, verification evidence |
80
- | Harness readiness check | validate, readiness, placeholder, missing file, release gate | `Harness/scripts/validate-harness.mjs`, `Harness/scripts/validate-harness.mjs --strict` | missing files and unresolved project placeholders |
80
+ | Harness readiness check | validate, readiness, placeholder, missing file, release gate | `Harness/scripts/validate-harness.mjs`, `Harness/scripts/validate-harness.mjs --strict` | structural install check; strict bootstrap/release placeholder check |
81
81
  | Need harness update | /wf-update, $wf-update, update, check for updates, harness version | `.claude/skills/wf-update/SKILL.md`, `.agents/skills/wf-update/SKILL.md`, `Harness/.harness-version`, `Harness/scripts/wf-update-check.mjs` | script-driven comparison, SAFE/CONFLICT/PRESERVE classification, user decides conflicts |
82
82
  | Need harness removal | /wf-remove, $wf-remove, wf remove, remove harness, uninstall harness | `.claude/skills/wf-remove/SKILL.md`, `.agents/skills/wf-remove/SKILL.md`, `Harness/scripts/wf-remove.mjs` | safe removal plan: auto-remove SAFE, confirm MODIFIED, never touch USER DATA |
83
83
 
@@ -103,7 +103,7 @@ Routing priority: if a request explicitly says `/wf <task>`, `$wf`, `wf mode`, `
103
103
  - Do not add stack-specific agents or skills without following `extension.md`.
104
104
  - Do not close work without tests or recorded manual verification.
105
105
  - Do not mark work `Verified` until evidence is recorded in the current task's `tasks/<id>/PROGRESS.md` and `tasks/<id>/PLAN.md` or the feature doc.
106
- - Run `node Harness/scripts/validate-harness.mjs` for scaffold structure; run `node Harness/scripts/validate-harness.mjs --strict` after bootstrap and before release.
106
+ - Run `node Harness/scripts/validate-harness.mjs` for install-complete scaffold structure; run `node Harness/scripts/validate-harness.mjs --strict` only after bootstrap resolves project-fact placeholders and before release.
107
107
  - If a doc still has `{{...}}`, treat that section as a template, not project fact.
108
108
 
109
109
  ## Doc Map
@@ -31,7 +31,7 @@ First clarify the idea, then create Mini PRD, acceptance criteria, UI/API contra
31
31
 
32
32
  ## Required Bootstrap Sequence
33
33
 
34
- Claude must follow this order:
34
+ Claude or Codex must follow this order during bootstrap. This sequence is broader than installation; if the user only asked to install/configure the harness in an existing project, follow the "Existing Project Fast Path" below and stop after the non-strict validator passes.
35
35
 
36
36
  0. **ECC Stack Configuration** — Detect the project's tech stack. If the repo is empty or has no stack markers (`package.json`, `go.mod`, `pyproject.toml`, `Cargo.toml`, `Gemfile`, `composer.json`, `build.gradle`, etc.), ask the user: "What's your tech stack? (language/framework)" Then install the matching ECC rule sets from `~/.claude/rules/ecc/`. See `Harness/ECC-GUIDE.md` for the stack→rules mapping. Minimum: always install `common/`. Verify with `ls .claude/rules/ecc/`.
37
37
  1. Read `CLAUDE.md`, `Harness/MEMORY.md`, `Harness/README.md`, `Harness/lifecycle.md`, and `Harness/ACCEPTANCE_PROTOCOL.md`. Load `Harness/memory/*` only when the router or memory trigger applies.
@@ -45,8 +45,8 @@ Claude must follow this order:
45
45
  9. Implement only after PRD-GATE, AC-GATE, CONTRACT-GATE, and TEST-GATE pass.
46
46
  10. Independently validate with an AC-by-AC result matrix; use `Harness/HARNESS_BRIDGE.md` for browser/API/CDP flows.
47
47
  11. For `/wf-auto` or memory scenario hints, read `Harness/WF-AUTO.md` and `Harness/MEMORY_PROTOCOL.md`; do not enable a background runner by default. The only allowed runtime hook is the optional `/wf-auto` bounded tick hook.
48
- 11. Run `node Harness/scripts/validate-harness.mjs --strict`.
49
- 12. Record final verification and next feedback step in `Harness/tasks/<task-id>/PROGRESS.md`. If repeated tool failures, repeated user corrections, or reusable review/debug lessons appeared, record the concise reflection in the relevant `Harness/memory/` file.
48
+ 12. Run `node Harness/scripts/validate-harness.mjs --strict` after project-fact placeholders are resolved.
49
+ 13. Record final verification and next feedback step in `Harness/tasks/<task-id>/PROGRESS.md`. If repeated tool failures, repeated user corrections, or reusable review/debug lessons appeared, record the concise reflection in the relevant `Harness/memory/` file.
50
50
 
51
51
  ## Install or Upgrade Path
52
52
 
@@ -59,20 +59,25 @@ Before writing, identify the project state:
59
59
  | Legacy architecture or older project docs | Treat existing code/docs as source of truth, dry-run first, then fill PRD, research, architecture, and task plans from observed facts |
60
60
  | Existing `Harness/` | Do not use `npx` as an updater; ask whether to run `/wf-update`, `$wf-update`, `node Harness/scripts/wf-update-check.mjs`, keep untouched, or remove/reinstall after approval |
61
61
 
62
- When adding this harness to a project that already has source code, docs, CI, or tool configuration, treat the existing project as the source of truth before filling harness docs.
63
-
64
- 1. Get the machine-readable install report first with `npx create-harness-vibe-coding@latest <project-name> <target-dir> -y --dry-run --on-conflict skip --json`. Use `scan.markers` and `agent.aiMergeRequired` instead of hand-written root probes for install decisions. Do manual project-fact reading only after the script has created missing Harness files.
65
- 2. Record discovered facts and open questions in `Harness/tasks/<task-id>/PROGRESS.md` before changing harness docs.
66
- 3. Fill `Harness/research/PRD.md`, `Harness/research/research-results.md`, `Harness/architecture.md` from observed project facts plus explicit user input.
62
+ When adding this harness to a project that already has source code, docs, CI, or tool configuration, treat the existing project as the source of truth before filling harness docs.
63
+
64
+ ### Existing Project Fast Path
65
+
66
+ Use this path when the user asks only to install or configure the harness in an existing project. Do not bootstrap PRD, research, architecture, or task capsules unless the user explicitly asks for bootstrap.
67
+
68
+ 1. Get the machine-readable install report first with `npx create-harness-vibe-coding@latest <project-name> <target-dir> -y --dry-run --on-conflict skip --json`. Use `scan.markers` and `agent.aiMergeRequired` instead of hand-written root probes for install decisions. Do manual project-fact reading only after the script has created missing Harness files.
69
+ 2. Run the JSON `agent.safeMergeCommand` to create only missing files.
70
+ 3. Record discovered facts in the final install summary. Create or update task capsules only when bootstrap or multi-step implementation work begins.
67
71
  4. Existing configuration is project fact. Do not overwrite `CLAUDE.md`, `AGENTS.md`, `.claude/`, `.agents/`, `.codex/`, `.gitignore`, settings, package files, CI, docs routers, workflow docs, or installed skills/plugins/rules unless the user explicitly approves that exact overwrite.
68
- 5. When a harness file conflicts with an existing file, preserve the existing file and register any missing harness guidance manually using `Harness/extension.md`.
69
- 6. Run `node Harness/scripts/validate-harness.mjs --strict` after project-fact placeholders have been resolved or intentionally recorded as open. Use the non-strict validator only for early structural checks.
72
+ 5. When a harness file conflicts with an existing file, preserve the existing file and register any missing harness guidance manually using `Harness/extension.md`.
73
+ 6. Run `node Harness/scripts/validate-harness.mjs` as the install-complete gate.
74
+ 7. Defer `node Harness/scripts/validate-harness.mjs --strict` until bootstrap removes project-fact placeholders. If placeholders intentionally remain, report strict validation as deferred rather than treating install as failed.
70
75
 
71
76
  `npx create-harness-vibe-coding` is an install/safe-merge entry, not an update engine for a project that already has an installed Harness. If `Harness/` already exists, use `/wf-update`, `$wf-update`, or `node Harness/scripts/wf-update-check.mjs`; root entry files and user-modified Harness docs require agent-mediated merge decisions.
72
77
 
73
78
  ### Agent-Link Install Intake
74
79
 
75
- When the user installs by pasting the GitHub link into an agent, get the JSON install report before editing or asking generic questions. Summarize `scan.markers`, then ask only questions that affect writes, architecture, security, or workflow. Ask at most three blocking questions up front, record safe defaults for the rest, and ask follow-ups only when that choice becomes active.
80
+ When the user installs by pasting the GitHub link into an agent, get the JSON install report before editing or asking generic questions. Do not fetch full template files or read package source until `agent.aiMergeRequired` names a file that needs semantic comparison. Summarize `scan.markers`, then ask only questions that affect writes, architecture, security, or workflow. Ask at most three blocking questions up front, record safe defaults for the rest, and ask follow-ups only when that choice becomes active.
76
81
 
77
82
  | Topic | Ask When | Default If Unanswered |
78
83
  | --- | --- | --- |
@@ -117,9 +122,9 @@ When `--on-conflict skip` leaves existing files untouched, the script still owns
117
122
  - **[Overwrite]** — Replace with the template version. Optionally backup the original first (`--on-conflict backup`).
118
123
  - **[Keep]** — Leave the existing file as-is. Skip this file.
119
124
 
120
- 4. For Merge: use Edit (not Write) to add missing content. Only insert sections, headings, and text that are structurally required. Do not reorder or modify existing content. Do not remove custom project-specific registrations.
121
-
122
- 5. After all merges, run `node Harness/scripts/validate-harness.mjs --strict` once after project-fact placeholders are resolved. Run the non-strict validator earlier only when you need a quick structural check before bootstrap is complete.
125
+ 4. For Merge: use targeted edits, not a full-file rewrite. In Codex, use `apply_patch` or an equivalent patch operation. Only insert sections, headings, and text that are structurally required. Do not reorder or modify existing content. Do not remove custom project-specific registrations. After merging `CLAUDE.md` or `AGENTS.md`, inspect the heading outline and remove duplicate headings or repeated bullets introduced by the merge.
126
+
127
+ 5. After all install merges, run `node Harness/scripts/validate-harness.mjs`. Run `node Harness/scripts/validate-harness.mjs --strict` only after project-fact placeholders are resolved during bootstrap or release preparation.
123
128
 
124
129
  **File-specific gap checklists:**
125
130
 
@@ -131,12 +136,12 @@ The harness validator checks for specific structural invariants. When comparing
131
136
  | `AGENTS.md` | Root agent entry points to `CLAUDE.md` and `Harness/README.md`; for existing projects, merge only after explicit user consent |
132
137
  | `README.md` | Existing README is project-owned. Preserve by default; ask whether to append only Development notes or run `wf-readme` for a structure pass with tables/diagrams before broad edits |
133
138
  | `Harness/MEMORY.md` | All common agents registered under `## Agents`; all common harness skills registered under `## Skills`; all 3 `Harness/memory/` files registered under `## Memory Folder`; `Harness/memory/` folder usage guidance; `Project Resource Index` in title |
134
- | `.claude/rules/ecc/common.md` | `## Context` section with the durable communication invariant (`project files are the only durable communication channel`); `## Memory` section with three reflection file entries; `## Security` section |
139
+ | `.claude/rules/ecc/common.md` | Required project-local universal rules. Keep it even when global `~/.claude/rules/ecc/common/` exists; that directory and this file have different scopes. Required sections: `## Context` with the durable communication invariant (`project files are the only durable communication channel`); `## Memory` with three reflection file entries; `## Security` |
135
140
  | `Harness/README.md` | `## Keyword Routing` heading; `## Load By Task` table with at minimum the rows: "Need WF mode", "Adding harness to existing project", "Need implementation plan", "Need parallel agents", "Need subagents", "Need durable memory or reflection"; WF routing keywords include `/wf`, `wf mode`, `workflow mode`, and `wk mode`; explicit WF/WK output says subagent docs load immediately; `## Doc Map` with `memory/` and `subagents.md` entries; the durable communication invariant text; `Harness/README.md is the primary router` |
136
141
  | `Harness/WF.md` | `WF mode requires multi-subagent orchestration by default`; explicit `/wf`, `$wf`, `wf mode`, `workflow mode`, or `wk mode` requires at least 3 distinct role passes before second planning; `collaboration decision tree`; `Heartbeat Protocol` |
137
142
  | `Harness/extension.md` | `## Non-Invasive Extension Rules` section with the "Preserve existing" rule; `## Agent Contract` section; `## Registration` section |
138
- | `Harness/dispatch.md` | The durable communication invariant; common agent entries for all 9 agents; `## Handoff Format` heading |
139
- | `Harness/context-loading.md` | The durable communication invariant; `Harness/README.md is the primary router`; all 10 subagent context packs (Explorer Pass, Planner, Researcher, Docs Researcher, Architect, Test Writer, Implementer, Reviewer, Debugger, Verifier) |
143
+ | `Harness/dispatch.md` | The durable communication invariant; registered common agent entries; `## Handoff Format` heading |
144
+ | `Harness/context-loading.md` | The durable communication invariant; `Harness/README.md is the primary router`; all 12 subagent context packs (Explorer Pass, Planner, Researcher, Docs Researcher, Architect, Test Writer, Implementer, Reviewer, Debugger, Verifier, Memory Master, Context Master) |
140
145
  | `Harness/subagents.md` | `## Source Attribution`; `## Built-in Agent Roster`; `## WF Default Fan-Out`; `Controller Role`; `Efficiency Ladder`; `Review Gates`; `collaboration decision tree`; source markers for `npx skills find`, `dispatching-parallel-agents`, and `subagent-driven-development` |
141
146
  | `Harness/architecture.md` | `## 2. Interface Decoupling`; `## 3. State Design`; `Avoid speculative abstraction`; layer constraints derived from actual project facts |
142
147
  | `Harness/PROGRESS.md` | global task index with Active Task and task history; cross-task decisions |
@@ -146,12 +151,14 @@ The harness validator checks for specific structural invariants. When comparing
146
151
  | `Harness/workflows/browser-e2e.md` (if installed as optional) | `data-testid`, `accessible labels/roles`, and `inputs, buttons, filters, rows, empty/error/loading states` requirement |
147
152
  | `Harness/workflows/ts-react-frontend.md` (if installed as optional) | Same UI selector contract as above |
148
153
 
149
- **Files that do NOT need manual merge when the path does not already exist (auto-created by harness):**
154
+ **Files that do NOT need manual merge when the path does not already exist (auto-created by harness):**
155
+
156
+ The generated file list is authoritative by path, not by stale count labels. Current common scaffolds include WF-MAX manager agents and `tdd-guide`; keep every file created by the scaffold unless a removal workflow explicitly classifies it as safe to remove.
150
157
 
151
158
  - `Harness/memory/tool-usage-reflections.md`, `Harness/memory/user-corrections-preferences.md`, `Harness/memory/agent-lessons-patterns.md` — these are new empty files
152
- - `.claude/agents/*.md` all 9 common agents
159
+ - `.claude/agents/*.md` - all built-in common agent files, including WF-MAX managers and `tdd-guide`
153
160
  - `.claude/skills/*.md` and mirrored `.agents/skills/*.md` — Claude Code and Codex skill adapters over the same Harness docs
154
- - `.claude/rules/ecc/common.md` universal rules (unless the project has custom rules in this file)
161
+ - `.claude/rules/ecc/common.md` - required project-local universal rules. Do not delete this file as a duplicate of a global `~/.claude/rules/ecc/common/` directory; they are different scopes.
155
162
  - `.claude/settings.json` — harness settings
156
163
  - `Harness/WF.md`, `Harness/lifecycle.md`, `Harness/subagents.md`, `Harness/agent-workflow.md`, `Harness/architecture.md` — harness runtime docs
157
164
  - `Harness/research/*.md` — research protocol and templates
@@ -314,5 +321,5 @@ After scaffolding, use the JSON output first. Files in `plan.create[]` were hand
314
321
 
315
322
  1. Read `CLAUDE.md`, `Harness/MEMORY.md`, and `Harness/README.md`.
316
323
  2. Follow the Required Bootstrap Sequence above.
317
- 3. Run `node Harness/scripts/validate-harness.mjs --strict` when done.
324
+ 3. Run `node Harness/scripts/validate-harness.mjs` after install. Run `node Harness/scripts/validate-harness.mjs --strict` after bootstrap resolves project-fact placeholders.
318
325
  4. Delete `Harness/SETUP.md`.
@@ -541,6 +541,9 @@ requireText('Harness/templates/TEST_PLAN.template.md', 'syntax-only checks', 'te
541
541
  requireText('.claude/skills/tdd/SKILL.md', 'Harness/ACCEPTANCE_PROTOCOL.md', 'tdd skill loads acceptance protocol');
542
542
  requireText('.claude/skills/tdd/SKILL.md', 'Harness/HARNESS_BRIDGE.md', 'tdd skill loads harness bridge');
543
543
  requireText('.claude/skills/tdd/SKILL.md', 'No syntax-only acceptance', 'tdd skill forbids syntax-only acceptance');
544
+ requireText('.claude/skills/wf-remove/SKILL.md', 'User-facing removal is the slash/skill command', 'wf-remove slash command is user-facing');
545
+ requireText('.claude/skills/wf-remove/SKILL.md', 'agent-internal execution steps', 'wf-remove script commands are agent-internal');
546
+ requireText('.claude/skills/wf-remove/SKILL.md', 'verify residual discovery folders', 'wf-remove residual discovery verification');
544
547
  requireText('.claude/agents/tdd-guide.md', 'Browser Acceptance Rules', 'tdd-guide browser acceptance rules');
545
548
  requireText('.claude/agents/tdd-guide.md', 'real user actions', 'tdd-guide real user action requirement');
546
549
  requireText('.claude/agents/test-writer.md', 'Harness/ACCEPTANCE_PROTOCOL.md', 'test-writer loads acceptance protocol');
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * wf-remove.mjs Safely remove Harness framework files.
3
+ * wf-remove.mjs �?Safely remove Harness framework files.
4
4
  *
5
5
  * Classifies all Harness-owned files into:
6
- * SAFE framework files matching stored checksums auto-remove
7
- * MODIFIED framework files edited by user MUST confirm
8
- * USER user data files NEVER remove
6
+ * SAFE �?framework files matching stored checksums �?auto-remove
7
+ * MODIFIED �?framework files edited by user �?MUST confirm
8
+ * USER �?user data files �?NEVER remove
9
9
  *
10
10
  * Usage:
11
11
  * node Harness/scripts/wf-remove.mjs # dry-run: show plan
@@ -23,12 +23,12 @@ import { resolve, dirname, join, sep } from 'path';
23
23
  import { fileURLToPath } from 'url';
24
24
  import { createInterface } from 'readline';
25
25
 
26
- const __dirname = dirname(fileURLToPath(import.meta.url));
26
+ const SCRIPT_FILE = fileURLToPath(import.meta.url);
27
+ const __dirname = dirname(SCRIPT_FILE);
28
+ const SCRIPT_ROOT = resolve(__dirname, '..', '..');
27
29
  const ROOT = process.env.WF_ROOT
28
30
  ? resolve(process.env.WF_ROOT)
29
- : (existsSync(resolve(process.cwd(), 'Harness', '.harness-version'))
30
- ? process.cwd()
31
- : resolve(__dirname, '..', '..'));
31
+ : SCRIPT_ROOT;
32
32
  const VERSION_FILE = resolve(ROOT, 'Harness', '.harness-version');
33
33
 
34
34
  // ── Classification ─────────────────────────────────────────────────
@@ -45,7 +45,7 @@ const HARNESS_PREFIXES = [
45
45
  'tests/.gitkeep',
46
46
  ];
47
47
 
48
- /** Files the user owns NEVER remove. Consistent with wf-update-check PRESERVE_PATTERNS. */
48
+ /** Files the user owns �?NEVER remove. Consistent with wf-update-check PRESERVE_PATTERNS. */
49
49
  const USER_DATA_PATTERNS = [
50
50
  /^Harness\/PROGRESS\.md$/,
51
51
  /^Harness\/tasks\//,
@@ -97,14 +97,67 @@ function isPurgeableHarnessData(file, { keepTasks }) {
97
97
  if (keepTasks && /^Harness\/tasks\//.test(file) && !isFrameworkTaskFile(file)) return false;
98
98
  return PURGEABLE_HARNESS_DATA_PATTERNS.some(p => p.test(file));
99
99
  }
100
-
101
- /** Framework files that should always exist (not part of removal). */
102
- const KEEP_FRAMEWORK = new Set([
103
- 'Harness/.harness-version',
104
- ]);
105
-
106
- /** Directories to clean up if empty after file removal. */
107
- const CLEANUP_DIRS = [
100
+
101
+ /** Framework files that should always exist (not part of removal). */
102
+ const KEEP_FRAMEWORK = new Set([
103
+ 'Harness/.harness-version',
104
+ ]);
105
+
106
+ const BUILT_IN_AGENT_NAMES = [
107
+ 'architect-manager',
108
+ 'architect',
109
+ 'context-master',
110
+ 'debugger',
111
+ 'docs-researcher',
112
+ 'explore-manager',
113
+ 'implement-manager',
114
+ 'implementer',
115
+ 'memory-master',
116
+ 'planner',
117
+ 'researcher',
118
+ 'review-manager',
119
+ 'reviewer',
120
+ 'tdd-guide',
121
+ 'test-writer',
122
+ 'verifier',
123
+ ];
124
+
125
+ const BUILT_IN_SKILL_NAMES = [
126
+ 'browser-e2e',
127
+ 'github-pr-review',
128
+ 'python-backend',
129
+ 'subagent-orchestrator',
130
+ 'tdd',
131
+ 'ts-react-frontend',
132
+ 'ui-ux-review',
133
+ 'wf',
134
+ 'wf-auto',
135
+ 'wf-auto-spark',
136
+ 'wf-browser',
137
+ 'wf-learn',
138
+ 'wf-max',
139
+ 'wf-readme',
140
+ 'wf-remove',
141
+ 'wf-review',
142
+ 'wf-update',
143
+ ];
144
+
145
+ const KNOWN_FRAMEWORK_FILES = new Set([
146
+ ...BUILT_IN_AGENT_NAMES.map(name => `.claude/agents/${name}.md`),
147
+ ...BUILT_IN_SKILL_NAMES.flatMap(name => [
148
+ `.claude/skills/${name}/SKILL.md`,
149
+ `.agents/skills/${name}/SKILL.md`,
150
+ ]),
151
+ '.claude/commands/wf-help.md',
152
+ '.claude/rules/ecc/common.md',
153
+ ]);
154
+
155
+ function isKnownFrameworkFile(file) {
156
+ return KNOWN_FRAMEWORK_FILES.has(file);
157
+ }
158
+
159
+ /** Directories to clean up if empty after file removal. */
160
+ const CLEANUP_DIRS = [
108
161
  '.claude/agents',
109
162
  '.claude/skills/wf-auto',
110
163
  '.claude/skills/wf-browser',
@@ -251,7 +304,7 @@ function removeEmptyDirs(startDir) {
251
304
 
252
305
  async function askUser(question) {
253
306
  if (!process.stdin.isTTY) {
254
- console.log(' (non-interactive defaulting to KEEP)');
307
+ console.log(' (non-interactive �?defaulting to KEEP)');
255
308
  return 'k';
256
309
  }
257
310
  const rl = createInterface({ input: process.stdin, output: process.stdout });
@@ -300,8 +353,9 @@ async function main() {
300
353
  addFilesUnder(allFiles, dir, scanIssues);
301
354
  }
302
355
 
303
- // Add framework files that might not be in checksums (newer additions)
356
+ // Add framework files that might not be in checksums (newer additions)
304
357
  const extraPatterns = [
358
+ ...KNOWN_FRAMEWORK_FILES,
305
359
  '.claude/skills/wf/SKILL.md',
306
360
  '.agents/skills/wf/SKILL.md',
307
361
  '.claude/skills/tdd/SKILL.md',
@@ -323,9 +377,9 @@ async function main() {
323
377
  }
324
378
 
325
379
  // 2. Classify every file
326
- const safe = []; // SAFE matches checksum, auto-remove
327
- const modified = []; // MODIFIED user edited, must confirm
328
- const user = []; // USER never remove
380
+ const safe = []; // SAFE �?matches checksum, auto-remove
381
+ const modified = []; // MODIFIED �?user edited, must confirm
382
+ const user = []; // USER �?never remove
329
383
  const skipped = []; // File not on disk, traversal rejected, or framework-keep
330
384
  const purge = []; // Explicitly requested Harness user-data removal
331
385
  skipped.push(...scanIssues);
@@ -347,13 +401,13 @@ async function main() {
347
401
  });
348
402
  continue;
349
403
  }
350
- user.push({ file, reason: 'user data NEVER removed' });
404
+ user.push({ file, reason: 'user data �?NEVER removed' });
351
405
  continue;
352
406
  }
353
407
 
354
408
  // Only allow deletion of files under harness-owned prefixes
355
409
  if (!isHarnessOwned(canonical)) {
356
- user.push({ file, reason: 'outside harness prefix NEVER removed' });
410
+ user.push({ file, reason: 'outside harness prefix �?NEVER removed' });
357
411
  continue;
358
412
  }
359
413
 
@@ -366,15 +420,24 @@ async function main() {
366
420
  skipped.push({ file, reason: 'not on disk' });
367
421
  continue;
368
422
  }
369
-
370
- const currentHash = sha256File(diskPath);
371
- const storedHash = storedChecksums[file];
372
-
373
- if (!storedHash) {
374
- modified.push({ file, currentHash, storedHash: 'none', reason: 'not in checksums' });
375
- } else if (currentHash === storedHash) {
376
- safe.push({ file, currentHash, storedHash });
377
- } else {
423
+
424
+ const currentHash = sha256File(diskPath);
425
+ const storedHash = storedChecksums[file];
426
+
427
+ if (!storedHash) {
428
+ if (isKnownFrameworkFile(canonical)) {
429
+ safe.push({
430
+ file,
431
+ currentHash,
432
+ storedHash: currentHash,
433
+ reason: 'known framework file missing from legacy checksums',
434
+ });
435
+ } else {
436
+ modified.push({ file, currentHash, storedHash: 'none', reason: 'not in checksums' });
437
+ }
438
+ } else if (currentHash === storedHash) {
439
+ safe.push({ file, currentHash, storedHash });
440
+ } else {
378
441
  modified.push({ file, currentHash, storedHash, reason: 'user modified' });
379
442
  }
380
443
  }
@@ -385,7 +448,7 @@ async function main() {
385
448
  const settingsHash = sha256File(settingsFile);
386
449
  const storedSettingsHash = storedChecksums['.claude/settings.json'];
387
450
  if (storedSettingsHash && settingsHash !== storedSettingsHash) {
388
- // User modified settings move to modified
451
+ // User modified settings �?move to modified
389
452
  // Remove from safe if it was there
390
453
  const idx = safe.findIndex(s => s.file === '.claude/settings.json');
391
454
  if (idx >= 0) {
@@ -429,16 +492,16 @@ async function main() {
429
492
  return;
430
493
  }
431
494
 
432
- console.log('\n🧹 WF-REMOVE Harness framework removal plan\n');
495
+ console.log('\n🧹 WF-REMOVE �?Harness framework removal plan\n');
433
496
 
434
497
  if (safe.length > 0) {
435
- console.log(`✅ SAFE (${safe.length} files auto-remove, unmodified framework):`);
436
- for (const s of safe) console.log(` ✕ ${s.file}`);
498
+ console.log(`�?SAFE (${safe.length} files �?auto-remove, unmodified framework):`);
499
+ for (const s of safe) console.log(` �?${s.file}`);
437
500
  console.log('');
438
501
  }
439
502
 
440
503
  if (modified.length > 0) {
441
- console.log(`⚠ MODIFIED (${modified.length} files REQUIRE CONFIRMATION):`);
504
+ console.log(`�?MODIFIED (${modified.length} files �?REQUIRE CONFIRMATION):`);
442
505
  for (const m of modified) {
443
506
  console.log(` ? ${m.file} [${m.reason}]`);
444
507
  }
@@ -446,8 +509,8 @@ async function main() {
446
509
  }
447
510
 
448
511
  if (user.length > 0) {
449
- console.log(`🔒 USER DATA (${user.length} files NEVER removed):`);
450
- for (const u of user) console.log(` ○ ${u.file} [${u.reason}]`);
512
+ console.log(`🔒 USER DATA (${user.length} files �?NEVER removed):`);
513
+ for (const u of user) console.log(` �?${u.file} [${u.reason}]`);
451
514
  console.log('');
452
515
  }
453
516
 
@@ -464,17 +527,17 @@ async function main() {
464
527
  return;
465
528
  }
466
529
 
467
- // 4. Apply remove SAFE files automatically (rehash before unlink)
530
+ // 4. Apply �?remove SAFE files automatically (rehash before unlink)
468
531
  let safeRemoved = 0;
469
532
  let safeFailed = 0;
470
533
  for (const s of safe) {
471
534
  const diskPath = safePath(s.file);
472
- if (!diskPath) { console.error(` Traversal rejected: ${s.file}`); safeFailed++; continue; }
535
+ if (!diskPath) { console.error(` �?Traversal rejected: ${s.file}`); safeFailed++; continue; }
473
536
  if (!existsSync(diskPath)) continue;
474
537
  // Re-verify hash hasn't changed since classification
475
538
  const currentHash = sha256File(diskPath);
476
539
  if (currentHash !== s.storedHash) {
477
- console.log(` Skipped (modified since classification): ${s.file}`);
540
+ console.log(` �?Skipped (modified since classification): ${s.file}`);
478
541
  safeFailed++;
479
542
  continue;
480
543
  }
@@ -482,13 +545,13 @@ async function main() {
482
545
  unlinkSync(diskPath);
483
546
  safeRemoved++;
484
547
  } catch (e) {
485
- console.error(` Failed to remove: ${s.file} — ${e.message}`);
548
+ console.error(` �?Failed to remove: ${s.file} �?${e.message}`);
486
549
  safeFailed++;
487
550
  }
488
551
  }
489
- console.log(`✓ Removed ${safeRemoved} safe files.`);
552
+ console.log(`�?Removed ${safeRemoved} safe files.`);
490
553
 
491
- // 5. Handle MODIFIED files prompt user
554
+ // 5. Handle MODIFIED files �?prompt user
492
555
  let modifiedRemoved = 0;
493
556
  let modifiedKept = 0;
494
557
  let modifiedFailed = 0;
@@ -508,7 +571,7 @@ async function main() {
508
571
  }
509
572
  if (yes) {
510
573
  // Non-interactive mode: skip all modified
511
- console.log(` Skipped (modified): ${m.file}`);
574
+ console.log(` �?Skipped (modified): ${m.file}`);
512
575
  modifiedKept++;
513
576
  continue;
514
577
  }
@@ -520,17 +583,17 @@ async function main() {
520
583
  const answer = await askUser(' Choose [d/k]: ');
521
584
  if (answer === 'd' || answer === 'delete') {
522
585
  const diskPath = safePath(m.file);
523
- if (!diskPath) { console.error(` Traversal rejected: ${m.file}`); modifiedFailed++; continue; }
586
+ if (!diskPath) { console.error(` �?Traversal rejected: ${m.file}`); modifiedFailed++; continue; }
524
587
  try {
525
588
  unlinkSync(diskPath);
526
- console.log(` Deleted: ${m.file}`);
589
+ console.log(` �?Deleted: ${m.file}`);
527
590
  modifiedRemoved++;
528
591
  } catch (e) {
529
- console.error(` Failed: ${m.file} — ${e.message}`);
592
+ console.error(` �?Failed: ${m.file} �?${e.message}`);
530
593
  modifiedFailed++;
531
594
  }
532
595
  } else {
533
- console.log(` Kept: ${m.file}`);
596
+ console.log(` �?Kept: ${m.file}`);
534
597
  modifiedKept++;
535
598
  }
536
599
  }
@@ -591,7 +654,7 @@ async function main() {
591
654
  }
592
655
  } else if (!existsSync(harPath) || (existsSync(harPath) && readdirSync(harPath).filter(f => f !== '.harness-version').length === 0)) {
593
656
  unlinkSync(VERSION_FILE);
594
- console.log('Removed .harness-version (Harness directory empty).');
657
+ console.log('�?Removed .harness-version (Harness directory empty).');
595
658
  }
596
659
  }
597
660
 
@@ -610,7 +673,7 @@ async function main() {
610
673
  if (pruned > 0) {
611
674
  versionData.checksums = checksums;
612
675
  writeFileSync(VERSION_FILE, JSON.stringify(versionData, null, 2) + '\n', 'utf-8');
613
- console.log(`✓ Pruned ${pruned} stale checksum(s) from .harness-version.`);
676
+ console.log(`�?Pruned ${pruned} stale checksum(s) from .harness-version.`);
614
677
  }
615
678
  }
616
679
 
@@ -624,7 +687,7 @@ async function main() {
624
687
  // Strip the harness section: everything from "## 1. Harness Binding" to the next "## "
625
688
  const cleaned = content.replace(/## 1\. Harness Binding[\s\S]*?(?=## 2\.)/, '');
626
689
  writeFileSync(claudePath, cleaned, 'utf-8');
627
- console.log('Stripped Harness binding section from CLAUDE.md.');
690
+ console.log('�?Stripped Harness binding section from CLAUDE.md.');
628
691
  }
629
692
  }
630
693
  }