maestro-flow 0.4.20 → 0.4.22

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 (151) 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/__pycache__/pheromone.cpython-313.pyc +0 -0
  6. package/.agents/skills/team-adversarial-swarm/scripts/__pycache__/scoring.cpython-313.pyc +0 -0
  7. package/.agents/skills/team-adversarial-swarm/scripts/aco.py +473 -0
  8. package/.agents/skills/team-adversarial-swarm/scripts/pheromone.py +144 -0
  9. package/.agents/skills/team-adversarial-swarm/scripts/scoring.py +92 -0
  10. package/.agents/skills/team-adversarial-swarm/scripts/test_aco.py +475 -0
  11. package/.agents/skills/team-adversarial-swarm/specs/ant-output-schema.md +115 -0
  12. package/.agents/skills/team-adversarial-swarm/specs/convergence-criteria.md +75 -0
  13. package/.agents/skills/team-adversarial-swarm/specs/pheromone-schema.md +90 -0
  14. package/.agents/skills/team-adversarial-swarm/specs/swarm-config-template.json +66 -0
  15. package/.agents/skills/team-adversarial-swarm/specs/swarm-protocol.md +105 -0
  16. package/.agents/skills/team-adversarial-swarm/workflows/wf-swarm-converge.js +197 -0
  17. package/.agents/skills/team-adversarial-swarm/workflows/wf-swarm-explore.js +194 -0
  18. package/.agents/skills/team-adversarial-swarm/workflows/wf-swarm-score.js +188 -0
  19. package/.agents/skills/team-adversarial-swarm/workflows/wf-swarm-synthesize.js +248 -0
  20. package/.agents/skills/team-swarm/scripts/aco.py +15 -15
  21. package/.agents/skills/team-swarm/scripts/pheromone.py +2 -2
  22. package/.agents/skills/team-swarm/scripts/scoring.py +1 -1
  23. package/.agy/skills/maestro-ralph-execute/SKILL.md +2 -1
  24. package/.agy/skills/maestro-swarm-workflow/SKILL.md +27 -19
  25. package/.agy/skills/maestro-universal-workflow/SKILL.md +560 -0
  26. package/.agy/skills/team-adversarial-swarm/SKILL.md +244 -0
  27. package/.agy/skills/team-adversarial-swarm/scripts/__pycache__/pheromone.cpython-313.pyc +0 -0
  28. package/.agy/skills/team-adversarial-swarm/scripts/__pycache__/scoring.cpython-313.pyc +0 -0
  29. package/.agy/skills/team-adversarial-swarm/scripts/aco.py +473 -0
  30. package/.agy/skills/team-adversarial-swarm/scripts/pheromone.py +144 -0
  31. package/.agy/skills/team-adversarial-swarm/scripts/scoring.py +92 -0
  32. package/.agy/skills/team-adversarial-swarm/scripts/test_aco.py +475 -0
  33. package/.agy/skills/team-adversarial-swarm/specs/ant-output-schema.md +115 -0
  34. package/.agy/skills/team-adversarial-swarm/specs/convergence-criteria.md +75 -0
  35. package/.agy/skills/team-adversarial-swarm/specs/pheromone-schema.md +90 -0
  36. package/.agy/skills/team-adversarial-swarm/specs/swarm-config-template.json +66 -0
  37. package/.agy/skills/team-adversarial-swarm/specs/swarm-protocol.md +105 -0
  38. package/.agy/skills/team-adversarial-swarm/workflows/wf-swarm-converge.js +197 -0
  39. package/.agy/skills/team-adversarial-swarm/workflows/wf-swarm-explore.js +194 -0
  40. package/.agy/skills/team-adversarial-swarm/workflows/wf-swarm-score.js +188 -0
  41. package/.agy/skills/team-adversarial-swarm/workflows/wf-swarm-synthesize.js +248 -0
  42. package/.agy/skills/team-swarm/scripts/aco.py +15 -15
  43. package/.agy/skills/team-swarm/scripts/pheromone.py +2 -2
  44. package/.agy/skills/team-swarm/scripts/scoring.py +1 -1
  45. package/.claude/commands/maestro-ralph-execute.md +2 -1
  46. package/.claude/commands/maestro-swarm-workflow.md +27 -19
  47. package/.claude/commands/maestro-universal-workflow.md +561 -0
  48. package/.claude/skills/team-adversarial-swarm/SKILL.md +233 -0
  49. package/.claude/skills/team-adversarial-swarm/scripts/__pycache__/pheromone.cpython-313.pyc +0 -0
  50. package/.claude/skills/team-adversarial-swarm/scripts/__pycache__/scoring.cpython-313.pyc +0 -0
  51. package/.claude/skills/team-adversarial-swarm/scripts/aco.py +473 -0
  52. package/.claude/skills/team-adversarial-swarm/scripts/pheromone.py +144 -0
  53. package/.claude/skills/team-adversarial-swarm/scripts/scoring.py +92 -0
  54. package/.claude/skills/team-adversarial-swarm/scripts/test_aco.py +475 -0
  55. package/.claude/skills/team-adversarial-swarm/specs/ant-output-schema.md +115 -0
  56. package/.claude/skills/team-adversarial-swarm/specs/convergence-criteria.md +75 -0
  57. package/.claude/skills/team-adversarial-swarm/specs/pheromone-schema.md +90 -0
  58. package/.claude/skills/team-adversarial-swarm/specs/swarm-config-template.json +66 -0
  59. package/.claude/skills/team-adversarial-swarm/specs/swarm-protocol.md +105 -0
  60. package/.claude/skills/team-adversarial-swarm/workflows/wf-swarm-converge.js +197 -0
  61. package/.claude/skills/team-adversarial-swarm/workflows/wf-swarm-explore.js +194 -0
  62. package/.claude/skills/team-adversarial-swarm/workflows/wf-swarm-score.js +188 -0
  63. package/.claude/skills/team-adversarial-swarm/workflows/wf-swarm-synthesize.js +248 -0
  64. package/.claude/skills/team-swarm/scripts/aco.py +15 -15
  65. package/.claude/skills/team-swarm/scripts/pheromone.py +2 -2
  66. package/.claude/skills/team-swarm/scripts/scoring.py +1 -1
  67. package/dashboard/dist-server/dashboard/src/server/wiki/graph-analysis.js +1 -1
  68. package/dashboard/dist-server/dashboard/src/server/wiki/graph-analysis.js.map +1 -1
  69. package/dashboard/dist-server/dashboard/src/server/wiki/search.js +1 -1
  70. package/dashboard/dist-server/dashboard/src/server/wiki/search.js.map +1 -1
  71. package/dashboard/dist-server/dashboard/src/server/wiki/virtual-wiki-adapters.d.ts +1 -1
  72. package/dashboard/dist-server/dashboard/src/server/wiki/virtual-wiki-adapters.js +5 -5
  73. package/dashboard/dist-server/dashboard/src/server/wiki/virtual-wiki-adapters.js.map +1 -1
  74. package/dashboard/dist-server/dashboard/src/server/wiki/wiki-indexer.js +3 -3
  75. package/dashboard/dist-server/dashboard/src/server/wiki/wiki-indexer.js.map +1 -1
  76. package/dashboard/dist-server/src/graph/types.d.ts +111 -0
  77. package/dashboard/dist-server/src/graph/types.js +2 -0
  78. package/dashboard/dist-server/src/graph/types.js.map +1 -0
  79. package/dist/src/commands/install-backend.d.ts +0 -7
  80. package/dist/src/commands/install-backend.d.ts.map +1 -1
  81. package/dist/src/commands/install-backend.js +0 -14
  82. package/dist/src/commands/install-backend.js.map +1 -1
  83. package/dist/src/commands/install.d.ts.map +1 -1
  84. package/dist/src/commands/install.js +0 -18
  85. package/dist/src/commands/install.js.map +1 -1
  86. package/dist/src/commands/kg.d.ts +2 -2
  87. package/dist/src/commands/kg.d.ts.map +1 -1
  88. package/dist/src/commands/kg.js +150 -179
  89. package/dist/src/commands/kg.js.map +1 -1
  90. package/dist/src/graph/analyzers/fs-analyzer.d.ts +10 -0
  91. package/dist/src/graph/analyzers/fs-analyzer.d.ts.map +1 -0
  92. package/dist/src/graph/analyzers/fs-analyzer.js +959 -0
  93. package/dist/src/graph/analyzers/fs-analyzer.js.map +1 -0
  94. package/dist/src/graph/index.d.ts +6 -0
  95. package/dist/src/graph/index.d.ts.map +1 -0
  96. package/dist/src/graph/index.js +6 -0
  97. package/dist/src/graph/index.js.map +1 -0
  98. package/dist/src/graph/loader.d.ts +3 -0
  99. package/dist/src/graph/loader.d.ts.map +1 -0
  100. package/dist/src/graph/loader.js +12 -0
  101. package/dist/src/graph/loader.js.map +1 -0
  102. package/dist/src/graph/merger.d.ts +56 -0
  103. package/dist/src/graph/merger.d.ts.map +1 -0
  104. package/dist/src/graph/merger.js +896 -0
  105. package/dist/src/graph/merger.js.map +1 -0
  106. package/dist/src/graph/query.d.ts +7 -0
  107. package/dist/src/graph/query.d.ts.map +1 -0
  108. package/dist/src/graph/query.js +126 -0
  109. package/dist/src/graph/query.js.map +1 -0
  110. package/dist/src/graph/types.d.ts +112 -0
  111. package/dist/src/graph/types.d.ts.map +1 -0
  112. package/dist/src/graph/types.js +2 -0
  113. package/dist/src/graph/types.js.map +1 -0
  114. package/dist/src/i18n/locales/en.d.ts.map +1 -1
  115. package/dist/src/i18n/locales/en.js +0 -10
  116. package/dist/src/i18n/locales/en.js.map +1 -1
  117. package/dist/src/i18n/locales/zh.d.ts.map +1 -1
  118. package/dist/src/i18n/locales/zh.js +0 -10
  119. package/dist/src/i18n/locales/zh.js.map +1 -1
  120. package/dist/src/i18n/types.d.ts +0 -9
  121. package/dist/src/i18n/types.d.ts.map +1 -1
  122. package/dist/src/tui/install-ui/InstallConfirm.d.ts +0 -1
  123. package/dist/src/tui/install-ui/InstallConfirm.d.ts.map +1 -1
  124. package/dist/src/tui/install-ui/InstallConfirm.js +1 -1
  125. package/dist/src/tui/install-ui/InstallConfirm.js.map +1 -1
  126. package/dist/src/tui/install-ui/InstallExecution.d.ts +0 -1
  127. package/dist/src/tui/install-ui/InstallExecution.d.ts.map +1 -1
  128. package/dist/src/tui/install-ui/InstallExecution.js +0 -22
  129. package/dist/src/tui/install-ui/InstallExecution.js.map +1 -1
  130. package/dist/src/tui/install-ui/InstallFlow.d.ts +1 -1
  131. package/dist/src/tui/install-ui/InstallFlow.d.ts.map +1 -1
  132. package/dist/src/tui/install-ui/InstallFlow.js +5 -23
  133. package/dist/src/tui/install-ui/InstallFlow.js.map +1 -1
  134. package/dist/src/tui/install-ui/InstallHub.d.ts +0 -2
  135. package/dist/src/tui/install-ui/InstallHub.d.ts.map +1 -1
  136. package/dist/src/tui/install-ui/InstallHub.js +0 -6
  137. package/dist/src/tui/install-ui/InstallHub.js.map +1 -1
  138. package/dist/src/tui/install-ui/InstallResult.d.ts.map +1 -1
  139. package/dist/src/tui/install-ui/InstallResult.js +1 -1
  140. package/dist/src/tui/install-ui/InstallResult.js.map +1 -1
  141. package/dist/src/utils/update-notices.js +12 -0
  142. package/dist/src/utils/update-notices.js.map +1 -1
  143. package/package.json +1 -1
  144. package/workflows/swarm/wf-analyze.js +195 -34
  145. package/workflows/swarm/wf-brainstorm.js +225 -53
  146. package/workflows/swarm/wf-execute.js +199 -23
  147. package/workflows/swarm/wf-grill.js +181 -20
  148. package/workflows/swarm/wf-milestone-audit.js +178 -29
  149. package/workflows/swarm/wf-plan.js +288 -53
  150. package/workflows/swarm/wf-review.js +195 -80
  151. package/workflows/swarm/wf-verify.js +125 -28
