create-harness-vibe-coding 0.8.0 → 0.8.2
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-CN.md +40 -24
- package/README.md +44 -20
- package/package.json +1 -1
- package/src/generator.js +1 -1
- package/src/index.js +211 -11
- package/src/prompts.js +1 -1
- package/templates/common/.claude/agents/tdd-guide.md +55 -0
- package/templates/common/.claude/settings.json +22 -0
- package/templates/common/.claude/skills/tdd/SKILL.md +30 -0
- package/templates/common/.claude/skills/wf-auto/SKILL.md +107 -0
- package/templates/common/.claude/skills/wf-auto-spark/SKILL.md +39 -0
- package/templates/common/.claude/skills/wf-max/SKILL.md +10 -2
- package/templates/common/.claude/skills/wf-remove/SKILL.md +12 -5
- package/templates/common/.claude/skills/wf-update/SKILL.md +12 -5
- package/templates/common/.codex/hooks.json +59 -37
- package/templates/common/.harness-version +48 -25
- package/templates/common/AGENTS.md +5 -5
- package/templates/common/CLAUDE.md +12 -17
- package/templates/common/Harness/ECC-GUIDE.md +246 -0
- package/templates/common/Harness/README.md +129 -130
- package/templates/common/Harness/TDD-GUIDE.md +83 -0
- package/templates/common/Harness/WF-AUTO-SPARK.md +297 -0
- package/templates/common/Harness/WF-AUTO.md +508 -0
- package/templates/common/Harness/WF-MAX.md +24 -0
- package/templates/common/Harness/context-loading.md +38 -1
- package/templates/common/Harness/dispatch.md +40 -40
- package/templates/common/Harness/subagents.md +7 -21
- package/templates/common/Harness/tasks/_template/NAMING.md +47 -0
- package/templates/common/MEMORY.md +73 -66
- package/templates/common/SETUP.md +98 -63
- package/templates/common/scripts/validate-harness.mjs +92 -58
- package/templates/common/scripts/wf-mode-hook.mjs +895 -318
- package/templates/common/scripts/wf-remove.mjs +301 -81
- package/templates/common/scripts/wf-statusline.ps1 +62 -38
- package/templates/common/scripts/wf-statusline.sh +67 -48
- package/templates/common/scripts/wf-update-check.mjs +179 -81
- package/templates/optional/catalog.json +5 -5
|
@@ -13,15 +13,15 @@ This scaffold is a 0-1 product harness:
|
|
|
13
13
|
- `Harness/MEMORY.md` plus a `Harness/memory/` folder for durable self-learning, user corrections, and tool reflections
|
|
14
14
|
- built-in common agents
|
|
15
15
|
- subagent orchestration and context-loading protocol
|
|
16
|
-
- skill-style dynamic loaders in `.claude/skills/` for Claude Code and `.agents/skills/` for Codex
|
|
16
|
+
- skill-style dynamic loaders in `.claude/skills/` for Claude Code and `.agents/skills/` for Codex
|
|
17
17
|
- lightweight harness validator
|
|
18
18
|
- test/review/feedback loop
|
|
19
19
|
|
|
20
|
-
It does not guess your stack or business domain.
|
|
20
|
+
It does not guess your stack or business domain. The agent MUST detect or ask, then install the right ECC rules for the project.
|
|
21
21
|
|
|
22
22
|
## Bootstrap Prompt
|
|
23
23
|
|
|
24
|
-
Start Claude Code or Codex, then say:
|
|
24
|
+
Start Claude Code or Codex, then say:
|
|
25
25
|
|
|
26
26
|
```text
|
|
27
27
|
Read Harness/SETUP.md. Bootstrap this project as a 0-1 product harness.
|
|
@@ -33,6 +33,7 @@ First clarify the idea, then create PRD, research, architecture, Harness/PROGRES
|
|
|
33
33
|
|
|
34
34
|
Claude must follow this order:
|
|
35
35
|
|
|
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/`.
|
|
36
37
|
1. Read `CLAUDE.md`, `Harness/MEMORY.md`, `Harness/README.md`, and `Harness/lifecycle.md`. Load `Harness/memory/*` only when the router or memory trigger applies.
|
|
37
38
|
2. Ask up to 3 blocking product questions. If not blocked, record assumptions in `Harness/tasks/<task-id>/PLAN.md`.
|
|
38
39
|
3. Fill `Harness/research/PRD.md` with MVP, non-goals, and acceptance criteria.
|
|
@@ -44,33 +45,42 @@ Claude must follow this order:
|
|
|
44
45
|
10. Run `node Harness/scripts/validate-harness.mjs --strict`.
|
|
45
46
|
11. 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.
|
|
46
47
|
|
|
47
|
-
##
|
|
48
|
+
## Install or Upgrade Path
|
|
48
49
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
50
|
+
Before writing, identify the project state:
|
|
51
|
+
|
|
52
|
+
| Project state | Required action |
|
|
53
|
+
| --- | --- |
|
|
54
|
+
| Empty or new project | Run the scaffold, then follow this file for 0-1 bootstrap |
|
|
55
|
+
| Existing project, no `Harness/` | Scan project facts first, run `--dry-run`, preserve existing files, merge only missing Harness guidance |
|
|
56
|
+
| 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 |
|
|
57
|
+
| 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 |
|
|
58
|
+
|
|
59
|
+
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.
|
|
60
|
+
|
|
61
|
+
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.
|
|
62
|
+
2. Record discovered facts and open questions in `Harness/tasks/<task-id>/PROGRESS.md` before changing harness docs.
|
|
63
|
+
3. Fill `Harness/research/PRD.md`, `Harness/research/research-results.md`, `Harness/architecture.md` from observed project facts plus explicit user input.
|
|
64
|
+
4. Existing configuration is project fact. Do not overwrite `CLAUDE.md`, `AGENTS.md`, `.claude/`, `.agents/`, `.codex/`, `.gitignore`, settings, hooks, package files, CI, docs routers, workflow docs, or installed skills/plugins/rules unless the user explicitly approves that exact overwrite.
|
|
65
|
+
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`.
|
|
66
|
+
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.
|
|
67
|
+
|
|
68
|
+
`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.
|
|
59
69
|
|
|
60
70
|
### Agent-Link Install Intake
|
|
61
71
|
|
|
62
|
-
When the user installs by pasting the GitHub link into an agent,
|
|
63
|
-
|
|
64
|
-
| Topic | Ask When | Default If Unanswered |
|
|
65
|
-
| --- | --- | --- |
|
|
66
|
-
| Root agent entry | `CLAUDE.md`, `AGENTS.md`, `.claude/`, `.agents/`, `.codex/`, or other agent entry files already exist | Preserve files; ask before merging the Harness entry contract |
|
|
67
|
-
| Existing Harness | `Harness/` already exists | Stop and ask whether to run `/wf-update`, dry-run merge missing files, keep it untouched, or remove/reinstall after approval |
|
|
68
|
-
| Harness location | Always | Use root `Harness/`; do not write harness docs into `docs/` |
|
|
69
|
-
| README ownership | root `README.md` is a public product page, package docs, or heavily customized | Preserve existing README and propose a minimal Development section |
|
|
70
|
-
| README optimization | existing README is stale, sparse, missing command tables, or the user asks for diagrams/polished docs | Offer `wf-readme`; default to append-only Development notes until the user approves a structure pass or full rewrite |
|
|
71
|
-
| Extensions | ECC,
|
|
72
|
-
| Optional capabilities | stack is known or the user wants setup guidance | Offer local workflows plus recommendation-only
|
|
73
|
-
| Skills | stack is known and optional skills could improve testing, frontend, backend, review, or browser evidence | Install 1-2 relevant local workflows only after user approval |
|
|
72
|
+
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.
|
|
73
|
+
|
|
74
|
+
| Topic | Ask When | Default If Unanswered |
|
|
75
|
+
| --- | --- | --- |
|
|
76
|
+
| Root agent entry | `CLAUDE.md`, `AGENTS.md`, `.claude/`, `.agents/`, `.codex/`, or other agent entry files already exist | Preserve files; ask before merging the Harness entry contract |
|
|
77
|
+
| Existing Harness | `Harness/` already exists | Stop and ask whether to run `/wf-update`, dry-run merge missing files, keep it untouched, or remove/reinstall after approval |
|
|
78
|
+
| Harness location | Always | Use root `Harness/`; do not write harness docs into `docs/` |
|
|
79
|
+
| README ownership | root `README.md` is a public product page, package docs, or heavily customized | Preserve existing README and propose a minimal Development section |
|
|
80
|
+
| README optimization | existing README is stale, sparse, missing command tables, or the user asks for diagrams/polished docs | Offer `wf-readme`; default to append-only Development notes until the user approves a structure pass or full rewrite |
|
|
81
|
+
| Extensions | ECC, custom rules, or stack-specific skills may be useful | Scan installed skills/plugins/rules first; recommend only missing capabilities; install only after user approval |
|
|
82
|
+
| Optional capabilities | stack is known or the user wants setup guidance | Offer local workflows plus recommendation-only GitHub links: Superpowers, Caveman, agent research, and code graph; do not duplicate already-installed capabilities |
|
|
83
|
+
| Skills | stack is known and optional skills could improve testing, frontend, backend, review, or browser evidence | Install 1-2 relevant local workflows only after user approval |
|
|
74
84
|
| CI/CD | CI config exists or the project lacks a test/build gate | Document existing commands first; add CI/CD only after user approval |
|
|
75
85
|
| Verification depth | browser-visible, API, database, auth, payment, or deployment behavior is affected | Require real command evidence; require browser/API evidence when relevant |
|
|
76
86
|
| Memory/privacy | repo contains sensitive domain data, customer data, secrets, or private workflows | Enable memory index only; never record secrets or private data |
|
|
@@ -79,23 +89,23 @@ When the user installs by pasting the GitHub link into an agent, scan the projec
|
|
|
79
89
|
|
|
80
90
|
### Agent Conflict Resolution Protocol
|
|
81
91
|
|
|
82
|
-
When `--on-conflict skip` leaves existing files untouched, the agent resolves
|
|
92
|
+
When `--on-conflict skip` leaves existing files untouched, the script still owns file creation and the agent resolves only the files named in `agent.aiMergeRequired`.
|
|
83
93
|
|
|
84
94
|
**Workflow:**
|
|
85
95
|
|
|
86
96
|
1. Run the harness tool in planning mode to get the conflict list:
|
|
87
97
|
```
|
|
88
|
-
npx create-harness-vibe-coding@latest . . -y --dry-run --json
|
|
98
|
+
npx create-harness-vibe-coding@latest . . -y --dry-run --on-conflict skip --json
|
|
89
99
|
```
|
|
90
|
-
Parse the JSON output. Files in `plan.
|
|
100
|
+
Parse the JSON output. Files in `plan.create[]` are handled automatically by the script. If `agent.aiMergeRequired[]` is empty, do not read package source or templates; run the safe merge command from `agent.safeMergeCommand`.
|
|
91
101
|
|
|
92
|
-
2. For each
|
|
93
|
-
- From npm: `node_modules/create-harness-vibe-coding
|
|
94
|
-
- From GitHub: `https://raw.githubusercontent.com/zingspark/create-harness-vibe-coding/main
|
|
102
|
+
2. For each file in `agent.aiMergeRequired[]`, use its `templateHint` to locate the harness template counterpart only when semantic comparison is needed:
|
|
103
|
+
- From npm: `node_modules/create-harness-vibe-coding/<templateHint>`
|
|
104
|
+
- From GitHub: `https://raw.githubusercontent.com/zingspark/create-harness-vibe-coding/main/<templateHint>`
|
|
95
105
|
|
|
96
106
|
3. For each skipped file:
|
|
97
107
|
- Read the existing project file.
|
|
98
|
-
- Read the harness template counterpart.
|
|
108
|
+
- Read the harness template counterpart only for that file.
|
|
99
109
|
- Compare sections and headings. Identify structural sections, registration entries, and required text patterns that exist in the template but are missing from the existing file.
|
|
100
110
|
- If the skipped file is `CLAUDE.md`, tell the user that it is the root agent entry contract. Ask whether they consent to refactor or merge it before editing. Preserve project-specific rules while adding the Harness startup, memory, router, workflow, and subagent orchestration contract.
|
|
101
111
|
- If the skipped file is `AGENTS.md`, tell the user that it is part of the root agent entry contract and ask whether they consent to merge or replace it before editing.
|
|
@@ -106,7 +116,7 @@ When `--on-conflict skip` leaves existing files untouched, the agent resolves ea
|
|
|
106
116
|
|
|
107
117
|
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.
|
|
108
118
|
|
|
109
|
-
5. After all merges, run `node Harness/scripts/validate-harness.mjs
|
|
119
|
+
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.
|
|
110
120
|
|
|
111
121
|
**File-specific gap checklists:**
|
|
112
122
|
|
|
@@ -117,10 +127,10 @@ The harness validator checks for specific structural invariants. When comparing
|
|
|
117
127
|
| `CLAUDE.md` | Must be merged only after user confirmation when it already exists. Required contract: `## 1. Harness Binding & Startup` with the `Harness/SETUP.md` bootstrap contract line; `## 6. Memory & Self-Learning` section; the tool reflection trigger text (`same tool/use pattern fails 3+ times`); the user correction trigger text (`user corrects the same assumption/pattern 2+ times`); `Never bulk-read Harness/` in Startup |
|
|
118
128
|
| `AGENTS.md` | Root agent entry points to `CLAUDE.md` and `Harness/README.md`; for existing projects, merge only after explicit user consent |
|
|
119
129
|
| `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 |
|
|
120
|
-
| `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 |
|
|
130
|
+
| `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 |
|
|
121
131
|
| `.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 |
|
|
122
132
|
| `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` |
|
|
123
|
-
| `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` |
|
|
133
|
+
| `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` |
|
|
124
134
|
| `Harness/extension.md` | `## Non-Invasive Extension Rules` section with the "Preserve existing" rule; `## Agent Contract` section; `## Registration` section |
|
|
125
135
|
| `Harness/dispatch.md` | The durable communication invariant; common agent entries for all 9 agents; `## Handoff Format` heading |
|
|
126
136
|
| `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) |
|
|
@@ -129,7 +139,7 @@ The harness validator checks for specific structural invariants. When comparing
|
|
|
129
139
|
| `Harness/PROGRESS.md` | global task index with Active Task and task history; cross-task decisions |
|
|
130
140
|
| `Harness/tasks/<id>/PROGRESS.md` | `## Current Goal`, `## Phase`, `## Heartbeat`, `## Loaded Context` headings |
|
|
131
141
|
| `Harness/tasks/<id>/PLAN.md` | `## Tasks`, `## Parallel Dispatch`, `## Subagent Synthesis`, `## Verification` headings |
|
|
132
|
-
| `Harness/SETUP.md` |
|
|
142
|
+
| `Harness/SETUP.md` | Temporary install/bootstrap guide for new projects, existing projects, legacy upgrades, and Harness update decisions. If kept, ensure "Install or Upgrade Path" is present. |
|
|
133
143
|
| `Harness/workflows/browser-e2e.md` (if installed as optional) | `data-testid`, `accessible labels/roles`, and `inputs, buttons, filters, rows, empty/error/loading states` requirement |
|
|
134
144
|
| `Harness/workflows/ts-react-frontend.md` (if installed as optional) | Same UI selector contract as above |
|
|
135
145
|
|
|
@@ -137,7 +147,7 @@ The harness validator checks for specific structural invariants. When comparing
|
|
|
137
147
|
|
|
138
148
|
- `Harness/memory/tool-usage-reflections.md`, `Harness/memory/user-corrections-preferences.md`, `Harness/memory/agent-lessons-patterns.md` — these are new empty files
|
|
139
149
|
- `.claude/agents/*.md` — all 9 common agents
|
|
140
|
-
- `.claude/skills/*.md` and mirrored `.agents/skills/*.md` — Claude Code and Codex skill adapters over the same Harness docs
|
|
150
|
+
- `.claude/skills/*.md` and mirrored `.agents/skills/*.md` — Claude Code and Codex skill adapters over the same Harness docs
|
|
141
151
|
- `.claude/rules/ecc/common.md` — universal rules (unless the project has custom rules in this file)
|
|
142
152
|
- `.claude/settings.json` — harness settings
|
|
143
153
|
- `Harness/WF.md`, `Harness/lifecycle.md`, `Harness/subagents.md`, `Harness/agent-workflow.md`, `Harness/architecture.md` — harness runtime docs
|
|
@@ -145,15 +155,15 @@ The harness validator checks for specific structural invariants. When comparing
|
|
|
145
155
|
- `AGENTS.md` — agent registry; if it already exists, ask for user consent before merging or replacing it
|
|
146
156
|
- `Harness/scripts/validate-harness.mjs` and `tests/.gitkeep` — tooling
|
|
147
157
|
|
|
148
|
-
Optional workflow examples:
|
|
149
|
-
|
|
150
|
-
```bash
|
|
151
|
-
npx create-harness-vibe-coding@latest my-app ./my-app -y --with browser-e2e,ts-react-frontend
|
|
152
|
-
npx create-harness-vibe-coding@latest my-app ./my-app -y --preset web-app
|
|
153
|
-
npx create-harness-vibe-coding@latest my-app ./my-app -y --recommend superpowers,codegraph
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
`--recommend` records recommendation-only external
|
|
158
|
+
Optional workflow examples:
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
npx create-harness-vibe-coding@latest my-app ./my-app -y --with browser-e2e,ts-react-frontend
|
|
162
|
+
npx create-harness-vibe-coding@latest my-app ./my-app -y --preset web-app
|
|
163
|
+
npx create-harness-vibe-coding@latest my-app ./my-app -y --recommend superpowers,codegraph
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
`--recommend` records recommendation-only external capability links in this file. It does not install third-party skills or plugins.
|
|
157
167
|
|
|
158
168
|
### Template Fill Guide
|
|
159
169
|
|
|
@@ -200,7 +210,7 @@ False confidence is worse than a question. If you catch yourself thinking "this
|
|
|
200
210
|
|
|
201
211
|
## How to Find Proper Skills
|
|
202
212
|
|
|
203
|
-
After the architecture stage reveals your stack,
|
|
213
|
+
After the architecture stage reveals your stack, inspect existing `.claude/skills/`, `.agents/skills/`, plugins, hooks, and custom rules before recommending anything. Skills teach Claude Code and Codex domain-specific patterns, testing conventions, and design rules, but duplicate skills create routing noise.
|
|
204
214
|
|
|
205
215
|
**Built-in route**: invoke the `/find-skills` skill (or say "help me find skills for X"). Examples:
|
|
206
216
|
|
|
@@ -211,28 +221,53 @@ After the architecture stage reveals your stack, install matching agent skills.
|
|
|
211
221
|
"I need a skill for PostgreSQL schema design."
|
|
212
222
|
```
|
|
213
223
|
|
|
214
|
-
**
|
|
224
|
+
**External recommendation links**:
|
|
215
225
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
226
|
+
| Recommendation | Source | Purpose |
|
|
227
|
+
| --- | --- | --- |
|
|
228
|
+
| Superpowers | <https://github.com/obra/Superpowers> | **[RECOMMENDED]** community skill registry for agent workflows. Installed alongside ECC — Superpowers teaches *how to execute*, ECC defines *what standards to meet*. |
|
|
229
|
+
| Caveman | <https://github.com/JuliusBrussee/caveman> | terse, low-token agent behavior and memory compression |
|
|
230
|
+
| Agent Research | <https://github.com/lingzhi227/agent-research-skills> | research-agent skills for literature, product, dependency, and ecosystem investigation |
|
|
231
|
+
| CodeGraph | <https://github.com/colbymchenry/codegraph> | code graph or repository-map tooling |
|
|
232
|
+
|
|
233
|
+
These are links for the user's agent to evaluate. This scaffold does not maintain third-party install steps. If a user selects one, first check whether an equivalent capability is already installed; then present the GitHub link and ask for approval before the user's agent follows that project's own README.
|
|
234
|
+
|
|
235
|
+
### ECC (Rules) vs Superpowers (Skills) — Complementary, Not Redundant
|
|
236
|
+
|
|
237
|
+
ECC and Superpowers overlap ~80% in topic coverage but serve different purposes:
|
|
238
|
+
|
|
239
|
+
| | ECC Rules | Superpowers Skills |
|
|
240
|
+
|---|------|------|
|
|
241
|
+
| **Role** | Coding STANDARD (what to enforce) | Coding GUIDE (how to execute) |
|
|
242
|
+
| **Enforcement** | Hooks (PreToolUse/PostToolUse), validator | Agent self-discipline |
|
|
243
|
+
| **Scope** | Universal + per-language (TS/Python/Go/...) | Universal (no language specifics) |
|
|
244
|
+
| **TDD** | `testing.md`: coverage ≥80%, AAA pattern | `test-driven-development`: red-green-refactor workflow |
|
|
245
|
+
| **Code Review** | `code-review.md`: severity levels, checklist | `requesting-code-review`: dispatch reviewer subagent |
|
|
246
|
+
| **Subagents** | `subagents.md` + `dispatch.md`: role packs, write sets | `subagent-driven-development`: two-stage review after each task |
|
|
247
|
+
| **Verification** | `testing.md` + `agent-workflow.md`: evidence before claims | `verification-before-completion`: verification before claiming done |
|
|
248
|
+
| **Unique** | Design quality, performance budgets, security CSP, per-language idioms, hooks | Brainstorming, git worktrees |
|
|
249
|
+
|
|
250
|
+
**Installation rule:**
|
|
251
|
+
1. **ECC is mandatory.** Install `common/` + stack-specific rules during bootstrap step 0. See `Harness/ECC-GUIDE.md`.
|
|
252
|
+
2. **Superpowers is recommended.** Install after ECC. It adds ~14 workflow skills that teach agents *how* to execute ECC standards.
|
|
253
|
+
3. **No duplicates from other sources.** If a Superpowers skill has an ECC equivalent, keep both — they don't conflict. ECC sets the bar, Superpowers shows the path.
|
|
254
|
+
4. **Priority**: ECC rules take precedence when there's a conflict. ECC is the contract; Superpowers is the training manual.
|
|
221
255
|
|
|
222
256
|
**Manual discovery**: search GitHub and npm directly using patterns from `Harness/research/README.md#Architecture Decision References`.
|
|
223
257
|
|
|
224
258
|
**Priority order**:
|
|
225
|
-
1.
|
|
226
|
-
2.
|
|
227
|
-
3. GitHub
|
|
259
|
+
1. Existing project skills/plugins/rules first - do not recommend duplicates.
|
|
260
|
+
2. `/find-skills` or the runtime's local skill discovery - fastest and respects the user's tool environment.
|
|
261
|
+
3. Selected external GitHub links - let the user's agent read that project's README and install only after approval.
|
|
262
|
+
4. GitHub search - when the first three miss niche domains.
|
|
228
263
|
|
|
229
|
-
**What to install**: after finding skills, add the canonical copy to `.claude/skills/<name>/SKILL.md` and mirror the same file to `.agents/skills/<name>/SKILL.md` when Codex should discover it. Follow `Harness/extension.md` for compatibility. Start with 1-2 skills per stack area; more is not better.
|
|
264
|
+
**What to install**: after finding skills, add the canonical copy to `.claude/skills/<name>/SKILL.md` and mirror the same file to `.agents/skills/<name>/SKILL.md` when Codex should discover it. Follow `Harness/extension.md` for compatibility. Start with 1-2 skills per stack area; more is not better.
|
|
230
265
|
|
|
231
|
-
This scaffold includes built-in harness skills in `.claude/skills/*` and mirrored Codex repo skills in `.agents/skills/*`. Keep those. Add stack-specific ones alongside them.
|
|
266
|
+
This scaffold includes built-in harness skills in `.claude/skills/*` and mirrored Codex repo skills in `.agents/skills/*`. Keep those. Add stack-specific ones alongside them.
|
|
232
267
|
|
|
233
268
|
## Optional Agent Assets
|
|
234
269
|
|
|
235
|
-
After the product shape is known, Claude Code may also install or copy stack-specific agents, rules, and hooks into `.claude/`. Codex-discoverable workflow skills belong in `.agents/skills/`. Follow `Harness/extension.md` for every added asset.
|
|
270
|
+
After the product shape is known, Claude Code may also install or copy stack-specific agents, rules, and hooks into `.claude/`. Codex-discoverable workflow skills belong in `.agents/skills/`. Follow `Harness/extension.md` for every added asset.
|
|
236
271
|
|
|
237
272
|
Examples:
|
|
238
273
|
|
|
@@ -262,16 +297,16 @@ After both steps, `Harness/SETUP.md` is fully isolated — no file references it
|
|
|
262
297
|
If you are an AI agent running `create-harness-vibe-coding` to scaffold your own project harness, use non-interactive mode:
|
|
263
298
|
|
|
264
299
|
```bash
|
|
265
|
-
npx create-harness-vibe-coding@latest <project-name> <target-dir> -y
|
|
300
|
+
npx create-harness-vibe-coding@latest <project-name> <target-dir> -y --on-conflict skip --json
|
|
266
301
|
```
|
|
267
302
|
|
|
268
303
|
Example:
|
|
269
304
|
|
|
270
305
|
```bash
|
|
271
|
-
npx create-harness-vibe-coding@latest my-agent-project ./my-agent-project -y
|
|
306
|
+
npx create-harness-vibe-coding@latest my-agent-project ./my-agent-project -y --on-conflict skip --json
|
|
272
307
|
```
|
|
273
308
|
|
|
274
|
-
After scaffolding, bootstrap the harness yourself:
|
|
309
|
+
After scaffolding, use the JSON output first. Files in `plan.create[]` were handled by the script; only files in `agent.aiMergeRequired[]` need AI merge work. Then bootstrap the harness yourself:
|
|
275
310
|
|
|
276
311
|
1. Read `CLAUDE.md`, `Harness/MEMORY.md`, and `Harness/README.md`.
|
|
277
312
|
2. Follow the Required Bootstrap Sequence above.
|
|
@@ -33,15 +33,17 @@ const commonAgents = [
|
|
|
33
33
|
'review-manager',
|
|
34
34
|
];
|
|
35
35
|
|
|
36
|
-
const commonSkills = [
|
|
37
|
-
'wf',
|
|
38
|
-
'wf-update',
|
|
36
|
+
const commonSkills = [
|
|
37
|
+
'wf',
|
|
38
|
+
'wf-update',
|
|
39
39
|
'wf-max',
|
|
40
40
|
'wf-review',
|
|
41
41
|
'wf-learn',
|
|
42
42
|
'subagent-orchestrator',
|
|
43
43
|
'wf-readme',
|
|
44
44
|
'wf-remove',
|
|
45
|
+
'wf-auto',
|
|
46
|
+
'wf-auto-spark',
|
|
45
47
|
];
|
|
46
48
|
|
|
47
49
|
const memoryFiles = [
|
|
@@ -56,15 +58,15 @@ const required = [
|
|
|
56
58
|
'README.md',
|
|
57
59
|
'Harness/MEMORY.md',
|
|
58
60
|
'Harness/WF.md',
|
|
59
|
-
'Harness/WF-MAX.md',
|
|
60
|
-
...memoryFiles,
|
|
61
|
-
'.codex/config.toml',
|
|
62
|
-
'.codex/hooks.json',
|
|
63
|
-
'.claude/settings.json',
|
|
64
|
-
'.claude/rules/ecc/common.md',
|
|
65
|
-
...commonAgents.map(agent => `.claude/agents/${agent}.md`),
|
|
66
|
-
...commonSkills.map(skill => `.claude/skills/${skill}/SKILL.md`),
|
|
67
|
-
...commonSkills.map(skill => `.agents/skills/${skill}/SKILL.md`),
|
|
61
|
+
'Harness/WF-MAX.md',
|
|
62
|
+
...memoryFiles,
|
|
63
|
+
'.codex/config.toml',
|
|
64
|
+
'.codex/hooks.json',
|
|
65
|
+
'.claude/settings.json',
|
|
66
|
+
'.claude/rules/ecc/common.md',
|
|
67
|
+
...commonAgents.map(agent => `.claude/agents/${agent}.md`),
|
|
68
|
+
...commonSkills.map(skill => `.claude/skills/${skill}/SKILL.md`),
|
|
69
|
+
...commonSkills.map(skill => `.agents/skills/${skill}/SKILL.md`),
|
|
68
70
|
'Harness/README.md',
|
|
69
71
|
'Harness/PROGRESS.md',
|
|
70
72
|
'Harness/lifecycle.md',
|
|
@@ -77,11 +79,11 @@ const required = [
|
|
|
77
79
|
'Harness/research/README.md',
|
|
78
80
|
'Harness/research/research-results.md',
|
|
79
81
|
'Harness/research/PRD.md',
|
|
80
|
-
'Harness/scripts/wf-update-check.mjs',
|
|
81
|
-
'Harness/scripts/wf-remove.mjs',
|
|
82
|
-
'Harness/scripts/scan-clean.mjs',
|
|
83
|
-
'Harness/.harness-version',
|
|
84
|
-
];
|
|
82
|
+
'Harness/scripts/wf-update-check.mjs',
|
|
83
|
+
'Harness/scripts/wf-remove.mjs',
|
|
84
|
+
'Harness/scripts/scan-clean.mjs',
|
|
85
|
+
'Harness/.harness-version',
|
|
86
|
+
];
|
|
85
87
|
|
|
86
88
|
const projectFacts = [
|
|
87
89
|
'Harness/PROGRESS.md',
|
|
@@ -97,7 +99,7 @@ const contextPacks = [
|
|
|
97
99
|
'Docs Researcher:',
|
|
98
100
|
'Architect:',
|
|
99
101
|
'Test Writer:',
|
|
100
|
-
'Implementer
|
|
102
|
+
'Implementer', // matches "Implementer:", "Implementer (Frontend):", "Implementer (Backend):"
|
|
101
103
|
'Reviewer:',
|
|
102
104
|
'Debugger:',
|
|
103
105
|
'Verifier:',
|
|
@@ -146,6 +148,28 @@ function listMarkdownFiles(rel) {
|
|
|
146
148
|
.map(entry => `${normalizedRel}/${entry.name}`);
|
|
147
149
|
}
|
|
148
150
|
|
|
151
|
+
// Task naming convention: task-<verb>-<noun>[-detail], kebab-case, ≤46 chars
|
|
152
|
+
// Prefix "task-" required for new tasks. Existing tasks without prefix grandfathered (warning only).
|
|
153
|
+
// Reserved: _template (system), auto (auto-mode capsule)
|
|
154
|
+
const TASK_NAME_RE = /^task-[a-z]+(-[a-z0-9]+){1,4}$/;
|
|
155
|
+
const TASK_NAME_MAX = 46; // "task-" (5) + ≤40 chars body + 1 safety = 46
|
|
156
|
+
const TASK_RESERVED = new Set(['_template', 'auto']);
|
|
157
|
+
|
|
158
|
+
function validateTaskName(name, strict) {
|
|
159
|
+
if (TASK_RESERVED.has(name)) return null;
|
|
160
|
+
if (name.startsWith('_')) return `Task name "${name}" — leading underscore reserved for system dirs`;
|
|
161
|
+
if (name.length > TASK_NAME_MAX) return `Task name "${name}" — ${name.length} chars, max ${TASK_NAME_MAX}`;
|
|
162
|
+
if (!TASK_NAME_RE.test(name)) {
|
|
163
|
+
// Grandfather: existing tasks without "task-" prefix get a warning, not an error
|
|
164
|
+
if (/^[a-z]+(-[a-z0-9]+){1,4}$/.test(name)) {
|
|
165
|
+
if (strict) return `Task name "${name}" — missing "task-" prefix (required for new tasks). Rename to "task-${name}".`;
|
|
166
|
+
return null; // non-strict: allow grandfathered names
|
|
167
|
+
}
|
|
168
|
+
return `Task name "${name}" — must be task-<verb>-<noun>[-detail], kebab-case, 2-5 words after prefix`;
|
|
169
|
+
}
|
|
170
|
+
return null;
|
|
171
|
+
}
|
|
172
|
+
|
|
149
173
|
function unresolvedTemplatePlaceholders(text) {
|
|
150
174
|
const placeholders = [];
|
|
151
175
|
const pattern = /\{\{([^{}\r\n]+)\}\}/g;
|
|
@@ -161,7 +185,7 @@ function unresolvedTemplatePlaceholders(text) {
|
|
|
161
185
|
|
|
162
186
|
function registeredSkillFiles(...texts) {
|
|
163
187
|
const files = new Set();
|
|
164
|
-
const pattern = /(?:\.\.\/)?((?:\.claude|\.agents)\/skills\/[a-z0-9-]+\/SKILL\.md)/g;
|
|
188
|
+
const pattern = /(?:\.\.\/)?((?:\.claude|\.agents)\/skills\/[a-z0-9-]+\/SKILL\.md)/g;
|
|
165
189
|
|
|
166
190
|
for (const text of texts) {
|
|
167
191
|
for (const match of text.matchAll(pattern)) {
|
|
@@ -210,6 +234,10 @@ const taskDirs = fs.existsSync(path.join(root, 'Harness', 'tasks'))
|
|
|
210
234
|
.map(e => e.name)
|
|
211
235
|
: [];
|
|
212
236
|
for (const taskDir of taskDirs) {
|
|
237
|
+
// Validate task naming convention
|
|
238
|
+
const nameErr = validateTaskName(taskDir, strict);
|
|
239
|
+
if (nameErr) errors.push(nameErr);
|
|
240
|
+
|
|
213
241
|
const planPath = `Harness/tasks/${taskDir}/PLAN.md`;
|
|
214
242
|
const planText = read(planPath);
|
|
215
243
|
if (!planText) continue;
|
|
@@ -327,7 +355,8 @@ for (const skillFile of registeredSkillFiles(docsReadme, memory)) {
|
|
|
327
355
|
|
|
328
356
|
for (const workflowFile of registeredWorkflowFiles(docsReadme, memory)) {
|
|
329
357
|
if (!fs.existsSync(path.join(root, workflowFile))) {
|
|
330
|
-
|
|
358
|
+
// Optional workflows (browser-e2e, ts-react-frontend, etc.) may not be installed
|
|
359
|
+
continue;
|
|
331
360
|
}
|
|
332
361
|
}
|
|
333
362
|
|
|
@@ -349,24 +378,24 @@ function requireUiSelectorContract(rel) {
|
|
|
349
378
|
requireUiSelectorContract('Harness/workflows/browser-e2e.md');
|
|
350
379
|
requireUiSelectorContract('Harness/workflows/ts-react-frontend.md');
|
|
351
380
|
|
|
352
|
-
for (const skill of commonSkills) {
|
|
353
|
-
const rel = `.claude/skills/${skill}/SKILL.md`;
|
|
354
|
-
const text = read(rel);
|
|
355
|
-
if (!text) continue;
|
|
356
|
-
if (frontmatterField(text, 'name') !== skill) errors.push(`${rel} frontmatter name does not match directory`);
|
|
357
|
-
if (!frontmatterField(text, 'description')) errors.push(`${rel} missing frontmatter field: description`);
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
for (const skill of commonSkills) {
|
|
361
|
-
const claudeRel = `.claude/skills/${skill}/SKILL.md`;
|
|
362
|
-
const codexRel = `.agents/skills/${skill}/SKILL.md`;
|
|
363
|
-
const claudeText = read(claudeRel);
|
|
364
|
-
const codexText = read(codexRel);
|
|
365
|
-
if (!claudeText || !codexText) continue;
|
|
366
|
-
if (claudeText !== codexText) errors.push(`${codexRel} must mirror ${claudeRel}`);
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
for (const skill of listDirectories('.claude/skills')) {
|
|
381
|
+
for (const skill of commonSkills) {
|
|
382
|
+
const rel = `.claude/skills/${skill}/SKILL.md`;
|
|
383
|
+
const text = read(rel);
|
|
384
|
+
if (!text) continue;
|
|
385
|
+
if (frontmatterField(text, 'name') !== skill) errors.push(`${rel} frontmatter name does not match directory`);
|
|
386
|
+
if (!frontmatterField(text, 'description')) errors.push(`${rel} missing frontmatter field: description`);
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
for (const skill of commonSkills) {
|
|
390
|
+
const claudeRel = `.claude/skills/${skill}/SKILL.md`;
|
|
391
|
+
const codexRel = `.agents/skills/${skill}/SKILL.md`;
|
|
392
|
+
const claudeText = read(claudeRel);
|
|
393
|
+
const codexText = read(codexRel);
|
|
394
|
+
if (!claudeText || !codexText) continue;
|
|
395
|
+
if (claudeText !== codexText) errors.push(`${codexRel} must mirror ${claudeRel}`);
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
for (const skill of listDirectories('.claude/skills')) {
|
|
370
399
|
if (commonSkills.includes(skill)) continue;
|
|
371
400
|
|
|
372
401
|
const rel = `.claude/skills/${skill}/SKILL.md`;
|
|
@@ -374,22 +403,22 @@ for (const skill of listDirectories('.claude/skills')) {
|
|
|
374
403
|
if (!text) continue;
|
|
375
404
|
|
|
376
405
|
if (frontmatterField(text, 'name') !== skill) errors.push(`${rel} frontmatter name does not match directory`);
|
|
377
|
-
if (!frontmatterField(text, 'description')) errors.push(`${rel} missing frontmatter field: description`);
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
for (const skill of listDirectories('.agents/skills')) {
|
|
381
|
-
const rel = `.agents/skills/${skill}/SKILL.md`;
|
|
382
|
-
const text = read(rel);
|
|
383
|
-
if (!text) continue;
|
|
384
|
-
|
|
385
|
-
if (frontmatterField(text, 'name') !== skill) errors.push(`${rel} frontmatter name does not match directory`);
|
|
386
|
-
if (!frontmatterField(text, 'description')) errors.push(`${rel} missing frontmatter field: description`);
|
|
387
|
-
|
|
388
|
-
const claudeMirror = `.claude/skills/${skill}/SKILL.md`;
|
|
389
|
-
if (fs.existsSync(path.join(root, claudeMirror)) && text !== read(claudeMirror)) {
|
|
390
|
-
errors.push(`${rel} must mirror ${claudeMirror}`);
|
|
391
|
-
}
|
|
392
|
-
}
|
|
406
|
+
if (!frontmatterField(text, 'description')) errors.push(`${rel} missing frontmatter field: description`);
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
for (const skill of listDirectories('.agents/skills')) {
|
|
410
|
+
const rel = `.agents/skills/${skill}/SKILL.md`;
|
|
411
|
+
const text = read(rel);
|
|
412
|
+
if (!text) continue;
|
|
413
|
+
|
|
414
|
+
if (frontmatterField(text, 'name') !== skill) errors.push(`${rel} frontmatter name does not match directory`);
|
|
415
|
+
if (!frontmatterField(text, 'description')) errors.push(`${rel} missing frontmatter field: description`);
|
|
416
|
+
|
|
417
|
+
const claudeMirror = `.claude/skills/${skill}/SKILL.md`;
|
|
418
|
+
if (fs.existsSync(path.join(root, claudeMirror)) && text !== read(claudeMirror)) {
|
|
419
|
+
errors.push(`${rel} must mirror ${claudeMirror}`);
|
|
420
|
+
}
|
|
421
|
+
}
|
|
393
422
|
|
|
394
423
|
for (const agent of commonAgents) {
|
|
395
424
|
const rel = `.claude/agents/${agent}.md`;
|
|
@@ -420,17 +449,17 @@ requireText('Harness/research/README.md', 'research-results.md');
|
|
|
420
449
|
requireText('Harness/WF.md', 'Ralph-style harness loop', 'WF loop description');
|
|
421
450
|
requireText('Harness/WF.md', 'Heartbeat Protocol', 'heartbeat protocol');
|
|
422
451
|
requireText('Harness/WF.md', 'WF mode requires multi-subagent orchestration by default', 'WF multi-subagent default');
|
|
423
|
-
requireText('Harness/WF.md', 'Explicit `/wf`, `$wf`, `wf mode`, `workflow mode`, or `wk mode` MUST use at least 3 distinct role passes', 'explicit WF/WK role-pass minimum');
|
|
452
|
+
requireText('Harness/WF.md', 'Explicit `/wf`, `$wf`, `wf mode`, `workflow mode`, or `wk mode` MUST use at least 3 distinct role passes', 'explicit WF/WK role-pass minimum');
|
|
424
453
|
requireText('Harness/WF.md', '.claude/agents/', 'WF built-in agent roster path');
|
|
425
454
|
requireText('Harness/WF.md', 'Collaboration decision tree', 'WF decision tree');
|
|
426
455
|
requireText('Harness/WF.md', 'Harness/tasks/', 'WF task directory reference');
|
|
427
456
|
requireText('Harness/README.md', '`wf mode`, `workflow mode`, or `wk mode`', 'WF/WK router aliases');
|
|
428
457
|
requireText('Harness/README.md', 'explicit WF/WK loads subagent docs immediately', 'explicit WF/WK router output');
|
|
429
|
-
requireText('.claude/skills/wf/SKILL.md', 'Harness/WF.md', 'wf skill loads core WF doc');
|
|
430
|
-
requireText('.agents/skills/wf/SKILL.md', 'Harness/WF.md', 'Codex wf skill loads core WF doc');
|
|
458
|
+
requireText('.claude/skills/wf/SKILL.md', 'Harness/WF.md', 'wf skill loads core WF doc');
|
|
459
|
+
requireText('.agents/skills/wf/SKILL.md', 'Harness/WF.md', 'Codex wf skill loads core WF doc');
|
|
431
460
|
requireText('.claude/skills/subagent-orchestrator/SKILL.md', 'Harness/subagents.md', 'subagent-orchestrator loads subagents doc');
|
|
432
461
|
requireText('.claude/skills/subagent-orchestrator/SKILL.md', '.claude/agents/', 'subagent-orchestrator built-in agent roster path');
|
|
433
|
-
requireText('.claude/skills/subagent-orchestrator/SKILL.md', '`workflow mode`, or `wk mode`', 'subagent-orchestrator WF/WK aliases');
|
|
462
|
+
requireText('.claude/skills/subagent-orchestrator/SKILL.md', '`workflow mode`, or `wk mode`', 'subagent-orchestrator WF/WK aliases');
|
|
434
463
|
requireText('.claude/skills/wf-readme/SKILL.md', 'README.md', 'wf-readme loads README');
|
|
435
464
|
requireText('.claude/skills/wf-readme/SKILL.md', 'Harness/architecture.md', 'wf-readme links architecture docs');
|
|
436
465
|
requireText('Harness/subagents.md', '## Source Attribution', 'subagent source attribution');
|
|
@@ -449,6 +478,8 @@ requireText('Harness/architecture.md', 'Avoid speculative abstraction', 'anti-ov
|
|
|
449
478
|
requireText('CLAUDE.md', 'Use explicit interfaces or state models only when they protect a real boundary', 'CLAUDE interface/state simplicity rule');
|
|
450
479
|
requireText('CLAUDE.md', '/wf-update', 'wf update startup instruction');
|
|
451
480
|
requireText('Harness/README.md', 'Need harness update', 'update routing row');
|
|
481
|
+
requireText('Harness/WF-MAX.md', 'three-layer architecture', 'WF-MAX three-layer architecture');
|
|
482
|
+
requireText('Harness/WF-MAX.md', 'agent role', 'WF-MAX agent role separation');
|
|
452
483
|
requireText('Harness/WF-MAX.md', 'write-set coloring', 'WF-MAX coloring algorithm');
|
|
453
484
|
requireText('Harness/WF-MAX.md', 'wave dispatch', 'WF-MAX wave dispatch');
|
|
454
485
|
requireText('Harness/README.md', '/wf-max', 'wf max router alias');
|
|
@@ -457,6 +488,9 @@ requireText('Harness/subagents.md', 'Max parallelism', 'subagents max parallelis
|
|
|
457
488
|
requireText('Harness/dispatch.md', 'Concurrency group', 'dispatch concurrency group field');
|
|
458
489
|
requireText('Harness/dispatch.md', 'File claim', 'dispatch file claim field');
|
|
459
490
|
requireText('CLAUDE.md', '/wf-max', 'wf max startup instruction');
|
|
491
|
+
requireText('CLAUDE.md', 'three-layer architecture', 'CLAUDE.md three-layer role architecture');
|
|
492
|
+
requireText('Harness/scripts/wf-mode-hook.mjs', 'agentRole', 'hook agentRole validation');
|
|
493
|
+
requireText('Harness/scripts/wf-mode-hook.mjs', 'writeSet', 'hook writeSet enforcement');
|
|
460
494
|
|
|
461
495
|
if (errors.length) {
|
|
462
496
|
console.error(`Harness validation failed${strict ? ' (strict)' : ''}:`);
|