create-harness-vibe-coding 0.8.7 → 0.8.8

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 (77) hide show
  1. package/README-CN.md +157 -105
  2. package/README.md +160 -244
  3. package/bin/create-harness-vibe-coding.js +2 -2
  4. package/docs/images/harness-architecture-light.png +0 -0
  5. package/docs/images/harness-architecture.drawio +164 -0
  6. package/package.json +46 -44
  7. package/src/generator.js +5 -5
  8. package/src/index.js +14 -9
  9. package/src/prompts.js +37 -37
  10. package/templates/common/.claude/agents/architect-manager.md +45 -45
  11. package/templates/common/.claude/agents/context-master.md +75 -75
  12. package/templates/common/.claude/agents/debugger.md +41 -41
  13. package/templates/common/.claude/agents/explore-manager.md +41 -41
  14. package/templates/common/.claude/agents/implement-manager.md +49 -49
  15. package/templates/common/.claude/agents/implementer.md +40 -40
  16. package/templates/common/.claude/agents/memory-master.md +64 -64
  17. package/templates/common/.claude/agents/planner.md +34 -34
  18. package/templates/common/.claude/agents/researcher.md +41 -41
  19. package/templates/common/.claude/agents/review-manager.md +56 -56
  20. package/templates/common/.claude/agents/verifier.md +29 -29
  21. package/templates/common/.claude/commands/wf-help.md +1 -1
  22. package/templates/common/.claude/rules/ecc/common.md +44 -44
  23. package/templates/common/.claude/skills/wf-auto/SKILL.md +8 -6
  24. package/templates/common/.claude/skills/wf-readme/SKILL.md +49 -49
  25. package/templates/common/.claude/skills/wf-remove/SKILL.md +7 -7
  26. package/templates/common/.harness-version +54 -14
  27. package/templates/common/.opencode/agents/architect-manager.md +52 -0
  28. package/templates/common/.opencode/agents/architect.md +35 -0
  29. package/templates/common/.opencode/agents/context-master.md +81 -0
  30. package/templates/common/.opencode/agents/debugger.md +43 -0
  31. package/templates/common/.opencode/agents/docs-researcher.md +42 -0
  32. package/templates/common/.opencode/agents/explore-manager.md +49 -0
  33. package/templates/common/.opencode/agents/implement-manager.md +56 -0
  34. package/templates/common/.opencode/agents/implementer.md +42 -0
  35. package/templates/common/.opencode/agents/memory-master.md +70 -0
  36. package/templates/common/.opencode/agents/planner.md +38 -0
  37. package/templates/common/.opencode/agents/reflector.md +39 -0
  38. package/templates/common/.opencode/agents/researcher.md +42 -0
  39. package/templates/common/.opencode/agents/review-manager.md +63 -0
  40. package/templates/common/.opencode/agents/reviewer.md +37 -0
  41. package/templates/common/.opencode/agents/tdd-guide.md +83 -0
  42. package/templates/common/.opencode/agents/test-writer.md +54 -0
  43. package/templates/common/.opencode/agents/verifier.md +37 -0
  44. package/templates/common/.opencode/commands/wf-help.md +23 -0
  45. package/templates/common/CLAUDE.md +85 -88
  46. package/templates/common/Harness/PROGRESS.md +17 -17
  47. package/templates/common/Harness/README.md +16 -5
  48. package/templates/common/Harness/WF-AUTO-ANGLES.md +170 -0
  49. package/templates/common/Harness/WF-AUTO-SPARK.md +5 -5
  50. package/templates/common/Harness/WF-AUTO.md +85 -96
  51. package/templates/common/Harness/architecture.md +124 -124
  52. package/templates/common/Harness/context-loading.md +111 -111
  53. package/templates/common/Harness/extension.md +66 -66
  54. package/templates/common/Harness/lifecycle.md +20 -20
  55. package/templates/common/Harness/research/PRD.md +56 -56
  56. package/templates/common/Harness/research/README.md +169 -169
  57. package/templates/common/Harness/research/research-results.md +66 -66
  58. package/templates/common/Harness/subagents.md +208 -208
  59. package/templates/common/Harness/tasks/_template/ARTIFACTS.md +2 -2
  60. package/templates/common/Harness/tasks/_template/NOTES.md +2 -2
  61. package/templates/common/MEMORY.md +1 -1
  62. package/templates/common/README.md +36 -36
  63. package/templates/common/memory/agent-lessons-patterns.md +21 -21
  64. package/templates/common/memory/tool-usage-reflections.md +21 -21
  65. package/templates/common/memory/user-corrections-preferences.md +21 -21
  66. package/templates/common/opencode.json +19 -0
  67. package/templates/common/scripts/scan-clean.mjs +415 -415
  68. package/templates/common/scripts/validate-harness.mjs +274 -245
  69. package/templates/common/scripts/wf-remove.mjs +56 -39
  70. package/templates/common/scripts/wf-update-check.mjs +599 -599
  71. package/templates/optional/catalog.json +41 -33
  72. package/templates/optional/skills/browser-e2e/.claude/skills/wf-browser/SKILL.md +193 -193
  73. package/templates/optional/skills/browser-e2e/Harness/workflows/browser-e2e.md +48 -48
  74. package/templates/optional/skills/github-pr-review/Harness/workflows/github-pr-review.md +28 -28
  75. package/templates/optional/skills/python-backend/Harness/workflows/python-backend.md +34 -34
  76. package/templates/optional/skills/ts-react-frontend/Harness/workflows/ts-react-frontend.md +34 -34
  77. package/templates/optional/skills/ui-ux-review/Harness/workflows/ui-ux-review.md +26 -26
