workspace-maxxing 0.1.0

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 (198) hide show
  1. package/.agents/skills/workspace-maxxing/.workspace-templates/CONTEXT.md +44 -0
  2. package/.agents/skills/workspace-maxxing/.workspace-templates/SYSTEM.md +44 -0
  3. package/.agents/skills/workspace-maxxing/.workspace-templates/references/anti-patterns.md +16 -0
  4. package/.agents/skills/workspace-maxxing/.workspace-templates/references/iron-laws.md +26 -0
  5. package/.agents/skills/workspace-maxxing/.workspace-templates/references/reporting-format.md +52 -0
  6. package/.agents/skills/workspace-maxxing/.workspace-templates/scripts/benchmark.ts +171 -0
  7. package/.agents/skills/workspace-maxxing/.workspace-templates/scripts/dispatch.ts +473 -0
  8. package/.agents/skills/workspace-maxxing/.workspace-templates/scripts/generate-tests.ts +158 -0
  9. package/.agents/skills/workspace-maxxing/.workspace-templates/scripts/install-tool.ts +82 -0
  10. package/.agents/skills/workspace-maxxing/.workspace-templates/scripts/iterate.ts +265 -0
  11. package/.agents/skills/workspace-maxxing/.workspace-templates/scripts/orchestrator.ts +539 -0
  12. package/.agents/skills/workspace-maxxing/.workspace-templates/scripts/scaffold.ts +282 -0
  13. package/.agents/skills/workspace-maxxing/.workspace-templates/scripts/validate.ts +452 -0
  14. package/.agents/skills/workspace-maxxing/.workspace-templates/skills/architecture/SKILL.md +95 -0
  15. package/.agents/skills/workspace-maxxing/.workspace-templates/skills/fixer/SKILL.md +109 -0
  16. package/.agents/skills/workspace-maxxing/.workspace-templates/skills/iteration/SKILL.md +89 -0
  17. package/.agents/skills/workspace-maxxing/.workspace-templates/skills/prompt-engineering/SKILL.md +87 -0
  18. package/.agents/skills/workspace-maxxing/.workspace-templates/skills/research/SKILL.md +94 -0
  19. package/.agents/skills/workspace-maxxing/.workspace-templates/skills/testing/SKILL.md +89 -0
  20. package/.agents/skills/workspace-maxxing/.workspace-templates/skills/tooling/SKILL.md +87 -0
  21. package/.agents/skills/workspace-maxxing/.workspace-templates/skills/validation/SKILL.md +103 -0
  22. package/.agents/skills/workspace-maxxing/.workspace-templates/skills/worker/SKILL.md +79 -0
  23. package/.agents/skills/workspace-maxxing/.workspace-templates/workspace/00-meta/CONTEXT.md +6 -0
  24. package/.agents/skills/workspace-maxxing/.workspace-templates/workspace/00-meta/execution-log.md +27 -0
  25. package/.agents/skills/workspace-maxxing/.workspace-templates/workspace/01-input/CONTEXT.md +29 -0
  26. package/.agents/skills/workspace-maxxing/.workspace-templates/workspace/02-process/CONTEXT.md +29 -0
  27. package/.agents/skills/workspace-maxxing/.workspace-templates/workspace/03-output/CONTEXT.md +29 -0
  28. package/.agents/skills/workspace-maxxing/.workspace-templates/workspace/README.md +14 -0
  29. package/.agents/skills/workspace-maxxing/SKILL.md +312 -0
  30. package/.agents/skills/workspace-maxxing/scripts/benchmark.ts +171 -0
  31. package/.agents/skills/workspace-maxxing/scripts/dispatch.ts +473 -0
  32. package/.agents/skills/workspace-maxxing/scripts/generate-tests.ts +158 -0
  33. package/.agents/skills/workspace-maxxing/scripts/install-tool.ts +82 -0
  34. package/.agents/skills/workspace-maxxing/scripts/iterate.ts +265 -0
  35. package/.agents/skills/workspace-maxxing/scripts/orchestrator.ts +539 -0
  36. package/.agents/skills/workspace-maxxing/scripts/scaffold.ts +282 -0
  37. package/.agents/skills/workspace-maxxing/scripts/validate.ts +452 -0
  38. package/README.md +144 -0
  39. package/dist/agent-creator.d.ts +9 -0
  40. package/dist/agent-creator.d.ts.map +1 -0
  41. package/dist/agent-creator.js +199 -0
  42. package/dist/agent-creator.js.map +1 -0
  43. package/dist/agent-iterator.d.ts +38 -0
  44. package/dist/agent-iterator.d.ts.map +1 -0
  45. package/dist/agent-iterator.js +327 -0
  46. package/dist/agent-iterator.js.map +1 -0
  47. package/dist/index.d.ts +3 -0
  48. package/dist/index.d.ts.map +1 -0
  49. package/dist/index.js +197 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/install.d.ts +18 -0
  52. package/dist/install.d.ts.map +1 -0
  53. package/dist/install.js +117 -0
  54. package/dist/install.js.map +1 -0
  55. package/dist/platforms/claude.d.ts +7 -0
  56. package/dist/platforms/claude.d.ts.map +1 -0
  57. package/dist/platforms/claude.js +70 -0
  58. package/dist/platforms/claude.js.map +1 -0
  59. package/dist/platforms/copilot.d.ts +7 -0
  60. package/dist/platforms/copilot.d.ts.map +1 -0
  61. package/dist/platforms/copilot.js +75 -0
  62. package/dist/platforms/copilot.js.map +1 -0
  63. package/dist/platforms/gemini.d.ts +7 -0
  64. package/dist/platforms/gemini.d.ts.map +1 -0
  65. package/dist/platforms/gemini.js +81 -0
  66. package/dist/platforms/gemini.js.map +1 -0
  67. package/dist/platforms/index.d.ts +8 -0
  68. package/dist/platforms/index.d.ts.map +1 -0
  69. package/dist/platforms/index.js +41 -0
  70. package/dist/platforms/index.js.map +1 -0
  71. package/dist/platforms/opencode.d.ts +7 -0
  72. package/dist/platforms/opencode.d.ts.map +1 -0
  73. package/dist/platforms/opencode.js +70 -0
  74. package/dist/platforms/opencode.js.map +1 -0
  75. package/dist/scripts/benchmark.d.ts +20 -0
  76. package/dist/scripts/benchmark.d.ts.map +1 -0
  77. package/dist/scripts/benchmark.js +170 -0
  78. package/dist/scripts/benchmark.js.map +1 -0
  79. package/dist/scripts/dispatch.d.ts +32 -0
  80. package/dist/scripts/dispatch.d.ts.map +1 -0
  81. package/dist/scripts/dispatch.js +386 -0
  82. package/dist/scripts/dispatch.js.map +1 -0
  83. package/dist/scripts/generate-tests.d.ts +11 -0
  84. package/dist/scripts/generate-tests.d.ts.map +1 -0
  85. package/dist/scripts/generate-tests.js +118 -0
  86. package/dist/scripts/generate-tests.js.map +1 -0
  87. package/dist/scripts/install-tool.d.ts +8 -0
  88. package/dist/scripts/install-tool.d.ts.map +1 -0
  89. package/dist/scripts/install-tool.js +98 -0
  90. package/dist/scripts/install-tool.js.map +1 -0
  91. package/dist/scripts/iterate.d.ts +44 -0
  92. package/dist/scripts/iterate.d.ts.map +1 -0
  93. package/dist/scripts/iterate.js +260 -0
  94. package/dist/scripts/iterate.js.map +1 -0
  95. package/dist/scripts/orchestrator.d.ts +40 -0
  96. package/dist/scripts/orchestrator.d.ts.map +1 -0
  97. package/dist/scripts/orchestrator.js +378 -0
  98. package/dist/scripts/orchestrator.js.map +1 -0
  99. package/dist/scripts/scaffold.d.ts +8 -0
  100. package/dist/scripts/scaffold.d.ts.map +1 -0
  101. package/dist/scripts/scaffold.js +279 -0
  102. package/dist/scripts/scaffold.js.map +1 -0
  103. package/dist/scripts/validate.d.ts +11 -0
  104. package/dist/scripts/validate.d.ts.map +1 -0
  105. package/dist/scripts/validate.js +472 -0
  106. package/dist/scripts/validate.js.map +1 -0
  107. package/docs/superpowers/plans/2026-04-07-autonomous-iteration-plan.md +1123 -0
  108. package/docs/superpowers/plans/2026-04-07-autonomous-iteration-sub-agent-batches.md +1923 -0
  109. package/docs/superpowers/plans/2026-04-07-autonomous-workflow-sub-skill-plan.md +1505 -0
  110. package/docs/superpowers/plans/2026-04-07-benchmarking-multi-agent-plan.md +854 -0
  111. package/docs/superpowers/plans/2026-04-07-workspace-builder-logic-plan.md +1426 -0
  112. package/docs/superpowers/plans/2026-04-07-workspace-maxxing-plan.md +1299 -0
  113. package/docs/superpowers/plans/2026-04-08-session-294c-subagent-invocation-plan.md +320 -0
  114. package/docs/superpowers/plans/2026-04-08-workflow-prompt-hardening-plan.md +1025 -0
  115. package/docs/superpowers/plans/2026-04-12-workspace-agent-creation-plan.md +992 -0
  116. package/docs/superpowers/specs/2026-04-07-autonomous-iteration-design.md +214 -0
  117. package/docs/superpowers/specs/2026-04-07-autonomous-iteration-sub-agent-batches-design.md +188 -0
  118. package/docs/superpowers/specs/2026-04-07-autonomous-workflow-sub-skill-design.md +137 -0
  119. package/docs/superpowers/specs/2026-04-07-benchmarking-multi-agent-design.md +105 -0
  120. package/docs/superpowers/specs/2026-04-07-workspace-builder-logic-design.md +179 -0
  121. package/docs/superpowers/specs/2026-04-07-workspace-maxxing-design.md +227 -0
  122. package/docs/superpowers/specs/2026-04-08-session-294c-subagent-invocation-design.md +265 -0
  123. package/docs/superpowers/specs/2026-04-08-workflow-prompt-hardening-design.md +146 -0
  124. package/docs/superpowers/specs/2026-04-12-workspace-agent-creation-design.md +239 -0
  125. package/jest.config.js +8 -0
  126. package/package.json +32 -0
  127. package/src/agent-creator.ts +180 -0
  128. package/src/agent-iterator.ts +397 -0
  129. package/src/index.ts +189 -0
  130. package/src/install.ts +105 -0
  131. package/src/platforms/claude.ts +40 -0
  132. package/src/platforms/copilot.ts +50 -0
  133. package/src/platforms/gemini.ts +55 -0
  134. package/src/platforms/index.ts +45 -0
  135. package/src/platforms/opencode.ts +41 -0
  136. package/src/scripts/benchmark.ts +171 -0
  137. package/src/scripts/dispatch.ts +473 -0
  138. package/src/scripts/generate-tests.ts +112 -0
  139. package/src/scripts/install-tool.ts +82 -0
  140. package/src/scripts/iterate.ts +271 -0
  141. package/src/scripts/orchestrator.ts +539 -0
  142. package/src/scripts/scaffold.ts +282 -0
  143. package/src/scripts/validate.ts +516 -0
  144. package/templates/.workspace-templates/CONTEXT.md +44 -0
  145. package/templates/.workspace-templates/SYSTEM.md +44 -0
  146. package/templates/.workspace-templates/references/anti-patterns.md +16 -0
  147. package/templates/.workspace-templates/references/iron-laws.md +26 -0
  148. package/templates/.workspace-templates/references/reporting-format.md +52 -0
  149. package/templates/.workspace-templates/scripts/benchmark.ts +171 -0
  150. package/templates/.workspace-templates/scripts/dispatch.ts +473 -0
  151. package/templates/.workspace-templates/scripts/generate-tests.ts +158 -0
  152. package/templates/.workspace-templates/scripts/install-tool.ts +82 -0
  153. package/templates/.workspace-templates/scripts/iterate.ts +265 -0
  154. package/templates/.workspace-templates/scripts/orchestrator.ts +539 -0
  155. package/templates/.workspace-templates/scripts/scaffold.ts +282 -0
  156. package/templates/.workspace-templates/scripts/validate.ts +452 -0
  157. package/templates/.workspace-templates/skills/architecture/SKILL.md +95 -0
  158. package/templates/.workspace-templates/skills/fixer/SKILL.md +109 -0
  159. package/templates/.workspace-templates/skills/iteration/SKILL.md +89 -0
  160. package/templates/.workspace-templates/skills/prompt-engineering/SKILL.md +87 -0
  161. package/templates/.workspace-templates/skills/research/SKILL.md +94 -0
  162. package/templates/.workspace-templates/skills/testing/SKILL.md +89 -0
  163. package/templates/.workspace-templates/skills/tooling/SKILL.md +87 -0
  164. package/templates/.workspace-templates/skills/validation/SKILL.md +103 -0
  165. package/templates/.workspace-templates/skills/worker/SKILL.md +79 -0
  166. package/templates/.workspace-templates/workspace/00-meta/CONTEXT.md +6 -0
  167. package/templates/.workspace-templates/workspace/00-meta/execution-log.md +27 -0
  168. package/templates/.workspace-templates/workspace/01-input/CONTEXT.md +29 -0
  169. package/templates/.workspace-templates/workspace/02-process/CONTEXT.md +29 -0
  170. package/templates/.workspace-templates/workspace/03-output/CONTEXT.md +29 -0
  171. package/templates/.workspace-templates/workspace/README.md +14 -0
  172. package/templates/SKILL.md +347 -0
  173. package/tests/benchmark.test.ts +158 -0
  174. package/tests/cli.test.ts +109 -0
  175. package/tests/dispatch-parallel.test.ts +124 -0
  176. package/tests/dispatch.test.ts +218 -0
  177. package/tests/fixer-skill.test.ts +203 -0
  178. package/tests/generate-tests.test.ts +101 -0
  179. package/tests/install-tool.test.ts +141 -0
  180. package/tests/install.test.ts +144 -0
  181. package/tests/integration.test.ts +324 -0
  182. package/tests/iterate.test.ts +219 -0
  183. package/tests/orchestrator.test.ts +710 -0
  184. package/tests/scaffold.test.ts +238 -0
  185. package/tests/templates-enhanced.test.ts +208 -0
  186. package/tests/templates.test.ts +219 -0
  187. package/tests/validate.test.ts +421 -0
  188. package/tests/validation-enhanced.test.ts +303 -0
  189. package/tests/worker-skill.test.ts +88 -0
  190. package/tsconfig.json +19 -0
  191. package/workspace/00-meta/CONTEXT.md +3 -0
  192. package/workspace/00-meta/execution-log.md +17 -0
  193. package/workspace/00-meta/tools.md +11 -0
  194. package/workspace/01-input/CONTEXT.md +27 -0
  195. package/workspace/CONTEXT.md +35 -0
  196. package/workspace/README.md +14 -0
  197. package/workspace/SYSTEM.md +36 -0
  198. package/workspace-maxxing-0.1.0.tgz +0 -0
