maestro-flow 0.4.20 → 0.4.21

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 (136) hide show
  1. package/.agents/skills/maestro-ralph-execute/SKILL.md +2 -1
  2. package/.agents/skills/maestro-swarm-workflow/SKILL.md +27 -19
  3. package/.agents/skills/maestro-universal-workflow/SKILL.md +563 -0
  4. package/.agents/skills/team-adversarial-swarm/SKILL.md +235 -0
  5. package/.agents/skills/team-adversarial-swarm/scripts/aco.py +473 -0
  6. package/.agents/skills/team-adversarial-swarm/scripts/pheromone.py +144 -0
  7. package/.agents/skills/team-adversarial-swarm/scripts/scoring.py +92 -0
  8. package/.agents/skills/team-adversarial-swarm/scripts/test_aco.py +475 -0
  9. package/.agents/skills/team-adversarial-swarm/specs/ant-output-schema.md +115 -0
  10. package/.agents/skills/team-adversarial-swarm/specs/convergence-criteria.md +75 -0
  11. package/.agents/skills/team-adversarial-swarm/specs/pheromone-schema.md +90 -0
  12. package/.agents/skills/team-adversarial-swarm/specs/swarm-config-template.json +66 -0
  13. package/.agents/skills/team-adversarial-swarm/specs/swarm-protocol.md +105 -0
  14. package/.agents/skills/team-adversarial-swarm/workflows/wf-swarm-converge.js +197 -0
  15. package/.agents/skills/team-adversarial-swarm/workflows/wf-swarm-explore.js +194 -0
  16. package/.agents/skills/team-adversarial-swarm/workflows/wf-swarm-score.js +188 -0
  17. package/.agents/skills/team-adversarial-swarm/workflows/wf-swarm-synthesize.js +248 -0
  18. package/.agy/skills/maestro-ralph-execute/SKILL.md +2 -1
  19. package/.agy/skills/maestro-swarm-workflow/SKILL.md +27 -19
  20. package/.agy/skills/maestro-universal-workflow/SKILL.md +560 -0
  21. package/.agy/skills/team-adversarial-swarm/SKILL.md +244 -0
  22. package/.agy/skills/team-adversarial-swarm/scripts/aco.py +473 -0
  23. package/.agy/skills/team-adversarial-swarm/scripts/pheromone.py +144 -0
  24. package/.agy/skills/team-adversarial-swarm/scripts/scoring.py +92 -0
  25. package/.agy/skills/team-adversarial-swarm/scripts/test_aco.py +475 -0
  26. package/.agy/skills/team-adversarial-swarm/specs/ant-output-schema.md +115 -0
  27. package/.agy/skills/team-adversarial-swarm/specs/convergence-criteria.md +75 -0
  28. package/.agy/skills/team-adversarial-swarm/specs/pheromone-schema.md +90 -0
  29. package/.agy/skills/team-adversarial-swarm/specs/swarm-config-template.json +66 -0
  30. package/.agy/skills/team-adversarial-swarm/specs/swarm-protocol.md +105 -0
  31. package/.agy/skills/team-adversarial-swarm/workflows/wf-swarm-converge.js +197 -0
  32. package/.agy/skills/team-adversarial-swarm/workflows/wf-swarm-explore.js +194 -0
  33. package/.agy/skills/team-adversarial-swarm/workflows/wf-swarm-score.js +188 -0
  34. package/.agy/skills/team-adversarial-swarm/workflows/wf-swarm-synthesize.js +248 -0
  35. package/.claude/commands/maestro-ralph-execute.md +2 -1
  36. package/.claude/commands/maestro-swarm-workflow.md +27 -19
  37. package/.claude/commands/maestro-universal-workflow.md +561 -0
  38. package/.claude/skills/team-adversarial-swarm/SKILL.md +233 -0
  39. package/.claude/skills/team-adversarial-swarm/scripts/aco.py +473 -0
  40. package/.claude/skills/team-adversarial-swarm/scripts/pheromone.py +144 -0
  41. package/.claude/skills/team-adversarial-swarm/scripts/scoring.py +92 -0
  42. package/.claude/skills/team-adversarial-swarm/scripts/test_aco.py +475 -0
  43. package/.claude/skills/team-adversarial-swarm/specs/ant-output-schema.md +115 -0
  44. package/.claude/skills/team-adversarial-swarm/specs/convergence-criteria.md +75 -0
  45. package/.claude/skills/team-adversarial-swarm/specs/pheromone-schema.md +90 -0
  46. package/.claude/skills/team-adversarial-swarm/specs/swarm-config-template.json +66 -0
  47. package/.claude/skills/team-adversarial-swarm/specs/swarm-protocol.md +105 -0
  48. package/.claude/skills/team-adversarial-swarm/workflows/wf-swarm-converge.js +197 -0
  49. package/.claude/skills/team-adversarial-swarm/workflows/wf-swarm-explore.js +194 -0
  50. package/.claude/skills/team-adversarial-swarm/workflows/wf-swarm-score.js +188 -0
  51. package/.claude/skills/team-adversarial-swarm/workflows/wf-swarm-synthesize.js +248 -0
  52. package/dashboard/dist-server/dashboard/src/server/wiki/graph-analysis.js +1 -1
  53. package/dashboard/dist-server/dashboard/src/server/wiki/graph-analysis.js.map +1 -1
  54. package/dashboard/dist-server/dashboard/src/server/wiki/search.js +1 -1
  55. package/dashboard/dist-server/dashboard/src/server/wiki/search.js.map +1 -1
  56. package/dashboard/dist-server/dashboard/src/server/wiki/virtual-wiki-adapters.d.ts +1 -1
  57. package/dashboard/dist-server/dashboard/src/server/wiki/virtual-wiki-adapters.js +5 -5
  58. package/dashboard/dist-server/dashboard/src/server/wiki/virtual-wiki-adapters.js.map +1 -1
  59. package/dashboard/dist-server/dashboard/src/server/wiki/wiki-indexer.js +3 -3
  60. package/dashboard/dist-server/dashboard/src/server/wiki/wiki-indexer.js.map +1 -1
  61. package/dashboard/dist-server/src/graph/types.d.ts +111 -0
  62. package/dashboard/dist-server/src/graph/types.js +2 -0
  63. package/dashboard/dist-server/src/graph/types.js.map +1 -0
  64. package/dist/src/commands/install-backend.d.ts +0 -7
  65. package/dist/src/commands/install-backend.d.ts.map +1 -1
  66. package/dist/src/commands/install-backend.js +0 -14
  67. package/dist/src/commands/install-backend.js.map +1 -1
  68. package/dist/src/commands/install.d.ts.map +1 -1
  69. package/dist/src/commands/install.js +0 -18
  70. package/dist/src/commands/install.js.map +1 -1
  71. package/dist/src/commands/kg.d.ts +2 -2
  72. package/dist/src/commands/kg.d.ts.map +1 -1
  73. package/dist/src/commands/kg.js +150 -179
  74. package/dist/src/commands/kg.js.map +1 -1
  75. package/dist/src/graph/analyzers/fs-analyzer.d.ts +10 -0
  76. package/dist/src/graph/analyzers/fs-analyzer.d.ts.map +1 -0
  77. package/dist/src/graph/analyzers/fs-analyzer.js +959 -0
  78. package/dist/src/graph/analyzers/fs-analyzer.js.map +1 -0
  79. package/dist/src/graph/index.d.ts +6 -0
  80. package/dist/src/graph/index.d.ts.map +1 -0
  81. package/dist/src/graph/index.js +6 -0
  82. package/dist/src/graph/index.js.map +1 -0
  83. package/dist/src/graph/loader.d.ts +3 -0
  84. package/dist/src/graph/loader.d.ts.map +1 -0
  85. package/dist/src/graph/loader.js +12 -0
  86. package/dist/src/graph/loader.js.map +1 -0
  87. package/dist/src/graph/merger.d.ts +56 -0
  88. package/dist/src/graph/merger.d.ts.map +1 -0
  89. package/dist/src/graph/merger.js +896 -0
  90. package/dist/src/graph/merger.js.map +1 -0
  91. package/dist/src/graph/query.d.ts +7 -0
  92. package/dist/src/graph/query.d.ts.map +1 -0
  93. package/dist/src/graph/query.js +126 -0
  94. package/dist/src/graph/query.js.map +1 -0
  95. package/dist/src/graph/types.d.ts +112 -0
  96. package/dist/src/graph/types.d.ts.map +1 -0
  97. package/dist/src/graph/types.js +2 -0
  98. package/dist/src/graph/types.js.map +1 -0
  99. package/dist/src/i18n/locales/en.d.ts.map +1 -1
  100. package/dist/src/i18n/locales/en.js +0 -10
  101. package/dist/src/i18n/locales/en.js.map +1 -1
  102. package/dist/src/i18n/locales/zh.d.ts.map +1 -1
  103. package/dist/src/i18n/locales/zh.js +0 -10
  104. package/dist/src/i18n/locales/zh.js.map +1 -1
  105. package/dist/src/i18n/types.d.ts +0 -9
  106. package/dist/src/i18n/types.d.ts.map +1 -1
  107. package/dist/src/tui/install-ui/InstallConfirm.d.ts +0 -1
  108. package/dist/src/tui/install-ui/InstallConfirm.d.ts.map +1 -1
  109. package/dist/src/tui/install-ui/InstallConfirm.js +1 -1
  110. package/dist/src/tui/install-ui/InstallConfirm.js.map +1 -1
  111. package/dist/src/tui/install-ui/InstallExecution.d.ts +0 -1
  112. package/dist/src/tui/install-ui/InstallExecution.d.ts.map +1 -1
  113. package/dist/src/tui/install-ui/InstallExecution.js +0 -22
  114. package/dist/src/tui/install-ui/InstallExecution.js.map +1 -1
  115. package/dist/src/tui/install-ui/InstallFlow.d.ts +1 -1
  116. package/dist/src/tui/install-ui/InstallFlow.d.ts.map +1 -1
  117. package/dist/src/tui/install-ui/InstallFlow.js +5 -23
  118. package/dist/src/tui/install-ui/InstallFlow.js.map +1 -1
  119. package/dist/src/tui/install-ui/InstallHub.d.ts +0 -2
  120. package/dist/src/tui/install-ui/InstallHub.d.ts.map +1 -1
  121. package/dist/src/tui/install-ui/InstallHub.js +0 -6
  122. package/dist/src/tui/install-ui/InstallHub.js.map +1 -1
  123. package/dist/src/tui/install-ui/InstallResult.d.ts.map +1 -1
  124. package/dist/src/tui/install-ui/InstallResult.js +1 -1
  125. package/dist/src/tui/install-ui/InstallResult.js.map +1 -1
  126. package/dist/src/utils/update-notices.js +12 -0
  127. package/dist/src/utils/update-notices.js.map +1 -1
  128. package/package.json +1 -1
  129. package/workflows/swarm/wf-analyze.js +195 -34
  130. package/workflows/swarm/wf-brainstorm.js +225 -53
  131. package/workflows/swarm/wf-execute.js +199 -23
  132. package/workflows/swarm/wf-grill.js +181 -20
  133. package/workflows/swarm/wf-milestone-audit.js +178 -29
  134. package/workflows/swarm/wf-plan.js +288 -53
  135. package/workflows/swarm/wf-review.js +195 -80
  136. package/workflows/swarm/wf-verify.js +125 -28
