create-harness-vibe-coding 0.8.6 → 0.8.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/generator.js +30 -11
- package/src/index.js +129 -5
- package/templates/common/.claude/agents/reflector.md +35 -0
- package/templates/common/.claude/agents/verifier.md +5 -3
- package/templates/common/.claude/commands/wf-help.md +1 -2
- package/templates/common/.claude/skills/subagent-orchestrator/SKILL.md +10 -4
- package/templates/common/.claude/skills/wf/SKILL.md +7 -3
- package/templates/common/.claude/skills/wf-auto/SKILL.md +59 -107
- package/templates/common/.claude/skills/wf-auto-spark/SKILL.md +19 -17
- package/templates/common/.claude/skills/wf-max/SKILL.md +40 -21
- package/templates/common/.claude/skills/wf-update/SKILL.md +9 -4
- package/templates/common/.codex/config.toml +5 -0
- package/templates/common/.harness-version +36 -34
- package/templates/common/AGENTS.md +26 -25
- package/templates/common/CLAUDE.md +10 -9
- package/templates/common/Harness/ACCEPTANCE_PROTOCOL.md +12 -4
- package/templates/common/Harness/README.md +10 -11
- package/templates/common/Harness/WF-AUTO-SPARK.md +18 -1
- package/templates/common/Harness/WF-AUTO.md +518 -492
- package/templates/common/Harness/WF-MAX.md +284 -232
- package/templates/common/Harness/WF.md +47 -29
- package/templates/common/Harness/agent-workflow.md +108 -76
- package/templates/common/Harness/dispatch.md +96 -95
- package/templates/common/Harness/extension.md +1 -1
- package/templates/common/Harness/subagents.md +78 -56
- package/templates/common/Harness/tasks/_template/ARTIFACTS.md +1 -1
- package/templates/common/Harness/tasks/_template/NOTES.md +1 -1
- package/templates/common/Harness/tasks/_template/PLAN.md +53 -60
- package/templates/common/Harness/tasks/_template/PROGRESS.md +26 -29
- package/templates/common/MEMORY.md +26 -29
- package/templates/common/SETUP.md +1 -1
- package/templates/common/scripts/scan-clean.mjs +80 -41
- package/templates/common/scripts/validate-harness.mjs +101 -31
- package/templates/common/scripts/wf-remove.mjs +279 -278
- package/templates/common/scripts/wf-update-check.mjs +395 -195
- package/templates/optional/skills/browser-e2e/.claude/skills/wf-browser/SKILL.md +1 -1
- package/templates/optional/skills/browser-e2e/Harness/workflows/browser-e2e.md +57 -21
|
@@ -20,37 +20,39 @@ import { resolve, dirname, sep, join } from 'path';
|
|
|
20
20
|
import { fileURLToPath } from 'url';
|
|
21
21
|
import { createInterface } from 'readline';
|
|
22
22
|
|
|
23
|
-
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
24
|
-
const ROOT = process.env.WF_ROOT ? resolve(process.env.WF_ROOT) : resolve(__dirname, '..', '..');
|
|
25
|
-
const VERSION_FILE = resolve(ROOT, 'Harness', '.harness-version');
|
|
26
|
-
const
|
|
23
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
24
|
+
const ROOT = process.env.WF_ROOT ? resolve(process.env.WF_ROOT) : resolve(__dirname, '..', '..');
|
|
25
|
+
const VERSION_FILE = resolve(ROOT, 'Harness', '.harness-version');
|
|
26
|
+
const DEFAULT_SOURCE_BASE = 'https://raw.githubusercontent.com/zingspark/create-harness-vibe-coding/main/templates/common/';
|
|
27
27
|
|
|
28
28
|
// ── Classification constants ────────────────────────────────────────
|
|
29
29
|
|
|
30
30
|
/** Files we NEVER delete, even if dead. */
|
|
31
|
-
const PRESERVE_PATTERNS = [
|
|
32
|
-
/^Harness\/PROGRESS\.md$/,
|
|
33
|
-
/^Harness\/tasks\//,
|
|
34
|
-
/^Harness\/memory\//,
|
|
35
|
-
/^Harness\/research\/PRD\.md$/,
|
|
36
|
-
/^Harness\/research\/research-results\.md$/,
|
|
37
|
-
/^Harness\/architecture\.md$/,
|
|
38
|
-
/^
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
/^package
|
|
42
|
-
|
|
31
|
+
const PRESERVE_PATTERNS = [
|
|
32
|
+
/^Harness\/PROGRESS\.md$/,
|
|
33
|
+
/^Harness\/tasks\//,
|
|
34
|
+
/^Harness\/memory\//,
|
|
35
|
+
/^Harness\/research\/PRD\.md$/,
|
|
36
|
+
/^Harness\/research\/research-results\.md$/,
|
|
37
|
+
/^Harness\/architecture\.md$/,
|
|
38
|
+
/^tests\/\.gitkeep$/,
|
|
39
|
+
/^README\.md$/,
|
|
40
|
+
/^\.gitignore$/,
|
|
41
|
+
/^package\.json$/,
|
|
42
|
+
/^package-lock\.json$/,
|
|
43
|
+
];
|
|
43
44
|
|
|
44
45
|
/** Directories scanned for orphan files (untracked by either checksum set). */
|
|
45
46
|
const FRAMEWORK_DIRS = [
|
|
46
47
|
'.claude/agents',
|
|
48
|
+
'.claude/commands',
|
|
47
49
|
'.claude/skills',
|
|
48
50
|
'.claude/rules',
|
|
49
51
|
'.agents/skills',
|
|
50
|
-
'.codex',
|
|
51
|
-
'Harness/scripts',
|
|
52
|
-
'Harness/workflows',
|
|
53
|
-
];
|
|
52
|
+
'.codex',
|
|
53
|
+
'Harness/scripts',
|
|
54
|
+
'Harness/workflows',
|
|
55
|
+
];
|
|
54
56
|
|
|
55
57
|
// ── Helpers ──────────────────────────────────────────────────────────
|
|
56
58
|
|
|
@@ -67,25 +69,60 @@ function safePath(file) {
|
|
|
67
69
|
}
|
|
68
70
|
|
|
69
71
|
/** Canonical normalization for classification matching. */
|
|
70
|
-
function canonicalPath(file) {
|
|
71
|
-
return file.replace(/\\/g, '/').replace(/\/+/g, '/');
|
|
72
|
-
}
|
|
72
|
+
function canonicalPath(file) {
|
|
73
|
+
return file.replace(/\\/g, '/').replace(/\/+/g, '/');
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function readFlagValue(args, flagName) {
|
|
77
|
+
const idx = args.indexOf(flagName);
|
|
78
|
+
if (idx === -1) return null;
|
|
79
|
+
const value = args[idx + 1];
|
|
80
|
+
if (!value || value.startsWith('--')) return null;
|
|
81
|
+
return value;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function normalizeSourceBase(sourceBase) {
|
|
85
|
+
return sourceBase.endsWith('/') ? sourceBase : sourceBase + '/';
|
|
86
|
+
}
|
|
73
87
|
|
|
74
88
|
/** Check whether a canonical path matches any PRESERVE pattern. */
|
|
75
|
-
function isPreserved(canonical) {
|
|
76
|
-
for (const p of PRESERVE_PATTERNS) {
|
|
77
|
-
if (p.test(canonical)) return true;
|
|
78
|
-
}
|
|
79
|
-
return false;
|
|
80
|
-
}
|
|
89
|
+
function isPreserved(canonical) {
|
|
90
|
+
for (const p of PRESERVE_PATTERNS) {
|
|
91
|
+
if (p.test(canonical)) return true;
|
|
92
|
+
}
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function selectedOptionIds(localVersion) {
|
|
97
|
+
return new Set(
|
|
98
|
+
Array.isArray(localVersion?.options)
|
|
99
|
+
? localVersion.options.map(String).filter(Boolean)
|
|
100
|
+
: [],
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function optionalSkillFromSource(source) {
|
|
105
|
+
const normalized = canonicalPath(source || '');
|
|
106
|
+
const match = normalized.match(/^skills\/([^/]+)\//);
|
|
107
|
+
return match ? match[1] : null;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function isInstalledOptionalFile(file, localVersion) {
|
|
111
|
+
const skillId = optionalSkillFromSource(localVersion?.sources?.[file]);
|
|
112
|
+
return Boolean(skillId && selectedOptionIds(localVersion).has(skillId));
|
|
113
|
+
}
|
|
81
114
|
|
|
82
115
|
/** Detect template placeholders in remote content. */
|
|
83
116
|
function isTemplate(raw) {
|
|
84
117
|
return /\{\{[a-zA-Z]+\}\}/.test(raw);
|
|
85
118
|
}
|
|
86
119
|
|
|
87
|
-
async function fetchRemote(url, timeoutMs = 30000) {
|
|
88
|
-
|
|
120
|
+
async function fetchRemote(url, timeoutMs = 30000) {
|
|
121
|
+
if (url.startsWith('file://')) {
|
|
122
|
+
return readFileSync(fileURLToPath(url), 'utf-8');
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const controller = new AbortController();
|
|
89
126
|
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
90
127
|
try {
|
|
91
128
|
const res = await fetch(url, { signal: controller.signal });
|
|
@@ -217,9 +254,10 @@ function removeEmptyParents(fileAbsPath) {
|
|
|
217
254
|
|
|
218
255
|
async function main() {
|
|
219
256
|
const args = process.argv.slice(2);
|
|
220
|
-
const clean = args.includes('--clean');
|
|
221
|
-
const yes = args.includes('--yes');
|
|
222
|
-
const jsonOut = args.includes('--json');
|
|
257
|
+
const clean = args.includes('--clean');
|
|
258
|
+
const yes = args.includes('--yes');
|
|
259
|
+
const jsonOut = args.includes('--json');
|
|
260
|
+
const sourceBase = normalizeSourceBase(readFlagValue(args, '--source-base') || process.env.WF_SOURCE_BASE || DEFAULT_SOURCE_BASE);
|
|
223
261
|
|
|
224
262
|
// 1. Read local state
|
|
225
263
|
if (!existsSync(VERSION_FILE)) {
|
|
@@ -248,7 +286,7 @@ async function main() {
|
|
|
248
286
|
// 2. Fetch remote version file
|
|
249
287
|
let remoteVersion;
|
|
250
288
|
try {
|
|
251
|
-
const raw = await fetchRemote(
|
|
289
|
+
const raw = await fetchRemote(sourceBase + '.harness-version');
|
|
252
290
|
if (isTemplate(raw)) {
|
|
253
291
|
if (jsonOut) {
|
|
254
292
|
console.log(JSON.stringify({ status: 'error', message: 'Remote .harness-version is a template (contains {{placeholders}}). Cannot determine dead files.' }));
|
|
@@ -275,12 +313,13 @@ async function main() {
|
|
|
275
313
|
// 3. Classify dead files
|
|
276
314
|
// DEAD = in local checksums but NOT in remote checksums, AND NOT preserved
|
|
277
315
|
const deadFiles = [];
|
|
278
|
-
for (const file of Object.keys(localChecksums)) {
|
|
279
|
-
const canonical = canonicalPath(file);
|
|
280
|
-
if (remoteChecksums[file]) continue; // still in remote, not dead
|
|
281
|
-
if (isPreserved(canonical)) continue; // user data, never dead
|
|
282
|
-
|
|
283
|
-
|
|
316
|
+
for (const file of Object.keys(localChecksums)) {
|
|
317
|
+
const canonical = canonicalPath(file);
|
|
318
|
+
if (remoteChecksums[file]) continue; // still in remote, not dead
|
|
319
|
+
if (isPreserved(canonical)) continue; // user data, never dead
|
|
320
|
+
if (isInstalledOptionalFile(file, localVersion)) continue; // installed optional workflow/skill
|
|
321
|
+
deadFiles.push({ file, reason: 'not in remote template' });
|
|
322
|
+
}
|
|
284
323
|
|
|
285
324
|
// 4. Find orphan files
|
|
286
325
|
const orphanFiles = findOrphanFiles(localChecksums, remoteChecksums);
|
|
@@ -22,10 +22,11 @@ const commonAgents = [
|
|
|
22
22
|
'architect',
|
|
23
23
|
'test-writer',
|
|
24
24
|
'implementer',
|
|
25
|
-
'debugger',
|
|
26
|
-
'reviewer',
|
|
27
|
-
'verifier',
|
|
28
|
-
'
|
|
25
|
+
'debugger',
|
|
26
|
+
'reviewer',
|
|
27
|
+
'verifier',
|
|
28
|
+
'reflector',
|
|
29
|
+
'memory-master',
|
|
29
30
|
'context-master',
|
|
30
31
|
'explore-manager',
|
|
31
32
|
'architect-manager',
|
|
@@ -214,18 +215,33 @@ function registeredSkillFiles(...texts) {
|
|
|
214
215
|
return [...files].sort();
|
|
215
216
|
}
|
|
216
217
|
|
|
217
|
-
function registeredWorkflowFiles(...texts) {
|
|
218
|
-
const files = new Set();
|
|
219
|
-
const pattern = /(?:Harness\/)?workflows\/([A-Za-z0-9._-]+\.md)/g;
|
|
218
|
+
function registeredWorkflowFiles(...texts) {
|
|
219
|
+
const files = new Set();
|
|
220
|
+
const pattern = /(?:Harness\/)?workflows\/([A-Za-z0-9._-]+\.md)/g;
|
|
220
221
|
|
|
221
222
|
for (const text of texts) {
|
|
222
223
|
for (const match of text.matchAll(pattern)) {
|
|
223
224
|
files.add(`Harness/workflows/${match[1]}`);
|
|
224
225
|
}
|
|
225
226
|
}
|
|
226
|
-
|
|
227
|
-
return [...files].sort();
|
|
228
|
-
}
|
|
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
|
+
}
|
|
229
245
|
|
|
230
246
|
for (const rel of required) {
|
|
231
247
|
if (!fs.existsSync(path.join(root, rel))) {
|
|
@@ -380,13 +396,25 @@ for (const workflow of listMarkdownFiles('Harness/workflows')) {
|
|
|
380
396
|
}
|
|
381
397
|
}
|
|
382
398
|
|
|
383
|
-
for (const skillFile of registeredSkillFiles(docsReadme, memory)) {
|
|
384
|
-
if (!fs.existsSync(path.join(root, skillFile))) {
|
|
385
|
-
errors.push(`registered skill file is missing: ${skillFile}`);
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
for (const
|
|
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)) {
|
|
390
418
|
if (!fs.existsSync(path.join(root, workflowFile))) {
|
|
391
419
|
// Optional workflows (browser-e2e, ts-react-frontend, etc.) may not be installed
|
|
392
420
|
continue;
|
|
@@ -478,13 +506,23 @@ for (const agent of commonAgents) {
|
|
|
478
506
|
|
|
479
507
|
requireText('Harness/extension.md', 'Skills should extend the harness');
|
|
480
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');
|
|
481
517
|
requireText('Harness/agent-workflow.md', 'TDD-GUIDE.md', 'agent workflow loads TDD guide');
|
|
482
518
|
requireText('Harness/agent-workflow.md', 'real user-path test', 'agent workflow real user path requirement');
|
|
483
519
|
requireText('Harness/research/README.md', 'research-results.md');
|
|
484
520
|
requireText('Harness/WF.md', 'Ralph-style harness loop', 'WF loop description');
|
|
485
521
|
requireText('Harness/WF.md', 'Heartbeat Protocol', 'heartbeat protocol');
|
|
486
|
-
requireText('Harness/WF.md', 'WF mode requires
|
|
487
|
-
requireText('Harness/WF.md', '
|
|
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');
|
|
488
526
|
requireText('Harness/WF.md', '.claude/agents/', 'WF built-in agent roster path');
|
|
489
527
|
requireText('Harness/WF.md', 'Collaboration decision tree', 'WF decision tree');
|
|
490
528
|
requireText('Harness/WF.md', 'Harness/tasks/', 'WF task directory reference');
|
|
@@ -502,23 +540,43 @@ requireText('Harness/subagents.md', '## Source Attribution', 'subagent source at
|
|
|
502
540
|
requireText('Harness/subagents.md', 'npx skills find', 'find-skills discovery attribution');
|
|
503
541
|
requireText('Harness/subagents.md', 'superpowers:dispatching-parallel-agents', 'parallel-agent source attribution');
|
|
504
542
|
requireText('Harness/subagents.md', 'superpowers:subagent-driven-development', 'subagent-driven source attribution');
|
|
505
|
-
requireText('Harness/subagents.md', '## Built-in Agent Roster', 'built-in agent roster');
|
|
506
|
-
requireText('Harness/subagents.md', '## WF Default Fan-Out', 'WF default fan-out');
|
|
507
|
-
requireText('Harness/subagents.md', 'concrete conditions', 'subagent decision tree');
|
|
508
|
-
requireText('Harness/subagents.md', 'parallel planner/researcher/docs-researcher/architect subagents', 'WF roster orchestration shape');
|
|
509
|
-
requireText('Harness/subagents.md', '
|
|
510
|
-
requireText('Harness/subagents.md', '
|
|
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');
|
|
511
551
|
requireText('Harness/architecture.md', '## 2. Interface Decoupling', 'architecture interface decoupling');
|
|
512
552
|
requireText('Harness/architecture.md', '## 3. State Design', 'architecture state design');
|
|
513
553
|
requireText('Harness/architecture.md', 'Avoid speculative abstraction', 'anti-overengineering architecture rule');
|
|
514
554
|
requireText('CLAUDE.md', 'Use explicit interfaces or state models only when they protect a real boundary', 'CLAUDE interface/state simplicity rule');
|
|
515
555
|
requireText('CLAUDE.md', '/wf-update', 'wf update startup instruction');
|
|
516
556
|
requireText('Harness/README.md', 'Need harness update', 'update routing row');
|
|
517
|
-
requireText('Harness/WF-MAX.md', 'three-layer architecture', 'WF-MAX three-layer architecture');
|
|
518
|
-
requireText('Harness/WF-MAX.md', 'agent role', 'WF-MAX agent role separation');
|
|
519
|
-
requireText('Harness/WF-MAX.md', 'write-set coloring', 'WF-MAX coloring algorithm');
|
|
520
|
-
requireText('Harness/WF-MAX.md', 'wave dispatch', 'WF-MAX wave dispatch');
|
|
521
|
-
requireText('Harness/
|
|
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');
|
|
522
580
|
requireText('Harness/README.md', 'WF-MAX.md', 'WF-MAX router reference');
|
|
523
581
|
requireText('Harness/README.md', 'ACCEPTANCE_PROTOCOL.md', 'acceptance protocol router reference');
|
|
524
582
|
requireText('Harness/README.md', 'TDD-GUIDE.md', 'TDD guide router reference');
|
|
@@ -529,6 +587,12 @@ requireText('Harness/ACCEPTANCE_PROTOCOL.md', 'Syntax-only checks', 'syntax-only
|
|
|
529
587
|
requireText('Harness/AGENT_ISOLATION.md', 'implementer', 'agent isolation implementer rule');
|
|
530
588
|
requireText('Harness/HARNESS_BRIDGE.md', 'Network Trace Collector', 'harness bridge network trace collector');
|
|
531
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');
|
|
532
596
|
requireText('Harness/MEMORY_PROTOCOL.md', 'Scenario Memory Hints', 'memory protocol scenario hints');
|
|
533
597
|
requireText('Harness/MEMORY_PROTOCOL.md', 'WF closeout', 'memory protocol WF closeout injection row');
|
|
534
598
|
requireText('Harness/MEMORY_PROTOCOL.md', 'memory-master owns writes', 'memory protocol memory write ownership');
|
|
@@ -536,7 +600,7 @@ requireText('Harness/TDD-GUIDE.md', 'Browser/UI Acceptance TDD Gate', 'browser U
|
|
|
536
600
|
requireText('Harness/TDD-GUIDE.md', 'syntax-only', 'syntax-only acceptance prohibition');
|
|
537
601
|
requireText('Harness/TDD-GUIDE.md', 'Playwright/CDP', 'Playwright/CDP acceptance requirement');
|
|
538
602
|
requireText('Harness/TDD-GUIDE.md', 'AC-by-AC result matrix', 'AC-by-AC TDD evidence matrix');
|
|
539
|
-
requireText('Harness/tasks/_template/PLAN.md', '
|
|
603
|
+
requireText('Harness/tasks/_template/PLAN.md', 'Expanded evidence required when triggered', 'task template expanded evidence trigger');
|
|
540
604
|
requireText('Harness/templates/TEST_PLAN.template.md', 'syntax-only checks', 'test plan template syntax-only prohibition');
|
|
541
605
|
requireText('.claude/skills/tdd/SKILL.md', 'Harness/ACCEPTANCE_PROTOCOL.md', 'tdd skill loads acceptance protocol');
|
|
542
606
|
requireText('.claude/skills/tdd/SKILL.md', 'Harness/HARNESS_BRIDGE.md', 'tdd skill loads harness bridge');
|
|
@@ -549,6 +613,7 @@ requireText('.claude/agents/tdd-guide.md', 'real user actions', 'tdd-guide real
|
|
|
549
613
|
requireText('.claude/agents/test-writer.md', 'Harness/ACCEPTANCE_PROTOCOL.md', 'test-writer loads acceptance protocol');
|
|
550
614
|
requireText('.claude/agents/test-writer.md', 'real user-path test', 'test-writer real user path requirement');
|
|
551
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');
|
|
552
617
|
requireText('Harness/DEBUG_PROTOCOL.md', 'Layer Classification', 'debug layer classification');
|
|
553
618
|
requireText('Harness/MEMORY_PROTOCOL.md', 'AC ID', 'memory AC traceability');
|
|
554
619
|
requireText('Harness/subagents.md', 'Max parallelism', 'subagents max parallelism row');
|
|
@@ -568,12 +633,17 @@ requireText('Harness/README.md', 'no runtime hook state', 'README no-hook runtim
|
|
|
568
633
|
requireText('Harness/WF-AUTO.md', 'WF-AUTO Hook Exception', 'wf-auto-only hook exception');
|
|
569
634
|
requireText('Harness/WF-AUTO.md', 'only `/wf-auto` may use a runtime hook', 'wf-auto-only hook boundary');
|
|
570
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');
|
|
571
639
|
forbidText('CLAUDE.md', 'WF-MAX hooks', 'WF-MAX hook enforcement claim');
|
|
572
640
|
forbidText('Harness/README.md', 'PreToolUse hook', 'WF-MAX PreToolUse hook claim');
|
|
573
641
|
forbidText('Harness/README.md', 'SessionStart hook', 'WF-MAX SessionStart hook claim');
|
|
574
642
|
forbidText('Harness/README.md', 'hook-managed', 'hook-managed runtime claim');
|
|
575
643
|
forbidText('Harness/README.md', 'HOOK_PROTOCOL.md', 'removed hook protocol reference');
|
|
576
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');
|
|
577
647
|
forbidText('Harness/MEMORY_PROTOCOL.md', 'Hooks may', 'hook-triggered memory claim');
|
|
578
648
|
forbidText('.claude/settings.json', 'wf-mode-hook.mjs', 'Claude WF hook command registration');
|
|
579
649
|
forbidText('.codex/hooks.json', 'wf-mode-hook.mjs', 'Codex WF hook command registration');
|