@@ -0,0 +1,421 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import * as os from 'os';
4
+ import { validateWorkspace, ValidationResult } from '../src/scripts/validate';
5
+
6
+ describe('validate', () => {
7
+ let tempDir: string;
8
+
9
+ beforeEach(() => {
10
+ tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'validate-test-'));
11
+ });
12
+
13
+ afterEach(() => {
14
+ fs.rmSync(tempDir, { recursive: true, force: true });
15
+ });
16
+
17
+ function createValidWorkspace(): string {
18
+ const ws = path.join(tempDir, 'workspace');
19
+ fs.mkdirSync(ws, { recursive: true });
20
+
21
+ fs.writeFileSync(path.join(ws, 'SYSTEM.md'), [
22
+ '# Test',
23
+ '',
24
+ '## Role',
25
+ 'Workspace role.',
26
+ '',
27
+ '## Folder Map',
28
+ '- `01-input/`',
29
+ '- `02-output/`',
30
+ '',
31
+ '## Workflow Rules',
32
+ 'Follow selective loading and canonical source rules.',
33
+ '',
34
+ '## Scope Guardrails',
35
+ 'Create markdown workflow artifacts only; do not implement product code in stage folders.',
36
+ '',
37
+ '## Sequential Execution Protocol',
38
+ 'Complete stages in numerical order and record completion in 00-meta/execution-log.md.',
39
+ '',
40
+ '## Stage Boundaries',
41
+ 'One-way dependencies only.',
42
+ '',
43
+ '## Tooling Policy',
44
+ 'Use tools.md for inventory.',
45
+ '',
46
+ ].join('\n'));
47
+
48
+ fs.writeFileSync(path.join(ws, 'CONTEXT.md'), [
49
+ '# Router',
50
+ '',
51
+ '## How to Use This File',
52
+ 'Route tasks by stage.',
53
+ '',
54
+ '## Task Routing',
55
+ '- 01-input/CONTEXT.md',
56
+ '- 02-output/CONTEXT.md',
57
+ '',
58
+ '## Loading Order',
59
+ '1. SYSTEM.md',
60
+ '2. CONTEXT.md',
61
+ '3. Stage CONTEXT.md',
62
+ '4. Only the task files needed',
63
+ '',
64
+ '## Scope Guardrails',
65
+ 'Route domain requests into markdown workflow design outputs only.',
66
+ '',
67
+ '## Sequential Routing Contract',
68
+ 'Never route directly to later stages before earlier stage completion is logged.',
69
+ '',
70
+ '## Stage Handoff Routing',
71
+ '01-input -> 02-output',
72
+ '',
73
+ '## Escalation',
74
+ 'Escalate when routing is ambiguous.',
75
+ '',
76
+ '## Routing Table',
77
+ 'Compatibility marker for legacy checks.',
78
+ '',
79
+ ].join('\n'));
80
+
81
+ fs.mkdirSync(path.join(ws, '01-input'), { recursive: true });
82
+ fs.writeFileSync(path.join(ws, '01-input', 'CONTEXT.md'), [
83
+ '# 01-input',
84
+ '',
85
+ '## Purpose',
86
+ 'Input stage.',
87
+ '',
88
+ '## Inputs',
89
+ 'Raw data.',
90
+ '',
91
+ '## Outputs',
92
+ 'Validated data.',
93
+ '',
94
+ '## Dependencies',
95
+ 'None.',
96
+ '',
97
+ '## Required Evidence',
98
+ '- Update 00-meta/execution-log.md for 01-input completion',
99
+ '',
100
+ '## Completion Criteria',
101
+ 'Inputs validated.',
102
+ '',
103
+ '## Handoff',
104
+ 'Hand off to 02-output.',
105
+ '',
106
+ ].join('\n'));
107
+
108
+ fs.mkdirSync(path.join(ws, '02-output'), { recursive: true });
109
+ fs.writeFileSync(path.join(ws, '02-output', 'CONTEXT.md'), [
110
+ '# 02-output',
111
+ '',
112
+ '## Purpose',
113
+ 'Output stage.',
114
+ '',
115
+ '## Inputs',
116
+ 'Validated data.',
117
+ '',
118
+ '## Outputs',
119
+ 'Final report.',
120
+ '',
121
+ '## Dependencies',
122
+ '01-input.',
123
+ '',
124
+ '## Required Evidence',
125
+ '- Update 00-meta/execution-log.md for 02-output completion',
126
+ '',
127
+ '## Completion Criteria',
128
+ 'Output complete.',
129
+ '',
130
+ '## Handoff',
131
+ 'Deliver final output.',
132
+ '',
133
+ ].join('\n'));
134
+
135
+ fs.mkdirSync(path.join(ws, '00-meta'), { recursive: true });
136
+ fs.writeFileSync(path.join(ws, '00-meta', 'CONTEXT.md'), '# 00-meta\n\nMeta content.\n');
137
+ fs.writeFileSync(path.join(ws, '00-meta', 'tools.md'), '# Tools\n\n| Tool | Version |\n|------|---------|\n');
138
+ fs.writeFileSync(path.join(ws, '00-meta', 'execution-log.md'), [
139
+ '# Execution Log',
140
+ '',
141
+ '## Stage Checklist',
142
+ '- [ ] 01-input',
143
+ '- [ ] 02-output',
144
+ '',
145
+ ].join('\n'));
146
+
147
+ // Agent-driven test-cases (required by validator)
148
+ const agentsIter = path.join(ws, '.agents', 'iteration');
149
+ fs.mkdirSync(agentsIter, { recursive: true });
150
+ const testCasesPayload = [
151
+ { id: 'tc-001', title: 'sample', input: { type: 'text', payload: 'a' }, expected: { matcher: 'equals', criteria: ['a'] }, metadata: { priority: 'high' } },
152
+ ];
153
+ fs.writeFileSync(path.join(agentsIter, 'test-cases.json'), JSON.stringify(testCasesPayload, null, 2));
154
+ fs.writeFileSync(path.join(agentsIter, '.test-cases-ready'), 'ready');
155
+
156
+ return ws;
157
+ }
158
+
159
+ describe('validateWorkspace', () => {
160
+ it('passes for a valid workspace', () => {
161
+ const ws = createValidWorkspace();
162
+ const result = validateWorkspace(ws);
163
+
164
+ expect(result.passed).toBe(true);
165
+ expect(result.checks.every((c) => c.passed)).toBe(true);
166
+ });
167
+
168
+ it('fails if SYSTEM.md is missing', () => {
169
+ const ws = createValidWorkspace();
170
+ fs.unlinkSync(path.join(ws, 'SYSTEM.md'));
171
+
172
+ const result = validateWorkspace(ws);
173
+
174
+ expect(result.passed).toBe(false);
175
+ const systemCheck = result.checks.find((c) => c.name === 'SYSTEM.md exists');
176
+ expect(systemCheck?.passed).toBe(false);
177
+ });
178
+
179
+ it('fails if SYSTEM.md has no folder map', () => {
180
+ const ws = createValidWorkspace();
181
+ fs.writeFileSync(path.join(ws, 'SYSTEM.md'), '# Test\n\nNo directory listing here.\n');
182
+
183
+ const result = validateWorkspace(ws);
184
+
185
+ expect(result.passed).toBe(false);
186
+ const check = result.checks.find((c) => c.name.includes('folder map'));
187
+ expect(check?.passed).toBe(false);
188
+ });
189
+
190
+ it('fails when SYSTEM.md misses required workflow sections', () => {
191
+ const ws = createValidWorkspace();
192
+ fs.writeFileSync(path.join(ws, 'SYSTEM.md'), '# Test\n\n## Role\nRole only\n');
193
+
194
+ const result = validateWorkspace(ws);
195
+
196
+ expect(result.passed).toBe(false);
197
+ expect(result.checks.some((c) => c.name.includes('SYSTEM.md contains ## Workflow Rules') && !c.passed)).toBe(true);
198
+ });
199
+
200
+ it('fails when root CONTEXT.md misses required router sections', () => {
201
+ const ws = createValidWorkspace();
202
+ fs.writeFileSync(path.join(ws, 'CONTEXT.md'), '# Router\n\n## Task Routing\n- 01-input/CONTEXT.md\n');
203
+
204
+ const result = validateWorkspace(ws);
205
+
206
+ expect(result.passed).toBe(false);
207
+ expect(result.checks.some((c) => c.name.includes('CONTEXT.md contains ## Loading Order') && !c.passed)).toBe(true);
208
+ });
209
+
210
+ it('fails when stage CONTEXT.md misses completion and handoff sections', () => {
211
+ const ws = createValidWorkspace();
212
+ fs.writeFileSync(path.join(ws, '01-input', 'CONTEXT.md'), '# 01-input\n\n## Purpose\nInput stage\n');
213
+
214
+ const result = validateWorkspace(ws);
215
+
216
+ expect(result.passed).toBe(false);
217
+ expect(result.checks.some((c) => c.name.includes('01-input/CONTEXT.md contains ## Completion Criteria') && !c.passed)).toBe(true);
218
+ expect(result.checks.some((c) => c.name.includes('01-input/CONTEXT.md contains ## Handoff') && !c.passed)).toBe(true);
219
+ });
220
+
221
+ it('fails when execution log is missing', () => {
222
+ const ws = createValidWorkspace();
223
+ fs.unlinkSync(path.join(ws, '00-meta', 'execution-log.md'));
224
+
225
+ const result = validateWorkspace(ws);
226
+
227
+ expect(result.passed).toBe(false);
228
+ expect(result.checks.some((c) => c.name.includes('00-meta/execution-log.md exists') && !c.passed)).toBe(true);
229
+ });
230
+
231
+ it('fails when execution log marks later stage complete before earlier stage', () => {
232
+ const ws = createValidWorkspace();
233
+ fs.writeFileSync(path.join(ws, '00-meta', 'execution-log.md'), [
234
+ '# Execution Log',
235
+ '',
236
+ '## Stage Checklist',
237
+ '- [ ] 01-input',
238
+ '- [x] 02-output',
239
+ '',
240
+ ].join('\n'));
241
+
242
+ const result = validateWorkspace(ws);
243
+
244
+ expect(result.passed).toBe(false);
245
+ expect(result.checks.some((c) => c.name.includes('Execution log stage completion order is sequential') && !c.passed)).toBe(true);
246
+ });
247
+
248
+ it('fails when root routing misses a numbered stage folder', () => {
249
+ const ws = createValidWorkspace();
250
+ fs.writeFileSync(path.join(ws, 'CONTEXT.md'), [
251
+ '# Router',
252
+ '',
253
+ '## How to Use This File',
254
+ 'Route tasks by stage.',
255
+ '',
256
+ '## Task Routing',
257
+ '- 01-input/CONTEXT.md',
258
+ '',
259
+ '## Loading Order',
260
+ '1. SYSTEM.md',
261
+ '2. CONTEXT.md',
262
+ '3. Stage CONTEXT.md',
263
+ '4. Only the task files needed',
264
+ '',
265
+ '## Stage Handoff Routing',
266
+ '01-input -> 02-output',
267
+ '',
268
+ '## Escalation',
269
+ 'Escalate when routing is ambiguous.',
270
+ '',
271
+ ].join('\n'));
272
+
273
+ const result = validateWorkspace(ws);
274
+
275
+ expect(result.passed).toBe(false);
276
+ expect(result.checks.some((c) => c.name.includes('Root routing references all numbered stages') && !c.passed)).toBe(true);
277
+ });
278
+
279
+ it('fails when stage dependencies point to a later stage number', () => {
280
+ const ws = createValidWorkspace();
281
+ fs.writeFileSync(path.join(ws, '01-input', 'CONTEXT.md'), [
282
+ '# 01-input',
283
+ '',
284
+ '## Purpose',
285
+ 'Input stage.',
286
+ '',
287
+ '## Inputs',
288
+ 'Raw data.',
289
+ '',
290
+ '## Outputs',
291
+ 'Validated data.',
292
+ '',
293
+ '## Dependencies',
294
+ '02-output',
295
+ '',
296
+ '## Completion Criteria',
297
+ 'Inputs validated.',
298
+ '',
299
+ '## Handoff',
300
+ 'Hand off to 02-output.',
301
+ '',
302
+ ].join('\n'));
303
+
304
+ const result = validateWorkspace(ws);
305
+
306
+ expect(result.passed).toBe(false);
307
+ expect(result.checks.some((c) => c.name.includes('01-input dependencies do not point to later stages') && !c.passed)).toBe(true);
308
+ });
309
+
310
+ it('fails if CONTEXT.md is missing at root', () => {
311
+ const ws = createValidWorkspace();
312
+ fs.unlinkSync(path.join(ws, 'CONTEXT.md'));
313
+
314
+ const result = validateWorkspace(ws);
315
+
316
+ expect(result.passed).toBe(false);
317
+ const check = result.checks.find((c) => c.name.includes('CONTEXT.md exists'));
318
+ expect(check?.passed).toBe(false);
319
+ });
320
+
321
+ it('fails if a numbered folder is missing CONTEXT.md', () => {
322
+ const ws = createValidWorkspace();
323
+ fs.unlinkSync(path.join(ws, '01-input', 'CONTEXT.md'));
324
+
325
+ const result = validateWorkspace(ws);
326
+
327
+ expect(result.passed).toBe(false);
328
+ const check = result.checks.find((c) => c.name === '01-input/CONTEXT.md exists');
329
+ expect(check?.passed).toBe(false);
330
+ });
331
+
332
+ it('fails if a CONTEXT.md is empty', () => {
333
+ const ws = createValidWorkspace();
334
+ fs.writeFileSync(path.join(ws, '01-input', 'CONTEXT.md'), '');
335
+
336
+ const result = validateWorkspace(ws);
337
+
338
+ expect(result.passed).toBe(false);
339
+ const check = result.checks.find((c) => c.name === '01-input/CONTEXT.md is not empty');
340
+ expect(check?.passed).toBe(false);
341
+ });
342
+
343
+ it('fails if duplicate content exists across files', () => {
344
+ const ws = createValidWorkspace();
345
+ const duplicateText = 'This is a long duplicate text block that appears in multiple files and should be flagged as a potential duplicate content issue for testing purposes.';
346
+ fs.appendFileSync(path.join(ws, '01-input', 'CONTEXT.md'), duplicateText);
347
+ fs.appendFileSync(path.join(ws, '02-output', 'CONTEXT.md'), duplicateText);
348
+
349
+ const result = validateWorkspace(ws);
350
+
351
+ expect(result.passed).toBe(false);
352
+ const check = result.checks.find((c) => c.name.includes('duplicate'));
353
+ expect(check?.passed).toBe(false);
354
+ });
355
+
356
+ it('fails when numbered stage folders contain product source code files', () => {
357
+ const ws = createValidWorkspace();
358
+ fs.writeFileSync(path.join(ws, '01-input', 'predictor.py'), 'print("not markdown")\n');
359
+
360
+ const result = validateWorkspace(ws);
361
+
362
+ expect(result.passed).toBe(false);
363
+ expect(result.checks.some((c) => c.name.includes('contains no product source code files') && !c.passed)).toBe(true);
364
+ });
365
+
366
+ it('returns structured output with all check names', () => {
367
+ const ws = createValidWorkspace();
368
+ const result = validateWorkspace(ws);
369
+
370
+ const checkNames = result.checks.map((c) => c.name);
371
+ expect(checkNames).toContain('SYSTEM.md exists');
372
+ expect(checkNames).toContain('CONTEXT.md exists at root');
373
+ });
374
+
375
+ it('fails when agent-driven test-cases are missing', () => {
376
+ const ws = createValidWorkspace();
377
+ // remove agent-generated test-cases
378
+ fs.rmSync(path.join(ws, '.agents', 'iteration'), { recursive: true, force: true });
379
+
380
+ const result = validateWorkspace(ws);
381
+ expect(result.passed).toBe(false);
382
+ expect(result.checks.some((c) => c.name.includes('test-cases.json exists') && !c.passed)).toBe(true);
383
+ });
384
+
385
+ it('fails when test-cases readiness marker is missing', () => {
386
+ const ws = createValidWorkspace();
387
+ fs.unlinkSync(path.join(ws, '.agents', 'iteration', '.test-cases-ready'));
388
+
389
+ const result = validateWorkspace(ws);
390
+
391
+ expect(result.passed).toBe(false);
392
+ expect(result.checks.some((c) => c.name.includes('.test-cases-ready exists') && !c.passed)).toBe(true);
393
+ });
394
+
395
+ it('fails when test-cases.json is malformed JSON', () => {
396
+ const ws = createValidWorkspace();
397
+ fs.writeFileSync(path.join(ws, '.agents', 'iteration', 'test-cases.json'), '{ not-valid-json }');
398
+
399
+ const result = validateWorkspace(ws);
400
+
401
+ expect(result.passed).toBe(false);
402
+ expect(result.checks.some((c) => c.name.includes('parseable JSON') && !c.passed)).toBe(true);
403
+ });
404
+
405
+ it('fails when test-cases.json items miss required fields', () => {
406
+ const ws = createValidWorkspace();
407
+ fs.writeFileSync(
408
+ path.join(ws, '.agents', 'iteration', 'test-cases.json'),
409
+ JSON.stringify([
410
+ { id: 'tc-001', input: { type: 'text', payload: 'a' }, expected: { matcher: 'equals' } },
411
+ { id: 'tc-002', input: { type: 'text', payload: 'b' } },
412
+ ], null, 2),
413
+ );
414
+
415
+ const result = validateWorkspace(ws);
416
+
417
+ expect(result.passed).toBe(false);
418
+ expect(result.checks.some((c) => c.name.includes('items have minimal fields') && !c.passed)).toBe(true);
419
+ });
420
+ });
421
+ });