maestro-flow 0.4.19 → 0.4.20

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 (122) hide show
  1. package/.agents/agents/workflow-collab-planner.md +4 -1
  2. package/.agents/agents/workflow-plan-checker.md +11 -1
  3. package/.agents/agents/workflow-planner.md +4 -1
  4. package/.agents/skills/maestro/SKILL.md +8 -5
  5. package/.agents/skills/maestro-analyze/SKILL.md +1 -1
  6. package/.agents/skills/maestro-brainstorm/SKILL.md +2 -1
  7. package/.agents/skills/maestro-companion/SKILL.md +533 -0
  8. package/.agents/skills/maestro-grill/SKILL.md +116 -0
  9. package/.agents/skills/maestro-plan/SKILL.md +4 -0
  10. package/.agents/skills/maestro-ralph/SKILL.md +11 -7
  11. package/.agents/skills/maestro-swarm-workflow/SKILL.md +258 -0
  12. package/.agents/skills/manage-codebase-rebuild/SKILL.md +13 -1
  13. package/.agents/skills/manage-codebase-refresh/SKILL.md +3 -0
  14. package/.agents/skills/spec-setup/SKILL.md +9 -5
  15. package/.agy/agents/workflow-collab-planner.md +4 -1
  16. package/.agy/agents/workflow-plan-checker.md +11 -1
  17. package/.agy/agents/workflow-planner.md +4 -1
  18. package/.agy/skills/maestro/SKILL.md +8 -5
  19. package/.agy/skills/maestro-analyze/SKILL.md +1 -1
  20. package/.agy/skills/maestro-brainstorm/SKILL.md +2 -1
  21. package/.agy/skills/maestro-companion/SKILL.md +529 -0
  22. package/.agy/skills/maestro-grill/SKILL.md +116 -0
  23. package/.agy/skills/maestro-plan/SKILL.md +4 -0
  24. package/.agy/skills/maestro-ralph/SKILL.md +11 -7
  25. package/.agy/skills/maestro-swarm-workflow/SKILL.md +255 -0
  26. package/.agy/skills/manage-codebase-rebuild/SKILL.md +13 -1
  27. package/.agy/skills/manage-codebase-refresh/SKILL.md +3 -0
  28. package/.agy/skills/spec-setup/SKILL.md +9 -5
  29. package/.claude/agents/workflow-collab-planner.md +4 -1
  30. package/.claude/agents/workflow-plan-checker.md +11 -1
  31. package/.claude/agents/workflow-planner.md +4 -1
  32. package/.claude/commands/maestro-analyze.md +1 -1
  33. package/.claude/commands/maestro-brainstorm.md +2 -1
  34. package/.claude/commands/maestro-companion.md +531 -0
  35. package/.claude/commands/maestro-grill.md +114 -0
  36. package/.claude/commands/maestro-plan.md +4 -0
  37. package/.claude/commands/maestro-ralph.md +11 -7
  38. package/.claude/commands/maestro-swarm-workflow.md +256 -0
  39. package/.claude/commands/maestro.md +8 -5
  40. package/.claude/commands/manage-codebase-rebuild.md +13 -1
  41. package/.claude/commands/manage-codebase-refresh.md +3 -0
  42. package/.claude/commands/spec-setup.md +9 -5
  43. package/.codex/skills/maestro/SKILL.md +7 -2
  44. package/.codex/skills/maestro-companion/SKILL.md +485 -0
  45. package/.codex/skills/maestro-grill/SKILL.md +111 -0
  46. package/.codex/skills/maestro-ralph/SKILL.md +11 -7
  47. package/.codex/skills/manage-codebase-rebuild/SKILL.md +6 -0
  48. package/.codex/skills/manage-codebase-refresh/SKILL.md +6 -0
  49. package/dashboard/dist-server/dashboard/src/server/wiki/graph-analysis.d.ts +36 -0
  50. package/dashboard/dist-server/dashboard/src/server/wiki/graph-analysis.js +138 -2
  51. package/dashboard/dist-server/dashboard/src/server/wiki/graph-analysis.js.map +1 -1
  52. package/dashboard/dist-server/dashboard/src/server/wiki/search.js +13 -0
  53. package/dashboard/dist-server/dashboard/src/server/wiki/search.js.map +1 -1
  54. package/dashboard/dist-server/dashboard/src/server/wiki/virtual-wiki-adapters.d.ts +11 -0
  55. package/dashboard/dist-server/dashboard/src/server/wiki/virtual-wiki-adapters.js +178 -0
  56. package/dashboard/dist-server/dashboard/src/server/wiki/virtual-wiki-adapters.js.map +1 -1
  57. package/dashboard/dist-server/dashboard/src/server/wiki/wiki-indexer.d.ts +1 -0
  58. package/dashboard/dist-server/dashboard/src/server/wiki/wiki-indexer.js +39 -23
  59. package/dashboard/dist-server/dashboard/src/server/wiki/wiki-indexer.js.map +1 -1
  60. package/dist/src/cli.js +1 -0
  61. package/dist/src/cli.js.map +1 -1
  62. package/dist/src/commands/install-backend.d.ts +7 -0
  63. package/dist/src/commands/install-backend.d.ts.map +1 -1
  64. package/dist/src/commands/install-backend.js +14 -0
  65. package/dist/src/commands/install-backend.js.map +1 -1
  66. package/dist/src/commands/install.d.ts.map +1 -1
  67. package/dist/src/commands/install.js +18 -0
  68. package/dist/src/commands/install.js.map +1 -1
  69. package/dist/src/commands/kg.d.ts +11 -0
  70. package/dist/src/commands/kg.d.ts.map +1 -0
  71. package/dist/src/commands/kg.js +515 -0
  72. package/dist/src/commands/kg.js.map +1 -0
  73. package/dist/src/i18n/locales/en.d.ts.map +1 -1
  74. package/dist/src/i18n/locales/en.js +10 -0
  75. package/dist/src/i18n/locales/en.js.map +1 -1
  76. package/dist/src/i18n/locales/zh.d.ts.map +1 -1
  77. package/dist/src/i18n/locales/zh.js +10 -0
  78. package/dist/src/i18n/locales/zh.js.map +1 -1
  79. package/dist/src/i18n/types.d.ts +9 -0
  80. package/dist/src/i18n/types.d.ts.map +1 -1
  81. package/dist/src/tui/install-ui/InstallConfirm.d.ts +1 -0
  82. package/dist/src/tui/install-ui/InstallConfirm.d.ts.map +1 -1
  83. package/dist/src/tui/install-ui/InstallConfirm.js +1 -1
  84. package/dist/src/tui/install-ui/InstallConfirm.js.map +1 -1
  85. package/dist/src/tui/install-ui/InstallExecution.d.ts +1 -0
  86. package/dist/src/tui/install-ui/InstallExecution.d.ts.map +1 -1
  87. package/dist/src/tui/install-ui/InstallExecution.js +22 -0
  88. package/dist/src/tui/install-ui/InstallExecution.js.map +1 -1
  89. package/dist/src/tui/install-ui/InstallFlow.d.ts +1 -1
  90. package/dist/src/tui/install-ui/InstallFlow.d.ts.map +1 -1
  91. package/dist/src/tui/install-ui/InstallFlow.js +23 -5
  92. package/dist/src/tui/install-ui/InstallFlow.js.map +1 -1
  93. package/dist/src/tui/install-ui/InstallHub.d.ts +2 -0
  94. package/dist/src/tui/install-ui/InstallHub.d.ts.map +1 -1
  95. package/dist/src/tui/install-ui/InstallHub.js +6 -0
  96. package/dist/src/tui/install-ui/InstallHub.js.map +1 -1
  97. package/dist/src/tui/install-ui/InstallResult.d.ts.map +1 -1
  98. package/dist/src/tui/install-ui/InstallResult.js +1 -1
  99. package/dist/src/tui/install-ui/InstallResult.js.map +1 -1
  100. package/dist/src/tui/install-ui/KgVendorConfig.d.ts +7 -0
  101. package/dist/src/tui/install-ui/KgVendorConfig.d.ts.map +1 -0
  102. package/dist/src/tui/install-ui/KgVendorConfig.js +9 -0
  103. package/dist/src/tui/install-ui/KgVendorConfig.js.map +1 -0
  104. package/dist/src/utils/update-notices.js +11 -0
  105. package/dist/src/utils/update-notices.js.map +1 -1
  106. package/package.json +1 -1
  107. package/workflows/analyze.md +2 -1
  108. package/workflows/brainstorm.md +24 -1
  109. package/workflows/codebase-rebuild.md +141 -1
  110. package/workflows/codebase-refresh.md +20 -0
  111. package/workflows/finish-work.md +7 -2
  112. package/workflows/grill.md +513 -0
  113. package/workflows/plan.md +7 -4
  114. package/workflows/specs-setup.md +99 -3
  115. package/workflows/swarm/wf-analyze.js +186 -0
  116. package/workflows/swarm/wf-brainstorm.js +284 -0
  117. package/workflows/swarm/wf-execute.js +203 -0
  118. package/workflows/swarm/wf-grill.js +198 -0
  119. package/workflows/swarm/wf-milestone-audit.js +236 -0
  120. package/workflows/swarm/wf-plan.js +233 -0
  121. package/workflows/swarm/wf-review.js +226 -0
  122. package/workflows/swarm/wf-verify.js +298 -0
