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.
- package/.agents/skills/maestro-ralph-execute/SKILL.md +2 -1
- package/.agents/skills/maestro-swarm-workflow/SKILL.md +27 -19
- package/.agents/skills/maestro-universal-workflow/SKILL.md +563 -0
- package/.agents/skills/team-adversarial-swarm/SKILL.md +235 -0
- package/.agents/skills/team-adversarial-swarm/scripts/aco.py +473 -0
- package/.agents/skills/team-adversarial-swarm/scripts/pheromone.py +144 -0
- package/.agents/skills/team-adversarial-swarm/scripts/scoring.py +92 -0
- package/.agents/skills/team-adversarial-swarm/scripts/test_aco.py +475 -0
- package/.agents/skills/team-adversarial-swarm/specs/ant-output-schema.md +115 -0
- package/.agents/skills/team-adversarial-swarm/specs/convergence-criteria.md +75 -0
- package/.agents/skills/team-adversarial-swarm/specs/pheromone-schema.md +90 -0
- package/.agents/skills/team-adversarial-swarm/specs/swarm-config-template.json +66 -0
- package/.agents/skills/team-adversarial-swarm/specs/swarm-protocol.md +105 -0
- package/.agents/skills/team-adversarial-swarm/workflows/wf-swarm-converge.js +197 -0
- package/.agents/skills/team-adversarial-swarm/workflows/wf-swarm-explore.js +194 -0
- package/.agents/skills/team-adversarial-swarm/workflows/wf-swarm-score.js +188 -0
- package/.agents/skills/team-adversarial-swarm/workflows/wf-swarm-synthesize.js +248 -0
- package/.agy/skills/maestro-ralph-execute/SKILL.md +2 -1
- package/.agy/skills/maestro-swarm-workflow/SKILL.md +27 -19
- package/.agy/skills/maestro-universal-workflow/SKILL.md +560 -0
- package/.agy/skills/team-adversarial-swarm/SKILL.md +244 -0
- package/.agy/skills/team-adversarial-swarm/scripts/aco.py +473 -0
- package/.agy/skills/team-adversarial-swarm/scripts/pheromone.py +144 -0
- package/.agy/skills/team-adversarial-swarm/scripts/scoring.py +92 -0
- package/.agy/skills/team-adversarial-swarm/scripts/test_aco.py +475 -0
- package/.agy/skills/team-adversarial-swarm/specs/ant-output-schema.md +115 -0
- package/.agy/skills/team-adversarial-swarm/specs/convergence-criteria.md +75 -0
- package/.agy/skills/team-adversarial-swarm/specs/pheromone-schema.md +90 -0
- package/.agy/skills/team-adversarial-swarm/specs/swarm-config-template.json +66 -0
- package/.agy/skills/team-adversarial-swarm/specs/swarm-protocol.md +105 -0
- package/.agy/skills/team-adversarial-swarm/workflows/wf-swarm-converge.js +197 -0
- package/.agy/skills/team-adversarial-swarm/workflows/wf-swarm-explore.js +194 -0
- package/.agy/skills/team-adversarial-swarm/workflows/wf-swarm-score.js +188 -0
- package/.agy/skills/team-adversarial-swarm/workflows/wf-swarm-synthesize.js +248 -0
- package/.claude/commands/maestro-ralph-execute.md +2 -1
- package/.claude/commands/maestro-swarm-workflow.md +27 -19
- package/.claude/commands/maestro-universal-workflow.md +561 -0
- package/.claude/skills/team-adversarial-swarm/SKILL.md +233 -0
- package/.claude/skills/team-adversarial-swarm/scripts/aco.py +473 -0
- package/.claude/skills/team-adversarial-swarm/scripts/pheromone.py +144 -0
- package/.claude/skills/team-adversarial-swarm/scripts/scoring.py +92 -0
- package/.claude/skills/team-adversarial-swarm/scripts/test_aco.py +475 -0
- package/.claude/skills/team-adversarial-swarm/specs/ant-output-schema.md +115 -0
- package/.claude/skills/team-adversarial-swarm/specs/convergence-criteria.md +75 -0
- package/.claude/skills/team-adversarial-swarm/specs/pheromone-schema.md +90 -0
- package/.claude/skills/team-adversarial-swarm/specs/swarm-config-template.json +66 -0
- package/.claude/skills/team-adversarial-swarm/specs/swarm-protocol.md +105 -0
- package/.claude/skills/team-adversarial-swarm/workflows/wf-swarm-converge.js +197 -0
- package/.claude/skills/team-adversarial-swarm/workflows/wf-swarm-explore.js +194 -0
- package/.claude/skills/team-adversarial-swarm/workflows/wf-swarm-score.js +188 -0
- package/.claude/skills/team-adversarial-swarm/workflows/wf-swarm-synthesize.js +248 -0
- package/dashboard/dist-server/dashboard/src/server/wiki/graph-analysis.js +1 -1
- package/dashboard/dist-server/dashboard/src/server/wiki/graph-analysis.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/server/wiki/search.js +1 -1
- package/dashboard/dist-server/dashboard/src/server/wiki/search.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/server/wiki/virtual-wiki-adapters.d.ts +1 -1
- package/dashboard/dist-server/dashboard/src/server/wiki/virtual-wiki-adapters.js +5 -5
- package/dashboard/dist-server/dashboard/src/server/wiki/virtual-wiki-adapters.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/server/wiki/wiki-indexer.js +3 -3
- package/dashboard/dist-server/dashboard/src/server/wiki/wiki-indexer.js.map +1 -1
- package/dashboard/dist-server/src/graph/types.d.ts +111 -0
- package/dashboard/dist-server/src/graph/types.js +2 -0
- package/dashboard/dist-server/src/graph/types.js.map +1 -0
- package/dist/src/commands/install-backend.d.ts +0 -7
- package/dist/src/commands/install-backend.d.ts.map +1 -1
- package/dist/src/commands/install-backend.js +0 -14
- package/dist/src/commands/install-backend.js.map +1 -1
- package/dist/src/commands/install.d.ts.map +1 -1
- package/dist/src/commands/install.js +0 -18
- package/dist/src/commands/install.js.map +1 -1
- package/dist/src/commands/kg.d.ts +2 -2
- package/dist/src/commands/kg.d.ts.map +1 -1
- package/dist/src/commands/kg.js +150 -179
- package/dist/src/commands/kg.js.map +1 -1
- package/dist/src/graph/analyzers/fs-analyzer.d.ts +10 -0
- package/dist/src/graph/analyzers/fs-analyzer.d.ts.map +1 -0
- package/dist/src/graph/analyzers/fs-analyzer.js +959 -0
- package/dist/src/graph/analyzers/fs-analyzer.js.map +1 -0
- package/dist/src/graph/index.d.ts +6 -0
- package/dist/src/graph/index.d.ts.map +1 -0
- package/dist/src/graph/index.js +6 -0
- package/dist/src/graph/index.js.map +1 -0
- package/dist/src/graph/loader.d.ts +3 -0
- package/dist/src/graph/loader.d.ts.map +1 -0
- package/dist/src/graph/loader.js +12 -0
- package/dist/src/graph/loader.js.map +1 -0
- package/dist/src/graph/merger.d.ts +56 -0
- package/dist/src/graph/merger.d.ts.map +1 -0
- package/dist/src/graph/merger.js +896 -0
- package/dist/src/graph/merger.js.map +1 -0
- package/dist/src/graph/query.d.ts +7 -0
- package/dist/src/graph/query.d.ts.map +1 -0
- package/dist/src/graph/query.js +126 -0
- package/dist/src/graph/query.js.map +1 -0
- package/dist/src/graph/types.d.ts +112 -0
- package/dist/src/graph/types.d.ts.map +1 -0
- package/dist/src/graph/types.js +2 -0
- package/dist/src/graph/types.js.map +1 -0
- package/dist/src/i18n/locales/en.d.ts.map +1 -1
- package/dist/src/i18n/locales/en.js +0 -10
- package/dist/src/i18n/locales/en.js.map +1 -1
- package/dist/src/i18n/locales/zh.d.ts.map +1 -1
- package/dist/src/i18n/locales/zh.js +0 -10
- package/dist/src/i18n/locales/zh.js.map +1 -1
- package/dist/src/i18n/types.d.ts +0 -9
- package/dist/src/i18n/types.d.ts.map +1 -1
- package/dist/src/tui/install-ui/InstallConfirm.d.ts +0 -1
- package/dist/src/tui/install-ui/InstallConfirm.d.ts.map +1 -1
- package/dist/src/tui/install-ui/InstallConfirm.js +1 -1
- package/dist/src/tui/install-ui/InstallConfirm.js.map +1 -1
- package/dist/src/tui/install-ui/InstallExecution.d.ts +0 -1
- package/dist/src/tui/install-ui/InstallExecution.d.ts.map +1 -1
- package/dist/src/tui/install-ui/InstallExecution.js +0 -22
- package/dist/src/tui/install-ui/InstallExecution.js.map +1 -1
- package/dist/src/tui/install-ui/InstallFlow.d.ts +1 -1
- package/dist/src/tui/install-ui/InstallFlow.d.ts.map +1 -1
- package/dist/src/tui/install-ui/InstallFlow.js +5 -23
- package/dist/src/tui/install-ui/InstallFlow.js.map +1 -1
- package/dist/src/tui/install-ui/InstallHub.d.ts +0 -2
- package/dist/src/tui/install-ui/InstallHub.d.ts.map +1 -1
- package/dist/src/tui/install-ui/InstallHub.js +0 -6
- package/dist/src/tui/install-ui/InstallHub.js.map +1 -1
- package/dist/src/tui/install-ui/InstallResult.d.ts.map +1 -1
- package/dist/src/tui/install-ui/InstallResult.js +1 -1
- package/dist/src/tui/install-ui/InstallResult.js.map +1 -1
- package/dist/src/utils/update-notices.js +12 -0
- package/dist/src/utils/update-notices.js.map +1 -1
- package/package.json +1 -1
- package/workflows/swarm/wf-analyze.js +195 -34
- package/workflows/swarm/wf-brainstorm.js +225 -53
- package/workflows/swarm/wf-execute.js +199 -23
- package/workflows/swarm/wf-grill.js +181 -20
- package/workflows/swarm/wf-milestone-audit.js +178 -29
- package/workflows/swarm/wf-plan.js +288 -53
- package/workflows/swarm/wf-review.js +195 -80
- 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
|
|
4
|
-
whenToUse: 'Accelerate maestro-brainstorm with parallel
|
|
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: '
|
|
8
|
-
{ title: '
|
|
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
|
-
|
|
214
|
-
|
|
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
|
-
|
|
219
|
-
1.
|
|
220
|
-
2.
|
|
221
|
-
3.
|
|
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
|
-
|
|
224
|
-
|
|
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
|
-
|
|
228
|
-
|
|
229
|
-
|
|
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
|
-
|
|
232
|
-
|
|
233
|
-
).join('\n')
|
|
282
|
+
${validAnalyses.length} role analyses:
|
|
283
|
+
${analysesDigest}
|
|
234
284
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
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
|
-
|
|
240
|
-
|
|
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
|
-
|
|
245
|
-
|
|
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
|
-
|
|
248
|
-
|
|
249
|
-
|
|
360
|
+
Topic: ${topic}
|
|
361
|
+
Role Analyses:\n${analysesDigest}
|
|
362
|
+
|
|
363
|
+
Cross-Review:\n${crossReviewDigest}
|
|
250
364
|
|
|
251
|
-
|
|
252
|
-
|
|
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
|
-
|
|
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
|
-
|
|
257
|
-
|
|
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
|
-
|
|
264
|
-
|
|
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
|
-
-
|
|
267
|
-
|
|
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
|
-
|
|
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:
|
|
279
|
-
blocking_conflicts:
|
|
280
|
-
synergy_count:
|
|
281
|
-
gap_count:
|
|
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
|
|
4
|
-
whenToUse: 'Accelerate maestro-execute with parallel task implementation
|
|
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: '
|
|
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
|
|
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
|
|
62
|
-
4. Filter: only
|
|
63
|
-
5. Return the wave structure with full task context
|
|
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
|
|
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
|
|
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
|
-
|
|
172
|
-
|
|
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
|
-
|
|
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
|
-
|
|
183
|
-
-
|
|
184
|
-
-
|
|
185
|
-
-
|
|
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
|
-
|
|
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
|
}
|