create-harness-vibe-coding 0.8.13 → 0.8.16

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 (115) hide show
  1. package/CHANGELOG.md +165 -0
  2. package/README-CN.md +41 -9
  3. package/README.md +39 -9
  4. package/package.json +2 -1
  5. package/src/generator.js +601 -472
  6. package/src/index.js +4 -4
  7. package/templates/common/.claude/agents/architect-manager.md +1 -0
  8. package/templates/common/.claude/agents/architect.md +2 -1
  9. package/templates/common/.claude/agents/codebase-explorer.md +1 -0
  10. package/templates/common/.claude/agents/context-master.md +2 -1
  11. package/templates/common/.claude/agents/debugger.md +1 -0
  12. package/templates/common/.claude/agents/docs-researcher.md +2 -1
  13. package/templates/common/.claude/agents/explore-manager.md +1 -0
  14. package/templates/common/.claude/agents/implement-manager.md +1 -0
  15. package/templates/common/.claude/agents/implementer.md +1 -0
  16. package/templates/common/.claude/agents/memory-master.md +2 -1
  17. package/templates/common/.claude/agents/planner.md +3 -2
  18. package/templates/common/.claude/agents/reflector.md +1 -0
  19. package/templates/common/.claude/agents/researcher.md +1 -0
  20. package/templates/common/.claude/agents/review-manager.md +1 -0
  21. package/templates/common/.claude/agents/reviewer.md +2 -1
  22. package/templates/common/.claude/agents/task-scribe.md +1 -0
  23. package/templates/common/.claude/agents/tdd-guide.md +5 -4
  24. package/templates/common/.claude/agents/test-writer.md +6 -5
  25. package/templates/common/.claude/agents/verifier.md +1 -0
  26. package/templates/common/.claude/commands/wf-help.md +1 -0
  27. package/templates/common/.claude/commands/wf-update.md +68 -10
  28. package/templates/common/.claude/rules/ecc/common.md +6 -5
  29. package/templates/common/.claude/skills/subagent-orchestrator/SKILL.md +12 -6
  30. package/templates/common/.claude/skills/tdd/SKILL.md +5 -5
  31. package/templates/common/.claude/skills/wf/SKILL.md +13 -5
  32. package/templates/common/.claude/skills/wf-agents-docs/SKILL.md +119 -0
  33. package/templates/common/.claude/skills/wf-auto/SKILL.md +27 -7
  34. package/templates/common/.claude/skills/wf-auto-spark/SKILL.md +12 -5
  35. package/templates/common/.claude/skills/wf-learn/SKILL.md +6 -0
  36. package/templates/common/.claude/skills/wf-max/SKILL.md +22 -7
  37. package/templates/common/.claude/skills/wf-readme/SKILL.md +8 -2
  38. package/templates/common/.claude/skills/wf-remove/SKILL.md +6 -0
  39. package/templates/common/.claude/skills/wf-review/SKILL.md +10 -3
  40. package/templates/common/.claude/skills/wf-update/SKILL.md +41 -4
  41. package/templates/common/.harness-version +290 -128
  42. package/templates/common/.opencode/agents/architect-manager.md +1 -0
  43. package/templates/common/.opencode/agents/architect.md +2 -1
  44. package/templates/common/.opencode/agents/codebase-explorer.md +1 -0
  45. package/templates/common/.opencode/agents/context-master.md +2 -1
  46. package/templates/common/.opencode/agents/debugger.md +1 -0
  47. package/templates/common/.opencode/agents/docs-researcher.md +2 -1
  48. package/templates/common/.opencode/agents/explore-manager.md +1 -0
  49. package/templates/common/.opencode/agents/implement-manager.md +1 -0
  50. package/templates/common/.opencode/agents/implementer.md +1 -0
  51. package/templates/common/.opencode/agents/memory-master.md +2 -1
  52. package/templates/common/.opencode/agents/planner.md +3 -2
  53. package/templates/common/.opencode/agents/reflector.md +1 -0
  54. package/templates/common/.opencode/agents/researcher.md +1 -0
  55. package/templates/common/.opencode/agents/review-manager.md +1 -0
  56. package/templates/common/.opencode/agents/reviewer.md +2 -1
  57. package/templates/common/.opencode/agents/task-scribe.md +1 -0
  58. package/templates/common/.opencode/agents/tdd-guide.md +5 -4
  59. package/templates/common/.opencode/agents/test-writer.md +6 -5
  60. package/templates/common/.opencode/agents/verifier.md +1 -0
  61. package/templates/common/.opencode/commands/wf-auto-spark.md +3 -2
  62. package/templates/common/.opencode/commands/wf-auto.md +3 -2
  63. package/templates/common/.opencode/commands/wf-help.md +1 -0
  64. package/templates/common/.opencode/commands/wf-learn.md +3 -2
  65. package/templates/common/.opencode/commands/wf-max.md +3 -2
  66. package/templates/common/.opencode/commands/wf-readme.md +3 -2
  67. package/templates/common/.opencode/commands/wf-remove.md +3 -2
  68. package/templates/common/.opencode/commands/wf-review.md +3 -2
  69. package/templates/common/.opencode/commands/wf-update.md +68 -10
  70. package/templates/common/.opencode/commands/wf.md +3 -2
  71. package/templates/common/CLAUDE.md +14 -12
  72. package/templates/common/Harness/MEMORY.md +21 -18
  73. package/templates/common/Harness/README.md +41 -39
  74. package/templates/common/Harness/ownership.manifest.json +815 -0
  75. package/templates/common/Harness/{architecture.md → project/architecture.md} +1 -1
  76. package/templates/common/Harness/research/README.md +3 -3
  77. package/templates/common/Harness/scripts/context-budget.mjs +95 -0
  78. package/templates/common/Harness/scripts/l2-cache-telemetry.mjs +703 -0
  79. package/templates/common/Harness/scripts/scan-clean.mjs +13 -3
  80. package/templates/common/Harness/scripts/validate-harness.mjs +332 -175
  81. package/templates/common/Harness/scripts/wf-remove.mjs +60 -34
  82. package/templates/common/Harness/scripts/wf-update-check.mjs +355 -45
  83. package/templates/common/Harness/settings.json +43 -0
  84. package/templates/common/Harness/{ECC-GUIDE.md → specs/guides/ECC-GUIDE.md} +4 -4
  85. package/templates/common/Harness/{SETUP.md → specs/guides/SETUP.md} +32 -35
  86. package/templates/common/Harness/{extension.md → specs/guides/extension.md} +3 -3
  87. package/templates/common/Harness/{lifecycle.md → specs/guides/lifecycle.md} +2 -2
  88. package/templates/common/Harness/{agent-workflow.md → specs/runtime/agent-workflow.md} +6 -6
  89. package/templates/common/Harness/{context-loading.md → specs/runtime/context-loading.md} +85 -21
  90. package/templates/common/Harness/{dispatch.md → specs/runtime/dispatch.md} +3 -2
  91. package/templates/common/Harness/{subagents.md → specs/runtime/subagents.md} +10 -5
  92. package/templates/common/Harness/{WF-AUTO-SPARK.md → specs/workflows/WF-AUTO-SPARK.md} +2 -2
  93. package/templates/common/Harness/{WF-AUTO.md → specs/workflows/WF-AUTO.md} +6 -1
  94. package/templates/common/Harness/{WF-KERNEL.md → specs/workflows/WF-KERNEL.md} +10 -0
  95. package/templates/common/Harness/{WF-MAX.md → specs/workflows/WF-MAX.md} +10 -5
  96. package/templates/common/Harness/{WF-STATE.md → specs/workflows/WF-STATE.md} +5 -0
  97. package/templates/common/Harness/{WF.md → specs/workflows/WF.md} +12 -1
  98. package/templates/common/README.md +8 -6
  99. package/templates/common/memory/startup-hints.md +19 -17
  100. package/templates/optional/skills/browser-e2e/.claude/skills/browser-e2e/SKILL.md +1 -1
  101. package/templates/optional/skills/browser-e2e/.claude/skills/wf-browser/SKILL.md +7 -0
  102. package/templates/optional/skills/browser-e2e/.opencode/commands/wf-browser.md +3 -2
  103. package/templates/optional/skills/browser-e2e/Harness/workflows/browser-e2e.md +4 -4
  104. package/templates/optional/skills/github-pr-review/.claude/skills/github-pr-review/SKILL.md +1 -1
  105. package/templates/optional/skills/python-backend/.claude/skills/python-backend/SKILL.md +1 -1
  106. package/templates/optional/skills/ts-react-frontend/.claude/skills/ts-react-frontend/SKILL.md +1 -1
  107. package/templates/optional/skills/ui-ux-review/.claude/skills/ui-ux-review/SKILL.md +1 -1
  108. /package/templates/common/Harness/{ACCEPTANCE_PROTOCOL.md → specs/protocols/ACCEPTANCE_PROTOCOL.md} +0 -0
  109. /package/templates/common/Harness/{AGENT_ISOLATION.md → specs/protocols/AGENT_ISOLATION.md} +0 -0
  110. /package/templates/common/Harness/{DEBUG_PROTOCOL.md → specs/protocols/DEBUG_PROTOCOL.md} +0 -0
  111. /package/templates/common/Harness/{HARNESS_BRIDGE.md → specs/protocols/HARNESS_BRIDGE.md} +0 -0
  112. /package/templates/common/Harness/{MEMORY_PROTOCOL.md → specs/protocols/MEMORY_PROTOCOL.md} +0 -0
  113. /package/templates/common/Harness/{TASK_ARCHIVE.md → specs/protocols/TASK_ARCHIVE.md} +0 -0
  114. /package/templates/common/Harness/{TDD-GUIDE.md → specs/protocols/TDD-GUIDE.md} +0 -0
  115. /package/templates/common/Harness/{WF-AUTO-ANGLES.md → specs/workflows/WF-AUTO-ANGLES.md} +0 -0