@@ -1,11 +1,12 @@
1
1
  export const meta = {
2
2
  name: 'wf-plan',
3
- description: 'Parallel context exploration + task decomposition via workflow-planner',
4
- whenToUse: 'Accelerate maestro-plan with parallel context gathering and plan generation',
3
+ description: 'Parallel context + 3-proposal judge panel planning + 3-critic adversarial verification',
4
+ whenToUse: 'Accelerate maestro-plan with parallel context + competing plan proposals + multi-critic adversarial check',
5
5
  phases: [
6
6
  { title: 'Context', detail: 'Parallel context exploration from multiple sources' },
7
- { title: 'Plan', detail: 'Task decomposition and wave assignment via workflow-planner' },
8
- { title: 'Check', detail: 'Plan quality verification via workflow-plan-checker' },
7
+ { title: 'Compete', detail: '3 independent plan proposals from competing strategies' },
8
+ { title: 'Select', detail: 'Judge panel scores proposals and selects best' },
9
+ { title: 'Check', detail: '3 specialized critics (dependency/scope/quality) challenge the selected plan' },
9
10
  ],
10
11
  }
11
12
 
@@ -25,6 +26,7 @@ const CONTEXT_SCHEMA = {
25
26
  const PLAN_SCHEMA = {
26
27
  type: 'object',
27
28
  properties: {
29
+ strategy: { type: 'string' },
28
30
  summary: { type: 'string' },
29
31
  approach: { type: 'string' },
30
32
  complexity: { type: 'string', enum: ['low', 'medium', 'high'] },
@@ -58,14 +60,74 @@ const PLAN_SCHEMA = {
58
60
  },
59
61
  },
60
62
  total_tasks: { type: 'number' },
63
+ trade_offs: { type: 'string' },
64
+ confidence: { type: 'number', minimum: 0, maximum: 100 },
61
65
  },
62
- required: ['summary', 'approach', 'waves', 'total_tasks'],
66
+ required: ['strategy', 'summary', 'approach', 'waves', 'total_tasks', 'confidence'],
67
+ }
68
+
69
+ const PLAN_SCORE_SCHEMA = {
70
+ type: 'object',
71
+ properties: {
72
+ proposal_strategy: { type: 'string' },
73
+ scores: {
74
+ type: 'object',
75
+ properties: {
76
+ coverage: { type: 'number', minimum: 1, maximum: 5 },
77
+ parallelism: { type: 'number', minimum: 1, maximum: 5 },
78
+ risk_mitigation: { type: 'number', minimum: 1, maximum: 5 },
79
+ convergence_quality: { type: 'number', minimum: 1, maximum: 5 },
80
+ simplicity: { type: 'number', minimum: 1, maximum: 5 },
81
+ },
82
+ required: ['coverage', 'parallelism', 'risk_mitigation', 'convergence_quality', 'simplicity'],
83
+ },
84
+ total_score: { type: 'number' },
85
+ strengths: { type: 'array', items: { type: 'string' } },
86
+ weaknesses: { type: 'array', items: { type: 'string' } },
87
+ recommendation: { type: 'string' },
88
+ },
89
+ required: ['proposal_strategy', 'scores', 'total_score', 'strengths', 'weaknesses'],
90
+ }
91
+
92
+ const CRITIC_SCHEMA = {
93
+ type: 'object',
94
+ properties: {
95
+ critic_type: { type: 'string' },
96
+ verdict: { type: 'string', enum: ['pass', 'pass-with-notes', 'needs-revision'] },
97
+ issues: {
98
+ type: 'array',
99
+ items: {
100
+ type: 'object',
101
+ properties: {
102
+ severity: { type: 'string', enum: ['critical', 'warning', 'note'] },
103
+ category: { type: 'string' },
104
+ description: { type: 'string' },
105
+ affected_tasks: { type: 'array', items: { type: 'string' } },
106
+ suggestion: { type: 'string' },
107
+ },
108
+ required: ['severity', 'category', 'description'],
109
+ },
110
+ },
111
+ confidence: { type: 'number', minimum: 0, maximum: 100 },
112
+ summary: { type: 'string' },
113
+ },
114
+ required: ['critic_type', 'verdict', 'issues', 'confidence', 'summary'],
63
115
  }