@@ -1,11 +1,12 @@
1
1
  export const meta = {
2
2
  name: 'wf-brainstorm',
3
- description: 'Multi-role parallel brainstorm with cross-role reviewer synthesis, aligned with maestro-brainstorm',
4
- whenToUse: 'Accelerate maestro-brainstorm with parallel role analysis and cross-role conflict/synergy detection',
3
+ description: 'Multi-role brainstorm with 3-specialist cross-review and adversarial guidance arbitration',
4
+ whenToUse: 'Accelerate maestro-brainstorm with parallel roles + 3-specialist cross-review + adversarial guidance synthesis',
5
5
  phases: [
6
6
  { title: 'Analyze', detail: 'Parallel multi-role analysis via role-design-author' },
7
- { title: 'CrossReview', detail: 'Cross-role conflict detection via cross-role-reviewer' },
8
- { title: 'Synthesize', detail: 'Resolution synthesis into guidance specification' },
7
+ { title: 'CrossReview', detail: '3 specialized reviewers (conflict-hunter, synergy-finder, gap-detector) in parallel' },
8
+ { title: 'Compete', detail: '3 independent guidance proposals from competing philosophies' },
9
+ { title: 'Arbitrate', detail: 'Adversarial arbitrator resolves competing proposals into unified guidance' },
9
10
  ],
10
11
  }