@@ -0,0 +1,226 @@
1
+ export const meta = {
2
+ name: 'wf-review',
3
+ description: 'Multi-dimension parallel code review via workflow-reviewer with adversarial verification',
4
+ whenToUse: 'Accelerate quality-review with parallel dimension-specific scanning and finding verification',
5
+ phases: [
6
+ { title: 'Scan', detail: 'Parallel dimension scanning via workflow-reviewer' },
7
+ { title: 'Verify', detail: 'Adversarial verification of critical findings' },
8
+ { title: 'Report', detail: 'Consolidated review report with verdict' },
9
+ ],
10
+ }
11
+
12
+ // Aligned with workflow-reviewer.md dimension definitions
13
+ const REVIEW_DIMENSIONS = [
14
+ { key: 'correctness', prefix: 'COR', prompt: 'Dimension: correctness. Focus: Logic errors, off-by-one, null handling, missing error propagation, type mismatches, unhandled edge cases, broken invariants, incorrect conditions.' },
15
+ { key: 'security', prefix: 'SEC', prompt: 'Dimension: security. Focus: Injection vectors (SQL/command/XSS), auth bypass, hardcoded secrets, missing input validation, data exposure in logs/errors, SSRF, IDOR, insecure crypto.' },
16
+ { key: 'performance', prefix: 'PRF', prompt: 'Dimension: performance. Focus: O(n^2+) algorithms, N+1 queries, missing pagination, resource leaks (unclosed handles/streams), synchronous blocking, missing caching, bundle size impact.' },
17
+ { key: 'architecture', prefix: 'ARC', prompt: 'Dimension: architecture. Focus: Layer violations (UI calling DB directly), circular dependencies, god classes/functions, inconsistent patterns, tight coupling, missing abstractions.' },
18
+ { key: 'maintainability', prefix: 'MNT', prompt: 'Dimension: maintainability. Focus: Functions >50 lines, cyclomatic complexity >10, duplicated logic, unclear naming, dead code, missing error context, poor separation of concerns.' },
19
+ { key: 'best-practices', prefix: 'BPR', prompt: 'Dimension: best-practices. Focus: Deprecated API usage, framework anti-patterns, inconsistent style with codebase, missing TypeScript strict checks, raw `any` types, missing documentation for public APIs.' },
20
+ ]
21
+
22
+ const FINDING_SCHEMA = {
23
+ type: 'object',
24
+ properties: {
25
+ dimension: { type: 'string' },
26
+ findings: {
27
+ type: 'array',
28
+ items: {
29
+ type: 'object',
30
+ properties: {
31
+ id: { type: 'string' },
32
+ dimension: { type: 'string' },
33
+ severity: { type: 'string', enum: ['critical', 'high', 'medium', 'low'] },
34
+ title: { type: 'string' },
35
+ file: { type: 'string' },
36
+ line: { type: 'number' },
37
+ description: { type: 'string' },
38
+ suggestion: { type: 'string' },
39
+ evidence: { type: 'string' },
40
+ },
41
+ required: ['id', 'dimension', 'severity', 'title', 'file', 'description'],
42
+ },
43
+ },
44
+ },
45
+ required: ['dimension', 'findings'],
46
+ }
47
+
48
+ const VERDICT_SCHEMA = {
49
+ type: 'object',
50
+ properties: {
51
+ finding_id: { type: 'string' },
52
+ is_real: { type: 'boolean' },
53
+ confidence: { type: 'number', minimum: 0, maximum: 100 },
54
+ reasoning: { type: 'string' },
55
+ adjusted_severity: { type: 'string', enum: ['critical', 'high', 'medium', 'low', 'false-positive'] },
56
+ },
57
+ required: ['finding_id', 'is_real', 'confidence', 'reasoning'],
58
+ }
59
+
60
+ const REPORT_SCHEMA = {
61
+ type: 'object',
62
+ properties: {
63
+ verdict: { type: 'string', enum: ['APPROVE', 'REQUEST_CHANGES', 'BLOCK'] },
64
+ overall_quality: { type: 'number', minimum: 1, maximum: 5 },
65
+ dimension_summary: {
66
+ type: 'array',
67
+ items: {
68
+ type: 'object',
69
+ properties: {
70
+ dimension: { type: 'string' },
71
+ finding_count: { type: 'number' },
72
+ max_severity: { type: 'string' },
73
+ assessment: { type: 'string' },
74
+ },
75
+ required: ['dimension', 'finding_count'],
76
+ },
77
+ },
78
+ blocking_issues: { type: 'array', items: { type: 'object', properties: { id: { type: 'string' }, title: { type: 'string' }, file: { type: 'string' }, severity: { type: 'string' }, suggestion: { type: 'string' } }, required: ['id', 'title', 'file', 'severity'] } },
79
+ summary: { type: 'string' },
80
+ },
81
+ required: ['verdict', 'overall_quality', 'dimension_summary', 'blocking_issues', 'summary'],
82
+ }
83
+
84
+ const target = args?.target || 'changed files on current branch'
85
+ const scope = args?.scope || ''
86
+ const specs = args?.specs || ''
87
+ const tier = args?.tier || 'standard'
88
+ const dimensions = args?.dimensions
89
+ ? REVIEW_DIMENSIONS.filter(d => args.dimensions.includes(d.key))
90
+ : (tier === 'quick' ? REVIEW_DIMENSIONS.slice(0, 3) : REVIEW_DIMENSIONS)
91
+
92
+ // Phase 1: Parallel dimension scanning via workflow-reviewer
93
+ phase('Scan')
94
+ log(`Scanning ${dimensions.length} dimensions in parallel via workflow-reviewer...`)
95
+
96
+ const scans = await parallel(
97
+ dimensions.map(dim => () =>
98
+ agent(
99
+ `${dim.prompt}
100
+
101
+ Review target: ${target}
102
+ ${scope ? 'Files to review: ' + scope : 'Find changed files via git diff and review them.'}
103
+ ${specs ? 'Project specs/conventions: ' + specs : ''}
104
+
105
+ Process:
106
+ 1. Read the target files (use git diff if no explicit file list)
107
+ 2. Perform structural scan — imports, exports, function signatures, complexity indicators
108
+ 3. Apply dimension-specific analysis rules
109
+ 4. Classify severity: Critical (security vuln, data corruption, crash) / High (logic bug, resource leak) / Medium (code smell, maintainability) / Low (style, minor optimization)
110
+ 5. Return only real, actionable findings with specific file paths, line numbers, and evidence
111
+
112
+ Finding IDs use format: ${dim.prefix}-{NNN}`,
113
+ { label: `scan:${dim.key}`, phase: 'Scan', schema: FINDING_SCHEMA, agentType: 'workflow-reviewer' }
114
+ )
115
+ )
116
+ )
117
+
118
+ const validScans = scans.filter(Boolean)
119
+ const allFindings = validScans.flatMap(s => s.findings)
120
+ const criticalHigh = allFindings.filter(f => f.severity === 'critical' || f.severity === 'high')
121
+
122
+ log(`Found ${allFindings.length} total (${criticalHigh.length} critical/high across ${validScans.length} dimensions)`)
123
+
124
+ // Phase 2: Adversarial verification of critical/high findings
125
+ phase('Verify')
126
+
127
+ if (criticalHigh.length > 0) {
128
+ log(`Adversarially verifying ${criticalHigh.length} critical/high findings...`)
129
+
130
+ const verified = await pipeline(
131
+ criticalHigh,
132
+ (finding) => agent(
133
+ `Adversarially verify this code review finding. Your job is to REFUTE it — find reasons it might be:
134
+ - A false positive (the code is actually correct)
135
+ - Less severe than claimed (downgrade severity)
136
+ - Not applicable in this context
137
+
138
+ Finding: [${finding.severity}] ${finding.id}: ${finding.title}
139
+ File: ${finding.file}${finding.line ? ':' + finding.line : ''}
140
+ Description: ${finding.description}
141
+ Evidence: ${finding.evidence || 'none provided'}
142
+
143
+ Read the actual source code at the specified location. Check:
144
+ 1. Is the code actually doing what the finding claims?
145
+ 2. Is there handling elsewhere that mitigates this?
146
+ 3. Is the severity justified?
147
+
148
+ Default to is_real=false and adjusted_severity=false-positive if uncertain.
149
+ Only confirm findings you can verify in the actual code with high confidence.`,
150
+ { label: `verify:${finding.id}`, phase: 'Verify', schema: VERDICT_SCHEMA }
151
+ )
152
+ )
153
+
154
+ const confirmedFindings = []
155
+ const falsePositives = []
156
+
157
+ verified.filter(Boolean).forEach((verdict, i) => {
158
+ const finding = criticalHigh[i]
159
+ if (verdict.is_real && verdict.confidence >= 60) {
160
+ confirmedFindings.push({ ...finding, verdict: verdict, adjusted_severity: verdict.adjusted_severity || finding.severity })
161
+ } else {
162
+ falsePositives.push({ ...finding, verdict: verdict })
163
+ }
164
+ })
165
+
166
+ const lowMedFindings = allFindings.filter(f => f.severity === 'medium' || f.severity === 'low')
167
+
168
+ // Phase 3: Consolidated report
169
+ phase('Report')
170
+
171
+ const report = await agent(
172
+ `Generate a consolidated code review report.
173
+
174
+ Confirmed findings (adversarially verified, ${confirmedFindings.length}):
175
+ ${confirmedFindings.map(f => `- [${f.adjusted_severity}] ${f.id}: ${f.title} @ ${f.file}:${f.line || '?'} (confidence: ${f.verdict.confidence}%)\n ${f.description}`).join('\n') || 'None'}
176
+
177
+ False positives filtered: ${falsePositives.length}
178
+ ${falsePositives.map(f => `- ${f.id}: ${f.title} — ${f.verdict.reasoning}`).join('\n') || ''}
179
+
180
+ Low/medium findings (not individually verified, ${lowMedFindings.length}):
181
+ ${lowMedFindings.map(f => `- [${f.severity}] ${f.id}: ${f.title} @ ${f.file}`).join('\n') || 'None'}
182
+
183
+ Determine verdict:
184
+ - APPROVE: no confirmed critical/high findings
185
+ - REQUEST_CHANGES: has confirmed high findings but no critical
186
+ - BLOCK: has confirmed critical findings
187
+
188
+ Rate overall quality (1-5) and summarize per dimension.`,
189
+ { label: 'report', phase: 'Report', schema: REPORT_SCHEMA }
190
+ )
191
+
192
+ return {
193
+ report: report,
194
+ confirmed: confirmedFindings,
195
+ false_positives: falsePositives,
196
+ low_findings: lowMedFindings,
197
+ metadata: {
198
+ target: target,
199
+ dimensions_scanned: dimensions.length,
200
+ total_findings: allFindings.length,
201
+ verified_count: criticalHigh.length,
202
+ confirmed_count: confirmedFindings.length,
203
+ false_positive_count: falsePositives.length,
204
+ verdict: report ? report.verdict : 'UNKNOWN',
205
+ },
206
+ }
207
+ } else {
208
+ phase('Report')
209
+ log('No critical/high findings — generating clean report')
210
+
211
+ return {
212
+ report: { verdict: 'APPROVE', overall_quality: 4, dimension_summary: validScans.map(s => ({ dimension: s.dimension, finding_count: s.findings.length, max_severity: s.findings[0]?.severity || 'none', assessment: 'Clean' })), blocking_issues: [], summary: 'No critical or high severity issues found. Code passes review.' },
213
+ confirmed: [],
214
+ false_positives: [],
215
+ low_findings: allFindings,
216
+ metadata: {
217
+ target: target,
218
+ dimensions_scanned: dimensions.length,
219
+ total_findings: allFindings.length,
220
+ verified_count: 0,
221
+ confirmed_count: 0,
222
+ false_positive_count: 0,
223
+ verdict: 'APPROVE',
224
+ },
225
+ }
226
+ }
@@ -0,0 +1,298 @@
1
+ export const meta = {
2
+ name: 'wf-verify',
3
+ description: 'Three-layer goal-backward verification via workflow-verifier + anti-pattern scan',
4
+ whenToUse: 'Accelerate maestro-verify with parallel existence/substance/connection checks and convergence validation',
5
+ phases: [
6
+ { title: 'Check', detail: 'Parallel 3-layer verification + anti-pattern scan via workflow-verifier' },
7
+ { title: 'Aggregate', detail: 'Cross-layer aggregation and gap analysis' },
8
+ ],
9
+ }
10
+
11
+ // Aligned with workflow-verifier.md: Layer 1 Existence, Layer 2 Substance, Layer 3 Connection
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 AGGREGATE_SCHEMA = {
82
+ type: 'object',
83
+ properties: {
84
+ status: { type: 'string', enum: ['pass', 'fail'] },
85
+ confidence: { type: 'number', minimum: 0, maximum: 100 },
86
+ layers: {
87
+ type: 'array',
88
+ items: {
89
+ type: 'object',
90
+ properties: {
91
+ layer: { type: 'string' },
92
+ passed: { type: 'boolean' },
93
+ total_checks: { type: 'number' },
94
+ passed_checks: { type: 'number' },
95
+ failed_checks: { type: 'number' },
96
+ },
97
+ required: ['layer', 'passed', 'total_checks', 'passed_checks'],
98
+ },
99
+ },
100
+ convergence_summary: {
101
+ type: 'object',
102
+ properties: {
103
+ total_tasks: { type: 'number' },
104
+ converged_tasks: { type: 'number' },
105
+ unmet_criteria: { type: 'array', items: { type: 'object', properties: { task: { type: 'string' }, criterion: { type: 'string' } }, required: ['task', 'criterion'] } },
106
+ },
107
+ required: ['total_tasks', 'converged_tasks'],
108
+ },
109
+ gaps: {
110
+ type: 'array',
111
+ items: {
112
+ type: 'object',
113
+ properties: {
114
+ description: { type: 'string' },
115
+ source_layer: { type: 'string' },
116
+ severity: { type: 'string', enum: ['critical', 'high', 'medium', 'low'] },
117
+ remediation: { type: 'string' },
118
+ affected_files: { type: 'array', items: { type: 'string' } },
119
+ },
120
+ required: ['description', 'source_layer', 'severity', 'remediation'],
121
+ },
122
+ },
123
+ antipattern_blockers: { type: 'number' },
124
+ executive_summary: { type: 'string' },
125
+ },
126
+ required: ['status', 'confidence', 'layers', 'gaps', 'executive_summary'],
127
+ }
128
+
129
+ const goals = args?.goals || ''
130
+ const planDir = args?.plan_dir || ''
131
+ const scope = args?.scope || ''
132
+ const taskFiles = args?.task_files || []
133
+ const skipTests = args?.skip_tests || false
134
+ const skipAntipattern = args?.skip_antipattern || false
135
+ const mustHaves = args?.must_haves || ''
136
+
137
+ // Phase 1: Parallel 3-layer + anti-pattern + convergence checks
138
+ phase('Check')
139
+
140
+ const checks = [
141
+ // Layer 1: Existence — verify all expected artifacts exist
142
+ () => agent(
143
+ `Layer 1 — EXISTENCE verification.
144
+ Goals: ${goals}
145
+ ${planDir ? 'Plan directory: ' + planDir + ' — read task JSONs for expected files[]' : ''}
146
+ ${scope ? 'Scope: ' + scope : ''}
147
+ ${mustHaves ? 'Must-haves (artifacts): ' + mustHaves : ''}
148
+
149
+ Verify all expected artifacts EXIST:
150
+ 1. Read task JSON files in plan directory to find files[].path where action="create"
151
+ 2. Check each expected file exists on disk (Glob/Read)
152
+ 3. Verify functions/classes/modules are present at files[].target
153
+ 4. Check configuration entries are added
154
+ 5. Report pass/fail with evidence (actual file paths found or missing)
155
+
156
+ Set layer="existence" in output.`,
157
+ { label: 'layer:existence', phase: 'Check', schema: LAYER_SCHEMA, agentType: 'workflow-verifier' }
158
+ ),
159
+
160
+ // Layer 2: Substance — verify artifacts are non-trivial
161
+ () => agent(
162
+ `Layer 2 — SUBSTANCE verification.
163
+ Goals: ${goals}
164
+ ${planDir ? 'Plan directory: ' + planDir : ''}
165
+ ${scope ? 'Scope: ' + scope : ''}
166
+
167
+ Verify artifacts contain REAL SUBSTANCE (not stubs):
168
+ 1. Read implementation files — check for meaningful logic (not empty bodies, not pass-through)
169
+ 2. Verify functions have real implementations (not "throw new Error('not implemented')")
170
+ 3. Check tests actually test behavior (not empty test cases or skipped tests)
171
+ 4. Verify configuration values are real (not placeholder/TODO values)
172
+ 5. Check error handling is substantive (not empty catch blocks)
173
+
174
+ Set layer="substance" in output.`,
175
+ { label: 'layer:substance', phase: 'Check', schema: LAYER_SCHEMA, agentType: 'workflow-verifier' }
176
+ ),
177
+
178
+ // Layer 3: Connection — verify wiring
179
+ () => agent(
180
+ `Layer 3 — CONNECTION verification.
181
+ Goals: ${goals}
182
+ ${planDir ? 'Plan directory: ' + planDir : ''}
183
+ ${scope ? 'Scope: ' + scope : ''}
184
+ ${mustHaves ? 'Must-haves (key_links): ' + mustHaves : ''}
185
+
186
+ Verify artifacts are properly WIRED together:
187
+ 1. Check imports resolve correctly (no broken import paths)
188
+ 2. Verify new modules are registered/exported from index files
189
+ 3. Check routes are mounted, handlers connected
190
+ 4. Verify event handlers and callbacks are wired
191
+ 5. Check database models are used consistently across layers
192
+ 6. Verify dependency injection and configuration loading
193
+
194
+ Set layer="connection" in output.`,
195
+ { label: 'layer:connection', phase: 'Check', schema: LAYER_SCHEMA, agentType: 'workflow-verifier' }
196
+ ),
197
+ ]
198
+
199
+ // Anti-pattern scan (unless skipped)
200
+ if (!skipAntipattern) {
201
+ checks.push(() => agent(
202
+ `Anti-pattern scan for modified files.
203
+ ${scope ? 'Scope: ' + scope : 'Scan recently modified files (use git diff --name-only).'}
204
+
205
+ Search for code quality anti-patterns using grep:
206
+ - TODO / FIXME comments that indicate incomplete work
207
+ - Empty catch blocks: catch (e) {} or catch { }
208
+ - Empty returns in functions that should return values
209
+ - @ts-ignore / @ts-expect-error without explanatory comment
210
+ - Skipped tests: .skip, xit, xdescribe, test.skip
211
+ - Hardcoded secrets: password=, api_key=, secret= with literal values
212
+ - Placeholder text: "lorem ipsum", "test123", "TODO", "PLACEHOLDER"
213
+ - Not-implemented stubs: throw new Error("not implemented"), pass, ...
214
+
215
+ Use Grep tool to find these patterns. Report each with exact file and line number.
216
+ Severity: "blocker" for stubs/not-implemented/hardcoded-secrets, "warning" for TODO/FIXME.`,
217
+ { label: 'antipattern', phase: 'Check', schema: ANTIPATTERN_SCHEMA, agentType: 'workflow-verifier' }
218
+ ))
219
+ }
220
+
221
+ // Per-task convergence validation (if task files provided)
222
+ if (taskFiles.length > 0) {
223
+ checks.push(...taskFiles.map((taskFile, idx) => () => agent(
224
+ `Per-task convergence validation for: ${taskFile}
225
+
226
+ 1. Read the task JSON file at: ${taskFile}
227
+ 2. Find convergence.criteria[] — each item is a condition that must be true
228
+ 3. If convergence.verification command exists, run it via Bash
229
+ 4. Check each criterion individually (pass/fail with specific evidence)
230
+ 5. Cross-reference with task summaries in .summaries/ if they exist
231
+
232
+ Report overall_converged=true only if ALL criteria are met.`,
233
+ { label: `convergence:task-${idx}`, phase: 'Check', schema: CONVERGENCE_SCHEMA, agentType: 'workflow-verifier' }
234
+ )))
235
+ }
236
+
237
+ log(`Running ${checks.length} parallel verification checks...`)
238
+ const results = await parallel(checks)
239
+ const validResults = results.filter(Boolean)
240
+
241
+ const layers = validResults.filter(r => r.layer)
242
+ const antipatterns = validResults.find(r => r.clean !== undefined) || { clean: true, findings: [] }
243
+ const convergenceResults = validResults.filter(r => r.task_id)
244
+
245
+ // Phase 2: Aggregate
246
+ phase('Aggregate')
247
+
248
+ const layerDigest = layers.map(l => {
249
+ const passCount = l.checks.filter(c => c.status === 'pass').length
250
+ const failCount = l.checks.filter(c => c.status === 'fail').length
251
+ 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'}`
252
+ }).join('\n\n')
253
+
254
+ const convergenceDigest = convergenceResults.length > 0
255
+ ? `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'}`
256
+ : 'No convergence criteria checked (no task files provided).'
257
+
258
+ const antipatternDigest = antipatterns.clean
259
+ ? 'Anti-pattern scan: CLEAN'
260
+ : `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')}`
261
+
262
+ const aggregate = await agent(
263
+ `Aggregate all verification results into a final assessment.
264
+
265
+ ${layerDigest}
266
+
267
+ ${convergenceDigest}
268
+
269
+ ${antipatternDigest}
270
+
271
+ Determine:
272
+ 1. Overall status: "pass" requires ALL layers pass AND no antipattern blockers AND all convergence met
273
+ 2. Confidence score (0-100) — based on evidence strength and coverage
274
+ 3. Per-layer summary with check counts
275
+ 4. Convergence summary (if tasks checked)
276
+ 5. Consolidated gap list: extract every failed check and antipattern blocker, assign severity, suggest remediation
277
+ 6. Executive summary (what works, what's broken, what to do next)`,
278
+ { label: 'aggregate', phase: 'Aggregate', schema: AGGREGATE_SCHEMA }
279
+ )
280
+
281
+ return {
282
+ layers: layers,
283
+ convergence: convergenceResults,
284
+ antipatterns: antipatterns,
285
+ aggregate: aggregate,
286
+ metadata: {
287
+ layer_count: layers.length,
288
+ total_checks: layers.reduce((sum, l) => sum + l.checks.length, 0),
289
+ passed_checks: layers.reduce((sum, l) => sum + l.checks.filter(c => c.status === 'pass').length, 0),
290
+ failed_checks: layers.reduce((sum, l) => sum + l.checks.filter(c => c.status === 'fail').length, 0),
291
+ convergence_tasks: convergenceResults.length,
292
+ converged_tasks: convergenceResults.filter(c => c.overall_converged).length,
293
+ antipattern_count: antipatterns.findings.length,
294
+ blocker_count: antipatterns.findings.filter(f => f.severity === 'blocker').length,
295
+ overall_status: aggregate ? aggregate.status : 'unknown',
296
+ confidence: aggregate ? aggregate.confidence : 0,
297
+ },
298
+ }