64
116
 
65
117
  const CHECK_SCHEMA = {
66
118
  type: 'object',
67
119
  properties: {
68
120
  verdict: { type: 'string', enum: ['pass', 'pass-with-notes', 'needs-revision'] },
121
+ adversarial_outcome: {
122
+ type: 'object',
123
+ properties: {
124
+ dependency_verdict: { type: 'string' },
125
+ scope_verdict: { type: 'string' },
126
+ quality_verdict: { type: 'string' },
127
+ decisive_factor: { type: 'string' },
128
+ },
129
+ required: ['dependency_verdict', 'scope_verdict', 'quality_verdict', 'decisive_factor'],
130
+ },
69
131
  issues: {
70
132
  type: 'array',
71
133
  items: {
@@ -76,6 +138,7 @@ const CHECK_SCHEMA = {
76
138
  description: { type: 'string' },
77
139
  affected_tasks: { type: 'array', items: { type: 'string' } },
78
140
  suggestion: { type: 'string' },
141
+ source_critic: { type: 'string' },
79
142
  },
80
143
  required: ['severity', 'category', 'description'],
81
144
  },
@@ -92,12 +155,12 @@ const CHECK_SCHEMA = {
92
155
  },
93
156
  summary: { type: 'string' },
94
157
  },
95
- required: ['verdict', 'issues', 'summary'],
158
+ required: ['verdict', 'adversarial_outcome', 'issues', 'summary'],
96
159
  }
97
160
 
98
161
  const contextDir = args?.context_dir || ''
99
162
  const fromSource = args?.from || ''
100
- const phase_num = args?.phase || null
163
+ const phaseNum = args?.phase || null
101
164
  const scope = args?.scope || ''
102
165
  const specs = args?.specs || ''
103
166
  const gaps = args?.gaps || false
@@ -112,7 +175,7 @@ const contextSources = [
112
175
  `Load analysis context for planning.
113
176
  ${contextDir ? 'Context directory: ' + contextDir + ' — read context.md and context-package.json' : ''}
114
177
  ${fromSource ? 'Upstream source: ' + fromSource + ' — resolve and load context-package.json' : ''}
115
- ${phase_num ? 'Phase: ' + phase_num + ' — read roadmap.md for phase definition' : ''}
178
+ ${phaseNum ? 'Phase: ' + phaseNum + ' — read roadmap.md for phase definition' : ''}
116
179
  ${gaps ? 'Gap-fix mode: load issues from .workflow/issues/issues.jsonl with analysis records' : ''}
117
180
 
118
181
  Extract:
@@ -124,7 +187,7 @@ Extract:
124
187
  ),
125
188
  () => agent(
126
189
  `Explore existing codebase patterns relevant to the planned work.
127
- ${scope ? 'Scope: ' + scope : phase_num ? 'Phase ' + phase_num + ' scope from roadmap' : 'Full project'}
190
+ ${scope ? 'Scope: ' + scope : phaseNum ? 'Phase ' + phaseNum + ' scope from roadmap' : 'Full project'}
128
191
  ${specs ? 'Specs to respect: ' + specs : 'Load via: maestro spec load --category arch'}
129
192
 
130
193
  Find:
@@ -149,10 +212,6 @@ const mergedConstraints = validContexts.flatMap(c => c.constraints || [])
149
212
 
150
213
  log(`Context gathered: ${mergedDecisions.length} decisions, ${mergedRequirements.length} requirements, ${mergedPatterns.length} patterns`)
151
214
 
152
- // Phase 2: Plan generation via workflow-planner
153
- phase('Plan')
154
- log('Generating execution plan with task decomposition...')
155
-
156
215
  const contextDigest = `Decisions (${mergedDecisions.length}):
157
216
  ${mergedDecisions.map(d => `- [${d.status}] ${d.decision}${d.rationale ? ' — ' + d.rationale : ''}`).join('\n')}
158
217
 
@@ -164,69 +223,245 @@ Constraints: ${mergedConstraints.join('; ') || 'none'}
164
223
  Existing patterns:
165
224
  ${mergedPatterns.map(p => `- ${p.pattern} @ ${p.file}`).join('\n') || 'none found'}`
166
225
 
167
- const plan = await agent(
168
- `Create an execution plan from the following context.
169
- ${phase_num ? 'Phase: ' + phase_num : ''}
226
+ // Phase 2: 3 competing plan proposals from different strategies
227
+ phase('Compete')
228
+ log('Launching 3 competing plan proposals...')
229
+
230
+ const planProposals = await parallel([
231
+ () => agent(
232
+ `Create an execution plan using BREADTH-FIRST strategy.
233
+ ${phaseNum ? 'Phase: ' + phaseNum : ''}
170
234
  ${scope ? 'Scope: ' + scope : ''}
171
- ${quick ? 'MODE: QUICK one task per feature, minimal waves, fast execution' : 'MODE: STANDARD — full decomposition with convergence criteria'}
172
- ${gaps ? 'MODE: GAP-FIX tasks fix identified issues, link via issue_id' : ''}
235
+ ${quick ? 'QUICK mode: minimize tasks' : ''}
236
+ ${gaps ? 'GAP-FIX mode: tasks fix identified issues' : ''}
237
+
238
+ Context:\n${contextDigest}
239
+
240
+ Strategy: BREADTH-FIRST
241
+ - Maximize parallelism: put as many tasks as possible in wave 1
242
+ - Minimize dependencies between tasks
243
+ - Prefer many small independent tasks over fewer large sequential ones
244
+ - Trade off: may have more integration work later but faster early progress
173
245
 
174
- Context:
175
- ${contextDigest}
246
+ Set strategy="breadth-first" in output.
176
247
 
177
248
  Rules:
178
- 1. Group work into FEATURE-LEVEL tasks (one feature = one task, even if 3-5 files)
179
- 2. Assign independent tasks to same wave (parallel execution)
180
- 3. Dependent tasks in later waves only add depends_on when truly needed
181
- 4. Each task needs ≥2 testable convergence criteria (grep-verifiable or command-runnable)
182
- 5. Include focus_paths and files[] with specific paths and actions
183
- 6. Respect all Locked decisions they are non-negotiable
184
- 7. Free decisions are implementer's choice — don't over-specify
185
- 8. Task IDs: TASK-001, TASK-002, etc.
186
-
187
- ${quick ? 'Quick mode: single wave unless genuine dependency. Batch unrelated small changes into one task.' : ''}`,
188
- { label: 'plan:generate', phase: 'Plan', schema: PLAN_SCHEMA, agentType: 'workflow-planner' }
249
+ 1. Feature-level tasks (one feature = one task)
250
+ 2. Each task needs >=2 testable convergence criteria
251
+ 3. Include focus_paths and files[] with specific paths
252
+ 4. Respect Locked decisions
253
+ 5. Task IDs: TASK-001, TASK-002, etc.`,
254
+ { label: 'plan:breadth', phase: 'Compete', schema: PLAN_SCHEMA, agentType: 'workflow-planner' }
255
+ ),
256
+ () => agent(
257
+ `Create an execution plan using DEPTH-FIRST strategy.
258
+ ${phaseNum ? 'Phase: ' + phaseNum : ''}
259
+ ${scope ? 'Scope: ' + scope : ''}
260
+ ${quick ? 'QUICK mode: minimize tasks' : ''}
261
+ ${gaps ? 'GAP-FIX mode: tasks fix identified issues' : ''}
262
+
263
+ Context:\n${contextDigest}
264
+
265
+ Strategy: DEPTH-FIRST
266
+ - Build foundation first: core infrastructure in wave 1, features on top in wave 2+
267
+ - Strong dependency chains ensure solid base before building up
268
+ - Fewer tasks per wave but each fully tested before moving on
269
+ - Trade off: slower start but less rework and integration issues
270
+
271
+ Set strategy="depth-first" in output.
272
+
273
+ Rules:
274
+ 1. Feature-level tasks (one feature = one task)
275
+ 2. Each task needs >=2 testable convergence criteria
276
+ 3. Include focus_paths and files[] with specific paths
277
+ 4. Respect Locked decisions
278
+ 5. Task IDs: TASK-001, TASK-002, etc.`,
279
+ { label: 'plan:depth', phase: 'Compete', schema: PLAN_SCHEMA, agentType: 'workflow-planner' }
280
+ ),
281
+ () => agent(
282
+ `Create an execution plan using RISK-FIRST strategy.
283
+ ${phaseNum ? 'Phase: ' + phaseNum : ''}
284
+ ${scope ? 'Scope: ' + scope : ''}
285
+ ${quick ? 'QUICK mode: minimize tasks' : ''}
286
+ ${gaps ? 'GAP-FIX mode: tasks fix identified issues' : ''}
287
+
288
+ Context:\n${contextDigest}
289
+
290
+ Strategy: RISK-FIRST
291
+ - Tackle highest-risk items first (complex integrations, uncertain requirements, new patterns)
292
+ - Wave 1 = risk spikes and proof-of-concepts
293
+ - Wave 2+ = validated features building on proven foundations
294
+ - Trade off: may seem slow early but catches showstoppers before heavy investment
295
+
296
+ Set strategy="risk-first" in output.
297
+
298
+ Rules:
299
+ 1. Feature-level tasks (one feature = one task)
300
+ 2. Each task needs >=2 testable convergence criteria
301
+ 3. Include focus_paths and files[] with specific paths
302
+ 4. Respect Locked decisions
303
+ 5. Task IDs: TASK-001, TASK-002, etc.`,
304
+ { label: 'plan:risk', phase: 'Compete', schema: PLAN_SCHEMA, agentType: 'workflow-planner' }
305
+ ),
306
+ ])
307
+
308
+ const validProposals = planProposals.filter(Boolean)
309
+ log(`${validProposals.length} competing plans generated`)
310
+
311
+ // Judge panel scores each proposal
312
+ phase('Select')
313
+ log('Judge panel scoring proposals...')
314
+
315
+ const judgeScores = await parallel(
316
+ validProposals.map(proposal => () =>
317
+ agent(
318
+ `Score this plan proposal objectively.
319
+
320
+ Strategy: ${proposal.strategy}
321
+ Summary: ${proposal.summary}
322
+ Approach: ${proposal.approach}
323
+ Complexity: ${proposal.complexity}
324
+ Tasks: ${proposal.total_tasks} across ${proposal.waves.length} waves
325
+ Trade-offs: ${proposal.trade_offs || 'not stated'}
326
+
327
+ Wave breakdown:
328
+ ${proposal.waves.map(w => `Wave ${w.wave_index} (${w.tasks.length} tasks): ${w.tasks.map(t => t.task_id + ': ' + t.title).join(', ')}`).join('\n')}
329
+
330
+ Requirements to cover:
331
+ ${mergedRequirements.map(r => r.objective).join('\n')}
332
+
333
+ Score each dimension 1-5:
334
+ - coverage: do tasks cover all requirements?
335
+ - parallelism: how much work can run concurrently?
336
+ - risk_mitigation: are high-risk items addressed early?
337
+ - convergence_quality: are criteria specific and testable?
338
+ - simplicity: is the plan as simple as possible?
339
+
340
+ Calculate total_score = sum of all dimensions.
341
+ List specific strengths and weaknesses.`,
342
+ { label: `judge:${proposal.strategy}`, phase: 'Select', schema: PLAN_SCORE_SCHEMA }
343
+ )
344
+ )
189
345
  )