@@ -22,11 +22,11 @@ const commonAgents = [
22
22
  'architect',
23
23
  'test-writer',
24
24
  'implementer',
25
- 'debugger',
26
- 'reviewer',
27
- 'verifier',
28
- 'reflector',
29
- 'memory-master',
25
+ 'debugger',
26
+ 'reviewer',
27
+ 'verifier',
28
+ 'reflector',
29
+ 'memory-master',
30
30
  'context-master',
31
31
  'explore-manager',
32
32
  'architect-manager',
@@ -34,12 +34,12 @@ const commonAgents = [
34
34
  'review-manager',
35
35
  ];
36
36
 
37
- const commonSkills = [
38
- 'wf',
39
- 'tdd',
40
- 'wf-update',
41
- 'wf-max',
42
- 'wf-review',
37
+ const commonSkills = [
38
+ 'wf',
39
+ 'tdd',
40
+ 'wf-update',
41
+ 'wf-max',
42
+ 'wf-review',
43
43
  'wf-learn',
44
44
  'subagent-orchestrator',
45
45
  'wf-readme',
@@ -58,27 +58,30 @@ const required = [
58
58
  'AGENTS.md',
59
59
  'CLAUDE.md',
60
60
  'README.md',
61
- 'Harness/MEMORY.md',
62
- 'Harness/WF.md',
63
- 'Harness/WF-MAX.md',
64
- 'Harness/ACCEPTANCE_PROTOCOL.md',
65
- 'Harness/AGENT_ISOLATION.md',
66
- 'Harness/HARNESS_BRIDGE.md',
67
- 'Harness/DEBUG_PROTOCOL.md',
68
- 'Harness/MEMORY_PROTOCOL.md',
69
- 'Harness/templates/PRD.template.md',
70
- 'Harness/templates/ACCEPTANCE.template.md',
71
- 'Harness/templates/UI_CONTRACT.template.md',
72
- 'Harness/templates/API_CONTRACT.template.md',
73
- 'Harness/templates/TEST_PLAN.template.md',
74
- 'Harness/templates/PLAYWRIGHT_SPEC.template.ts',
75
- 'Harness/templates/VALIDATION_REPORT.template.md',
76
- ...memoryFiles,
77
- '.codex/config.toml',
78
- '.claude/settings.json',
79
- '.claude/commands/wf-help.md',
80
- '.claude/rules/ecc/common.md',
61
+ 'Harness/MEMORY.md',
62
+ 'Harness/WF.md',
63
+ 'Harness/WF-MAX.md',
64
+ 'Harness/ACCEPTANCE_PROTOCOL.md',
65
+ 'Harness/AGENT_ISOLATION.md',
66
+ 'Harness/HARNESS_BRIDGE.md',
67
+ 'Harness/DEBUG_PROTOCOL.md',
68
+ 'Harness/MEMORY_PROTOCOL.md',
69
+ 'Harness/templates/PRD.template.md',
70
+ 'Harness/templates/ACCEPTANCE.template.md',
71
+ 'Harness/templates/UI_CONTRACT.template.md',
72
+ 'Harness/templates/API_CONTRACT.template.md',
73
+ 'Harness/templates/TEST_PLAN.template.md',
74
+ 'Harness/templates/PLAYWRIGHT_SPEC.template.ts',
75
+ 'Harness/templates/VALIDATION_REPORT.template.md',
76
+ ...memoryFiles,
77
+ '.codex/config.toml',
78
+ 'opencode.json',
79
+ '.claude/settings.json',
80
+ '.claude/commands/wf-help.md',
81
+ '.opencode/commands/wf-help.md',
82
+ '.claude/rules/ecc/common.md',
81
83
  ...commonAgents.map(agent => `.claude/agents/${agent}.md`),
84
+ ...commonAgents.map(agent => `.opencode/agents/${agent}.md`),
82
85
  ...commonSkills.map(skill => `.claude/skills/${skill}/SKILL.md`),
83
86
  ...commonSkills.map(skill => `.agents/skills/${skill}/SKILL.md`),
84
87
  'Harness/README.md',
@@ -92,8 +95,8 @@ const required = [
92
95
  'Harness/architecture.md',
93
96
  'Harness/research/README.md',
94
97
  'Harness/research/research-results.md',
95
- 'Harness/research/PRD.md',
96
- 'Harness/scripts/wf-update-check.mjs',
98
+ 'Harness/research/PRD.md',
99
+ 'Harness/scripts/wf-update-check.mjs',
97
100
  'Harness/scripts/wf-remove.mjs',
98
101
  'Harness/scripts/scan-clean.mjs',
99
102
  'Harness/.harness-version',
@@ -135,16 +138,16 @@ function read(rel) {
135
138
  return fs.existsSync(file) ? fs.readFileSync(file, 'utf8') : '';
136
139
  }
137
140
 
138
- function requireText(rel, text, label = text) {
139
- const body = read(rel);
140
- if (body && !body.includes(text)) errors.push(`${rel} missing ${label}`);
141
- }
142
-
143
- function forbidText(rel, text, label = text) {
144
- const body = read(rel);
145
- if (body && body.includes(text)) errors.push(`${rel} contains forbidden ${label}`);
146
- }
147
-
141
+ function requireText(rel, text, label = text) {
142
+ const body = read(rel);
143
+ if (body && !body.includes(text)) errors.push(`${rel} missing ${label}`);
144
+ }
145
+
146
+ function forbidText(rel, text, label = text) {
147
+ const body = read(rel);
148
+ if (body && body.includes(text)) errors.push(`${rel} contains forbidden ${label}`);
149
+ }
150
+
148
151
  function frontmatterField(text, field) {
149
152
  const match = text.match(new RegExp(`^${field}:\\s*(.+)$`, 'm'));
150
153
  return match ? match[1].trim() : '';
@@ -215,53 +218,53 @@ function registeredSkillFiles(...texts) {
215
218
  return [...files].sort();
216
219
  }
217
220
 
218
- function registeredWorkflowFiles(...texts) {
219
- const files = new Set();
220
- const pattern = /(?:Harness\/)?workflows\/([A-Za-z0-9._-]+\.md)/g;
221
+ function registeredWorkflowFiles(...texts) {
222
+ const files = new Set();
223
+ const pattern = /(?:Harness\/)?workflows\/([A-Za-z0-9._-]+\.md)/g;
221
224
 
222
225
  for (const text of texts) {
223
226
  for (const match of text.matchAll(pattern)) {
224
227
  files.add(`Harness/workflows/${match[1]}`);
225
228
  }
226
229
  }
227
-
228
- return [...files].sort();
229
- }
230
-
231
- function listedWorkflowCommands(...texts) {
232
- const commands = new Set();
233
- const pattern = /`\/(wf(?:-[a-z0-9]+)?)(?:\s+[^`]*)?`/g;
234
-
235
- for (const text of texts) {
236
- for (const match of text.matchAll(pattern)) {
237
- const command = `/${match[1]}`;
238
- if (command === '/wf-help') continue;
239
- commands.add(command);
240
- }
241
- }
242
-
243
- return [...commands].sort();
244
- }
245
-
246
- for (const rel of required) {
247
- if (!fs.existsSync(path.join(root, rel))) {
248
- errors.push(`missing required file: ${rel}`);
249
- }
250
- }
251
-
252
- const removedHookArtifacts = [
253
- 'Harness/HOOK_PROTOCOL.md',
254
- 'Harness/scripts/wf-mode-hook.mjs',
255
- 'Harness/scripts/wf-statusline.sh',
256
- 'Harness/scripts/wf-statusline.ps1',
257
- 'tests/e2e-wf-hooks.test.mjs',
258
- ];
259
-
260
- for (const rel of removedHookArtifacts) {
261
- if (fs.existsSync(path.join(root, rel))) {
262
- errors.push(`removed hook artifact should not exist: ${rel}`);
263
- }
264
- }
230
+
231
+ return [...files].sort();
232
+ }
233
+
234
+ function listedWorkflowCommands(...texts) {
235
+ const commands = new Set();
236
+ const pattern = /`\/(wf(?:-[a-z0-9]+)?)(?:\s+[^`]*)?`/g;
237
+
238
+ for (const text of texts) {
239
+ for (const match of text.matchAll(pattern)) {
240
+ const command = `/${match[1]}`;
241
+ if (command === '/wf-help') continue;
242
+ commands.add(command);
243
+ }
244
+ }
245
+
246
+ return [...commands].sort();
247
+ }
248
+
249
+ for (const rel of required) {
250
+ if (!fs.existsSync(path.join(root, rel))) {
251
+ errors.push(`missing required file: ${rel}`);
252
+ }
253
+ }
254
+
255
+ const removedHookArtifacts = [
256
+ 'Harness/HOOK_PROTOCOL.md',
257
+ 'Harness/scripts/wf-mode-hook.mjs',
258
+ 'Harness/scripts/wf-statusline.sh',
259
+ 'Harness/scripts/wf-statusline.ps1',
260
+ 'tests/e2e-wf-hooks.test.mjs',
261
+ ];
262
+
263
+ for (const rel of removedHookArtifacts) {
264
+ if (fs.existsSync(path.join(root, rel))) {
265
+ errors.push(`removed hook artifact should not exist: ${rel}`);
266
+ }
267
+ }
265
268
 
266
269
  // Task capsule template files
267
270
  const taskTemplateDir = path.join(root, 'Harness', 'tasks', '_template');
@@ -328,17 +331,17 @@ for (const rel of durableCommunicationDocs) {
328
331
  requireText(rel, 'chat/subagent transcript state is non-authoritative', 'non-authoritative transcript invariant');
329
332
  }
330
333
 
331
- requireText('CLAUDE.md', 'same tool/use pattern fails 3+ times', 'tool reflection trigger');
332
- requireText('CLAUDE.md', 'user corrects the same assumption/pattern 2+ times', 'user correction reflection trigger');
334
+ requireText('Harness/MEMORY_PROTOCOL.md', 'same tool or command pattern fails 3+ times', 'tool reflection trigger');
335
+ requireText('Harness/MEMORY_PROTOCOL.md', 'user corrects the same assumption or preference 2+ times', 'user correction reflection trigger');
333
336
  requireText('CLAUDE.md', 'If `Harness/` exists, this repository is governed by the Harness contract', 'Harness binding contract');
334
- requireText('CLAUDE.md', 'Harness/MEMORY.md` is the memory/resource router', 'memory/resource router');
335
- requireText('CLAUDE.md', 'Harness/README.md#Load By Task', 'Harness task router');
336
- requireText('CLAUDE.md', 'Harness/SETUP.md` exists, follow it before normal project work', 'setup bootstrap contract');
337
- requireText('Harness/SETUP.md', 'Harness/MEMORY_PROTOCOL.md', 'setup memory protocol reference');
338
- requireText('CLAUDE.md', 'subagent-orchestrator` and `Harness/subagents.md', 'subagent orchestrator entry trigger');
339
- requireText('CLAUDE.md', 'Harness/PROGRESS.md` is the global task index', 'PROGRESS global task index');
337
+ requireText('CLAUDE.md', 'memory and resource router', 'memory/resource router');
338
+ requireText('Harness/README.md', 'Load By Task', 'Harness task router');
339
+ requireText('CLAUDE.md', 'Harness/SETUP.md` exists, follow it before normal project work', 'setup bootstrap contract');
340
+ requireText('Harness/SETUP.md', 'Harness/MEMORY_PROTOCOL.md', 'setup memory protocol reference');
341
+ requireText('Harness/README.md', 'subagent-orchestrator', 'subagent orchestrator entry trigger');
342
+ requireText('Harness/README.md', 'PROGRESS.md', 'PROGRESS global task index');
340
343
  requireText('CLAUDE.md', 'Harness/tasks/', 'task capsule directory reference');
341
- requireText('CLAUDE.md', 'Subagents are readers and reporters', 'subagent state committer rule');
344
+ requireText('Harness/subagents.md', 'Subagents are readers and reporters', 'subagent state committer rule');
342
345
  for (const heading of ['## 2. Think Before Coding', '## 3. Simplicity First', '## 4. Surgical Changes', '## 5. Goal-Driven Execution']) {
343
346
  requireText('CLAUDE.md', heading, `Karpathy-style rule heading: ${heading}`);
344
347
  }
@@ -396,25 +399,25 @@ for (const workflow of listMarkdownFiles('Harness/workflows')) {
396
399
  }
397
400
  }
398
401
 
399
- for (const skillFile of registeredSkillFiles(docsReadme, memory)) {
400
- if (!fs.existsSync(path.join(root, skillFile))) {
401
- errors.push(`registered skill file is missing: ${skillFile}`);
402
- }
403
- }
404
-
405
- for (const command of listedWorkflowCommands(docsReadme, read('.claude/commands/wf-help.md'))) {
406
- const skill = command.slice(1);
407
- const claudeSkill = `.claude/skills/${skill}/SKILL.md`;
408
- const codexSkill = `.agents/skills/${skill}/SKILL.md`;
409
- if (!fs.existsSync(path.join(root, claudeSkill))) {
410
- errors.push(`command docs list missing Claude skill: ${command} -> ${claudeSkill}`);
411
- }
412
- if (!fs.existsSync(path.join(root, codexSkill))) {
413
- errors.push(`command docs list missing Codex skill: ${command} -> ${codexSkill}`);
414
- }
415
- }
416
-
417
- for (const workflowFile of registeredWorkflowFiles(docsReadme, memory)) {
402
+ for (const skillFile of registeredSkillFiles(docsReadme, memory)) {
403
+ if (!fs.existsSync(path.join(root, skillFile))) {
404
+ errors.push(`registered skill file is missing: ${skillFile}`);
405
+ }
406
+ }
407
+
408
+ for (const command of listedWorkflowCommands(docsReadme, read('.claude/commands/wf-help.md'))) {
409
+ const skill = command.slice(1);
410
+ const claudeSkill = `.claude/skills/${skill}/SKILL.md`;
411
+ const codexSkill = `.agents/skills/${skill}/SKILL.md`;
412
+ if (!fs.existsSync(path.join(root, claudeSkill))) {
413
+ errors.push(`command docs list missing Claude skill: ${command} -> ${claudeSkill}`);
414
+ }
415
+ if (!fs.existsSync(path.join(root, codexSkill))) {
416
+ errors.push(`command docs list missing Codex skill: ${command} -> ${codexSkill}`);
417
+ }
418
+ }
419
+
420
+ for (const workflowFile of registeredWorkflowFiles(docsReadme, memory)) {
418
421
  if (!fs.existsSync(path.join(root, workflowFile))) {
419
422
  // Optional workflows (browser-e2e, ts-react-frontend, etc.) may not be installed
420
423
  continue;
@@ -504,30 +507,44 @@ for (const agent of commonAgents) {
504
507
  }
505
508
  }
506
509
 
507
- requireText('Harness/extension.md', 'Skills should extend the harness');
508
- requireText('Harness/agent-workflow.md', 'Harness/tasks/<task-id>/PROGRESS.md');
509
- requireText('CLAUDE.md', 'Keep task records compact', 'compact task record startup rule');
510
- requireText('Harness/README.md', 'Task records are compact by default', 'compact task record router rule');
511
- requireText('Harness/agent-workflow.md', 'AC record size', 'compact AC record size rule');
512
- requireText('Harness/ACCEPTANCE_PROTOCOL.md', 'Default to 1-3 concise ACs', 'compact AC default');
513
- requireText('Harness/WF.md', 'Do not paste command logs or subagent transcripts', 'compact heartbeat rule');
514
- requireText('Harness/tasks/_template/PLAN.md', 'Compact task record', 'compact task PLAN template');
515
- requireText('Harness/tasks/_template/PLAN.md', 'Default: keep 1-3 concise ACs', 'compact task PLAN AC guidance');
516
- requireText('Harness/tasks/_template/PROGRESS.md', 'Compact heartbeat', 'compact task PROGRESS template');
517
- requireText('Harness/agent-workflow.md', 'TDD-GUIDE.md', 'agent workflow loads TDD guide');
518
- requireText('Harness/agent-workflow.md', 'real user-path test', 'agent workflow real user path requirement');
519
- requireText('Harness/research/README.md', 'research-results.md');
510
+ for (const agent of commonAgents) {
511
+ const rel = `.opencode/agents/${agent}.md`;
512
+ const text = read(rel);
513
+ if (!text) continue;
514
+
515
+ for (const field of ['description', 'mode']) {
516
+ if (!frontmatterField(text, field)) errors.push(`${rel} missing frontmatter field: ${field}:`);
517
+ }
518
+
519
+ const mode = frontmatterField(text, 'mode');
520
+ if (mode && mode !== 'subagent') {
521
+ errors.push(`${rel} frontmatter mode should be subagent (got: ${mode})`);
522
+ }
523
+ }
524
+
525
+ requireText('Harness/extension.md', 'Skills should extend the harness');
526
+ requireText('Harness/agent-workflow.md', 'Harness/tasks/<task-id>/PROGRESS.md');
527
+ requireText('Harness/README.md', 'Task records are compact by default', 'compact task record router rule');
528
+ requireText('Harness/agent-workflow.md', 'AC record size', 'compact AC record size rule');
529
+ requireText('Harness/ACCEPTANCE_PROTOCOL.md', 'Default to 1-3 concise ACs', 'compact AC default');
530
+ requireText('Harness/WF.md', 'Do not paste command logs or subagent transcripts', 'compact heartbeat rule');
531
+ requireText('Harness/tasks/_template/PLAN.md', 'Compact task record', 'compact task PLAN template');
532
+ requireText('Harness/tasks/_template/PLAN.md', 'Default: keep 1-3 concise ACs', 'compact task PLAN AC guidance');
533
+ requireText('Harness/tasks/_template/PROGRESS.md', 'Compact heartbeat', 'compact task PROGRESS template');
534
+ requireText('Harness/agent-workflow.md', 'TDD-GUIDE.md', 'agent workflow loads TDD guide');
535
+ requireText('Harness/agent-workflow.md', 'real user-path test', 'agent workflow real user path requirement');
536
+ requireText('Harness/research/README.md', 'research-results.md');
520
537
  requireText('Harness/WF.md', 'Ralph-style harness loop', 'WF loop description');
521
538
  requireText('Harness/WF.md', 'Heartbeat Protocol', 'heartbeat protocol');
522
- requireText('Harness/WF.md', 'WF mode requires the complete role chain by default', 'WF complete role chain default');
523
- requireText('Harness/WF.md', 'MUST cover every mandatory role class before closeout', 'explicit WF/WK complete role chain');
524
- requireText('Harness/WF.md', 'Independent Validation', 'WF independent validation role');
525
- requireText('Harness/WF.md', 'reflector', 'WF reflector gate');
539
+ requireText('Harness/WF.md', 'WF mode requires the complete role chain by default', 'WF complete role chain default');
540
+ requireText('Harness/WF.md', 'MUST cover every mandatory role class before closeout', 'explicit WF/WK complete role chain');
541
+ requireText('Harness/WF.md', 'Independent Validation', 'WF independent validation role');
542
+ requireText('Harness/WF.md', 'reflector', 'WF reflector gate');
526
543
  requireText('Harness/WF.md', '.claude/agents/', 'WF built-in agent roster path');
527
- requireText('Harness/WF.md', 'Collaboration decision tree', 'WF decision tree');
528
- requireText('Harness/WF.md', 'Harness/tasks/', 'WF task directory reference');
529
- requireText('Harness/WF.md', 'IMPLEMENT-GATE', 'WF implement gate naming');
530
- requireText('Harness/README.md', '`wf mode`, `workflow mode`, or `wk mode`', 'WF/WK router aliases');
544
+ requireText('Harness/WF.md', 'Collaboration decision tree', 'WF decision tree');
545
+ requireText('Harness/WF.md', 'Harness/tasks/', 'WF task directory reference');
546
+ requireText('Harness/WF.md', 'IMPLEMENT-GATE', 'WF implement gate naming');
547
+ requireText('Harness/README.md', '`wf mode`, `workflow mode`, or `wk mode`', 'WF/WK router aliases');
531
548
  requireText('Harness/README.md', 'explicit WF/WK loads subagent docs immediately', 'explicit WF/WK router output');
532
549
  requireText('.claude/skills/wf/SKILL.md', 'Harness/WF.md', 'wf skill loads core WF doc');
533
550
  requireText('.agents/skills/wf/SKILL.md', 'Harness/WF.md', 'Codex wf skill loads core WF doc');
@@ -540,125 +557,137 @@ requireText('Harness/subagents.md', '## Source Attribution', 'subagent source at
540
557
  requireText('Harness/subagents.md', 'npx skills find', 'find-skills discovery attribution');
541
558
  requireText('Harness/subagents.md', 'superpowers:dispatching-parallel-agents', 'parallel-agent source attribution');
542
559
  requireText('Harness/subagents.md', 'superpowers:subagent-driven-development', 'subagent-driven source attribution');
543
- requireText('Harness/subagents.md', '## Built-in Agent Roster', 'built-in agent roster');
544
- requireText('Harness/subagents.md', '## WF Default Fan-Out', 'WF default fan-out');
545
- requireText('Harness/subagents.md', 'concrete conditions', 'subagent decision tree');
546
- requireText('Harness/subagents.md', 'parallel planner/researcher/docs-researcher/architect subagents', 'WF roster orchestration shape');
547
- requireText('Harness/subagents.md', '`reflector`', 'reflector agent roster');
548
- requireText('Harness/subagents.md', 'reflector PASS', 'reflector review gate');
549
- requireText('Harness/subagents.md', '## Efficiency Ladder', 'subagent efficiency ladder');
550
- requireText('Harness/subagents.md', '## Review Gates', 'subagent review gates');
560
+ requireText('Harness/subagents.md', '## Built-in Agent Roster', 'built-in agent roster');
561
+ requireText('Harness/subagents.md', '## WF Default Fan-Out', 'WF default fan-out');
562
+ requireText('Harness/subagents.md', 'concrete conditions', 'subagent decision tree');
563
+ requireText('Harness/subagents.md', 'parallel planner/researcher/docs-researcher/architect subagents', 'WF roster orchestration shape');
564
+ requireText('Harness/subagents.md', '`reflector`', 'reflector agent roster');
565
+ requireText('Harness/subagents.md', 'reflector PASS', 'reflector review gate');
566
+ requireText('Harness/subagents.md', '## Efficiency Ladder', 'subagent efficiency ladder');
567
+ requireText('Harness/subagents.md', '## Review Gates', 'subagent review gates');
551
568
  requireText('Harness/architecture.md', '## 2. Interface Decoupling', 'architecture interface decoupling');
552
569
  requireText('Harness/architecture.md', '## 3. State Design', 'architecture state design');
553
570
  requireText('Harness/architecture.md', 'Avoid speculative abstraction', 'anti-overengineering architecture rule');
554
571
  requireText('CLAUDE.md', 'Use explicit interfaces or state models only when they protect a real boundary', 'CLAUDE interface/state simplicity rule');
555
- requireText('CLAUDE.md', '/wf-update', 'wf update startup instruction');
572
+ requireText('Harness/README.md', '/wf-update', 'wf update startup instruction');
556
573
  requireText('Harness/README.md', 'Need harness update', 'update routing row');
557
- requireText('Harness/WF-MAX.md', 'three-layer architecture', 'WF-MAX three-layer architecture');
558
- requireText('Harness/WF-MAX.md', 'agent role', 'WF-MAX agent role separation');
559
- requireText('Harness/WF-MAX.md', 'write-set coloring', 'WF-MAX coloring algorithm');
560
- requireText('Harness/WF-MAX.md', 'wave dispatch', 'WF-MAX wave dispatch');
561
- requireText('Harness/WF-MAX.md', 'strict superset', 'WF-MAX strict superset');
562
- requireText('Harness/WF-MAX.md', 'cross-CLI overflow', 'WF-MAX cross-CLI overflow');
563
- requireText('Harness/WF-MAX.md', 'claude -p', 'WF-MAX Claude CLI overflow');
564
- requireText('Harness/WF-MAX.md', 'codex exec', 'WF-MAX Codex CLI overflow');
565
- requireText('Harness/WF-MAX.md', 'agents.max_threads', 'WF-MAX Codex max_threads config');
566
- requireText('Harness/WF-MAX.md', 'agents.max_depth', 'WF-MAX Codex max_depth config');
567
- requireText('Harness/WF-MAX.md', 'max_threads = 12', 'WF-MAX Codex scaffold max_threads default');
568
- requireText('Harness/WF-MAX.md', 'max_depth = 1', 'WF-MAX Codex scaffold max_depth default');
569
- requireText('Harness/WF-MAX.md', 'ask the user before raising `agents.max_threads`', 'WF-MAX asks before raising Codex thread cap');
570
- requireText('Harness/WF-MAX.md', 'Close completed agents', 'WF-MAX close completed agents before overflow');
571
- requireText('Harness/WF-MAX.md', 'Codex++', 'WF-MAX forbids relying on Codex++ as stable capacity');
572
- requireText('.claude/skills/wf-max/SKILL.md', 'agents.max_threads', 'wf-max skill Codex thread config');
573
- requireText('.claude/skills/wf-max/SKILL.md', 'max_threads = 12', 'wf-max skill Codex scaffold max_threads default');
574
- requireText('.claude/skills/wf-max/SKILL.md', 'ask the user before raising', 'wf-max skill asks before raising Codex thread cap');
575
- requireText('.claude/skills/wf-max/SKILL.md', 'Codex++', 'wf-max skill forbids Codex++ capacity assumption');
576
- requireText('.codex/config.toml', '[agents]', 'Codex agents config table');
577
- requireText('.codex/config.toml', 'max_threads = 12', 'Codex scaffold max_threads default');
578
- requireText('.codex/config.toml', 'max_depth = 1', 'Codex scaffold max_depth default');
579
- requireText('Harness/README.md', '/wf-max', 'wf max router alias');
580
- requireText('Harness/README.md', 'WF-MAX.md', 'WF-MAX router reference');
581
- requireText('Harness/README.md', 'ACCEPTANCE_PROTOCOL.md', 'acceptance protocol router reference');
582
- requireText('Harness/README.md', 'TDD-GUIDE.md', 'TDD guide router reference');
583
- requireText('Harness/ACCEPTANCE_PROTOCOL.md', 'PRD-GATE', 'acceptance PRD gate');
584
- requireText('Harness/ACCEPTANCE_PROTOCOL.md', 'AC-GATE', 'acceptance AC gate');
585
- requireText('Harness/ACCEPTANCE_PROTOCOL.md', 'Acceptance Result', 'acceptance result matrix');
586
- requireText('Harness/ACCEPTANCE_PROTOCOL.md', 'Syntax-only checks', 'syntax-only checks are not browser acceptance evidence');
587
- requireText('Harness/AGENT_ISOLATION.md', 'implementer', 'agent isolation implementer rule');
588
- requireText('Harness/HARNESS_BRIDGE.md', 'Network Trace Collector', 'harness bridge network trace collector');
589
- requireText('Harness/WF-AUTO.md', 'Intent Checkpoint', 'wf-auto intent checkpoint');
590
- requireText('Harness/WF-AUTO.md', 'Inherited WF/WF-MAX Constraints', 'wf-auto inherited WF/WF-MAX constraints');
591
- requireText('Harness/WF-AUTO.md', 'Mini PRD -> AC IDs -> test/validation plan -> implementer -> verifier', 'wf-auto per-cycle WF chain');
592
- requireText('Harness/WF-AUTO.md', 'reflector PASS', 'wf-auto reflector gate');
593
- requireText('Harness/WF-AUTO-SPARK.md', 'Inherited Execution Chain', 'wf-auto-spark inherited execution chain');
594
- requireText('Harness/WF-AUTO-SPARK.md', 'External spark search replaces discovery only', 'wf-auto-spark discovery-only inheritance');
595
- requireText('Harness/WF-AUTO-SPARK.md', 'reflector PASS', 'wf-auto-spark reflector gate');
596
- requireText('Harness/MEMORY_PROTOCOL.md', 'Scenario Memory Hints', 'memory protocol scenario hints');
597
- requireText('Harness/MEMORY_PROTOCOL.md', 'WF closeout', 'memory protocol WF closeout injection row');
598
- requireText('Harness/MEMORY_PROTOCOL.md', 'memory-master owns writes', 'memory protocol memory write ownership');
599
- requireText('Harness/TDD-GUIDE.md', 'Browser/UI Acceptance TDD Gate', 'browser UI acceptance TDD gate');
600
- requireText('Harness/TDD-GUIDE.md', 'syntax-only', 'syntax-only acceptance prohibition');
601
- requireText('Harness/TDD-GUIDE.md', 'Playwright/CDP', 'Playwright/CDP acceptance requirement');
602
- requireText('Harness/TDD-GUIDE.md', 'AC-by-AC result matrix', 'AC-by-AC TDD evidence matrix');
603
- requireText('Harness/tasks/_template/PLAN.md', 'Expanded evidence required when triggered', 'task template expanded evidence trigger');
604
- requireText('Harness/templates/TEST_PLAN.template.md', 'syntax-only checks', 'test plan template syntax-only prohibition');
605
- requireText('.claude/skills/tdd/SKILL.md', 'Harness/ACCEPTANCE_PROTOCOL.md', 'tdd skill loads acceptance protocol');
606
- requireText('.claude/skills/tdd/SKILL.md', 'Harness/HARNESS_BRIDGE.md', 'tdd skill loads harness bridge');
607
- requireText('.claude/skills/tdd/SKILL.md', 'No syntax-only acceptance', 'tdd skill forbids syntax-only acceptance');
608
- requireText('.claude/skills/wf-remove/SKILL.md', 'User-facing removal is the slash/skill command', 'wf-remove slash command is user-facing');
609
- requireText('.claude/skills/wf-remove/SKILL.md', 'agent-internal execution steps', 'wf-remove script commands are agent-internal');
610
- requireText('.claude/skills/wf-remove/SKILL.md', 'verify residual discovery folders', 'wf-remove residual discovery verification');
611
- requireText('.claude/agents/tdd-guide.md', 'Browser Acceptance Rules', 'tdd-guide browser acceptance rules');
612
- requireText('.claude/agents/tdd-guide.md', 'real user actions', 'tdd-guide real user action requirement');
613
- requireText('.claude/agents/test-writer.md', 'Harness/ACCEPTANCE_PROTOCOL.md', 'test-writer loads acceptance protocol');
614
- requireText('.claude/agents/test-writer.md', 'real user-path test', 'test-writer real user path requirement');
615
- requireText('.claude/agents/test-writer.md', 'network URL, method, payload', 'test-writer network assertion requirement');
616
- requireText('.claude/agents/reflector.md', 'PASS, RETURN_TO_DEBUG, or BLOCKED', 'reflector verdict contract');
617
- requireText('Harness/DEBUG_PROTOCOL.md', 'Layer Classification', 'debug layer classification');
618
- requireText('Harness/MEMORY_PROTOCOL.md', 'AC ID', 'memory AC traceability');
619
- requireText('Harness/subagents.md', 'Max parallelism', 'subagents max parallelism row');
574
+ requireText('Harness/WF-MAX.md', 'three-layer architecture', 'WF-MAX three-layer architecture');
575
+ requireText('Harness/WF-MAX.md', 'agent role', 'WF-MAX agent role separation');
576
+ requireText('Harness/WF-MAX.md', 'write-set coloring', 'WF-MAX coloring algorithm');
577
+ requireText('Harness/WF-MAX.md', 'wave dispatch', 'WF-MAX wave dispatch');
578
+ requireText('Harness/WF-MAX.md', 'strict superset', 'WF-MAX strict superset');
579
+ requireText('Harness/WF-MAX.md', 'cross-CLI overflow', 'WF-MAX cross-CLI overflow');
580
+ requireText('Harness/WF-MAX.md', 'claude -p', 'WF-MAX Claude CLI overflow');
581
+ requireText('Harness/WF-MAX.md', 'codex exec', 'WF-MAX Codex CLI overflow');
582
+ requireText('Harness/WF-MAX.md', 'agents.max_threads', 'WF-MAX Codex max_threads config');
583
+ requireText('Harness/WF-MAX.md', 'agents.max_depth', 'WF-MAX Codex max_depth config');
584
+ requireText('Harness/WF-MAX.md', 'max_threads = 12', 'WF-MAX Codex scaffold max_threads default');
585
+ requireText('Harness/WF-MAX.md', 'max_depth = 1', 'WF-MAX Codex scaffold max_depth default');
586
+ requireText('Harness/WF-MAX.md', 'ask the user before raising `agents.max_threads`', 'WF-MAX asks before raising Codex thread cap');
587
+ requireText('Harness/WF-MAX.md', 'Close completed agents', 'WF-MAX close completed agents before overflow');
588
+ requireText('Harness/WF-MAX.md', 'Codex++', 'WF-MAX forbids relying on Codex++ as stable capacity');
589
+ requireText('.claude/skills/wf-max/SKILL.md', 'agents.max_threads', 'wf-max skill Codex thread config');
590
+ requireText('.claude/skills/wf-max/SKILL.md', 'max_threads = 12', 'wf-max skill Codex scaffold max_threads default');
591
+ requireText('.claude/skills/wf-max/SKILL.md', 'ask the user before raising', 'wf-max skill asks before raising Codex thread cap');
592
+ requireText('.claude/skills/wf-max/SKILL.md', 'Codex++', 'wf-max skill forbids Codex++ capacity assumption');
593
+ requireText('.codex/config.toml', '[agents]', 'Codex agents config table');
594
+ requireText('.codex/config.toml', 'max_threads = 12', 'Codex scaffold max_threads default');
595
+ requireText('.codex/config.toml', 'max_depth = 1', 'Codex scaffold max_depth default');
596
+ requireText('opencode.json', '"$schema": "https://opencode.ai/config.json"', 'OpenCode config schema');
597
+ requireText('opencode.json', '.claude/rules/ecc/common.md', 'OpenCode instructions reference to ECC rules');
598
+ requireText('Harness/README.md', '/wf-max', 'wf max router alias');
599
+ requireText('Harness/README.md', 'WF-MAX.md', 'WF-MAX router reference');
600
+ requireText('Harness/README.md', 'ACCEPTANCE_PROTOCOL.md', 'acceptance protocol router reference');
601
+ requireText('Harness/README.md', 'TDD-GUIDE.md', 'TDD guide router reference');
602
+ requireText('Harness/ACCEPTANCE_PROTOCOL.md', 'PRD-GATE', 'acceptance PRD gate');
603
+ requireText('Harness/ACCEPTANCE_PROTOCOL.md', 'AC-GATE', 'acceptance AC gate');
604
+ requireText('Harness/ACCEPTANCE_PROTOCOL.md', 'Acceptance Result', 'acceptance result matrix');
605
+ requireText('Harness/ACCEPTANCE_PROTOCOL.md', 'Syntax-only checks', 'syntax-only checks are not browser acceptance evidence');
606
+ requireText('Harness/AGENT_ISOLATION.md', 'implementer', 'agent isolation implementer rule');
607
+ requireText('Harness/HARNESS_BRIDGE.md', 'Network Trace Collector', 'harness bridge network trace collector');
608
+ requireText('Harness/WF-AUTO.md', 'Intent Checkpoint', 'wf-auto intent checkpoint');
609
+ requireText('Harness/WF-AUTO.md', 'Adaptive Coverage Exhaustion Gate', 'wf-auto adaptive coverage exhaustion gate');
610
+ requireText('Harness/WF-AUTO.md', 'dynamic high-risk obligations', 'wf-auto dynamic high-risk obligations');
611
+ requireText('Harness/WF-AUTO.md', 'two different confirmation strategies', 'wf-auto two different confirmation strategies');
612
+ requireText('Harness/WF-AUTO-ANGLES.md', 'Selection algorithm', 'wf-auto adaptive angle selection');
613
+ requireText('Harness/WF-AUTO-ANGLES.md', 'Dynamic obligations', 'wf-auto dynamic obligations');
614
+ requireText('Harness/WF-AUTO-ANGLES.md', 'Common probe recipes', 'wf-auto common probe recipes');
615
+ forbidText('Harness/WF-AUTO.md', 'All 8 exhausted', 'stale eight-angle exhaustion rule');
616
+ forbidText('Harness/WF-AUTO.md', '3 consecutive all-exhausted rounds', 'stale three-consecutive-all-exhausted stop rule');
617
+ forbidText('Harness/WF-AUTO.md', '8-Angle Exhaustion Gate', 'stale eight-angle exhaustion gate name');
618
+ forbidText('Harness/WF-AUTO-SPARK.md', '8 parallel external searches', 'stale eight-spark fixed-count search');
619
+ requireText('Harness/WF-AUTO.md', 'Inherited WF/WF-MAX Constraints', 'wf-auto inherited WF/WF-MAX constraints');
620
+ requireText('Harness/WF-AUTO.md', 'Mini PRD -> AC IDs -> test/validation plan -> implementer -> verifier', 'wf-auto per-cycle WF chain');
621
+ requireText('Harness/WF-AUTO.md', 'reflector PASS', 'wf-auto reflector gate');
622
+ requireText('Harness/WF-AUTO-SPARK.md', 'Inherited Execution Chain', 'wf-auto-spark inherited execution chain');
623
+ requireText('Harness/WF-AUTO-SPARK.md', 'External spark search replaces discovery only', 'wf-auto-spark discovery-only inheritance');
624
+ requireText('Harness/WF-AUTO-SPARK.md', 'reflector PASS', 'wf-auto-spark reflector gate');
625
+ requireText('Harness/MEMORY_PROTOCOL.md', 'Scenario Memory Hints', 'memory protocol scenario hints');
626
+ requireText('Harness/MEMORY_PROTOCOL.md', 'WF closeout', 'memory protocol WF closeout injection row');
627
+ requireText('Harness/MEMORY_PROTOCOL.md', 'memory-master owns writes', 'memory protocol memory write ownership');
628
+ requireText('Harness/TDD-GUIDE.md', 'Browser/UI Acceptance TDD Gate', 'browser UI acceptance TDD gate');
629
+ requireText('Harness/TDD-GUIDE.md', 'syntax-only', 'syntax-only acceptance prohibition');
630
+ requireText('Harness/TDD-GUIDE.md', 'Playwright/CDP', 'Playwright/CDP acceptance requirement');
631
+ requireText('Harness/TDD-GUIDE.md', 'AC-by-AC result matrix', 'AC-by-AC TDD evidence matrix');
632
+ requireText('Harness/tasks/_template/PLAN.md', 'Expanded evidence required when triggered', 'task template expanded evidence trigger');
633
+ requireText('Harness/templates/TEST_PLAN.template.md', 'syntax-only checks', 'test plan template syntax-only prohibition');
634
+ requireText('.claude/skills/tdd/SKILL.md', 'Harness/ACCEPTANCE_PROTOCOL.md', 'tdd skill loads acceptance protocol');
635
+ requireText('.claude/skills/tdd/SKILL.md', 'Harness/HARNESS_BRIDGE.md', 'tdd skill loads harness bridge');
636
+ requireText('.claude/skills/tdd/SKILL.md', 'No syntax-only acceptance', 'tdd skill forbids syntax-only acceptance');
637
+ requireText('.claude/skills/wf-remove/SKILL.md', 'User-facing removal is the slash/skill command', 'wf-remove slash command is user-facing');
638
+ requireText('.claude/skills/wf-remove/SKILL.md', 'agent-internal execution steps', 'wf-remove script commands are agent-internal');
639
+ requireText('.claude/skills/wf-remove/SKILL.md', 'verify residual discovery folders', 'wf-remove residual discovery verification');
640
+ requireText('.claude/agents/tdd-guide.md', 'Browser Acceptance Rules', 'tdd-guide browser acceptance rules');
641
+ requireText('.claude/agents/tdd-guide.md', 'real user actions', 'tdd-guide real user action requirement');
642
+ requireText('.claude/agents/test-writer.md', 'Harness/ACCEPTANCE_PROTOCOL.md', 'test-writer loads acceptance protocol');
643
+ requireText('.claude/agents/test-writer.md', 'real user-path test', 'test-writer real user path requirement');
644
+ requireText('.claude/agents/test-writer.md', 'network URL, method, payload', 'test-writer network assertion requirement');
645
+ requireText('.claude/agents/reflector.md', 'PASS, RETURN_TO_DEBUG, or BLOCKED', 'reflector verdict contract');
646
+ requireText('Harness/DEBUG_PROTOCOL.md', 'Layer Classification', 'debug layer classification');
647
+ requireText('Harness/MEMORY_PROTOCOL.md', 'AC ID', 'memory AC traceability');
648
+ requireText('Harness/subagents.md', 'Max parallelism', 'subagents max parallelism row');
620
649
  requireText('Harness/dispatch.md', 'Concurrency group', 'dispatch concurrency group field');
621
650
  requireText('Harness/dispatch.md', 'File claim', 'dispatch file claim field');
622
- requireText('CLAUDE.md', '/wf-max', 'wf max startup instruction');
623
- requireText('.claude/commands/wf-help.md', 'Do not invoke a skill', 'wf-help direct command boundary');
624
- requireText('.claude/commands/wf-help.md', '| `/wf-help` |', 'wf-help command row');
625
- requireText('.claude/commands/wf-help.md', '| `/wf-max <task>` |', 'wf-help wf-max row');
626
- requireText('.claude/commands/wf-help.md', '| `/wf-auto` |', 'wf-help wf-auto row');
627
- requireText('.claude/commands/wf-help.md', '| `/wf-readme <task>` |', 'wf-help wf-readme row');
628
- requireText('Harness/README.md', '## Direct Commands', 'direct commands section');
629
- requireText('Harness/README.md', '.claude/commands/wf-help.md', 'wf-help router reference');
630
- requireText('CLAUDE.md', 'three-layer architecture', 'CLAUDE.md three-layer role architecture');
631
- requireText('CLAUDE.md', 'not hook-enforced', 'CLAUDE no-hook role enforcement statement');
632
- requireText('Harness/README.md', 'no runtime hook state', 'README no-hook runtime statement');
633
- requireText('Harness/WF-AUTO.md', 'WF-AUTO Hook Exception', 'wf-auto-only hook exception');
634
- requireText('Harness/WF-AUTO.md', 'only `/wf-auto` may use a runtime hook', 'wf-auto-only hook boundary');
635
- forbidText('CLAUDE.md', 'Enforced by hooks', 'WF-MAX hook enforcement claim');
636
- forbidText('Harness/WF.md', 'MUST use at least 3 distinct role passes', 'old WF role-pass minimum');
637
- forbidText('Harness/WF.md', 'at least three distinct role passes', 'old WF role-pass wording');
638
- forbidText('Harness/dispatch.md', 'requires ≥3 distinct subagents', 'old dispatch WF role minimum');
639
- forbidText('CLAUDE.md', 'WF-MAX hooks', 'WF-MAX hook enforcement claim');
640
- forbidText('Harness/README.md', 'PreToolUse hook', 'WF-MAX PreToolUse hook claim');
641
- forbidText('Harness/README.md', 'SessionStart hook', 'WF-MAX SessionStart hook claim');
642
- forbidText('Harness/README.md', 'hook-managed', 'hook-managed runtime claim');
643
- forbidText('Harness/README.md', 'HOOK_PROTOCOL.md', 'removed hook protocol reference');
644
- forbidText('Harness/WF-AUTO.md', 'Hook-Assisted Long Loop', 'wf-auto hook loop section');
645
- forbidText('Harness/dispatch.md', 'removes the cap entirely', 'unbounded runtime-cap claim');
646
- forbidText('Harness/WF-MAX.md', 'no hard agent cap; recursion governed', 'unbounded agent-cap claim');
647
- forbidText('Harness/MEMORY_PROTOCOL.md', 'Hooks may', 'hook-triggered memory claim');
648
- forbidText('.claude/settings.json', 'wf-mode-hook.mjs', 'Claude WF hook command registration');
649
- forbidText('.codex/hooks.json', 'wf-mode-hook.mjs', 'Codex WF hook command registration');
650
- const codexHookConfig = read('.codex/hooks.json');
651
- const claudeSettings = read('.claude/settings.json');
652
- if (codexHookConfig && !codexHookConfig.includes('wf-auto')) {
653
- errors.push('.codex/hooks.json may only exist for a wf-auto hook configuration');
654
- }
655
- if (claudeSettings.includes('"hooks"') && !claudeSettings.includes('wf-auto')) {
656
- errors.push('.claude/settings.json hooks may only be used for wf-auto');
657
- }
658
- if (read('.codex/config.toml').includes('hooks = true') && !codexHookConfig.includes('wf-auto')) {
659
- errors.push('.codex/config.toml may enable hooks only with a wf-auto hook configuration');
660
- }
661
- if (errors.length) {
651
+ requireText('CLAUDE.md', '/wf-max', 'wf max startup instruction');
652
+ requireText('.claude/commands/wf-help.md', 'Do not invoke a skill', 'wf-help direct command boundary');
653
+ requireText('.claude/commands/wf-help.md', '| `/wf-help` |', 'wf-help command row');
654
+ requireText('.claude/commands/wf-help.md', '| `/wf-max <task>` |', 'wf-help wf-max row');
655
+ requireText('.claude/commands/wf-help.md', '| `/wf-auto` |', 'wf-help wf-auto row');
656
+ requireText('.claude/commands/wf-help.md', '| `/wf-readme <task>` |', 'wf-help wf-readme row');
657
+ requireText('Harness/README.md', '## Direct Commands', 'direct commands section');
658
+ requireText('Harness/README.md', '.claude/commands/wf-help.md', 'wf-help router reference');
659
+ requireText('Harness/WF-MAX.md', 'three-layer architecture', 'CLAUDE.md three-layer role architecture');
660
+ requireText('Harness/README.md', 'no runtime hook state', 'CLAUDE no-hook role enforcement statement');
661
+ requireText('Harness/README.md', 'no runtime hook state', 'README no-hook runtime statement');
662
+ requireText('Harness/WF-AUTO.md', 'WF-AUTO Hook Exception', 'wf-auto-only hook exception');
663
+ requireText('Harness/WF-AUTO.md', 'only `/wf-auto` may use a runtime hook', 'wf-auto-only hook boundary');
664
+ forbidText('CLAUDE.md', 'Enforced by hooks', 'WF-MAX hook enforcement claim');
665
+ forbidText('Harness/WF.md', 'MUST use at least 3 distinct role passes', 'old WF role-pass minimum');
666
+ forbidText('Harness/WF.md', 'at least three distinct role passes', 'old WF role-pass wording');
667
+ forbidText('Harness/dispatch.md', 'requires ≥3 distinct subagents', 'old dispatch WF role minimum');
668
+ forbidText('CLAUDE.md', 'WF-MAX hooks', 'WF-MAX hook enforcement claim');
669
+ forbidText('Harness/README.md', 'PreToolUse hook', 'WF-MAX PreToolUse hook claim');
670
+ forbidText('Harness/README.md', 'SessionStart hook', 'WF-MAX SessionStart hook claim');
671
+ forbidText('Harness/README.md', 'hook-managed', 'hook-managed runtime claim');
672
+ forbidText('Harness/README.md', 'HOOK_PROTOCOL.md', 'removed hook protocol reference');
673
+ forbidText('Harness/WF-AUTO.md', 'Hook-Assisted Long Loop', 'wf-auto hook loop section');
674
+ forbidText('Harness/dispatch.md', 'removes the cap entirely', 'unbounded runtime-cap claim');
675
+ forbidText('Harness/WF-MAX.md', 'no hard agent cap; recursion governed', 'unbounded agent-cap claim');
676
+ forbidText('Harness/MEMORY_PROTOCOL.md', 'Hooks may', 'hook-triggered memory claim');
677
+ forbidText('.claude/settings.json', 'wf-mode-hook.mjs', 'Claude WF hook command registration');
678
+ forbidText('.codex/hooks.json', 'wf-mode-hook.mjs', 'Codex WF hook command registration');
679
+ const codexHookConfig = read('.codex/hooks.json');
680
+ const claudeSettings = read('.claude/settings.json');
681
+ if (codexHookConfig && !codexHookConfig.includes('wf-auto')) {
682
+ errors.push('.codex/hooks.json may only exist for a wf-auto hook configuration');
683
+ }
684
+ if (claudeSettings.includes('"hooks"') && !claudeSettings.includes('wf-auto')) {
685
+ errors.push('.claude/settings.json hooks may only be used for wf-auto');
686
+ }
687
+ if (read('.codex/config.toml').includes('hooks = true') && !codexHookConfig.includes('wf-auto')) {
688
+ errors.push('.codex/config.toml may enable hooks only with a wf-auto hook configuration');
689
+ }
690
+ if (errors.length) {
662
691
  console.error(`Harness validation failed${strict ? ' (strict)' : ''}:`);
663
692
  for (const error of errors) console.error(`- ${error}`);
664
693
  process.exit(1);