11
12
 
@@ -83,6 +84,7 @@ const ROLE_ANALYSIS_SCHEMA = {
83
84
  const CROSS_REVIEW_SCHEMA = {
84
85
  type: 'object',
85
86
  properties: {
87
+ reviewer_type: { type: 'string' },
86
88
  conflicts: {
87
89
  type: 'array',
88
90
  items: {
@@ -123,7 +125,45 @@ const CROSS_REVIEW_SCHEMA = {
123
125
  },
124
126
  },
125
127
  },
126
- required: ['conflicts', 'synergies', 'gaps'],
128
+ required: ['reviewer_type', 'conflicts', 'synergies', 'gaps'],
129
+ }
130
+
131
+ const GUIDANCE_PROPOSAL_SCHEMA = {
132
+ type: 'object',
133
+ properties: {
134
+ philosophy: { type: 'string' },
135
+ guidelines: {
136
+ type: 'array',
137
+ items: {
138
+ type: 'object',
139
+ properties: {
140
+ id: { type: 'string' },
141
+ guideline: { type: 'string' },
142
+ category: { type: 'string', enum: ['must', 'must-not', 'should', 'should-not', 'may'] },
143
+ source_roles: { type: 'array', items: { type: 'string' } },
144
+ rationale: { type: 'string' },
145
+ resolved_conflict: { type: 'string' },
146
+ },
147
+ required: ['id', 'guideline', 'category', 'rationale'],
148
+ },
149
+ },
150
+ conflict_resolutions: {
151
+ type: 'array',
152
+ items: {
153
+ type: 'object',
154
+ properties: {
155
+ conflict_id: { type: 'string' },
156
+ resolution: { type: 'string' },
157
+ rationale: { type: 'string' },
158
+ winner_role: { type: 'string' },
159
+ },
160
+ required: ['conflict_id', 'resolution', 'rationale'],
161
+ },
162
+ },
163
+ trade_off_summary: { type: 'string' },
164
+ confidence: { type: 'number', minimum: 0, maximum: 100 },
165
+ },
166
+ required: ['philosophy', 'guidelines', 'conflict_resolutions', 'confidence'],
127
167
  }
128
168
 
129
169
  const GUIDANCE_SCHEMA = {
@@ -140,6 +180,7 @@ const GUIDANCE_SCHEMA = {
140
180
  source_roles: { type: 'array', items: { type: 'string' } },
141
181
  rationale: { type: 'string' },
142
182
  resolved_conflict: { type: 'string' },
183
+ source_proposal: { type: 'string' },
143
184
  },
144
185
  required: ['id', 'guideline', 'category', 'source_roles', 'rationale'],
145
186
  },
@@ -153,14 +194,16 @@ const GUIDANCE_SCHEMA = {
153
194
  resolution: { type: 'string' },
154
195
  rationale: { type: 'string' },
155
196
  winner_role: { type: 'string' },
197
+ dissenting_proposal: { type: 'string' },
156
198
  },
157
199
  required: ['conflict_id', 'resolution', 'rationale'],
158
200
  },
159
201
  },
202
+ arbitration_notes: { type: 'string' },
160
203
  open_questions: { type: 'array', items: { type: 'string' } },
161
204
  executive_summary: { type: 'string' },
162
205
  },
163
- required: ['guidelines', 'resolved_conflicts', 'executive_summary'],
206
+ required: ['guidelines', 'resolved_conflicts', 'arbitration_notes', 'executive_summary'],
164
207
  }
165
208
 
166
209
  const topic = args?.topic || 'the proposed system'
@@ -199,10 +242,6 @@ Be specific and opinionated — take clear stances with rationale.`,
199
242
  const validAnalyses = analyses.filter(Boolean)
200
243
  log(`${validAnalyses.length}/${selectedRoles.length} role analyses completed`)
201
244
 
202
- // Phase 2: Cross-role review via cross-role-reviewer
203
- phase('CrossReview')
204
- log('Cross-role conflict and synergy detection...')
205
-
206
245
  const analysesDigest = validAnalyses.map(a => {
207
246
  const decisions = a.decision_digest.map(d => ` ${d.id}: [${d.priority}] ${d.feature} — ${d.stance}`).join('\n')
208
247
  const positions = a.cross_cutting_positions.map(p => ` ${p.topic}: ${p.position} [${p.strength}]`).join('\n')
@@ -210,75 +249,208 @@ const analysesDigest = validAnalyses.map(a => {
210
249
  return `## ${a.role}\nKey insight: ${a.key_insight}\n\nDecisions:\n${decisions}\n\nPositions:\n${positions}\n\nFindings:\n${findings}`