190
346
 
191
- log(`Plan generated: ${plan ? plan.total_tasks : 0} tasks across ${plan ? plan.waves.length : 0} waves`)
347
+ const validJudges = judgeScores.filter(Boolean)
348
+ const bestIdx = validJudges.reduce((best, score, idx) => score.total_score > (validJudges[best] ? validJudges[best].total_score : 0) ? idx : best, 0)
349
+ const selectedPlan = validProposals[bestIdx]
350
+
351
+ const scoreDigest = validJudges.map((s, i) =>
352
+ `${validProposals[i].strategy}: ${s.total_score}/25 (cov:${s.scores.coverage} par:${s.scores.parallelism} risk:${s.scores.risk_mitigation} conv:${s.scores.convergence_quality} sim:${s.scores.simplicity})`
353
+ ).join('\n')
192
354
 
193
- // Phase 3: Plan quality check
355
+ log(`Selected: ${selectedPlan.strategy} (${validJudges[bestIdx].total_score}/25)\n${scoreDigest}`)
356
+
357
+ // Phase 4: 3 specialized critics challenge the selected plan
194
358
  phase('Check')
195
- log('Verifying plan quality...')
359
+ log('3 specialized critics challenging the selected plan...')
360
+
361
+ const criticResults = await parallel([
362
+ () => agent(
363
+ `You are the DEPENDENCY CRITIC. Challenge the task dependency structure.
364
+
365
+ Selected plan (${selectedPlan.strategy}):
366
+ ${selectedPlan.waves.map(w => `Wave ${w.wave_index}: ${w.tasks.map(t => t.task_id + ': ' + t.title + ' [depends: ' + (t.depends_on || []).join(',') + ']').join(', ')}`).join('\n')}
367
+
368
+ Focus:
369
+ 1. Are depends_on relationships correct? Any missing dependencies?
370
+ 2. Could more tasks be parallelized (false dependencies)?
371
+ 3. Are there circular or impossible dependency chains?
372
+ 4. Do later waves actually need ALL prior wave completions?
373
+ 5. Are file modification conflicts between parallel tasks?
374
+
375
+ Set critic_type="dependency" in output.
376
+ Be adversarial — assume dependencies are WRONG until proven correct.`,
377
+ { label: 'critic:dependency', phase: 'Check', schema: CRITIC_SCHEMA, agentType: 'workflow-plan-checker' }
378
+ ),
379
+ () => agent(
380
+ `You are the SCOPE CRITIC. Challenge the plan's coverage and boundaries.
381
+
382
+ Selected plan (${selectedPlan.strategy}):
383
+ ${selectedPlan.waves.map(w => `Wave ${w.wave_index}: ${w.tasks.map(t => t.task_id + ': ' + t.title).join(', ')}`).join('\n')}
384
+
385
+ Requirements:
386
+ ${mergedRequirements.map(r => `- ${r.objective}`).join('\n')}
387
+
388
+ Focus:
389
+ 1. Are there requirements without corresponding tasks?
390
+ 2. Are there tasks that don't map to any requirement (scope creep)?
391
+ 3. Is each task properly scoped (not too large, not too granular)?
392
+ 4. Are edge cases and error paths covered?
393
+ 5. Does the plan handle the Free decisions appropriately?
394
+
395
+ Set critic_type="scope" in output.
396
+ Be adversarial — assume requirements are NOT fully covered.`,
397
+ { label: 'critic:scope', phase: 'Check', schema: CRITIC_SCHEMA, agentType: 'workflow-plan-checker' }
398
+ ),
399
+ () => agent(
400
+ `You are the QUALITY CRITIC. Challenge the convergence criteria and testability.
401
+
402
+ Selected plan (${selectedPlan.strategy}):
403
+ ${selectedPlan.waves.map(w => `Wave ${w.wave_index}: ${w.tasks.map(t => t.task_id + ': ' + t.title + ' [criteria: ' + (t.convergence_criteria || []).join(' | ') + ']').join('\n')}`).join('\n')}
404
+
405
+ Focus:
406
+ 1. Are convergence criteria SPECIFIC and TESTABLE (grep-verifiable or command-runnable)?
407
+ 2. Would a robot be able to verify each criterion unambiguously?
408
+ 3. Are there vague criteria ("works correctly", "properly implemented")?
409
+ 4. Is each task's convergence achievable within that task's scope?
410
+ 5. Are there criteria that should exist but don't?
411
+
412
+ Set critic_type="quality" in output.
413
+ Be adversarial — assume criteria are VAGUE until proven specific.`,
414
+ { label: 'critic:quality', phase: 'Check', schema: CRITIC_SCHEMA, agentType: 'workflow-plan-checker' }
415
+ ),
416
+ ])
417
+
418
+ const validCritics = criticResults.filter(Boolean)
419
+ const criticDigest = validCritics.map(c =>
420
+ `${c.critic_type}: ${c.verdict} (confidence: ${c.confidence}%)\n${c.issues.map(i => ` [${i.severity}] ${i.category}: ${i.description}`).join('\n')}`
421
+ ).join('\n\n')
422
+
423
+ log('Synthesizing critic feedback into final verdict...')
196
424
 