@@ -45,6 +45,7 @@ const commonSkills = [
45
45
  'wf-learn',
46
46
  'subagent-orchestrator',
47
47
  'wf-readme',
48
+ 'wf-agents-docs',
48
49
  'wf-remove',
49
50
  'wf-auto',
50
51
  'wf-auto-spark',
@@ -61,6 +62,10 @@ const opencodeWorkflowCommands = [
61
62
  'wf-remove',
62
63
  ];
63
64
 
65
+ const cacheDisciplinedSkills = commonSkills.filter(skill => (
66
+ skill === 'subagent-orchestrator' || skill.startsWith('wf')
67
+ ));
68
+
64
69
  const memoryFiles = [
65
70
  'Harness/memory/startup-hints.md',
66
71
  'Harness/memory/routes.md',
@@ -74,13 +79,13 @@ const required = [
74
79
  'CLAUDE.md',
75
80
  'README.md',
76
81
  'Harness/MEMORY.md',
77
- 'Harness/WF.md',
78
- 'Harness/WF-MAX.md',
79
- 'Harness/ACCEPTANCE_PROTOCOL.md',
80
- 'Harness/AGENT_ISOLATION.md',
81
- 'Harness/HARNESS_BRIDGE.md',
82
- 'Harness/DEBUG_PROTOCOL.md',
83
- 'Harness/MEMORY_PROTOCOL.md',
82
+ 'Harness/specs/workflows/WF.md',
83
+ 'Harness/specs/workflows/WF-MAX.md',
84
+ 'Harness/specs/protocols/ACCEPTANCE_PROTOCOL.md',
85
+ 'Harness/specs/protocols/AGENT_ISOLATION.md',
86
+ 'Harness/specs/protocols/HARNESS_BRIDGE.md',
87
+ 'Harness/specs/protocols/DEBUG_PROTOCOL.md',
88
+ 'Harness/specs/protocols/MEMORY_PROTOCOL.md',
84
89
  'Harness/templates/PRD.template.md',
85
90
  'Harness/templates/ACCEPTANCE.template.md',
86
91
  'Harness/templates/UI_CONTRACT.template.md',
@@ -104,24 +109,29 @@ const required = [
104
109
  ...commonSkills.map(skill => `.claude/skills/${skill}/SKILL.md`),
105
110
  ...commonSkills.map(skill => `.agents/skills/${skill}/SKILL.md`),
106
111
  'Harness/README.md',
112
+ 'Harness/settings.json',
113
+ 'Harness/specs/guides/SETUP.md',
107
114
  'Harness/PROGRESS.md',
108
- 'Harness/lifecycle.md',
109
- 'Harness/subagents.md',
110
- 'Harness/dispatch.md',
111
- 'Harness/extension.md',
112
- 'Harness/context-loading.md',
113
- 'Harness/WF-KERNEL.md',
114
- 'Harness/agent-workflow.md',
115
- 'Harness/architecture.md',
115
+ 'Harness/specs/guides/lifecycle.md',
116
+ 'Harness/specs/runtime/subagents.md',
117
+ 'Harness/specs/runtime/dispatch.md',
118
+ 'Harness/specs/guides/extension.md',
119
+ 'Harness/specs/runtime/context-loading.md',
120
+ 'Harness/ownership.manifest.json',
121
+ 'Harness/specs/workflows/WF-KERNEL.md',
122
+ 'Harness/specs/runtime/agent-workflow.md',
123
+ 'Harness/project/architecture.md',
116
124
  'Harness/research/README.md',
117
125
  'Harness/research/research-results.md',
118
126
  'Harness/research/PRD.md',
127
+ 'Harness/scripts/context-budget.mjs',
128
+ 'Harness/scripts/l2-cache-telemetry.mjs',
119
129
  'Harness/scripts/wf-update-check.mjs',
120
130
  'Harness/scripts/wf-remove.mjs',
121
131
  'Harness/scripts/scan-clean.mjs',
122
132
  'Harness/scripts/archive-tasks.mjs',
123
- 'Harness/WF-STATE.md',
124
- 'Harness/TASK_ARCHIVE.md',
133
+ 'Harness/specs/workflows/WF-STATE.md',
134
+ 'Harness/specs/protocols/TASK_ARCHIVE.md',
125
135
  'Harness/.harness-version',
126
136
  ];
127
137
 
@@ -129,7 +139,7 @@ const projectFacts = [
129
139
  'Harness/PROGRESS.md',
130
140
  'Harness/research/PRD.md',
131
141
  'Harness/research/research-results.md',
132
- 'Harness/architecture.md',
142
+ 'Harness/project/architecture.md',
133
143
  ];
134
144
 
135
145
  const contextPacks = [
@@ -149,9 +159,34 @@ const contextPacks = [
149
159
 
150
160
  const durableCommunicationDocs = [
151
161
  'Harness/README.md',
152
- 'Harness/subagents.md',
153
- 'Harness/dispatch.md',
162
+ 'Harness/specs/runtime/subagents.md',
163
+ 'Harness/specs/runtime/dispatch.md',
164
+ 'Harness/specs/runtime/context-loading.md',
165
+ ];
166
+
167
+ const legacyRootSpecDocs = [
168
+ 'Harness/ACCEPTANCE_PROTOCOL.md',
169
+ 'Harness/AGENT_ISOLATION.md',
170
+ 'Harness/DEBUG_PROTOCOL.md',
171
+ 'Harness/ECC-GUIDE.md',
172
+ 'Harness/HARNESS_BRIDGE.md',
173
+ 'Harness/MEMORY_PROTOCOL.md',
174
+ 'Harness/SETUP.md',
175
+ 'Harness/TASK_ARCHIVE.md',
176
+ 'Harness/TDD-GUIDE.md',
177
+ 'Harness/WF-AUTO-ANGLES.md',
178
+ 'Harness/WF-AUTO-SPARK.md',
179
+ 'Harness/WF-AUTO.md',
180
+ 'Harness/WF-KERNEL.md',
181
+ 'Harness/WF-MAX.md',
182
+ 'Harness/WF-STATE.md',
183
+ 'Harness/WF.md',
184
+ 'Harness/agent-workflow.md',
154
185
  'Harness/context-loading.md',
186
+ 'Harness/dispatch.md',
187
+ 'Harness/extension.md',
188
+ 'Harness/lifecycle.md',
189
+ 'Harness/subagents.md',
155
190
  ];
156
191
 
157
192
  const errors = [];
@@ -276,6 +311,27 @@ for (const rel of required) {
276
311
  }
277
312
  }
278
313
 
314
+ for (const rel of legacyRootSpecDocs) {
315
+ if (fs.existsSync(path.join(root, rel))) {
316
+ errors.push(`legacy root Harness spec doc should be migrated to Harness/specs/**: ${rel}`);
317
+ }
318
+ }
319
+
320
+ const manifestText = read('Harness/ownership.manifest.json');
321
+ if (manifestText) {
322
+ try {
323
+ const manifest = JSON.parse(manifestText);
324
+ for (const entry of manifest.frameworkOwned || []) {
325
+ if (!entry || typeof entry.path !== 'string') continue;
326
+ if (!fs.existsSync(path.join(root, ...entry.path.split('/')))) {
327
+ errors.push(`ownership manifest frameworkOwned file missing: ${entry.path}`);
328
+ }
329
+ }
330
+ } catch (err) {
331
+ errors.push(`Harness/ownership.manifest.json is not valid JSON: ${err.message}`);
332
+ }
333
+ }
334
+
279
335
  const removedHookArtifacts = [
280
336
  'Harness/HOOK_PROTOCOL.md',
281
337
  'Harness/scripts/wf-mode-hook.mjs',
@@ -328,7 +384,7 @@ for (const taskDir of taskDirs) {
328
384
  // M2: MCP-as-Worker fake-compliance guard.
329
385
  // Task capsules MUST NOT record mcp__codex.codex_implement / mcp__claude.claude_implement
330
386
  // as Worker execution. Historical do-not-repeat references are allowed only when the
331
- // file is marked ANTI-PATTERN. See Harness/WF-MAX.md "Worker Channel Degradation & Independence".
387
+ // file is marked ANTI-PATTERN. See Harness/specs/workflows/WF-MAX.md "Worker Channel Degradation & Independence".
332
388
  const MCP_AS_WORKER_RE = /mcp__(?:codex)\.codex_implement|mcp__(?:claude)\.claude_implement/;
333
389
  for (const taskDir of taskDirs) {
334
390
  if (!taskDir.startsWith('task-')) continue;
@@ -372,13 +428,13 @@ for (const rel of durableCommunicationDocs) {
372
428
  requireText(rel, 'chat/subagent transcript state is non-authoritative', 'non-authoritative transcript invariant');
373
429
  }
374
430
 
375
- requireText('Harness/MEMORY_PROTOCOL.md', 'L1/L2/L3 Memory Architecture', 'L2/L3 memory architecture section');
376
- requireText('Harness/MEMORY_PROTOCOL.md', 'Memory Candidate Detection', 'memory candidate detection section');
377
- requireText('Harness/MEMORY_PROTOCOL.md', 'explicit user preference', 'explicit user preference immediate write rule');
378
- requireText('Harness/MEMORY_PROTOCOL.md', 'Memory Routing (L3)', 'memory routing section');
379
- requireText('Harness/MEMORY_PROTOCOL.md', 'Scenario pack', 'route scoring scenario pack');
380
- requireText('Harness/MEMORY_PROTOCOL.md', 'same tool or command pattern fails 3+ times', 'tool reflection trigger');
381
- requireText('Harness/MEMORY_PROTOCOL.md', 'user corrects the same assumption or preference 2+ times', 'user correction reflection trigger');
431
+ requireText('Harness/specs/protocols/MEMORY_PROTOCOL.md', 'L1/L2/L3 Memory Architecture', 'L2/L3 memory architecture section');
432
+ requireText('Harness/specs/protocols/MEMORY_PROTOCOL.md', 'Memory Candidate Detection', 'memory candidate detection section');
433
+ requireText('Harness/specs/protocols/MEMORY_PROTOCOL.md', 'explicit user preference', 'explicit user preference immediate write rule');
434
+ requireText('Harness/specs/protocols/MEMORY_PROTOCOL.md', 'Memory Routing (L3)', 'memory routing section');
435
+ requireText('Harness/specs/protocols/MEMORY_PROTOCOL.md', 'Scenario pack', 'route scoring scenario pack');
436
+ requireText('Harness/specs/protocols/MEMORY_PROTOCOL.md', 'same tool or command pattern fails 3+ times', 'tool reflection trigger');
437
+ requireText('Harness/specs/protocols/MEMORY_PROTOCOL.md', 'user corrects the same assumption or preference 2+ times', 'user correction reflection trigger');
382
438
  requireText('CLAUDE.md', 'startup-hints.md', 'CLAUDE startup-hints routing');
383
439
  requireText('.claude/rules/ecc/common.md', 'startup-hints.md', 'ECC startup-hints routing');
384
440
  requireText('.claude/rules/ecc/common.md', 'memory candidates', 'ECC memory candidate detection');
@@ -398,20 +454,57 @@ requireText('Harness/memory/tool-usage-reflections.md', 'supersedes', 'tool refl
398
454
  requireText('Harness/memory/agent-lessons-patterns.md', 'supersedes', 'agent lessons template date rule');
399
455
  requireText('Harness/MEMORY.md', 'startup-hints.md', 'MEMORY.md startup-hints registration');
400
456
  requireText('Harness/MEMORY.md', 'Memory routes', 'MEMORY.md routes.md registration');
457
+ requireText('Harness/MEMORY.md', '../.claude/commands/wf-update.md', 'MEMORY.md wf-update direct command registration');
401
458
  requireText('CLAUDE.md', 'If `Harness/` exists, this repository is governed by the Harness contract', 'Harness binding contract');
402
459
  requireText('CLAUDE.md', 'memory and resource router', 'memory/resource router');
403
460
  requireText('CLAUDE.md', '## 5a. Low-Noise Progress', 'low-noise progress section');
461
+ requireText('CLAUDE.md', "Match the user's language for all user-facing prose", 'user-facing language match rule');
404
462
  requireText('CLAUDE.md', 'Keep intermediate user updates to 1-2 short sentences', 'low-noise intermediate update rule');
405
463
  requireText('.claude/rules/ecc/common.md', '## Low-Noise Progress', 'ECC low-noise progress section');
464
+ requireText('.claude/rules/ecc/common.md', "Match the user's language for user-facing prose", 'ECC user-facing language match rule');
406
465
  requireText('.claude/rules/ecc/common.md', 'Do not recap plans, paste logs, or narrate obvious file reads', 'ECC low-noise no-recap rule');
466
+ requireText('.claude/rules/ecc/common.md', 'excluding `/wf-help` and `/wf-update`', 'ECC direct command exemption');
407
467
  requireText('Harness/README.md', 'Load By Task', 'Harness task router');
408
- requireText('CLAUDE.md', 'Harness/SETUP.md` is a bootstrap-only document', 'setup bootstrap-only contract');
468
+ requireText('Harness/README.md', 'Need context/cache/token efficiency', 'cache/token router row');
469
+ requireText('Harness/specs/runtime/context-loading.md', 'Context Tiers', 'context tier load budget section');
470
+ requireText('Harness/specs/runtime/context-loading.md', 'automatic route profiles, not user-selected modes', 'context tiers are automatic route profiles');
471
+ requireText('Harness/specs/runtime/context-loading.md', 'Budgets are regression guards, not exclusion rules', 'context budgets do not block required files');
472
+ requireText('Harness/specs/runtime/context-loading.md', 'Do not skip required rules', 'context budget correctness priority');
473
+ requireText('Harness/specs/runtime/context-loading.md', 'Escalation rule', 'context-loading targeted escalation rule');
474
+ requireText('Harness/specs/runtime/context-loading.md', 'Thin startup', 'thin startup context tier');
475
+ requireText('Harness/specs/runtime/context-loading.md', 'Routed skill/doc', 'routed skill/doc lazy tier');
476
+ requireText('Harness/specs/runtime/context-loading.md', 'Cache-First Context Contract', 'cache-first context contract');
477
+ requireText('Harness/specs/runtime/context-loading.md', 'Cache Validation Levels', 'cache validation levels');
478
+ requireText('Harness/specs/runtime/context-loading.md', 'Do not claim real cache hits', 'real cache telemetry boundary');
479
+ requireText('Harness/specs/runtime/context-loading.md', 'cached_tokens', 'OpenAI cache telemetry field');
480
+ requireText('Harness/specs/runtime/context-loading.md', 'cache_read_input_tokens', 'Anthropic cache telemetry field');
481
+ requireText('Harness/specs/workflows/WF.md', 'Cache Discipline', 'WF cache discipline');
482
+ requireText('Harness/specs/workflows/WF-KERNEL.md', 'Cache-First Context Contract', 'WF-KERNEL cache-first contract');
483
+ requireText('Harness/specs/runtime/dispatch.md', 'Cache-first dispatch', 'dispatch cache-first discipline');
484
+ requireText('Harness/specs/runtime/subagents.md', 'Cache-first discipline', 'subagents cache-first discipline');
485
+ forbidText('CLAUDE.md', 'Harness/specs/guides/SETUP.md', 'CLAUDE.md SETUP reference');
409
486
  forbidText('CLAUDE.md', 'follow it before normal project work', 'installed-project SETUP hot-path routing');
410
- requireText('Harness/SETUP.md', 'Harness/MEMORY_PROTOCOL.md', 'setup memory protocol reference');
487
+ requireText('Harness/specs/guides/SETUP.md', 'Harness/specs/protocols/MEMORY_PROTOCOL.md', 'setup memory protocol reference');
488
+ requireText('Harness/specs/guides/SETUP.md', 'no startup dependency on this setup reference', 'SETUP startup boundary');
489
+ forbidText('Harness/specs/guides/SETUP.md', 'bootstrap contract line', 'stale SETUP-to-CLAUDE bootstrap contract');
490
+ forbidText('Harness/specs/runtime/context-loading.md', 'Always keep:', 'ambiguous always-load context rule');
491
+ requireText('Harness/scripts/context-budget.mjs', 'thin-startup', 'context-budget thin startup route');
492
+ requireText('Harness/scripts/context-budget.mjs', 'cache-diagnostics-route', 'context-budget cache diagnostics route');
493
+ requireText('Harness/scripts/context-budget.mjs', 'not runtime exclusion rules', 'context-budget non-exclusion guard');
494
+ requireText('Harness/scripts/context-budget.mjs', 'approxTokens', 'context-budget approximate token output');
495
+ requireText('Harness/specs/runtime/context-loading.md', 'Harness/scripts/l2-cache-telemetry.mjs', 'L2 telemetry script reference');
496
+ requireText('Harness/README.md', 'scripts/l2-cache-telemetry.mjs', 'Harness README L2 telemetry script route');
497
+ requireText('Harness/scripts/l2-cache-telemetry.mjs', 'cache_read_input_tokens', 'L2 telemetry cache-read field');
498
+ requireText('Harness/scripts/l2-cache-telemetry.mjs', 'cache_creation_input_tokens', 'L2 telemetry cache-creation field');
499
+ requireText('Harness/scripts/l2-cache-telemetry.mjs', 'claimGate', 'L2 telemetry claim gate');
500
+ requireText('Harness/scripts/l2-cache-telemetry.mjs', '--strict-mcp-config', 'L2 telemetry strict MCP isolation');
501
+ requireText('Harness/scripts/l2-cache-telemetry.mjs', '--max-budget-usd', 'L2 telemetry per-turn budget');
502
+ requireText('Harness/scripts/l2-cache-telemetry.mjs', '--resume', 'L2 telemetry session resume');
503
+ forbidText('Harness/scripts/l2-cache-telemetry.mjs', '--bare', 'L2 telemetry bare mode');
411
504
  requireText('Harness/README.md', 'subagent', 'subagent orchestrator entry trigger');
412
505
  requireText('Harness/README.md', 'PROGRESS.md', 'PROGRESS global task index');
413
506
  requireText('CLAUDE.md', 'Harness/tasks/', 'task capsule directory reference');
414
- requireText('Harness/subagents.md', 'Subagents are readers and reporters', 'subagent state committer rule');
507
+ requireText('Harness/specs/runtime/subagents.md', 'Subagents are readers and reporters', 'subagent state committer rule');
415
508
  for (const heading of ['## 2. Think Before Coding', '## 3. Simplicity First', '## 4. Surgical Changes', '## 5. Goal-Driven Execution']) {
416
509
  requireText('CLAUDE.md', heading, `Karpathy-style rule heading: ${heading}`);
417
510
  }
@@ -426,21 +519,21 @@ if (progress) {
426
519
 
427
520
  // Legacy PLAN.md deprecation check (removed — stub only)
428
521
 
429
- const dispatch = read('Harness/dispatch.md');
522
+ const dispatch = read('Harness/specs/runtime/dispatch.md');
430
523
  if (dispatch) {
431
524
  for (const agent of commonAgents) {
432
- if (!dispatch.includes(`\`${agent}\``)) errors.push(`Harness/dispatch.md missing common agent: ${agent}`);
525
+ if (!dispatch.includes(`\`${agent}\``)) errors.push(`Harness/specs/runtime/dispatch.md missing common agent: ${agent}`);
433
526
  }
434
- if (!dispatch.includes('## Handoff Format')) errors.push('Harness/dispatch.md missing heading: ## Handoff Format');
527
+ if (!dispatch.includes('## Handoff Format')) errors.push('Harness/specs/runtime/dispatch.md missing heading: ## Handoff Format');
435
528
  }
436
529
 
437
- const contextLoading = read('Harness/context-loading.md');
530
+ const contextLoading = read('Harness/specs/runtime/context-loading.md');
438
531
  if (contextLoading) {
439
532
  if (!contextLoading.includes('Harness/README.md` is the primary Harness documentation router')) {
440
- errors.push('Harness/context-loading.md must declare Harness/README.md as the primary Harness documentation router');
533
+ errors.push('Harness/specs/runtime/context-loading.md must declare Harness/README.md as the primary Harness documentation router');
441
534
  }
442
535
  for (const pack of contextPacks) {
443
- if (!contextLoading.includes(pack)) errors.push(`Harness/context-loading.md missing subagent pack: ${pack}`);
536
+ if (!contextLoading.includes(pack)) errors.push(`Harness/specs/runtime/context-loading.md missing subagent pack: ${pack}`);
444
537
  }
445
538
  }
446
539
 
@@ -632,70 +725,82 @@ for (const claudeRel of listMarkdownFiles('.claude/commands')) {
632
725
  }
633
726
  }
634
727
 
635
- requireText('Harness/extension.md', 'Skills should extend the harness');
636
- requireText('Harness/agent-workflow.md', 'Harness/tasks/<task-id>/PROGRESS.md');
728
+ requireText('Harness/specs/guides/extension.md', 'Skills should extend the harness');
729
+ requireText('Harness/specs/runtime/agent-workflow.md', 'Harness/tasks/<task-id>/PROGRESS.md');
637
730
  requireText('Harness/README.md', 'Task records are compact by default', 'compact task record router rule');
638
- requireText('Harness/agent-workflow.md', 'AC record size', 'compact AC record size rule');
639
- requireText('Harness/ACCEPTANCE_PROTOCOL.md', 'Default to 1-3 concise ACs', 'compact AC default');
640
- requireText('Harness/WF.md', 'task-scribe', 'compact heartbeat rule');
731
+ requireText('Harness/specs/runtime/agent-workflow.md', 'AC record size', 'compact AC record size rule');
732
+ requireText('Harness/specs/protocols/ACCEPTANCE_PROTOCOL.md', 'Default to 1-3 concise ACs', 'compact AC default');
733
+ requireText('Harness/specs/workflows/WF.md', 'task-scribe', 'compact heartbeat rule');
641
734
  requireText('Harness/tasks/_template/PLAN.md', 'Compact task record', 'compact task PLAN template');
642
735
  requireText('Harness/tasks/_template/PLAN.md', 'Default: keep 1-3 concise ACs', 'compact task PLAN AC guidance');
643
736
  requireText('Harness/tasks/_template/PROGRESS.md', 'Compact heartbeat', 'compact task PROGRESS template');
644
- requireText('Harness/agent-workflow.md', 'TDD-GUIDE.md', 'agent workflow loads TDD guide');
645
- requireText('Harness/agent-workflow.md', 'real user-path test', 'agent workflow real user path requirement');
737
+ requireText('Harness/specs/runtime/agent-workflow.md', 'TDD-GUIDE.md', 'agent workflow loads TDD guide');
738
+ requireText('Harness/specs/runtime/agent-workflow.md', 'real user-path test', 'agent workflow real user path requirement');
646
739
  requireText('Harness/research/README.md', 'research-results.md');
647
- requireText('Harness/WF.md', 'Orchestration Loop', 'WF orchestration loop');
648
- requireText('Harness/WF.md', 'WF-KERNEL.md', 'WF references WF-KERNEL');
649
- requireText('Harness/WF.md', 'Cross-review and reflector NOT mandatory', 'WF-Light no mandatory cross-review');
650
- requireText('Harness/WF.md', '`.claude/agents/`', 'WF agent roster path');
651
- requireText('Harness/WF.md', 'Harness/tasks/', 'WF task directory reference');
740
+ requireText('Harness/specs/workflows/WF.md', 'Orchestration Loop', 'WF orchestration loop');
741
+ requireText('Harness/specs/workflows/WF.md', 'WF-KERNEL.md', 'WF references WF-KERNEL');
742
+ requireText('Harness/specs/workflows/WF.md', 'Cross-review and reflector NOT mandatory', 'WF-Light no mandatory cross-review');
743
+ requireText('Harness/specs/workflows/WF.md', '`.claude/agents/`', 'WF agent roster path');
744
+ requireText('Harness/specs/workflows/WF.md', 'Harness/tasks/', 'WF task directory reference');
745
+ const taskIdConvention = '`task-<verb>-<noun>[-detail]`';
746
+ requireText('Harness/specs/workflows/WF.md', taskIdConvention, 'WF task-id naming convention');
747
+ requireText('Harness/specs/workflows/WF-STATE.md', taskIdConvention, 'WF-STATE task-id naming convention');
748
+ requireText('Harness/specs/workflows/WF-MAX.md', taskIdConvention, 'WF-MAX task-id naming convention');
652
749
  requireText('Harness/README.md', 'explicit WF token', 'WF explicit contract');
653
750
  requireText('Harness/README.md', 'tier-gated acceptance', 'WF tiered acceptance router output');
654
- requireText('.claude/skills/wf/SKILL.md', 'Harness/WF.md', 'wf skill loads core WF doc');
751
+ requireText('.claude/skills/wf/SKILL.md', 'Harness/specs/workflows/WF.md', 'wf skill loads core WF doc');
655
752
  requireText('.claude/skills/wf/SKILL.md', 'Tier-aware acceptance', 'wf skill tier-aware acceptance');
656
- requireText('.agents/skills/wf/SKILL.md', 'Harness/WF.md', 'Codex wf skill loads core WF doc');
657
- requireText('.claude/skills/subagent-orchestrator/SKILL.md', 'Harness/subagents.md', 'subagent-orchestrator loads subagents doc');
753
+ requireText('.claude/skills/wf/SKILL.md', taskIdConvention, 'wf skill task-id naming convention');
754
+ requireText('.agents/skills/wf/SKILL.md', 'Harness/specs/workflows/WF.md', 'Codex wf skill loads core WF doc');
755
+ requireText('.agents/skills/wf/SKILL.md', taskIdConvention, 'Codex wf skill task-id naming convention');
756
+ requireText('.claude/skills/subagent-orchestrator/SKILL.md', 'Harness/specs/runtime/subagents.md', 'subagent-orchestrator loads subagents doc');
658
757
  requireText('.claude/skills/subagent-orchestrator/SKILL.md', '.claude/agents/', 'subagent-orchestrator built-in agent roster path');
659
758
  requireText('.claude/skills/subagent-orchestrator/SKILL.md', 'WF/WF-MAX requires tier-specific', 'subagent-orchestrator WF tier-specific contract');
660
759
  requireText('.claude/skills/wf-readme/SKILL.md', 'README.md', 'wf-readme loads README');
661
- requireText('.claude/skills/wf-readme/SKILL.md', 'Harness/architecture.md', 'wf-readme links architecture docs');
662
- requireText('Harness/subagents.md', '## Source Attribution', 'subagent source attribution');
663
- requireText('Harness/subagents.md', 'npx skills find', 'find-skills discovery attribution');
664
- requireText('Harness/subagents.md', 'superpowers:dispatching-parallel-agents', 'parallel-agent source attribution');
665
- requireText('Harness/subagents.md', 'superpowers:subagent-driven-development', 'subagent-driven source attribution');
666
- requireText('Harness/subagents.md', '## Built-in Agent Roster', 'built-in agent roster');
667
- requireText('Harness/subagents.md', '## WF Default Fan-Out', 'WF default fan-out');
668
- requireText('Harness/subagents.md', 'concrete conditions', 'subagent decision tree');
669
- requireText('Harness/subagents.md', 'parallel planner/researcher/docs-researcher/architect subagents', 'WF roster orchestration shape');
670
- requireText('Harness/subagents.md', '`reflector`', 'reflector agent roster');
671
- requireText('Harness/subagents.md', 'reflector PASS', 'reflector review gate');
672
- requireText('Harness/subagents.md', '## Efficiency Ladder', 'subagent efficiency ladder');
673
- requireText('Harness/subagents.md', '## Review Gates', 'subagent review gates');
674
- requireText('Harness/architecture.md', '## 2. Interface Decoupling', 'architecture interface decoupling');
675
- requireText('Harness/architecture.md', '## 3. State Design', 'architecture state design');
676
- requireText('Harness/architecture.md', 'Avoid speculative abstraction', 'anti-overengineering architecture rule');
760
+ requireText('.claude/skills/wf-readme/SKILL.md', 'Harness/project/architecture.md', 'wf-readme links architecture docs');
761
+ requireText('Harness/specs/runtime/subagents.md', '## Source Attribution', 'subagent source attribution');
762
+ requireText('Harness/specs/runtime/subagents.md', 'npx skills find', 'find-skills discovery attribution');
763
+ requireText('Harness/specs/runtime/subagents.md', 'superpowers:dispatching-parallel-agents', 'parallel-agent source attribution');
764
+ requireText('Harness/specs/runtime/subagents.md', 'superpowers:subagent-driven-development', 'subagent-driven source attribution');
765
+ requireText('Harness/specs/runtime/subagents.md', '## Built-in Agent Roster', 'built-in agent roster');
766
+ requireText('Harness/specs/runtime/subagents.md', '## WF Default Fan-Out', 'WF default fan-out');
767
+ requireText('Harness/specs/runtime/subagents.md', 'concrete conditions', 'subagent decision tree');
768
+ requireText('Harness/specs/runtime/subagents.md', 'parallel planner/researcher/docs-researcher/architect subagents', 'WF roster orchestration shape');
769
+ requireText('Harness/specs/runtime/subagents.md', '`reflector`', 'reflector agent roster');
770
+ requireText('Harness/specs/runtime/subagents.md', 'reflector PASS', 'reflector review gate');
771
+ requireText('Harness/specs/runtime/subagents.md', '## Efficiency Ladder', 'subagent efficiency ladder');
772
+ requireText('Harness/specs/runtime/subagents.md', '## Review Gates', 'subagent review gates');
773
+ requireText('Harness/project/architecture.md', '## 2. Interface Decoupling', 'architecture interface decoupling');
774
+ requireText('Harness/project/architecture.md', '## 3. State Design', 'architecture state design');
775
+ requireText('Harness/project/architecture.md', 'Avoid speculative abstraction', 'anti-overengineering architecture rule');
677
776
  requireText('CLAUDE.md', 'Use explicit interfaces or state models only when they protect a real boundary', 'CLAUDE interface/state simplicity rule');
678
777
  requireText('Harness/README.md', '/wf-update', 'wf update startup instruction');
679
778
  requireText('Harness/README.md', 'Need harness update', 'update routing row');
680
- requireText('Harness/WF-MAX.md', 'three-layer architecture', 'WF-MAX three-layer architecture');
681
- requireText('Harness/WF-MAX.md', 'dispatch permissions', 'WF-MAX role separation');
682
- requireText('Harness/WF-MAX.md', 'file_claim', 'WF-MAX coloring algorithm');
683
- requireText('Harness/WF-MAX.md', 'CEO → Manager → Worker', 'WF-MAX wave dispatch');
684
- requireText('Harness/WF-MAX.md', 'inherits the full', 'WF-MAX strict superset');
685
- requireText('Harness/WF-MAX.md', 'Cross-CLI', 'WF-MAX cross-CLI overflow');
686
- requireText('Harness/WF-MAX.md', 'claude -p', 'WF-MAX Claude CLI overflow');
687
- requireText('Harness/WF-MAX.md', 'codex exec', 'WF-MAX Codex CLI overflow');
688
- requireText('Harness/WF-MAX.md', 'agents.max_threads', 'WF-MAX Codex max_threads config');
689
- requireText('Harness/WF-MAX.md', 'agents.max_depth', 'WF-MAX Codex max_depth config');
690
- requireText('Harness/WF-MAX.md', 'max_threads = 12', 'WF-MAX Codex scaffold max_threads default');
691
- requireText('Harness/WF-MAX.md', 'max_depth = 1', 'WF-MAX Codex scaffold max_depth default');
692
- requireText('Harness/WF-MAX.md', 'Ask the user before raising', 'WF-MAX asks before raising Codex thread cap');
693
- requireText('Harness/WF-MAX.md', 'Close completed agents', 'WF-MAX close completed agents before overflow');
694
- requireText('Harness/WF-MAX.md', 'Codex++', 'WF-MAX forbids relying on Codex++ as stable capacity');
779
+ requireText('Harness/specs/workflows/WF-MAX.md', 'three-layer architecture', 'WF-MAX three-layer architecture');
780
+ requireText('Harness/specs/workflows/WF-MAX.md', 'dispatch permissions', 'WF-MAX role separation');
781
+ requireText('Harness/specs/workflows/WF-MAX.md', 'file_claim', 'WF-MAX coloring algorithm');
782
+ requireText('Harness/specs/workflows/WF-MAX.md', 'CEO → Manager → Worker', 'WF-MAX wave dispatch');
783
+ requireText('Harness/specs/workflows/WF-MAX.md', 'inherits the full', 'WF-MAX strict superset');
784
+ requireText('Harness/specs/workflows/WF-MAX.md', 'Cross-CLI', 'WF-MAX cross-CLI overflow');
785
+ requireText('Harness/specs/workflows/WF-MAX.md', 'claude -p', 'WF-MAX Claude CLI overflow');
786
+ requireText('Harness/specs/workflows/WF-MAX.md', 'codex exec', 'WF-MAX Codex CLI overflow');
787
+ requireText('Harness/specs/workflows/WF-MAX.md', 'agents.max_threads', 'WF-MAX Codex max_threads config');
788
+ requireText('Harness/specs/workflows/WF-MAX.md', 'agents.max_depth', 'WF-MAX Codex max_depth config');
789
+ requireText('Harness/specs/workflows/WF-MAX.md', 'max_threads = 12', 'WF-MAX Codex scaffold max_threads default');
790
+ requireText('Harness/specs/workflows/WF-MAX.md', 'max_depth = 1', 'WF-MAX Codex scaffold max_depth default');
791
+ requireText('Harness/specs/workflows/WF-MAX.md', 'Ask the user before raising', 'WF-MAX asks before raising Codex thread cap');
792
+ requireText('Harness/specs/workflows/WF-MAX.md', 'Close completed agents', 'WF-MAX close completed agents before overflow');
793
+ requireText('Harness/specs/workflows/WF-MAX.md', 'Codex++', 'WF-MAX forbids relying on Codex++ as stable capacity');
794
+ requireText('Harness/specs/workflows/WF-MAX.md', 'does not authorize CEO source edits', 'WF-MAX useful-degrade CEO source-edit boundary');
795
+ requireText('Harness/specs/workflows/WF-MAX.md', '## Cross-Task Decisions', 'WF-MAX PROGRESS heading preservation');
695
796
  requireText('.claude/skills/wf-max/SKILL.md', 'agents.max_threads', 'wf-max skill Codex thread config');
696
797
  requireText('.claude/skills/wf-max/SKILL.md', 'max_threads = 12', 'wf-max skill Codex scaffold max_threads default');
697
798
  requireText('.claude/skills/wf-max/SKILL.md', 'ask the user before raising', 'wf-max skill asks before raising Codex thread cap');
698
799
  requireText('.claude/skills/wf-max/SKILL.md', 'Codex++', 'wf-max skill forbids Codex++ capacity assumption');
800
+ requireText('.claude/skills/wf-max/SKILL.md', taskIdConvention, 'wf-max skill task-id naming convention');
801
+ requireText('.agents/skills/wf-max/SKILL.md', taskIdConvention, 'Codex wf-max skill task-id naming convention');
802
+ requireText('.claude/skills/wf-max/SKILL.md', 'does not authorize CEO source edits', 'wf-max skill useful-degrade CEO source-edit boundary');
803
+ requireText('.claude/skills/wf-max/SKILL.md', '## Cross-Task Decisions', 'wf-max skill PROGRESS heading preservation');
699
804
  requireText('.codex/config.toml', '[agents]', 'Codex agents config table');
700
805
  requireText('.codex/config.toml', 'max_threads = 12', 'Codex scaffold max_threads default');
701
806
  requireText('.codex/config.toml', 'max_depth = 1', 'Codex scaffold max_depth default');
@@ -705,66 +810,83 @@ requireText('Harness/README.md', '/wf-max', 'wf max router alias');
705
810
  requireText('Harness/README.md', 'WF-MAX.md', 'WF-MAX router reference');
706
811
  requireText('Harness/README.md', 'ACCEPTANCE_PROTOCOL.md', 'acceptance protocol router reference');
707
812
  requireText('Harness/README.md', 'TDD-GUIDE.md', 'TDD guide router reference');
708
- requireText('Harness/ACCEPTANCE_PROTOCOL.md', 'PRD-GATE', 'acceptance PRD gate');
709
- requireText('Harness/ACCEPTANCE_PROTOCOL.md', 'AC-GATE', 'acceptance AC gate');
710
- requireText('Harness/ACCEPTANCE_PROTOCOL.md', 'Acceptance Result', 'acceptance result matrix');
711
- requireText('Harness/ACCEPTANCE_PROTOCOL.md', 'Syntax-only checks', 'syntax-only checks are not browser acceptance evidence');
712
- requireText('Harness/AGENT_ISOLATION.md', 'implementer', 'agent isolation implementer rule');
713
- requireText('Harness/HARNESS_BRIDGE.md', 'Network Trace Collector', 'harness bridge network trace collector');
714
- requireText('Harness/WF-AUTO.md', 'Intent Checkpoint', 'wf-auto intent checkpoint');
715
- requireText('Harness/WF-AUTO.md', 'Adaptive Coverage Exhaustion Gate', 'wf-auto adaptive coverage exhaustion gate');
716
- requireText('Harness/WF-AUTO.md', 'dynamic high-risk obligations', 'wf-auto dynamic high-risk obligations');
717
- requireText('Harness/WF-AUTO.md', 'two different confirmation strategies', 'wf-auto two different confirmation strategies');
718
- requireText('Harness/WF-AUTO-ANGLES.md', 'Selection algorithm', 'wf-auto adaptive angle selection');
719
- requireText('Harness/WF-AUTO-ANGLES.md', 'Dynamic obligations', 'wf-auto dynamic obligations');
720
- requireText('Harness/WF-AUTO-ANGLES.md', 'Common probe recipes', 'wf-auto common probe recipes');
721
- forbidText('Harness/WF-AUTO.md', 'All 8 exhausted', 'stale eight-angle exhaustion rule');
722
- forbidText('Harness/WF-AUTO.md', '3 consecutive all-exhausted rounds', 'stale three-consecutive-all-exhausted stop rule');
723
- forbidText('Harness/WF-AUTO.md', '8-Angle Exhaustion Gate', 'stale eight-angle exhaustion gate name');
724
- forbidText('Harness/WF-AUTO-SPARK.md', '8 parallel external searches', 'stale eight-spark fixed-count search');
725
- requireText('Harness/WF-AUTO.md', 'Inherited WF/WF-MAX Constraints', 'wf-auto inherited WF/WF-MAX constraints');
726
- requireText('Harness/WF-AUTO.md', 'Mini PRD -> AC IDs -> test/validation plan -> implementer -> verifier', 'wf-auto per-cycle WF chain');
727
- requireText('Harness/WF-AUTO.md', 'reflector PASS', 'wf-auto reflector gate');
728
- requireText('Harness/WF-AUTO-SPARK.md', 'Inherited Execution Chain', 'wf-auto-spark inherited execution chain');
729
- requireText('Harness/WF-AUTO-SPARK.md', 'External spark search replaces discovery only', 'wf-auto-spark discovery-only inheritance');
730
- requireText('Harness/WF-AUTO-SPARK.md', 'reflector PASS', 'wf-auto-spark reflector gate');
731
- requireText('Harness/WF-AUTO-SPARK.md', 'task-scribe formats task-state writes', 'wf-auto-spark task-scribe recorder delegation');
732
- requireText('Harness/WF-AUTO-SPARK.md', 'searchFallback: ceo-direct', 'wf-auto-spark search fallback');
733
- requireText('Harness/WF-AUTO-SPARK.md', 'pre-implementation triage', 'wf-auto-spark reflector escalation');
734
- requireText('Harness/WF-AUTO-SPARK.md', 'Literal anti-pattern matching', 'wf-auto-spark anti-pattern invariant guard');
735
- requireText('Harness/WF-AUTO-SPARK.md', 'node scripts/build-version.mjs --check', 'wf-auto-spark checksum drift guard');
736
- requireText('Harness/WF-MAX.md', 'process-file delegation is the default', 'WF-MAX task-scribe process-file delegation default');
737
- requireText('Harness/MEMORY_PROTOCOL.md', 'Scenario Memory Hints', 'memory protocol scenario hints');
738
- requireText('Harness/MEMORY_PROTOCOL.md', 'WF closeout', 'memory protocol WF closeout injection row');
739
- requireText('Harness/MEMORY_PROTOCOL.md', 'memory-master owns writes', 'memory protocol memory write ownership');
740
- requireText('Harness/TDD-GUIDE.md', 'Browser/UI Acceptance TDD Gate', 'browser UI acceptance TDD gate');
741
- requireText('Harness/TDD-GUIDE.md', 'syntax-only', 'syntax-only acceptance prohibition');
742
- requireText('Harness/TDD-GUIDE.md', 'Playwright/CDP', 'Playwright/CDP acceptance requirement');
743
- requireText('Harness/TDD-GUIDE.md', 'AC-by-AC result matrix', 'AC-by-AC TDD evidence matrix');
813
+ requireText('Harness/specs/protocols/ACCEPTANCE_PROTOCOL.md', 'PRD-GATE', 'acceptance PRD gate');
814
+ requireText('Harness/specs/protocols/ACCEPTANCE_PROTOCOL.md', 'AC-GATE', 'acceptance AC gate');
815
+ requireText('Harness/specs/protocols/ACCEPTANCE_PROTOCOL.md', 'Acceptance Result', 'acceptance result matrix');
816
+ requireText('Harness/specs/protocols/ACCEPTANCE_PROTOCOL.md', 'Syntax-only checks', 'syntax-only checks are not browser acceptance evidence');
817
+ requireText('Harness/specs/protocols/AGENT_ISOLATION.md', 'implementer', 'agent isolation implementer rule');
818
+ requireText('Harness/specs/protocols/HARNESS_BRIDGE.md', 'Network Trace Collector', 'harness bridge network trace collector');
819
+ requireText('Harness/specs/workflows/WF-AUTO.md', 'Intent Checkpoint', 'wf-auto intent checkpoint');
820
+ requireText('Harness/specs/workflows/WF-AUTO.md', 'Adaptive Coverage Exhaustion Gate', 'wf-auto adaptive coverage exhaustion gate');
821
+ requireText('Harness/specs/workflows/WF-AUTO.md', 'dynamic high-risk obligations', 'wf-auto dynamic high-risk obligations');
822
+ requireText('Harness/specs/workflows/WF-AUTO.md', 'two different confirmation strategies', 'wf-auto two different confirmation strategies');
823
+ requireText('Harness/specs/workflows/WF-AUTO-ANGLES.md', 'Selection algorithm', 'wf-auto adaptive angle selection');
824
+ requireText('Harness/specs/workflows/WF-AUTO-ANGLES.md', 'Dynamic obligations', 'wf-auto dynamic obligations');
825
+ requireText('Harness/specs/workflows/WF-AUTO-ANGLES.md', 'Common probe recipes', 'wf-auto common probe recipes');
826
+ forbidText('Harness/specs/workflows/WF-AUTO.md', 'All 8 exhausted', 'stale eight-angle exhaustion rule');
827
+ forbidText('Harness/specs/workflows/WF-AUTO.md', '3 consecutive all-exhausted rounds', 'stale three-consecutive-all-exhausted stop rule');
828
+ forbidText('Harness/specs/workflows/WF-AUTO.md', '8-Angle Exhaustion Gate', 'stale eight-angle exhaustion gate name');
829
+ forbidText('Harness/specs/workflows/WF-AUTO-SPARK.md', '8 parallel external searches', 'stale eight-spark fixed-count search');
830
+ requireText('Harness/specs/workflows/WF-AUTO.md', 'Inherited WF/WF-MAX Constraints', 'wf-auto inherited WF/WF-MAX constraints');
831
+ requireText('Harness/specs/workflows/WF-AUTO.md', 'Mini PRD -> AC IDs -> test/validation plan -> implementer -> verifier', 'wf-auto per-cycle WF chain');
832
+ requireText('Harness/specs/workflows/WF-AUTO.md', 'reflector PASS', 'wf-auto reflector gate');
833
+ requireText('Harness/specs/workflows/WF-AUTO.md', 'Manual or benchmark-driven single-cycle', 'wf-auto bounded single-cycle tick contract');
834
+ requireText('Harness/specs/workflows/WF-AUTO.md', 'Harness/tasks/auto/PLAN.md', 'wf-auto bounded tick PLAN record');
835
+ requireText('Harness/specs/workflows/WF-AUTO.md', 'Harness/tasks/auto/PROGRESS.md', 'wf-auto bounded tick PROGRESS record');
836
+ requireText('Harness/specs/workflows/WF-AUTO-SPARK.md', 'Inherited Execution Chain', 'wf-auto-spark inherited execution chain');
837
+ requireText('Harness/specs/workflows/WF-AUTO-SPARK.md', 'External spark search replaces discovery only', 'wf-auto-spark discovery-only inheritance');
838
+ requireText('Harness/specs/workflows/WF-AUTO-SPARK.md', 'reflector PASS', 'wf-auto-spark reflector gate');
839
+ requireText('Harness/specs/workflows/WF-AUTO-SPARK.md', 'task-scribe formats task-state writes', 'wf-auto-spark task-scribe recorder delegation');
840
+ requireText('Harness/specs/workflows/WF-AUTO-SPARK.md', 'searchFallback: ceo-direct', 'wf-auto-spark search fallback');
841
+ requireText('Harness/specs/workflows/WF-AUTO-SPARK.md', 'pre-implementation triage', 'wf-auto-spark reflector escalation');
842
+ requireText('Harness/specs/workflows/WF-AUTO-SPARK.md', 'Literal anti-pattern matching', 'wf-auto-spark anti-pattern invariant guard');
843
+ requireText('Harness/specs/workflows/WF-AUTO-SPARK.md', 'node scripts/build-version.mjs --check', 'wf-auto-spark checksum drift guard');
844
+ requireText('Harness/specs/workflows/WF-MAX.md', 'process-file delegation is the default', 'WF-MAX task-scribe process-file delegation default');
845
+ requireText('Harness/specs/protocols/MEMORY_PROTOCOL.md', 'Scenario Memory Hints', 'memory protocol scenario hints');
846
+ requireText('Harness/specs/protocols/MEMORY_PROTOCOL.md', 'WF closeout', 'memory protocol WF closeout injection row');
847
+ requireText('Harness/specs/protocols/MEMORY_PROTOCOL.md', 'memory-master owns writes', 'memory protocol memory write ownership');
848
+ requireText('Harness/specs/protocols/TDD-GUIDE.md', 'Browser/UI Acceptance TDD Gate', 'browser UI acceptance TDD gate');
849
+ requireText('Harness/specs/protocols/TDD-GUIDE.md', 'syntax-only', 'syntax-only acceptance prohibition');
850
+ requireText('Harness/specs/protocols/TDD-GUIDE.md', 'Playwright/CDP', 'Playwright/CDP acceptance requirement');
851
+ requireText('Harness/specs/protocols/TDD-GUIDE.md', 'AC-by-AC result matrix', 'AC-by-AC TDD evidence matrix');
744
852
  requireText('Harness/tasks/_template/PLAN.md', 'Expanded evidence required when triggered', 'task template expanded evidence trigger');
745
853
  requireText('Harness/templates/TEST_PLAN.template.md', 'syntax-only checks', 'test plan template syntax-only prohibition');
746
- requireText('.claude/skills/tdd/SKILL.md', 'Harness/ACCEPTANCE_PROTOCOL.md', 'tdd skill loads acceptance protocol');
747
- requireText('.claude/skills/tdd/SKILL.md', 'Harness/HARNESS_BRIDGE.md', 'tdd skill loads harness bridge');
854
+ requireText('.claude/skills/tdd/SKILL.md', 'Harness/specs/protocols/ACCEPTANCE_PROTOCOL.md', 'tdd skill loads acceptance protocol');
855
+ requireText('.claude/skills/tdd/SKILL.md', 'Harness/specs/protocols/HARNESS_BRIDGE.md', 'tdd skill loads harness bridge');
748
856
  requireText('.claude/skills/tdd/SKILL.md', 'No syntax-only acceptance', 'tdd skill forbids syntax-only acceptance');
749
857
  requireText('.claude/skills/wf-remove/SKILL.md', 'User-facing removal is the slash/skill command', 'wf-remove slash command is user-facing');
750
858
  requireText('.claude/skills/wf-remove/SKILL.md', 'agent-internal execution steps', 'wf-remove script commands are agent-internal');
751
859
  requireText('.claude/skills/wf-remove/SKILL.md', 'verify residual discovery folders', 'wf-remove residual discovery verification');
860
+ forbidText('Harness/scripts/wf-remove.mjs', '\uFFFD', 'replacement character in wf-remove output');
861
+ for (const marker of ['codebase-explorer', 'task-scribe', 'wf-agents-docs', 'wf-auto-spark']) {
862
+ requireText('Harness/scripts/wf-remove.mjs', marker, `wf-remove built-in registry includes ${marker}`);
863
+ }
752
864
  requireText('.claude/skills/wf-review/SKILL.md', 'opencode run --agent reviewer', 'wf-review OpenCode peer CLI path');
753
865
  requireText('.claude/skills/wf-review/SKILL.md', 'Role: reviewer', 'wf-review installed reviewer role fallback');
754
866
  requireText('.claude/skills/wf-review/SKILL.md', 'The main agent is the controller', 'wf-review controller final authority');
867
+ requireText('.claude/skills/wf-agents-docs/SKILL.md', 'claude -p --output-format json', 'wf-agents-docs Claude JSON CLI path');
868
+ requireText('.claude/skills/wf-agents-docs/SKILL.md', 'codex exec --json', 'wf-agents-docs Codex JSONL CLI path');
869
+ requireText('.claude/skills/wf-agents-docs/SKILL.md', 'opencode run --format json', 'wf-agents-docs OpenCode JSON CLI path');
870
+ requireText('.claude/skills/wf-agents-docs/SKILL.md', 'cache_read_input_tokens', 'wf-agents-docs Claude cache telemetry field');
871
+ requireText('.claude/skills/wf-agents-docs/SKILL.md', 'Do not trust exit code alone', 'wf-agents-docs PowerShell wrapper guard');
872
+ requireText('.claude/skills/wf-agents-docs/SKILL.md', 'Evidence-Packet Review Pattern', 'wf-agents-docs evidence-packet review method');
873
+ requireText('.claude/skills/wf-agents-docs/SKILL.md', 'No Scratch-File Rule', 'wf-agents-docs scratch-file guard');
874
+ requireText('.claude/skills/wf-agents-docs/SKILL.md', 'Subagent Output Contract', 'wf-agents-docs subagent output contract');
875
+ requireText('.claude/skills/wf-agents-docs/SKILL.md', 'Do not write CLI probe output under `%TEMP%`', 'wf-agents-docs temp pollution guard');
876
+ requireText('Harness/README.md', 'Need peer CLI automation docs', 'Harness router peer CLI automation docs row');
755
877
  requireText('.opencode/commands/wf-review.md', 'peer-review contract', 'OpenCode wf-review wrapper peer-review contract');
756
- requireText('Harness/subagents.md', 'For `/wf-review`, use the installed `reviewer` role', 'subagents wf-review role fallback');
878
+ requireText('Harness/specs/runtime/subagents.md', 'For `/wf-review`, use the installed `reviewer` role', 'subagents wf-review role fallback');
757
879
  requireText('.claude/agents/tdd-guide.md', 'Browser Acceptance Rules', 'tdd-guide browser acceptance rules');
758
880
  requireText('.claude/agents/tdd-guide.md', 'real user actions', 'tdd-guide real user action requirement');
759
- requireText('.claude/agents/test-writer.md', 'Harness/ACCEPTANCE_PROTOCOL.md', 'test-writer loads acceptance protocol');
881
+ requireText('.claude/agents/test-writer.md', 'Harness/specs/protocols/ACCEPTANCE_PROTOCOL.md', 'test-writer loads acceptance protocol');
760
882
  requireText('.claude/agents/test-writer.md', 'real user-path test', 'test-writer real user path requirement');
761
883
  requireText('.claude/agents/test-writer.md', 'network URL, method, payload', 'test-writer network assertion requirement');
762
884
  requireText('.claude/agents/reflector.md', 'PASS, RETURN_TO_DEBUG, or BLOCKED', 'reflector verdict contract');
763
- requireText('Harness/DEBUG_PROTOCOL.md', 'Layer Classification', 'debug layer classification');
764
- requireText('Harness/MEMORY_PROTOCOL.md', 'AC ID', 'memory AC traceability');
765
- requireText('Harness/subagents.md', 'Max parallelism', 'subagents max parallelism row');
766
- requireText('Harness/dispatch.md', 'Concurrency group', 'dispatch concurrency group field');
767
- requireText('Harness/dispatch.md', 'File claim', 'dispatch file claim field');
885
+ requireText('Harness/specs/protocols/DEBUG_PROTOCOL.md', 'Layer Classification', 'debug layer classification');
886
+ requireText('Harness/specs/protocols/MEMORY_PROTOCOL.md', 'AC ID', 'memory AC traceability');
887
+ requireText('Harness/specs/runtime/subagents.md', 'Max parallelism', 'subagents max parallelism row');
888
+ requireText('Harness/specs/runtime/dispatch.md', 'Concurrency group', 'dispatch concurrency group field');
889
+ requireText('Harness/specs/runtime/dispatch.md', 'File claim', 'dispatch file claim field');
768
890
  requireText('CLAUDE.md', '/wf-max', 'wf max startup instruction');
769
891
  requireText('.claude/commands/wf-help.md', 'Do not invoke a skill', 'wf-help direct command boundary');
770
892
  requireText('.claude/commands/wf-help.md', '| `/wf-help` |', 'wf-help command row');
@@ -773,24 +895,24 @@ requireText('.claude/commands/wf-help.md', '| `/wf-auto` |', 'wf-help wf-auto ro
773
895
  requireText('.claude/commands/wf-help.md', '| `/wf-readme <task>` |', 'wf-help wf-readme row');
774
896
  requireText('Harness/README.md', '## Direct Commands', 'direct commands section');
775
897
  requireText('Harness/README.md', '.claude/commands/wf-help.md', 'wf-help router reference');
776
- requireText('Harness/WF-MAX.md', 'three-layer architecture', 'CLAUDE.md three-layer role architecture');
898
+ requireText('Harness/specs/workflows/WF-MAX.md', 'three-layer architecture', 'CLAUDE.md three-layer role architecture');
777
899
  requireText('Harness/README.md', 'no runtime hook state', 'CLAUDE no-hook role enforcement statement');
778
900
  requireText('Harness/README.md', 'no runtime hook state', 'README no-hook runtime statement');
779
- requireText('Harness/WF-AUTO.md', 'WF-AUTO Hook Exception', 'wf-auto-only hook exception');
780
- requireText('Harness/WF-AUTO.md', 'only `/wf-auto` may use a runtime hook', 'wf-auto-only hook boundary');
901
+ requireText('Harness/specs/workflows/WF-AUTO.md', 'WF-AUTO Hook Exception', 'wf-auto-only hook exception');
902
+ requireText('Harness/specs/workflows/WF-AUTO.md', 'only `/wf-auto` may use a runtime hook', 'wf-auto-only hook boundary');
781
903
  forbidText('CLAUDE.md', 'Enforced by hooks', 'WF-MAX hook enforcement claim');
782
- forbidText('Harness/WF.md', 'MUST use at least 3 distinct role passes', 'old WF role-pass minimum');
783
- forbidText('Harness/WF.md', 'at least three distinct role passes', 'old WF role-pass wording');
784
- forbidText('Harness/dispatch.md', 'requires ≥3 distinct subagents', 'old dispatch WF role minimum');
904
+ forbidText('Harness/specs/workflows/WF.md', 'MUST use at least 3 distinct role passes', 'old WF role-pass minimum');
905
+ forbidText('Harness/specs/workflows/WF.md', 'at least three distinct role passes', 'old WF role-pass wording');
906
+ forbidText('Harness/specs/runtime/dispatch.md', 'requires ≥3 distinct subagents', 'old dispatch WF role minimum');
785
907
  forbidText('CLAUDE.md', 'WF-MAX hooks', 'WF-MAX hook enforcement claim');
786
908
  forbidText('Harness/README.md', 'PreToolUse hook', 'WF-MAX PreToolUse hook claim');
787
909
  forbidText('Harness/README.md', 'SessionStart hook', 'WF-MAX SessionStart hook claim');
788
910
  forbidText('Harness/README.md', 'hook-managed', 'hook-managed runtime claim');
789
911
  forbidText('Harness/README.md', 'HOOK_PROTOCOL.md', 'removed hook protocol reference');
790
- forbidText('Harness/WF-AUTO.md', 'Hook-Assisted Long Loop', 'wf-auto hook loop section');
791
- forbidText('Harness/dispatch.md', 'removes the cap entirely', 'unbounded runtime-cap claim');
792
- forbidText('Harness/WF-MAX.md', 'no hard agent cap; recursion governed', 'unbounded agent-cap claim');
793
- forbidText('Harness/MEMORY_PROTOCOL.md', 'Hooks may', 'hook-triggered memory claim');
912
+ forbidText('Harness/specs/workflows/WF-AUTO.md', 'Hook-Assisted Long Loop', 'wf-auto hook loop section');
913
+ forbidText('Harness/specs/runtime/dispatch.md', 'removes the cap entirely', 'unbounded runtime-cap claim');
914
+ forbidText('Harness/specs/workflows/WF-MAX.md', 'no hard agent cap; recursion governed', 'unbounded agent-cap claim');
915
+ forbidText('Harness/specs/protocols/MEMORY_PROTOCOL.md', 'Hooks may', 'hook-triggered memory claim');
794
916
  forbidText('.claude/settings.json', 'wf-mode-hook.mjs', 'Claude WF hook command registration');
795
917
  forbidText('.codex/hooks.json', 'wf-mode-hook.mjs', 'Codex WF hook command registration');
796
918
  const codexHookConfig = read('.codex/hooks.json');
@@ -821,24 +943,53 @@ requireText('AGENTS.md', 'compatibility entry', 'AGENTS.md Codex shim purpose');
821
943
  requireText('AGENTS.md', 'single source', 'AGENTS.md CLAUDE.md as single source');
822
944
 
823
945
  // Implicit WF trigger phrases forbidden in active runtime docs and SETUP
824
- for (const rel of ['Harness/README.md', 'Harness/WF.md', 'Harness/context-loading.md', 'Harness/subagents.md', 'Harness/SETUP.md']) {
946
+ for (const rel of ['Harness/README.md', 'Harness/specs/workflows/WF.md', 'Harness/specs/runtime/context-loading.md', 'Harness/specs/runtime/subagents.md', 'Harness/specs/guides/SETUP.md']) {
825
947
  forbidText(rel, 'workflow mode', 'implicit WF trigger: workflow mode');
826
948
  forbidText(rel, 'wk mode', 'implicit WF trigger: wk mode');
827
949
  }
828
950
  // SETUP must not require old WF complete-role-chain contract
829
- requireText('Harness/SETUP.md', 'explicit WF entry only', 'SETUP explicit WF entry contract');
830
- requireText('Harness/SETUP.md', 'WF-Light', 'SETUP WF-Light tier reference');
831
- requireText('Harness/SETUP.md', 'WF-Max-Useful', 'SETUP WF-Max-Useful tier reference');
951
+ requireText('Harness/specs/guides/SETUP.md', 'explicit WF entry only', 'SETUP explicit WF entry contract');
952
+ requireText('Harness/specs/guides/SETUP.md', 'WF-Light', 'SETUP WF-Light tier reference');
953
+ requireText('Harness/specs/guides/SETUP.md', 'WF-Max-Useful', 'SETUP WF-Max-Useful tier reference');
832
954
 
833
955
  // Memory Preflight markers required in workflow skill adapters
834
- for (const skill of ['wf', 'wf-max', 'subagent-orchestrator']) {
956
+ for (const skill of ['wf', 'wf-max', 'wf-auto', 'subagent-orchestrator']) {
835
957
  requireText(`.claude/skills/${skill}/SKILL.md`, 'Memory Preflight', `${skill} skill Memory Preflight section`);
836
958
  }
959
+ for (const skill of cacheDisciplinedSkills) {
960
+ requireText(`.claude/skills/${skill}/SKILL.md`, 'Cache Discipline', `${skill} skill cache discipline`);
961
+ }
962
+ requireText('.claude/skills/wf-auto/SKILL.md', 'bounded test tick', 'wf-auto skill bounded tick auto capsule rule');
963
+ requireText('.claude/skills/wf-auto/SKILL.md', 'missing auto capsule evidence', 'wf-auto skill missing auto capsule failure rule');
964
+ requireText('.claude/skills/wf-auto/SKILL.md', 'Harness/tasks/auto/PLAN.md', 'wf-auto skill PLAN record');
965
+ requireText('.claude/skills/wf-auto/SKILL.md', 'Harness/tasks/auto/PROGRESS.md', 'wf-auto skill PROGRESS record');
966
+ requireText('.claude/skills/wf-auto/SKILL.md', 'evidence ledger path/summary', 'wf-auto skill return evidence ledger path');
967
+ if (fs.existsSync(path.join(root, '.claude/skills/wf-browser/SKILL.md'))) {
968
+ requireText('.claude/skills/wf-browser/SKILL.md', 'Cache Discipline', 'wf-browser skill cache discipline');
969
+ }
837
970
 
838
971
  // Direct command checks
839
972
  requireText('Harness/README.md', '/wf-update', 'wf-update direct command reference');
840
973
  requireText('.claude/commands/wf-update.md', 'Do not invoke a skill', 'wf-update direct command boundary');
974
+ for (const rel of ['.claude/commands/wf-update.md', '.opencode/commands/wf-update.md']) {
975
+ requireText(rel, '## Cache Discipline', `${rel} cache discipline`);
976
+ requireText(rel, 'agent.safeApplyCommand', `${rel} safe apply step`);
977
+ requireText(rel, '--apply-safe', `${rel} apply-safe command`);
978
+ requireText(rel, 'agent.aiMergeRequired', `${rel} AI merge step`);
979
+ requireText(rel, '--accept-local', `${rel} accept-local decision`);
980
+ requireText(rel, '--accept-merged', `${rel} accept-merged decision`);
981
+ requireText(rel, '--accept-template', `${rel} accept-template decision`);
982
+ requireText(rel, '--finalize', `${rel} finalize command`);
983
+ requireText(rel, 'strict `--apply` only when', `${rel} strict apply boundary`);
984
+ requireText(rel, '## Return', `${rel} return contract`);
985
+ requireText(rel, 'agent.releaseHighlights', `${rel} release highlights summary`);
986
+ requireText(rel, 'releaseNotes.highlights', `${rel} release notes fallback`);
987
+ }
988
+ requireText('Harness/scripts/wf-update-check.mjs', 'releaseHighlights', 'wf-update-check release highlights metadata');
989
+ requireText('Harness/scripts/wf-update-check.mjs', 'updateReportRequired', 'wf-update-check user update report requirement');
841
990
  requireText('.claude/commands/wf-help.md', 'direct command', 'wf-help wf-update direct command classification');
991
+ requireText('.claude/commands/wf-help.md', '/wf-browser', 'wf-help optional browser workflow row');
992
+ requireText('.opencode/commands/wf-help.md', '/wf-browser', 'OpenCode wf-help optional browser workflow row');
842
993
 
843
994
  // wf-update skill must NOT claim Claude Code /wf-update as a skill invocation
844
995
  // (allow mentions in the description/body that say "direct command" — those are correct)
@@ -853,6 +1004,10 @@ for (const command of opencodeWorkflowCommands) {
853
1004
  requireText(`.opencode/commands/${command}.md`, 'workflow command', `OpenCode ${command} workflow command classification`);
854
1005
  requireText(`.opencode/commands/${command}.md`, `.claude/skills/${command}/SKILL.md`, `OpenCode ${command} wrapper skill routing`);
855
1006
  requireText(`.opencode/commands/${command}.md`, 'Harness/MEMORY.md', `OpenCode ${command} wrapper router load`);
1007
+ requireText(`.opencode/commands/${command}.md`, 'Cache-First Context Contract', `OpenCode ${command} cache-first routing`);
1008
+ }
1009
+ if (fs.existsSync(path.join(root, '.opencode/commands/wf-browser.md'))) {
1010
+ requireText('.opencode/commands/wf-browser.md', 'Cache-First Context Contract', 'OpenCode wf-browser cache-first routing');
856
1011
  }
857
1012
 
858
1013
  // wf-max adapter must stay tier-aware, not the old unconditional contract
@@ -866,31 +1021,33 @@ requireText('.claude/agents/codebase-explorer.md', 'model: haiku', 'codebase-exp
866
1021
  requireText('.claude/agents/codebase-explorer.md', 'read-only', 'codebase-explorer read-only contract');
867
1022
 
868
1023
  // WF-KERNEL.md required invariants
869
- requireText('Harness/WF-KERNEL.md', 'Ready-Queue', 'WF-KERNEL ready-queue section');
870
- requireText('Harness/WF-KERNEL.md', 'Role / Model Matrix', 'WF-KERNEL role-model matrix');
871
- requireText('Harness/WF-KERNEL.md', 'Dispatch Packet', 'WF-KERNEL dispatch packet format');
872
- requireText('Harness/WF-KERNEL.md', 'Task Type', 'WF-KERNEL task type routing');
873
- requireText('Harness/WF-KERNEL.md', 'small-fast', 'WF-KERNEL small-fast tier mapping');
1024
+ requireText('Harness/specs/workflows/WF-KERNEL.md', 'Ready-Queue', 'WF-KERNEL ready-queue section');
1025
+ requireText('Harness/specs/workflows/WF-KERNEL.md', 'Role / Model Matrix', 'WF-KERNEL role-model matrix');
1026
+ requireText('Harness/specs/workflows/WF-KERNEL.md', 'Dispatch Packet', 'WF-KERNEL dispatch packet format');
1027
+ requireText('Harness/specs/workflows/WF-KERNEL.md', 'Task Type', 'WF-KERNEL task type routing');
1028
+ requireText('Harness/specs/workflows/WF-KERNEL.md', 'small-fast', 'WF-KERNEL small-fast tier mapping');
874
1029
 
875
1030
  // WF variants reference WF-KERNEL
876
- requireText('Harness/WF.md', 'WF-KERNEL.md', 'WF.md references WF-KERNEL');
877
- requireText('Harness/WF-MAX.md', 'WF-KERNEL.md', 'WF-MAX.md references WF-KERNEL');
878
- requireText('Harness/WF-MAX.md', 'probe-worker-channels.mjs', 'WF-MAX references worker-channel probe (M3 anti-regression)');
1031
+ requireText('Harness/specs/workflows/WF.md', 'WF-KERNEL.md', 'WF.md references WF-KERNEL');
1032
+ requireText('Harness/specs/workflows/WF-MAX.md', 'WF-KERNEL.md', 'WF-MAX.md references WF-KERNEL');
1033
+ requireText('Harness/specs/workflows/WF-MAX.md', 'Use proven channels only', 'WF-MAX proven-channel degradation rule');
1034
+ requireText('Harness/specs/workflows/WF-MAX.md', 'Evidence-Packet', 'WF-MAX evidence-packet channel record');
1035
+ requireText('Harness/specs/workflows/WF-MAX.md', 'Do not create ad hoc probe scripts', 'WF-MAX no ad hoc probe scripts');
879
1036
 
880
1037
  // Tier-aware acceptance: WF-Light must NOT require global cross-review/reflector
881
- requireText('Harness/WF.md', 'Cross-review and reflector NOT mandatory', 'WF.md WF-Light no mandatory cross-review');
882
- requireText('Harness/WF-KERNEL.md', 'Cross-review and reflector are NOT mandatory', 'WF-KERNEL WF-Light no mandatory cross-review');
1038
+ requireText('Harness/specs/workflows/WF.md', 'Cross-review and reflector NOT mandatory', 'WF.md WF-Light no mandatory cross-review');
1039
+ requireText('Harness/specs/workflows/WF-KERNEL.md', 'Cross-review and reflector are NOT mandatory', 'WF-KERNEL WF-Light no mandatory cross-review');
883
1040
 
884
1041
  // WF-MAX: maximum safe fan-out, not unconditional
885
- requireText('Harness/WF-MAX.md', 'maximum safe fan-out', 'WF-MAX maximum safe fan-out');
886
- requireText('Harness/WF-MAX.md', 'WF-Max-Useful', 'WF-MAX useful fan-out mode');
887
- requireText('Harness/WF-MAX.md', 'WF-Max-Strict', 'WF-MAX strict override mode');
1042
+ requireText('Harness/specs/workflows/WF-MAX.md', 'maximum safe fan-out', 'WF-MAX maximum safe fan-out');
1043
+ requireText('Harness/specs/workflows/WF-MAX.md', 'WF-Max-Useful', 'WF-MAX useful fan-out mode');
1044
+ requireText('Harness/specs/workflows/WF-MAX.md', 'WF-Max-Strict', 'WF-MAX strict override mode');
888
1045
 
889
1046
  // task-scribe is task-state write exception
890
- requireText('Harness/subagents.md', 'task-scribe', 'subagents.md task-scribe registration');
891
- requireText('Harness/dispatch.md', 'task-scribe', 'dispatch.md task-scribe roster');
892
- requireText('Harness/WF-KERNEL.md', 'task-scribe', 'WF-KERNEL task-scribe ownership');
893
- forbidText('Harness/WF-KERNEL.md', 'Only the main agent writes task', 'old single-writer rule');
1047
+ requireText('Harness/specs/runtime/subagents.md', 'task-scribe', 'subagents.md task-scribe registration');
1048
+ requireText('Harness/specs/runtime/dispatch.md', 'task-scribe', 'dispatch.md task-scribe roster');
1049
+ requireText('Harness/specs/workflows/WF-KERNEL.md', 'task-scribe', 'WF-KERNEL task-scribe ownership');
1050
+ forbidText('Harness/specs/workflows/WF-KERNEL.md', 'Only the main agent writes task', 'old single-writer rule');
894
1051
 
895
1052
  // Old WF contract must not return to hot-path docs:
896
1053
  // /wf is WF-KERNEL tiered orchestration, not a default complete role chain;
@@ -899,16 +1056,16 @@ const hotPathDocs = [
899
1056
  'CLAUDE.md',
900
1057
  'Harness/MEMORY.md',
901
1058
  'Harness/README.md',
902
- 'Harness/WF.md',
903
- 'Harness/WF-MAX.md',
904
- 'Harness/WF-AUTO.md',
905
- 'Harness/WF-AUTO-SPARK.md',
906
- 'Harness/WF-KERNEL.md',
907
- 'Harness/agent-workflow.md',
908
- 'Harness/dispatch.md',
909
- 'Harness/subagents.md',
910
- 'Harness/context-loading.md',
911
- 'Harness/ACCEPTANCE_PROTOCOL.md',
1059
+ 'Harness/specs/workflows/WF.md',
1060
+ 'Harness/specs/workflows/WF-MAX.md',
1061
+ 'Harness/specs/workflows/WF-AUTO.md',
1062
+ 'Harness/specs/workflows/WF-AUTO-SPARK.md',
1063
+ 'Harness/specs/workflows/WF-KERNEL.md',
1064
+ 'Harness/specs/runtime/agent-workflow.md',
1065
+ 'Harness/specs/runtime/dispatch.md',
1066
+ 'Harness/specs/runtime/subagents.md',
1067
+ 'Harness/specs/runtime/context-loading.md',
1068
+ 'Harness/specs/protocols/ACCEPTANCE_PROTOCOL.md',
912
1069
  ];
913
1070
  for (const rel of hotPathDocs) {
914
1071
  forbidText(rel, 'complete role chain mandatory', 'old /wf default complete-role-chain contract');
@@ -919,16 +1076,16 @@ for (const rel of hotPathDocs) {
919
1076
  }
920
1077
 
921
1078
  // WF-STATE.md and TASK_ARCHIVE.md must be reachable from the entry router
922
- requireText('CLAUDE.md', 'Harness/WF-STATE.md', 'CLAUDE.md WF-STATE routing');
923
- requireText('CLAUDE.md', 'Harness/TASK_ARCHIVE.md', 'CLAUDE.md TASK_ARCHIVE routing');
1079
+ requireText('CLAUDE.md', 'Harness/specs/workflows/WF-STATE.md', 'CLAUDE.md WF-STATE routing');
1080
+ requireText('CLAUDE.md', 'Harness/specs/protocols/TASK_ARCHIVE.md', 'CLAUDE.md TASK_ARCHIVE routing');
924
1081
  requireText('Harness/README.md', 'WF-STATE.md', 'README WF-STATE routing');
925
- requireText('Harness/TASK_ARCHIVE.md', 'archive-tasks.mjs', 'TASK_ARCHIVE script reference');
1082
+ requireText('Harness/specs/protocols/TASK_ARCHIVE.md', 'archive-tasks.mjs', 'TASK_ARCHIVE script reference');
926
1083
 
927
- // Outer task capsule cap: keep Harness/tasks/ lean (see Harness/TASK_ARCHIVE.md)
1084
+ // Outer task capsule cap: keep Harness/tasks/ lean (see Harness/specs/protocols/TASK_ARCHIVE.md)
928
1085
  const OUTER_TASK_CAP = 5;
929
1086
  const outerTasks = taskDirs.filter(name => !TASK_RESERVED.has(name) && !name.startsWith('_'));
930
1087
  if (outerTasks.length > OUTER_TASK_CAP) {
931
- const capMsg = `Harness/tasks/ has ${outerTasks.length} outer task capsules (cap ${OUTER_TASK_CAP}); archive completed tasks with node Harness/scripts/archive-tasks.mjs --apply (see Harness/TASK_ARCHIVE.md)`;
1088
+ const capMsg = `Harness/tasks/ has ${outerTasks.length} outer task capsules (cap ${OUTER_TASK_CAP}); archive completed tasks with node Harness/scripts/archive-tasks.mjs --apply (see Harness/specs/protocols/TASK_ARCHIVE.md)`;
932
1089
  if (strict) errors.push(capMsg);
933
1090
  else console.warn(`Warning: ${capMsg}`);
934
1091
  }