maestro-flow 0.4.19 → 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/agents/workflow-collab-planner.md +4 -1
- package/.agents/agents/workflow-plan-checker.md +11 -1
- package/.agents/agents/workflow-planner.md +4 -1
- package/.agents/skills/maestro/SKILL.md +8 -5
- package/.agents/skills/maestro-analyze/SKILL.md +1 -1
- package/.agents/skills/maestro-brainstorm/SKILL.md +2 -1
- package/.agents/skills/maestro-companion/SKILL.md +533 -0
- package/.agents/skills/maestro-grill/SKILL.md +116 -0
- package/.agents/skills/maestro-plan/SKILL.md +4 -0
- package/.agents/skills/maestro-ralph/SKILL.md +11 -7
- package/.agents/skills/maestro-ralph-execute/SKILL.md +2 -1
- package/.agents/skills/maestro-swarm-workflow/SKILL.md +266 -0
- package/.agents/skills/maestro-universal-workflow/SKILL.md +563 -0
- package/.agents/skills/manage-codebase-rebuild/SKILL.md +13 -1
- package/.agents/skills/manage-codebase-refresh/SKILL.md +3 -0
- package/.agents/skills/spec-setup/SKILL.md +9 -5
- 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/agents/workflow-collab-planner.md +4 -1
- package/.agy/agents/workflow-plan-checker.md +11 -1
- package/.agy/agents/workflow-planner.md +4 -1
- package/.agy/skills/maestro/SKILL.md +8 -5
- package/.agy/skills/maestro-analyze/SKILL.md +1 -1
- package/.agy/skills/maestro-brainstorm/SKILL.md +2 -1
- package/.agy/skills/maestro-companion/SKILL.md +529 -0
- package/.agy/skills/maestro-grill/SKILL.md +116 -0
- package/.agy/skills/maestro-plan/SKILL.md +4 -0
- package/.agy/skills/maestro-ralph/SKILL.md +11 -7
- package/.agy/skills/maestro-ralph-execute/SKILL.md +2 -1
- package/.agy/skills/maestro-swarm-workflow/SKILL.md +263 -0
- package/.agy/skills/maestro-universal-workflow/SKILL.md +560 -0
- package/.agy/skills/manage-codebase-rebuild/SKILL.md +13 -1
- package/.agy/skills/manage-codebase-refresh/SKILL.md +3 -0
- package/.agy/skills/spec-setup/SKILL.md +9 -5
- 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/agents/workflow-collab-planner.md +4 -1
- package/.claude/agents/workflow-plan-checker.md +11 -1
- package/.claude/agents/workflow-planner.md +4 -1
- package/.claude/commands/maestro-analyze.md +1 -1
- package/.claude/commands/maestro-brainstorm.md +2 -1
- package/.claude/commands/maestro-companion.md +531 -0
- package/.claude/commands/maestro-grill.md +114 -0
- package/.claude/commands/maestro-plan.md +4 -0
- package/.claude/commands/maestro-ralph-execute.md +2 -1
- package/.claude/commands/maestro-ralph.md +11 -7
- package/.claude/commands/maestro-swarm-workflow.md +264 -0
- package/.claude/commands/maestro-universal-workflow.md +561 -0
- package/.claude/commands/maestro.md +8 -5
- package/.claude/commands/manage-codebase-rebuild.md +13 -1
- package/.claude/commands/manage-codebase-refresh.md +3 -0
- package/.claude/commands/spec-setup.md +9 -5
- 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/.codex/skills/maestro/SKILL.md +7 -2
- package/.codex/skills/maestro-companion/SKILL.md +485 -0
- package/.codex/skills/maestro-grill/SKILL.md +111 -0
- package/.codex/skills/maestro-ralph/SKILL.md +11 -7
- package/.codex/skills/manage-codebase-rebuild/SKILL.md +6 -0
- package/.codex/skills/manage-codebase-refresh/SKILL.md +6 -0
- package/dashboard/dist-server/dashboard/src/server/wiki/graph-analysis.d.ts +36 -0
- package/dashboard/dist-server/dashboard/src/server/wiki/graph-analysis.js +138 -2
- package/dashboard/dist-server/dashboard/src/server/wiki/graph-analysis.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/server/wiki/search.js +13 -0
- 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 +11 -0
- package/dashboard/dist-server/dashboard/src/server/wiki/virtual-wiki-adapters.js +178 -0
- 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.d.ts +1 -0
- package/dashboard/dist-server/dashboard/src/server/wiki/wiki-indexer.js +39 -23
- 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/cli.js +1 -0
- package/dist/src/cli.js.map +1 -1
- package/dist/src/commands/kg.d.ts +11 -0
- package/dist/src/commands/kg.d.ts.map +1 -0
- package/dist/src/commands/kg.js +486 -0
- package/dist/src/commands/kg.js.map +1 -0
- 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/tui/install-ui/KgVendorConfig.d.ts +7 -0
- package/dist/src/tui/install-ui/KgVendorConfig.d.ts.map +1 -0
- package/dist/src/tui/install-ui/KgVendorConfig.js +9 -0
- package/dist/src/tui/install-ui/KgVendorConfig.js.map +1 -0
- package/dist/src/utils/update-notices.js +23 -0
- package/dist/src/utils/update-notices.js.map +1 -1
- package/package.json +1 -1
- package/workflows/analyze.md +2 -1
- package/workflows/brainstorm.md +24 -1
- package/workflows/codebase-rebuild.md +141 -1
- package/workflows/codebase-refresh.md +20 -0
- package/workflows/finish-work.md +7 -2
- package/workflows/grill.md +513 -0
- package/workflows/plan.md +7 -4
- package/workflows/specs-setup.md +99 -3
- package/workflows/swarm/wf-analyze.js +347 -0
- package/workflows/swarm/wf-brainstorm.js +456 -0
- package/workflows/swarm/wf-execute.js +379 -0
- package/workflows/swarm/wf-grill.js +359 -0
- package/workflows/swarm/wf-milestone-audit.js +385 -0
- package/workflows/swarm/wf-plan.js +468 -0
- package/workflows/swarm/wf-review.js +341 -0
- package/workflows/swarm/wf-verify.js +395 -0
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
export const meta = {
|
|
2
|
+
name: 'wf-verify',
|
|
3
|
+
description: 'Three-layer verification with prosecutor/defender/judge adversarial aggregation',
|
|
4
|
+
whenToUse: 'Accelerate maestro-verify with parallel layer checks + adversarial pass/fail determination',
|
|
5
|
+
phases: [
|
|
6
|
+
{ title: 'Check', detail: 'Parallel 3-layer verification + anti-pattern scan via workflow-verifier' },
|
|
7
|
+
{ title: 'Argue', detail: 'Prosecutor argues FAIL, Defender argues PASS — adversarial positions' },
|
|
8
|
+
{ title: 'Judge', detail: 'Judge resolves adversarial debate into final verdict' },
|
|
9
|
+
],
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const LAYER_SCHEMA = {
|
|
13
|
+
type: 'object',
|
|
14
|
+
properties: {
|
|
15
|
+
layer: { type: 'string', enum: ['existence', 'substance', 'connection'] },
|
|
16
|
+
passed: { type: 'boolean' },
|
|
17
|
+
checks: {
|
|
18
|
+
type: 'array',
|
|
19
|
+
items: {
|
|
20
|
+
type: 'object',
|
|
21
|
+
properties: {
|
|
22
|
+
goal: { type: 'string' },
|
|
23
|
+
status: { type: 'string', enum: ['pass', 'fail', 'partial', 'skip'] },
|
|
24
|
+
evidence: { type: 'string' },
|
|
25
|
+
file: { type: 'string' },
|
|
26
|
+
gap: { type: 'string' },
|
|
27
|
+
},
|
|
28
|
+
required: ['goal', 'status', 'evidence'],
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
summary: { type: 'string' },
|
|
32
|
+
},
|
|
33
|
+
required: ['layer', 'passed', 'checks', 'summary'],
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const CONVERGENCE_SCHEMA = {
|
|
37
|
+
type: 'object',
|
|
38
|
+
properties: {
|
|
39
|
+
task_id: { type: 'string' },
|
|
40
|
+
criteria_results: {
|
|
41
|
+
type: 'array',
|
|
42
|
+
items: {
|
|
43
|
+
type: 'object',
|
|
44
|
+
properties: {
|
|
45
|
+
criterion: { type: 'string' },
|
|
46
|
+
met: { type: 'boolean' },
|
|
47
|
+
evidence: { type: 'string' },
|
|
48
|
+
verification_command: { type: 'string' },
|
|
49
|
+
command_output: { type: 'string' },
|
|
50
|
+
},
|
|
51
|
+
required: ['criterion', 'met', 'evidence'],
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
overall_converged: { type: 'boolean' },
|
|
55
|
+
},
|
|
56
|
+
required: ['task_id', 'criteria_results', 'overall_converged'],
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const ANTIPATTERN_SCHEMA = {
|
|
60
|
+
type: 'object',
|
|
61
|
+
properties: {
|
|
62
|
+
clean: { type: 'boolean' },
|
|
63
|
+
findings: {
|
|
64
|
+
type: 'array',
|
|
65
|
+
items: {
|
|
66
|
+
type: 'object',
|
|
67
|
+
properties: {
|
|
68
|
+
type: { type: 'string', enum: ['stub', 'placeholder', 'todo', 'fixme', 'empty-return', 'empty-catch', 'ts-ignore', 'skip-test', 'hardcoded-secret', 'not-implemented'] },
|
|
69
|
+
file: { type: 'string' },
|
|
70
|
+
line: { type: 'number' },
|
|
71
|
+
content: { type: 'string' },
|
|
72
|
+
severity: { type: 'string', enum: ['blocker', 'warning'] },
|
|
73
|
+
},
|
|
74
|
+
required: ['type', 'file', 'content', 'severity'],
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
required: ['clean', 'findings'],
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const ARGUMENT_SCHEMA = {
|
|
82
|
+
type: 'object',
|
|
83
|
+
properties: {
|
|
84
|
+
role: { type: 'string', enum: ['prosecutor', 'defender'] },
|
|
85
|
+
stance: { type: 'string', enum: ['pass', 'fail'] },
|
|
86
|
+
argument: { type: 'string' },
|
|
87
|
+
key_points: {
|
|
88
|
+
type: 'array',
|
|
89
|
+
items: {
|
|
90
|
+
type: 'object',
|
|
91
|
+
properties: {
|
|
92
|
+
point: { type: 'string' },
|
|
93
|
+
evidence: { type: 'string' },
|
|
94
|
+
layer: { type: 'string' },
|
|
95
|
+
strength: { type: 'string', enum: ['strong', 'moderate', 'weak'] },
|
|
96
|
+
},
|
|
97
|
+
required: ['point', 'evidence', 'strength'],
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
concessions: { type: 'array', items: { type: 'string' } },
|
|
101
|
+
confidence: { type: 'number', minimum: 0, maximum: 100 },
|
|
102
|
+
},
|
|
103
|
+
required: ['role', 'stance', 'argument', 'key_points', 'confidence'],
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const AGGREGATE_SCHEMA = {
|
|
107
|
+
type: 'object',
|
|
108
|
+
properties: {
|
|
109
|
+
status: { type: 'string', enum: ['pass', 'fail'] },
|
|
110
|
+
confidence: { type: 'number', minimum: 0, maximum: 100 },
|
|
111
|
+
adversarial_outcome: {
|
|
112
|
+
type: 'object',
|
|
113
|
+
properties: {
|
|
114
|
+
prosecutor_confidence: { type: 'number' },
|
|
115
|
+
defender_confidence: { type: 'number' },
|
|
116
|
+
decisive_factor: { type: 'string' },
|
|
117
|
+
prosecutor_concessions: { type: 'array', items: { type: 'string' } },
|
|
118
|
+
defender_concessions: { type: 'array', items: { type: 'string' } },
|
|
119
|
+
},
|
|
120
|
+
required: ['prosecutor_confidence', 'defender_confidence', 'decisive_factor'],
|
|
121
|
+
},
|
|
122
|
+
layers: {
|
|
123
|
+
type: 'array',
|
|
124
|
+
items: {
|
|
125
|
+
type: 'object',
|
|
126
|
+
properties: {
|
|
127
|
+
layer: { type: 'string' },
|
|
128
|
+
passed: { type: 'boolean' },
|
|
129
|
+
total_checks: { type: 'number' },
|
|
130
|
+
passed_checks: { type: 'number' },
|
|
131
|
+
failed_checks: { type: 'number' },
|
|
132
|
+
},
|
|
133
|
+
required: ['layer', 'passed', 'total_checks', 'passed_checks'],
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
convergence_summary: {
|
|
137
|
+
type: 'object',
|
|
138
|
+
properties: {
|
|
139
|
+
total_tasks: { type: 'number' },
|
|
140
|
+
converged_tasks: { type: 'number' },
|
|
141
|
+
unmet_criteria: { type: 'array', items: { type: 'object', properties: { task: { type: 'string' }, criterion: { type: 'string' } }, required: ['task', 'criterion'] } },
|
|
142
|
+
},
|
|
143
|
+
required: ['total_tasks', 'converged_tasks'],
|
|
144
|
+
},
|
|
145
|
+
gaps: {
|
|
146
|
+
type: 'array',
|
|
147
|
+
items: {
|
|
148
|
+
type: 'object',
|
|
149
|
+
properties: {
|
|
150
|
+
description: { type: 'string' },
|
|
151
|
+
source_layer: { type: 'string' },
|
|
152
|
+
severity: { type: 'string', enum: ['critical', 'high', 'medium', 'low'] },
|
|
153
|
+
remediation: { type: 'string' },
|
|
154
|
+
affected_files: { type: 'array', items: { type: 'string' } },
|
|
155
|
+
},
|
|
156
|
+
required: ['description', 'source_layer', 'severity', 'remediation'],
|
|
157
|
+
},
|
|
158
|
+
},
|
|
159
|
+
antipattern_blockers: { type: 'number' },
|
|
160
|
+
executive_summary: { type: 'string' },
|
|
161
|
+
},
|
|
162
|
+
required: ['status', 'confidence', 'adversarial_outcome', 'layers', 'gaps', 'executive_summary'],
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const goals = args?.goals || ''
|
|
166
|
+
const planDir = args?.plan_dir || ''
|
|
167
|
+
const scope = args?.scope || ''
|
|
168
|
+
const taskFiles = args?.task_files || []
|
|
169
|
+
const skipTests = args?.skip_tests || false
|
|
170
|
+
const skipAntipattern = args?.skip_antipattern || false
|
|
171
|
+
const mustHaves = args?.must_haves || ''
|
|
172
|
+
|
|
173
|
+
// Phase 1: Parallel 3-layer + anti-pattern + convergence checks
|
|
174
|
+
phase('Check')
|
|
175
|
+
|
|
176
|
+
const checks = [
|
|
177
|
+
() => agent(
|
|
178
|
+
`Layer 1 — EXISTENCE verification.
|
|
179
|
+
Goals: ${goals}
|
|
180
|
+
${planDir ? 'Plan directory: ' + planDir + ' — read task JSONs for expected files[]' : ''}
|
|
181
|
+
${scope ? 'Scope: ' + scope : ''}
|
|
182
|
+
${mustHaves ? 'Must-haves (artifacts): ' + mustHaves : ''}
|
|
183
|
+
|
|
184
|
+
Verify all expected artifacts EXIST:
|
|
185
|
+
1. Read task JSON files in plan directory to find files[].path where action="create"
|
|
186
|
+
2. Check each expected file exists on disk (Glob/Read)
|
|
187
|
+
3. Verify functions/classes/modules are present at files[].target
|
|
188
|
+
4. Check configuration entries are added
|
|
189
|
+
5. Report pass/fail with evidence (actual file paths found or missing)
|
|
190
|
+
|
|
191
|
+
Set layer="existence" in output.`,
|
|
192
|
+
{ label: 'layer:existence', phase: 'Check', schema: LAYER_SCHEMA, agentType: 'workflow-verifier' }
|
|
193
|
+
),
|
|
194
|
+
() => agent(
|
|
195
|
+
`Layer 2 — SUBSTANCE verification.
|
|
196
|
+
Goals: ${goals}
|
|
197
|
+
${planDir ? 'Plan directory: ' + planDir : ''}
|
|
198
|
+
${scope ? 'Scope: ' + scope : ''}
|
|
199
|
+
|
|
200
|
+
Verify artifacts contain REAL SUBSTANCE (not stubs):
|
|
201
|
+
1. Read implementation files — check for meaningful logic (not empty bodies, not pass-through)
|
|
202
|
+
2. Verify functions have real implementations (not "throw new Error('not implemented')")
|
|
203
|
+
3. Check tests actually test behavior (not empty test cases or skipped tests)
|
|
204
|
+
4. Verify configuration values are real (not placeholder/TODO values)
|
|
205
|
+
5. Check error handling is substantive (not empty catch blocks)
|
|
206
|
+
|
|
207
|
+
Set layer="substance" in output.`,
|
|
208
|
+
{ label: 'layer:substance', phase: 'Check', schema: LAYER_SCHEMA, agentType: 'workflow-verifier' }
|
|
209
|
+
),
|
|
210
|
+
() => agent(
|
|
211
|
+
`Layer 3 — CONNECTION verification.
|
|
212
|
+
Goals: ${goals}
|
|
213
|
+
${planDir ? 'Plan directory: ' + planDir : ''}
|
|
214
|
+
${scope ? 'Scope: ' + scope : ''}
|
|
215
|
+
${mustHaves ? 'Must-haves (key_links): ' + mustHaves : ''}
|
|
216
|
+
|
|
217
|
+
Verify artifacts are properly WIRED together:
|
|
218
|
+
1. Check imports resolve correctly (no broken import paths)
|
|
219
|
+
2. Verify new modules are registered/exported from index files
|
|
220
|
+
3. Check routes are mounted, handlers connected
|
|
221
|
+
4. Verify event handlers and callbacks are wired
|
|
222
|
+
5. Check database models are used consistently across layers
|
|
223
|
+
6. Verify dependency injection and configuration loading
|
|
224
|
+
|
|
225
|
+
Set layer="connection" in output.`,
|
|
226
|
+
{ label: 'layer:connection', phase: 'Check', schema: LAYER_SCHEMA, agentType: 'workflow-verifier' }
|
|
227
|
+
),
|
|
228
|
+
]
|
|
229
|
+
|
|
230
|
+
if (!skipAntipattern) {
|
|
231
|
+
checks.push(() => agent(
|
|
232
|
+
`Anti-pattern scan for modified files.
|
|
233
|
+
${scope ? 'Scope: ' + scope : 'Scan recently modified files (use git diff --name-only).'}
|
|
234
|
+
|
|
235
|
+
Search for code quality anti-patterns using grep:
|
|
236
|
+
- TODO / FIXME comments that indicate incomplete work
|
|
237
|
+
- Empty catch blocks: catch (e) {} or catch { }
|
|
238
|
+
- Empty returns in functions that should return values
|
|
239
|
+
- @ts-ignore / @ts-expect-error without explanatory comment
|
|
240
|
+
- Skipped tests: .skip, xit, xdescribe, test.skip
|
|
241
|
+
- Hardcoded secrets: password=, api_key=, secret= with literal values
|
|
242
|
+
- Placeholder text: "lorem ipsum", "test123", "TODO", "PLACEHOLDER"
|
|
243
|
+
- Not-implemented stubs: throw new Error("not implemented"), pass, ...
|
|
244
|
+
|
|
245
|
+
Use Grep tool to find these patterns. Report each with exact file and line number.
|
|
246
|
+
Severity: "blocker" for stubs/not-implemented/hardcoded-secrets, "warning" for TODO/FIXME.`,
|
|
247
|
+
{ label: 'antipattern', phase: 'Check', schema: ANTIPATTERN_SCHEMA, agentType: 'workflow-verifier' }
|
|
248
|
+
))
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
if (taskFiles.length > 0) {
|
|
252
|
+
checks.push(...taskFiles.map((taskFile, idx) => () => agent(
|
|
253
|
+
`Per-task convergence validation for: ${taskFile}
|
|
254
|
+
|
|
255
|
+
1. Read the task JSON file at: ${taskFile}
|
|
256
|
+
2. Find convergence.criteria[] — each item is a condition that must be true
|
|
257
|
+
3. If convergence.verification command exists, run it via Bash
|
|
258
|
+
4. Check each criterion individually (pass/fail with specific evidence)
|
|
259
|
+
5. Cross-reference with task summaries in .summaries/ if they exist
|
|
260
|
+
|
|
261
|
+
Report overall_converged=true only if ALL criteria are met.`,
|
|
262
|
+
{ label: `convergence:task-${idx}`, phase: 'Check', schema: CONVERGENCE_SCHEMA, agentType: 'workflow-verifier' }
|
|
263
|
+
)))
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
log(`Running ${checks.length} parallel verification checks...`)
|
|
267
|
+
const results = await parallel(checks)
|
|
268
|
+
const validResults = results.filter(Boolean)
|
|
269
|
+
|
|
270
|
+
const layers = validResults.filter(r => r.layer)
|
|
271
|
+
const antipatterns = validResults.find(r => r.clean !== undefined) || { clean: true, findings: [] }
|
|
272
|
+
const convergenceResults = validResults.filter(r => r.task_id)
|
|
273
|
+
|
|
274
|
+
const layerDigest = layers.map(l => {
|
|
275
|
+
const passCount = l.checks.filter(c => c.status === 'pass').length
|
|
276
|
+
const failCount = l.checks.filter(c => c.status === 'fail').length
|
|
277
|
+
return `Layer: ${l.layer} — ${l.passed ? 'PASS' : 'FAIL'} (${passCount} pass, ${failCount} fail)\n${l.summary}\nFailed checks:\n${l.checks.filter(c => c.status === 'fail').map(c => ` - ${c.goal}: ${c.gap || c.evidence}`).join('\n') || ' none'}`
|
|
278
|
+
}).join('\n\n')
|
|
279
|
+
|
|
280
|
+
const convergenceDigest = convergenceResults.length > 0
|
|
281
|
+
? `Convergence: ${convergenceResults.filter(c => c.overall_converged).length}/${convergenceResults.length} tasks converged\nUnmet criteria:\n${convergenceResults.filter(c => !c.overall_converged).flatMap(c => c.criteria_results.filter(cr => !cr.met).map(cr => ` - ${c.task_id}: ${cr.criterion}`)).join('\n') || ' none'}`
|
|
282
|
+
: 'No convergence criteria checked (no task files provided).'
|
|
283
|
+
|
|
284
|
+
const antipatternDigest = antipatterns.clean
|
|
285
|
+
? 'Anti-pattern scan: CLEAN'
|
|
286
|
+
: `Anti-pattern scan: ${antipatterns.findings.length} issues (${antipatterns.findings.filter(f => f.severity === 'blocker').length} blockers)\n${antipatterns.findings.map(f => ` [${f.severity}] ${f.type} @ ${f.file}:${f.line || '?'}: ${f.content}`).join('\n')}`
|
|
287
|
+
|
|
288
|
+
const evidencePackage = `${layerDigest}\n\n${convergenceDigest}\n\n${antipatternDigest}`
|
|
289
|
+
|
|
290
|
+
// Phase 2: Adversarial Arguments — Prosecutor vs Defender
|
|
291
|
+
phase('Argue')
|
|
292
|
+
log('Launching adversarial debate: Prosecutor (FAIL) vs Defender (PASS)...')
|
|
293
|
+
|
|
294
|
+
const arguments_ = await parallel([
|
|
295
|
+
() => agent(
|
|
296
|
+
`You are the PROSECUTOR. Argue that this verification should FAIL.
|
|
297
|
+
|
|
298
|
+
=== VERIFICATION EVIDENCE ===
|
|
299
|
+
${evidencePackage}
|
|
300
|
+
|
|
301
|
+
Build the STRONGEST case for FAILURE:
|
|
302
|
+
1. Magnify every failed check — explain the downstream consequences
|
|
303
|
+
2. Connect antipattern findings to substance/connection failures
|
|
304
|
+
3. Challenge "pass" checks — are they truly passing or just not checking hard enough?
|
|
305
|
+
4. Highlight convergence gaps as unfinished work
|
|
306
|
+
5. Argue that partial passes are effectively failures
|
|
307
|
+
|
|
308
|
+
Your job is to convince the Judge that quality is insufficient.
|
|
309
|
+
Concede points where the evidence genuinely supports a pass — admitted concessions strengthen your credibility.
|
|
310
|
+
Confidence reflects how strong your FAIL case actually is.`,
|
|
311
|
+
{ label: 'prosecutor', phase: 'Argue', schema: ARGUMENT_SCHEMA }
|
|
312
|
+
),
|
|
313
|
+
() => agent(
|
|
314
|
+
`You are the DEFENDER. Argue that this verification should PASS.
|
|
315
|
+
|
|
316
|
+
=== VERIFICATION EVIDENCE ===
|
|
317
|
+
${evidencePackage}
|
|
318
|
+
|
|
319
|
+
Build the STRONGEST case for PASSING:
|
|
320
|
+
1. Emphasize passed checks and their coverage
|
|
321
|
+
2. Contextualize failures — are they truly blocking or just minor gaps?
|
|
322
|
+
3. Argue that antipattern warnings don't indicate real quality issues
|
|
323
|
+
4. Show that the core goals are met even if some checks are partial
|
|
324
|
+
5. Demonstrate that failed checks have low real-world impact
|
|
325
|
+
|
|
326
|
+
Your job is to convince the Judge that quality is sufficient.
|
|
327
|
+
Concede points where the evidence genuinely supports a fail — admitted concessions strengthen your credibility.
|
|
328
|
+
Confidence reflects how strong your PASS case actually is.`,
|
|
329
|
+
{ label: 'defender', phase: 'Argue', schema: ARGUMENT_SCHEMA }
|
|
330
|
+
),
|
|
331
|
+
])
|
|
332
|
+
|
|
333
|
+
const validArguments = arguments_.filter(Boolean)
|
|
334
|
+
const prosecutorArg = validArguments.find(a => a.role === 'prosecutor')
|
|
335
|
+
const defenderArg = validArguments.find(a => a.role === 'defender')
|
|
336
|
+
|
|
337
|
+
const debateDigest = validArguments.map(a =>
|
|
338
|
+
`### ${a.role.toUpperCase()} (stance: ${a.stance}, confidence: ${a.confidence}%)\n${a.argument}\n\nKey points:\n${a.key_points.map(p => `- [${p.strength}] ${p.point} (evidence: ${p.evidence})`).join('\n')}\n\nConcessions:\n${a.concessions.map(c => `- ${c}`).join('\n') || ' none'}`
|
|
339
|
+
).join('\n\n---\n\n')
|
|
340
|
+
|
|
341
|
+
log(`Prosecutor: ${prosecutorArg ? prosecutorArg.confidence : '?'}% confident FAIL | Defender: ${defenderArg ? defenderArg.confidence : '?'}% confident PASS`)
|
|
342
|
+
|
|
343
|
+
// Phase 3: Judge resolves the adversarial debate
|
|
344
|
+
phase('Judge')
|
|
345
|
+
log('Judge resolving adversarial verification debate...')
|
|
346
|
+
|
|
347
|
+
const aggregate = await agent(
|
|
348
|
+
`You are the JUDGE. Two advocates have argued for and against passing this verification.
|
|
349
|
+
|
|
350
|
+
=== ADVERSARIAL DEBATE ===
|
|
351
|
+
${debateDigest}
|
|
352
|
+
|
|
353
|
+
=== RAW EVIDENCE ===
|
|
354
|
+
${evidencePackage}
|
|
355
|
+
|
|
356
|
+
JUDGE the debate:
|
|
357
|
+
1. Evaluate each advocate's key points against the raw evidence
|
|
358
|
+
2. Weigh point strength: strong > moderate > weak
|
|
359
|
+
3. Points conceded by the opposing side have extra weight
|
|
360
|
+
4. Check for arguments NOT backed by evidence (rhetoric without substance)
|
|
361
|
+
|
|
362
|
+
Decision rules:
|
|
363
|
+
- If ALL layers truly pass AND antipattern clean AND convergence met → PASS
|
|
364
|
+
- If any layer has >50% failed checks → FAIL regardless of defense
|
|
365
|
+
- If antipattern has blockers → FAIL unless defender proves they're false positives
|
|
366
|
+
- If prosecutor confidence > 80% AND defender concedes major points → FAIL
|
|
367
|
+
- If defender confidence > 80% AND prosecutor only has weak points → PASS
|
|
368
|
+
- Otherwise → weigh evidence strength on both sides
|
|
369
|
+
|
|
370
|
+
Record adversarial_outcome with both confidences, concessions, and the decisive_factor.
|
|
371
|
+
Compile layers, convergence_summary, gaps, and executive_summary.`,
|
|
372
|
+
{ label: 'judge', phase: 'Judge', schema: AGGREGATE_SCHEMA }
|
|
373
|
+
)
|
|
374
|
+
|
|
375
|
+
return {
|
|
376
|
+
layers: layers,
|
|
377
|
+
convergence: convergenceResults,
|
|
378
|
+
antipatterns: antipatterns,
|
|
379
|
+
debate: { prosecutor: prosecutorArg, defender: defenderArg },
|
|
380
|
+
aggregate: aggregate,
|
|
381
|
+
metadata: {
|
|
382
|
+
layer_count: layers.length,
|
|
383
|
+
total_checks: layers.reduce((sum, l) => sum + l.checks.length, 0),
|
|
384
|
+
passed_checks: layers.reduce((sum, l) => sum + l.checks.filter(c => c.status === 'pass').length, 0),
|
|
385
|
+
failed_checks: layers.reduce((sum, l) => sum + l.checks.filter(c => c.status === 'fail').length, 0),
|
|
386
|
+
convergence_tasks: convergenceResults.length,
|
|
387
|
+
converged_tasks: convergenceResults.filter(c => c.overall_converged).length,
|
|
388
|
+
antipattern_count: antipatterns.findings.length,
|
|
389
|
+
blocker_count: antipatterns.findings.filter(f => f.severity === 'blocker').length,
|
|
390
|
+
prosecutor_confidence: prosecutorArg ? prosecutorArg.confidence : null,
|
|
391
|
+
defender_confidence: defenderArg ? defenderArg.confidence : null,
|
|
392
|
+
overall_status: aggregate ? aggregate.status : 'unknown',
|
|
393
|
+
confidence: aggregate ? aggregate.confidence : 0,
|
|
394
|
+
},
|
|
395
|
+
}
|