197
425
  const check = await agent(
198
- `Verify this execution plan for quality and completeness.
426
+ `Synthesize 3 critic assessments into a final plan verdict.
199
427
 
200
- Plan:
201
- ${plan ? `Summary: ${plan.summary}\nApproach: ${plan.approach}\nComplexity: ${plan.complexity}\nTasks: ${plan.total_tasks} across ${plan.waves.length} waves` : 'No plan generated'}
428
+ Selected plan: ${selectedPlan.strategy}
202
429
 
203
- Task details:
204
- ${plan ? plan.waves.map(w => `Wave ${w.wave_index}: ${w.tasks.map(t => t.task_id + ': ' + t.title + ' [' + (t.convergence_criteria || []).length + ' criteria]').join(', ')}`).join('\n') : 'none'}
430
+ === CRITIC ASSESSMENTS ===
431
+ ${criticDigest}
205
432
 
206
- Check:
207
- 1. DEPENDENCY CORRECTNESS: Are depends_on relationships correct? Any missing?
208
- 2. WAVE EFFICIENCY: Could more tasks be parallelized? Are waves minimized?
209
- 3. CONVERGENCE QUALITY: Are criteria specific and testable (not vague)?
210
- 4. SCOPE COMPLETENESS: Do tasks cover all requirements?
211
- 5. FILE CONFLICTS: Do parallel tasks modify the same files?
212
- 6. MISSING TASKS: Are there requirements without corresponding tasks?
433
+ === PLAN COMPETITION SCORES ===
434
+ ${scoreDigest}
213
435
 
214
- Requirements to cover:
215
- ${mergedRequirements.map(r => r.objective).join('\n')}`,
216
- { label: 'check:quality', phase: 'Check', schema: CHECK_SCHEMA, agentType: 'workflow-plan-checker' }
436
+ RESOLVE:
437
+ 1. Merge all issues from all critics, tagged with source_critic
438
+ 2. Verdict rules:
439
+ - Any critic has critical issues → "needs-revision"
440
+ - All critics pass → "pass"
441
+ - Only warnings/notes → "pass-with-notes"
442
+ 3. Record adversarial_outcome with each critic's verdict and decisive_factor
443
+ 4. Calculate metrics: task_count, wave_count, avg_convergence_criteria, dependency_depth, estimated_parallelism
444
+ 5. Summarize the competition outcome and critic feedback`,
445
+ { label: 'check:synthesize', phase: 'Check', schema: CHECK_SCHEMA }
217
446
  )
218
447
 
219
448
  return {
220
449
  contexts: validContexts,
221
- plan: plan,
450
+ proposals: validProposals,
451
+ scores: validJudges,
452
+ selected_plan: selectedPlan,
453
+ critics: validCritics,
222
454
  check: check,
223
455
  metadata: {
224
- phase: phase_num,
456
+ phase: phaseNum,
225
457
  scope: scope,
226
458
  decision_count: mergedDecisions.length,
227
459
  requirement_count: mergedRequirements.length,
228
- total_tasks: plan ? plan.total_tasks : 0,
229
- wave_count: plan ? plan.waves.length : 0,
460
+ proposals_generated: validProposals.length,
461
+ selected_strategy: selectedPlan.strategy,
462
+ selected_score: validJudges[bestIdx] ? validJudges[bestIdx].total_score : null,
463
+ total_tasks: selectedPlan.total_tasks,
464
+ wave_count: selectedPlan.waves.length,
230
465
  check_verdict: check ? check.verdict : 'unknown',
231
466
  critical_issues: check ? check.issues.filter(i => i.severity === 'critical').length : 0,
232
467
  },