211
250
  }).join('\n\n---\n\n')
212
251
 
213
- const crossReview = await agent(
214
- `Compare these ${validAnalyses.length} role analyses for conflicts, gaps, and synergies.
252
+ // Phase 2: 3 specialized cross-reviewers in parallel
253
+ phase('CrossReview')
254
+ log('Launching 3 specialized cross-reviewers in parallel...')
255
+
256
+ const crossReviews = await parallel([
257
+ () => agent(
258
+ `You are the CONFLICT HUNTER. Your sole mission is to find contradictions between roles.
215
259
 
260
+ ${validAnalyses.length} role analyses:
216
261
  ${analysesDigest}
217
262
 
218
- Identify:
219
- 1. CONFLICTS: Same feature/topic with contradictory stances between roles. Include severity (blocking/significant/minor).
220
- 2. SYNERGIES: Compatible positions that reinforce each other when combined.
221
- 3. GAPS: Areas where an important perspective is missing — a topic addressed by one role but not by another that should.
263
+ Focus EXCLUSIVELY on:
264
+ 1. Same feature/topic with CONTRADICTORY stances between roles
265
+ 2. Incompatible priorities (one role says must-have, another says not needed)
266
+ 3. Conflicting cross-cutting positions
267
+ 4. Interface mismatches (one produces X, another expects Y)
222
268
 
223
- For each conflict, suggest a resolution direction.`,
224
- { label: 'cross-review', phase: 'CrossReview', schema: CROSS_REVIEW_SCHEMA, agentType: 'cross-role-reviewer' }
225
- )
269
+ Classify each conflict:
270
+ - blocking: fundamental disagreement that prevents progress
271
+ - significant: meaningful disagreement but can be resolved
272
+ - minor: style/preference difference
226
273
 
227
- // Phase 3: Synthesis into guidance specification
228
- phase('Synthesize')
229
- log('Synthesizing guidance specification...')
274
+ For each conflict, suggest a resolution direction.
275
+ Set reviewer_type="conflict-hunter".
276
+ Be AGGRESSIVE — surface every possible contradiction, even subtle ones.`,
277
+ { label: 'review:conflicts', phase: 'CrossReview', schema: CROSS_REVIEW_SCHEMA, agentType: 'cross-role-reviewer' }
278
+ ),
279
+ () => agent(
280
+ `You are the SYNERGY FINDER. Your sole mission is to find reinforcing alignments between roles.
230
281
 
231
- const conflictDigest = crossReview.conflicts.map(c =>
232
- `[${c.severity}] ${c.topic}: ${c.stances.map(s => s.role + '→' + s.stance).join(' vs ')}\n Suggestion: ${c.resolution_suggestion}`
233
- ).join('\n')
282
+ ${validAnalyses.length} role analyses:
283
+ ${analysesDigest}
234
284
 
235
- const synergyDigest = crossReview.synergies.map(s =>
236
- `${s.roles.join(' + ')}: ${s.topic} ${s.combined_value}`
237
- ).join('\n')
285
+ Focus EXCLUSIVELY on:
286
+ 1. Compatible positions that create MORE value when combined
287
+ 2. Shared priorities that validate importance
288
+ 3. Complementary interfaces (one provides exactly what another needs)
289
+ 4. Cross-cutting alignments that reveal strong consensus
238
290
 
239
- const guidance = await agent(
240
- `Synthesize a unified guidance specification from multi-role brainstorm results.
291
+ For each synergy, explain the combined value — how the combination is more than the sum.
292
+ Set reviewer_type="synergy-finder".
293
+ Be GENEROUS — surface every alignment, including implicit ones.`,
294
+ { label: 'review:synergies', phase: 'CrossReview', schema: CROSS_REVIEW_SCHEMA, agentType: 'cross-role-reviewer' }
295
+ ),
296
+ () => agent(
297
+ `You are the GAP DETECTOR. Your sole mission is to find MISSING perspectives and blind spots.
298
+
299
+ ${validAnalyses.length} role analyses:
300
+ ${analysesDigest}
301
+
302
+ Focus EXCLUSIVELY on:
303
+ 1. Topics addressed by one role but IGNORED by others who should care
304
+ 2. Missing role perspectives entirely (security not represented? operations?)
305
+ 3. Unstated assumptions that no role challenged
306
+ 4. Edge cases and failure modes no one considered
307
+ 5. Integration points that fall between role responsibilities
308
+
309
+ For each gap, identify what perspective is missing and the impact of that blindspot.
310
+ Set reviewer_type="gap-detector".
311
+ Be THOROUGH — missing perspectives are the most dangerous type of oversight.`,
312
+ { label: 'review:gaps', phase: 'CrossReview', schema: CROSS_REVIEW_SCHEMA, agentType: 'cross-role-reviewer' }
313
+ ),
314
+ ])
315
+
316
+ const validReviews = crossReviews.filter(Boolean)
317
+ const allConflicts = validReviews.flatMap(r => r.conflicts)
318
+ const allSynergies = validReviews.flatMap(r => r.synergies)
319
+ const allGaps = validReviews.flatMap(r => r.gaps)
320
+
321
+ log(`Cross-review: ${allConflicts.length} conflicts, ${allSynergies.length} synergies, ${allGaps.length} gaps`)
322
+
323
+ const crossReviewDigest = `Conflicts (${allConflicts.length}):
324
+ ${allConflicts.map(c => `[${c.severity}] ${c.topic}: ${c.stances.map(s => s.role + '→' + s.stance).join(' vs ')}\n Suggestion: ${c.resolution_suggestion || 'none'}`).join('\n')}
325
+
326
+ Synergies (${allSynergies.length}):
327
+ ${allSynergies.map(s => `${s.roles.join(' + ')}: ${s.topic} — ${s.combined_value}`).join('\n')}
328
+
329
+ Gaps (${allGaps.length}):
330
+ ${allGaps.map(g => `${g.area} — missing: ${g.missing_perspective}${g.impact ? ' (impact: ' + g.impact + ')' : ''}`).join('\n')}`
331
+
332
+ // Phase 3: 3 competing guidance proposals from different philosophies
333
+ phase('Compete')
334
+ log('Launching 3 competing guidance proposals...')
335
+
336
+ const proposals = await parallel([
337
+ () => agent(
338
+ `You are the CONSERVATIVE proposal author. Generate guidance that MINIMIZES RISK.
241
339
 
242
340
  Topic: ${topic}
341
+ Role Analyses:\n${analysesDigest}
243
342
 
244
- Role Analyses:
245
- ${analysesDigest}
343
+ Cross-Review:\n${crossReviewDigest}
344
+
345
+ Your philosophy: SAFETY FIRST
346
+ - Resolve conflicts in favor of stability and backward compatibility
347
+ - MUST/MUST-NOT for anything with risk, SHOULD for everything else
348
+ - Prefer proven patterns over innovative approaches
349
+ - When in doubt, require explicit approval (deferred decision)
350
+ - Gaps should be addressed before proceeding
351
+
352
+ Generate guidelines using RFC-2119 (MUST, MUST NOT, SHOULD, SHOULD NOT, MAY).
353
+ Resolve each conflict with your conservative lens.
354
+ Report trade_off_summary: what you sacrifice for safety.`,
355
+ { label: 'proposal:conservative', phase: 'Compete', schema: GUIDANCE_PROPOSAL_SCHEMA }
356
+ ),
357
+ () => agent(
358
+ `You are the PROGRESSIVE proposal author. Generate guidance that MAXIMIZES VELOCITY.
246
359
 
247
- Cross-Review Findings:
248
- Conflicts (${crossReview.conflicts.length}):
249
- ${conflictDigest || 'None'}
360
+ Topic: ${topic}
361
+ Role Analyses:\n${analysesDigest}
362
+
363
+ Cross-Review:\n${crossReviewDigest}
250
364
 
251
- Synergies (${crossReview.synergies.length}):
252
- ${synergyDigest || 'None'}
365
+ Your philosophy: SHIP FAST, ITERATE
366
+ - Resolve conflicts in favor of speed and user value
367
+ - Use MAY/SHOULD liberally, reserve MUST only for safety-critical items
368
+ - Prefer pragmatic solutions, accept tech debt if it unblocks progress
369
+ - Gaps can be addressed incrementally post-launch
370
+ - Favor the role closest to the user (PM, UX) in conflict resolution
253
371
 
254
- Gaps: ${crossReview.gaps.map(g => g.area + ' missing ' + g.missing_perspective).join('; ') || 'None'}
372
+ Generate guidelines using RFC-2119 (MUST, MUST NOT, SHOULD, SHOULD NOT, MAY).
373
+ Resolve each conflict with your progressive lens.
374
+ Report trade_off_summary: what risks you accept for velocity.`,
375
+ { label: 'proposal:progressive', phase: 'Compete', schema: GUIDANCE_PROPOSAL_SCHEMA }
376
+ ),
377
+ () => agent(
378
+ `You are the BALANCED proposal author. Generate guidance that OPTIMIZES FOR SUSTAINABILITY.
255
379
 
256
- Produce:
257
- 1. Unified guidelines using RFC-2119 categories (MUST, MUST NOT, SHOULD, SHOULD NOT, MAY)
258
- 2. For each conflict: resolve by weighing evidence strength, severity, and downstream impact
259
- 3. Attribute each guideline to source roles
260
- 4. List remaining open questions that need user input
261
- 5. Executive summary (2-3 paragraphs)
380
+ Topic: ${topic}
381
+ Role Analyses:\n${analysesDigest}
262
382
 
263
- Priority rules for conflict resolution:
264
- - Security > correctness > user experience > performance > convenience
383
+ Cross-Review:\n${crossReviewDigest}
384
+
385
+ Your philosophy: SUSTAINABLE EXCELLENCE
386
+ - Resolve conflicts by weighing evidence strength from all perspectives
387
+ - Priority: security > correctness > user experience > performance > convenience
265
388
  - "must-have" from multiple roles > "must-have" from single role
266
- - Stances with strong evidence > moderate > weak`,
267
- { label: 'guidance', phase: 'Synthesize', schema: GUIDANCE_SCHEMA }
389
+ - Strong evidence > moderate > weak, regardless of role seniority
390
+ - Address critical gaps, defer minor ones
391
+ - Balance speed and quality based on risk level
392
+
393
+ Generate guidelines using RFC-2119 (MUST, MUST NOT, SHOULD, SHOULD NOT, MAY).
394
+ Resolve each conflict with your balanced lens.
395
+ Report trade_off_summary: what you optimize for and what you deprioritize.`,
396
+ { label: 'proposal:balanced', phase: 'Compete', schema: GUIDANCE_PROPOSAL_SCHEMA }
397
+ ),
398
+ ])
399
+
400
+ const validProposals = proposals.filter(Boolean)
401
+ const proposalDigest = validProposals.map(p =>
402
+ `### ${p.philosophy} (confidence: ${p.confidence}%)\nGuidelines: ${p.guidelines.length}\nConflict resolutions: ${p.conflict_resolutions.length}\nTrade-offs: ${p.trade_off_summary}\nKey guidelines:\n${p.guidelines.slice(0, 5).map(g => ` [${g.category.toUpperCase()}] ${g.guideline}`).join('\n')}`
403
+ ).join('\n\n')
404
+
405
+ log(`${validProposals.length} competing proposals generated`)
406
+
407
+ // Phase 4: Adversarial Arbitration
408
+ phase('Arbitrate')
409
+ log('Adversarial arbitrator resolving competing proposals...')
410
+
411
+ const guidance = await agent(
412
+ `You are the ARBITRATOR. Three competing guidance proposals approach the same problem differently.
413
+
414
+ Topic: ${topic}
415
+
416
+ === COMPETING PROPOSALS ===
417
+ ${proposalDigest}
418
+
419
+ === FULL PROPOSALS ===
420
+ ${validProposals.map(p => `## ${p.philosophy}\n${p.guidelines.map(g => `[${g.category}] ${g.id}: ${g.guideline} — ${g.rationale}`).join('\n')}\n\nConflict resolutions:\n${p.conflict_resolutions.map(r => `${r.conflict_id}: ${r.resolution} (winner: ${r.winner_role || 'compromise'})`).join('\n')}`).join('\n\n---\n\n')}
421
+
422
+ === CROSS-REVIEW DATA ===
423
+ ${crossReviewDigest}
424
+
425
+ ARBITRATE:
426
+ 1. For each guideline topic, compare how all 3 proposals handle it
427
+ 2. Select the BEST resolution for each conflict — not always the same philosophy
428
+ 3. Cherry-pick the strongest guidelines from each proposal
429
+ 4. When proposals agree → high-confidence MUST/MUST-NOT
430
+ 5. When proposals split 2-1 → go with the 2, note the dissent
431
+ 6. When all 3 disagree → evaluate evidence depth and pick the best-argued position
432
+ 7. List remaining open_questions that genuinely need user input
433
+ 8. Write arbitration_notes explaining your meta-reasoning
434
+ 9. Write executive_summary (2-3 paragraphs)
435
+
436
+ Tag each output guideline with source_proposal to trace its origin.`,
437
+ { label: 'arbitrate', phase: 'Arbitrate', schema: GUIDANCE_SCHEMA }
268
438
  )
269
439
 
270
440
  return {
271
441
  analyses: validAnalyses,
272
- crossReview: crossReview,
442
+ crossReviews: validReviews,
443
+ proposals: validProposals,
273
444
  guidance: guidance,
274
445
  metadata: {
275
446
  topic: topic,
276
447
  role_count: selectedRoles.length,
277
448
  completed_count: validAnalyses.length,
278
- conflict_count: crossReview.conflicts.length,
279
- blocking_conflicts: crossReview.conflicts.filter(c => c.severity === 'blocking').length,
280
- synergy_count: crossReview.synergies.length,
281
- gap_count: crossReview.gaps.length,
449
+ conflict_count: allConflicts.length,
450
+ blocking_conflicts: allConflicts.filter(c => c.severity === 'blocking').length,
451
+ synergy_count: allSynergies.length,
452
+ gap_count: allGaps.length,
453
+ proposal_count: validProposals.length,
282
454
  guideline_count: guidance ? guidance.guidelines.length : 0,
283
455
  },
284
456
  }
@@ -1,11 +1,12 @@
1
1
  export const meta = {
2
2
  name: 'wf-execute',
3
- description: 'Wave-based parallel task execution via workflow-executor agents',
4
- whenToUse: 'Accelerate maestro-execute with parallel task implementation within waves',
3
+ description: 'Wave-based parallel execution with adversarial convergence verification and 3-vote status determination',
4
+ whenToUse: 'Accelerate maestro-execute with parallel task implementation + adversarial convergence checks + 3-vote report',
5
5
  phases: [
6
6
  { title: 'Load', detail: 'Load plan and resolve task dependencies' },
7
7
  { title: 'Execute', detail: 'Wave-based parallel task execution via workflow-executor' },
8
- { title: 'Report', detail: 'Execution summary and status collection' },
8
+ { title: 'VerifyConvergence', detail: 'Adversarial spot-check of convergence claims' },
9
+ { title: 'Report', detail: '3-vote status determination (optimist/pessimist/realist)' },
9
10
  ],
10
11
  }
11
12
 
@@ -24,6 +25,44 @@ const TASK_RESULT_SCHEMA = {
24
25
  required: ['task_id', 'status', 'summary'],
25
26
  }
26
27
 
28
+ const CONVERGENCE_CHECK_SCHEMA = {
29
+ type: 'object',
30
+ properties: {
31
+ task_id: { type: 'string' },
32
+ claimed_complete: { type: 'boolean' },
33
+ actually_complete: { type: 'boolean' },
34
+ checks: {
35
+ type: 'array',
36
+ items: {
37
+ type: 'object',
38
+ properties: {
39
+ criterion: { type: 'string' },
40
+ claimed: { type: 'boolean' },
41
+ verified: { type: 'boolean' },
42
+ evidence: { type: 'string' },
43
+ discrepancy: { type: 'string' },
44
+ },
45
+ required: ['criterion', 'claimed', 'verified', 'evidence'],
46
+ },
47
+ },
48
+ trust_score: { type: 'number', minimum: 0, maximum: 100 },
49
+ assessment: { type: 'string' },
50
+ },
51
+ required: ['task_id', 'claimed_complete', 'actually_complete', 'checks', 'trust_score'],
52
+ }
53
+
54
+ const STATUS_VOTE_SCHEMA = {
55
+ type: 'object',
56
+ properties: {
57
+ perspective: { type: 'string' },
58
+ status: { type: 'string', enum: ['DONE', 'DONE_WITH_CONCERNS', 'NEEDS_RETRY'] },
59
+ rationale: { type: 'string' },
60
+ confidence: { type: 'number', minimum: 0, maximum: 100 },
61
+ blocking_concerns: { type: 'array', items: { type: 'string' } },
62
+ },
63
+ required: ['perspective', 'status', 'rationale', 'confidence'],
64
+ }
65
+
27
66
  const REPORT_SCHEMA = {
28
67
  type: 'object',
29
68
  properties: {
@@ -34,10 +73,22 @@ const REPORT_SCHEMA = {
34
73
  blocked: { type: 'number' },
35
74
  waves_executed: { type: 'number' },
36
75
  files_changed: { type: 'array', items: { type: 'string' } },
76
+ adversarial_outcome: {
77
+ type: 'object',
78
+ properties: {
79
+ optimist: { type: 'string' },
80
+ pessimist: { type: 'string' },
81
+ realist: { type: 'string' },
82
+ convergence_trust: { type: 'number' },
83
+ decisive_factor: { type: 'string' },
84
+ },
85
+ required: ['optimist', 'pessimist', 'realist', 'decisive_factor'],
86
+ },
87
+ convergence_discrepancies: { type: 'array', items: { type: 'object', properties: { task_id: { type: 'string' }, criterion: { type: 'string' }, discrepancy: { type: 'string' } }, required: ['task_id', 'criterion'] } },
37
88
  failed_tasks: { type: 'array', items: { type: 'object', properties: { task_id: { type: 'string' }, error: { type: 'string' }, unmet_criteria: { type: 'array', items: { type: 'string' } } }, required: ['task_id'] } },
38
89
  summary: { type: 'string' },
39
90
  },
40
- required: ['status', 'total_tasks', 'completed', 'failed', 'summary'],
91
+ required: ['status', 'total_tasks', 'completed', 'failed', 'adversarial_outcome', 'summary'],
41
92
  }
42
93
 
43
94
  const planDir = args?.plan_dir || ''
@@ -46,7 +97,7 @@ const codebaseContext = args?.codebase_context || ''
46
97
  const wikiContext = args?.wiki_context || ''
47
98
  const autoCommit = args?.auto_commit !== false
48
99
 
49
- // Phase 1: Load plan and resolve waves
100
+ // Phase 1: Load plan
50
101
  phase('Load')
51
102
  log('Loading plan and resolving task dependency waves...')
52
103
 
@@ -58,11 +109,9 @@ Plan directory: ${planDir || 'Find the most recent pending plan in .workflow/scr
58
109
  Steps:
59
110
  1. Read plan.json to get task_ids[], waves[], approach
60
111
  2. Read each .task/TASK-{NNN}.json to get: description, scope, focus_paths, depends_on, convergence.criteria, files[], implementation[], read_first[], test.commands
61
- 3. Verify dependency order: tasks in wave N must have all depends_on satisfied by waves < N
62
- 4. Filter: only include tasks with status="pending" (skip completed/blocked)
63
- 5. Return the wave structure with full task context for each pending task
64
-
65
- Return the complete wave plan as structured data.`,
112
+ 3. Verify dependency order
113
+ 4. Filter: only tasks with status="pending"
114
+ 5. Return the wave structure with full task context`,
66
115
  {
67
116
  label: 'load:plan',
68
117
  phase: 'Load',
@@ -113,7 +162,7 @@ if (!planLoad || !planLoad.waves || planLoad.waves.length === 0) {
113
162
 
114
163
  log(`Plan loaded: ${planLoad.total_pending} pending tasks across ${planLoad.waves.length} waves`)
115
164
 
116
- // Phase 2: Execute waves sequentially, tasks within each wave in parallel
165
+ // Phase 2: Execute waves
117
166
  phase('Execute')
118
167
 
119
168
  const allResults = []
@@ -147,7 +196,7 @@ ${autoCommit ? '7. Create atomic git commit with message referencing ' + task.ta
147
196
  8. Write summary to ${planLoad.plan_dir}/.summaries/${task.task_id}-summary.md
148
197
  9. Update task status to "completed" in the task JSON
149
198
 
150
- Stay within scope. Do not modify files outside focus_paths unless explicitly required by the task.`,
199
+ Stay within scope.`,
151
200
  { label: `exec:${task.task_id}`, phase: 'Execute', schema: TASK_RESULT_SCHEMA, agentType: 'workflow-executor', isolation: 'worktree' }
152
201
  )
153
202
  )
@@ -161,17 +210,73 @@ Stay within scope. Do not modify files outside focus_paths unless explicitly req
161
210
  }
162
211
  }
163
212
 
164
- // Phase 3: Execution report
165
- phase('Report')
166
-
167
213
  const completed = allResults.filter(r => r.status === 'completed')
168
214
  const failed = allResults.filter(r => r.status === 'failed')
169
215
  const blocked = allResults.filter(r => r.status === 'blocked')
170
216
 
171
- const report = await agent(
172
- `Generate execution report.
217
+ // Phase 3: Adversarial convergence verification
218
+ phase('VerifyConvergence')
219
+
220
+ const tasksToVerify = completed.slice(0, Math.min(completed.length, 5))
221
+
222
+ if (tasksToVerify.length > 0) {
223
+ log(`Adversarial convergence spot-check of ${tasksToVerify.length} completed tasks...`)
224
+
225
+ const convergenceChecks = await parallel(
226
+ tasksToVerify.map(task => () => {
227
+ const waveTask = planLoad.waves.flatMap(w => w.tasks).find(t => t.task_id === task.task_id)
228
+ return agent(
229
+ `ADVERSARIAL convergence verification for: ${task.task_id}
230
+
231
+ The executor claims this task is COMPLETED.
232
+ Claimed summary: ${task.summary}
233
+ Files changed: ${(task.files_changed || []).join(', ')}
234
+
235
+ Convergence criteria to verify:
236
+ ${(waveTask ? waveTask.convergence_criteria : []).map((c, i) => `${i + 1}. ${c}`).join('\n')}
173
237
 
174
- Results: ${completed.length} completed, ${failed.length} failed, ${blocked.length} blocked out of ${planLoad.total_pending} total.
238
+ Your job: VERIFY each criterion independently.
239
+ - Read the actual files that were supposedly changed
240
+ - Run any grep/search commands to verify claims
241
+ - Check if the implementation actually satisfies the criterion
242
+ - Do NOT trust the executor's self-assessment
243
+
244
+ For each criterion:
245
+ - claimed: what the executor says (true/false)
246
+ - verified: what YOU find after checking (true/false)
247
+ - evidence: your proof
248
+ - discrepancy: if claimed != verified, explain what's wrong
249
+
250
+ Set actually_complete=true ONLY if ALL criteria are genuinely met.
251
+ trust_score: 100 = perfect match, 0 = complete fabrication.`,
252
+ { label: `verify:${task.task_id}`, phase: 'VerifyConvergence', schema: CONVERGENCE_CHECK_SCHEMA, agentType: 'workflow-verifier' }
253
+ )
254
+ })
255
+ )
256
+
257
+ var validConvergenceChecks = convergenceChecks.filter(Boolean)
258
+ var discrepancies = validConvergenceChecks.flatMap(c =>
259
+ c.checks.filter(ch => ch.claimed !== ch.verified).map(ch => ({
260
+ task_id: c.task_id,
261
+ criterion: ch.criterion,
262
+ discrepancy: ch.discrepancy || 'claimed ' + ch.claimed + ' but verified ' + ch.verified,
263
+ }))
264
+ )
265
+ var avgTrust = validConvergenceChecks.length > 0
266
+ ? Math.round(validConvergenceChecks.reduce((s, c) => s + c.trust_score, 0) / validConvergenceChecks.length)
267
+ : 100
268
+
269
+ log(`Convergence verification: ${discrepancies.length} discrepancies found, avg trust: ${avgTrust}%`)
270
+ } else {
271
+ var validConvergenceChecks = []
272
+ var discrepancies = []
273
+ var avgTrust = 100
274
+ }
275
+
276
+ // Phase 4: 3-vote status determination
277
+ phase('Report')
278
+
279
+ const executionSummary = `Results: ${completed.length} completed, ${failed.length} failed, ${blocked.length} blocked out of ${planLoad.total_pending} total.
175
280
 
176
281
  Completed tasks:
177
282
  ${completed.map(r => `- ${r.task_id}: ${r.summary} (${(r.files_changed || []).length} files)`).join('\n') || 'None'}
@@ -179,18 +284,86 @@ ${completed.map(r => `- ${r.task_id}: ${r.summary} (${(r.files_changed || []).le
179
284
  Failed tasks:
180
285
  ${failed.map(r => `- ${r.task_id}: ${r.error || r.summary}\n Unmet: ${(r.unmet_criteria || []).join(', ') || 'unknown'}`).join('\n') || 'None'}
181
286
 
182
- Determine:
183
- - DONE: all tasks completed, no failures
184
- - DONE_WITH_CONCERNS: some failures but majority succeeded
185
- - NEEDS_RETRY: critical failures blocking downstream work
287
+ Convergence verification:
288
+ - Tasks spot-checked: ${validConvergenceChecks.length}
289
+ - Discrepancies: ${discrepancies.length}
290
+ - Average trust score: ${avgTrust}%
291
+ ${discrepancies.map(d => `- ${d.task_id}: ${d.criterion} — ${d.discrepancy}`).join('\n')}`
292
+
293
+ log('3-vote status determination (optimist / pessimist / realist)...')
294
+
295
+ const statusVotes = await parallel([
296
+ () => agent(
297
+ `OPTIMIST: Vote on execution status.
298
+
299
+ ${executionSummary}
300
+
301
+ Your lens: Focus on progress made. Discount minor convergence discrepancies. Trust high trust scores.
302
+ - DONE: if majority completed, failures are minor, trust is >70%
303
+ - DONE_WITH_CONCERNS: if some failures but not blocking
304
+ - NEEDS_RETRY: only if critical failures make the whole execution invalid`,
305
+ { label: 'vote:optimist', phase: 'Report', schema: STATUS_VOTE_SCHEMA }
306
+ ),
307
+ () => agent(
308
+ `PESSIMIST: Vote on execution status.
309
+
310
+ ${executionSummary}
311
+
312
+ Your lens: Focus on failures and convergence discrepancies. Low trust = unreliable results.
313
+ - NEEDS_RETRY: if any failures exist or trust < 80%
314
+ - DONE_WITH_CONCERNS: if all tasks completed but trust < 90%
315
+ - DONE: only if zero failures AND zero discrepancies AND trust > 95%`,
316
+ { label: 'vote:pessimist', phase: 'Report', schema: STATUS_VOTE_SCHEMA }
317
+ ),
318
+ () => agent(
319
+ `REALIST: Vote on execution status.
320
+
321
+ ${executionSummary}
322
+
323
+ Your lens: Evidence-based judgment. No bias.
324
+ - DONE: all tasks completed, convergence verified, no critical discrepancies
325
+ - DONE_WITH_CONCERNS: completed with minor issues that don't block downstream
326
+ - NEEDS_RETRY: critical failures or convergence trust below 60%`,
327
+ { label: 'vote:realist', phase: 'Report', schema: STATUS_VOTE_SCHEMA }
328
+ ),
329
+ ])
330
+
331
+ const validVotes = statusVotes.filter(Boolean)
332
+ const voteCounts = {}
333
+ validVotes.forEach(v => { voteCounts[v.status] = (voteCounts[v.status] || 0) + 1 })
334
+
335
+ const voteDigest = validVotes.map(v =>
336
+ `${v.perspective}: ${v.status} (confidence: ${v.confidence}%)\n ${v.rationale}`
337
+ ).join('\n\n')
338
+
339
+ log(`Status votes: ${Object.entries(voteCounts).map(([k, v]) => k + '=' + v).join(', ')}`)
340
+
341
+ const report = await agent(
342
+ `Generate execution report from 3-vote adversarial determination.
343
+
344
+ === VOTES ===
345
+ ${voteDigest}
346
+
347
+ Vote tally: ${Object.entries(voteCounts).map(([k, v]) => k + '=' + v).join(', ')}
348
+
349
+ === EXECUTION DATA ===
350
+ ${executionSummary}
186
351
 
187
- Summarize what was accomplished and what needs attention.`,
352
+ RESOLVE:
353
+ 1. Majority vote wins. Tie-break: go with REALIST.
354
+ 2. Record adversarial_outcome with each vote and convergence_trust
355
+ 3. Include convergence_discrepancies in report
356
+ 4. List failed_tasks with errors and unmet criteria
357
+ 5. Compile all files_changed across completed tasks
358
+ 6. Summarize execution including adversarial deliberation outcome`,
188
359
  { label: 'report', phase: 'Report', schema: REPORT_SCHEMA }
189
360
  )
190
361
 
191
362
  return {
192
363
  report: report,
193
364
  results: allResults,
365
+ convergence_checks: validConvergenceChecks,
366
+ status_votes: validVotes,
194
367
  metadata: {
195
368
  plan_dir: planLoad.plan_dir,
196
369
  waves_executed: waveIndex,
@@ -198,6 +371,9 @@ return {
198
371
  completed: completed.length,
199
372
  failed: failed.length,
200
373
  blocked: blocked.length,
374
+ convergence_trust: avgTrust,
375
+ discrepancy_count: discrepancies.length,
376
+ vote_counts: voteCounts,
201
377
  all_files_changed: completed.flatMap(r => r.files_changed || []),
202
378
  },
203
379
  }