agent-master-devsecops 3.9.0 → 5.1.0
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/README.md +205 -371
- package/agents/AGENT_DEVSECOPS.md +32 -417
- package/agents/AGENT_INFRA.md +31 -0
- package/agents/AGENT_ORCHESTRATOR.md +39 -264
- package/agents/AGENT_QA.md +58 -186
- package/agents/AGENT_SCRUM.md +23 -190
- package/agents/AGENT_SRE.md +22 -173
- package/agents/AGENT_UIUX.md +26 -162
- package/docs/ARCHITECTURE.md +152 -148
- package/docs/CALCULATIONS.md +17 -17
- package/docs/CHANGELOG.md +112 -49
- package/docs/ENGINEERING_RULES.md +56 -252
- package/docs/IDEAS.md +17 -17
- package/docs/LOCAL_BACKLOG.md +20 -0
- package/docs/STATE.md +111 -43
- package/docs/playbooks/PLAYBOOK_CIRCUIT_BREAKER_LLM.md +58 -58
- package/docs/playbooks/PLAYBOOK_OPENTELEMETRY_TRACING.md +58 -58
- package/package.json +59 -47
- package/scripts/auditors/a11y_auditor.js +462 -0
- package/scripts/auditors/code_quality_auditor.js +444 -0
- package/scripts/auditors/contract_test_validator.js +396 -0
- package/scripts/auditors/eval_harness.js +213 -0
- package/scripts/auditors/git_hygiene_linter.js +391 -0
- package/scripts/auditors/pr_reviewer.js +627 -0
- package/scripts/auditors/sast_scanner.js +442 -0
- package/scripts/auditors/sca_dependency_auditor.js +673 -0
- package/scripts/{bootstrap_cli.js → bin/bootstrap_cli.js} +597 -468
- package/scripts/bin/domain_idea_miner.js +658 -0
- package/scripts/bin/smart_onboarding.js +905 -0
- package/scripts/{web_inspector.js → bin/web_inspector.js} +578 -355
- package/scripts/core/architecture_advisor.js +378 -0
- package/scripts/core/ast_skeletonizer.js +413 -0
- package/scripts/core/autonomous_remediation_engine.js +305 -0
- package/scripts/{circuit_breaker.js → core/circuit_breaker.js} +546 -330
- package/scripts/core/context_compressor.js +237 -0
- package/scripts/core/fast_feature_scaffold.js +840 -0
- package/scripts/core/hot_state_cache.js +238 -0
- package/scripts/core/knowledge_gateway.js +888 -0
- package/scripts/{magic_prompt_generator.js → core/magic_prompt_generator.js} +250 -205
- package/scripts/{multi_agent_orchestrator.js → core/multi_agent_orchestrator.js} +421 -258
- package/scripts/{otel_tracer.js → core/otel_tracer.js} +335 -228
- package/scripts/{perf_benchmark.js → core/perf_benchmark.js} +212 -153
- package/scripts/core/sarif_engine.js +299 -0
- package/scripts/{sre_remediation_engine.js → core/sre_remediation_engine.js} +236 -174
- package/scripts/{universal_packager.js → core/universal_packager.js} +357 -313
- package/scripts/integrations/atlassian_client.js +600 -0
- package/scripts/integrations/atlassian_sync_action.js +576 -0
- package/scripts/integrations/confluence_sync.js +684 -0
- package/scripts/integrations/credentials_guard.js +500 -0
- package/scripts/integrations/jira_manager.js +722 -0
- package/scripts/mcp/handlers/atlassian_handlers.js +300 -0
- package/scripts/mcp/handlers/core_handlers.js +419 -0
- package/scripts/mcp/handlers/qa_handlers.js +502 -0
- package/scripts/mcp/handlers/rules_handlers.js +379 -0
- package/scripts/mcp/handlers/scaffold_handlers.js +334 -0
- package/scripts/mcp/handlers/sre_handlers.js +443 -0
- package/scripts/mcp/resources_registry.js +453 -0
- package/scripts/mcp/server.js +408 -0
- package/scripts/mcp/tool_handlers.js +444 -0
- package/scripts/mcp/tools_registry.js +1123 -0
- package/scripts/mcp_server.js +236 -1884
- package/.cursorignore +0 -23
- package/agents/compact/AGENT_ORCHESTRATOR_COMPACTO.md +0 -53
- package/scripts/a11y_auditor.js +0 -187
- package/scripts/ast_skeletonizer.js +0 -220
- package/scripts/atlassian_client.js +0 -238
- package/scripts/atlassian_sync_action.js +0 -269
- package/scripts/code_quality_auditor.js +0 -142
- package/scripts/confluence_sync.js +0 -337
- package/scripts/context_compressor.js +0 -139
- package/scripts/contract_test_validator.js +0 -166
- package/scripts/credentials_guard.js +0 -216
- package/scripts/domain_idea_miner.js +0 -364
- package/scripts/eval_harness.js +0 -100
- package/scripts/fast_feature_scaffold.js +0 -338
- package/scripts/git_hygiene_linter.js +0 -186
- package/scripts/hot_state_cache.js +0 -95
- package/scripts/jira_manager.js +0 -408
- package/scripts/pr_reviewer.js +0 -373
- package/scripts/sast_scanner.js +0 -180
- package/scripts/sca_dependency_auditor.js +0 -167
- package/scripts/smart_onboarding.js +0 -610
|
@@ -1,258 +1,421 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Multi-Agent Event Bus & Orchestration Engine
|
|
3
|
-
* Topologia de cooperação determinística, barramento de eventos lógicos
|
|
4
|
-
* e handovers automáticos entre os 6 modos da suíte multi-agente.
|
|
5
|
-
* Conforme especificado em docs/ARCHITECTURE.md.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
const fs = require('node:fs');
|
|
9
|
-
const path = require('node:path');
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
this.
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Multi-Agent Event Bus & Orchestration Engine
|
|
3
|
+
* Topologia de cooperação determinística, barramento de eventos lógicos
|
|
4
|
+
* e handovers automáticos entre os 6 modos da suíte multi-agente.
|
|
5
|
+
* Conforme especificado em docs/ARCHITECTURE.md.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const fs = require('node:fs');
|
|
9
|
+
const path = require('node:path');
|
|
10
|
+
const crypto = require('node:crypto');
|
|
11
|
+
const { SECURITY_RULES } = require('../auditors/sast_scanner.js');
|
|
12
|
+
const { createSarifReport } = require('./sarif_engine.js');
|
|
13
|
+
|
|
14
|
+
// Definição canônica dos 7 modos / personas oficiais (+ full-dev)
|
|
15
|
+
const AGENT_PERSONAS = {
|
|
16
|
+
ORCHESTRATOR: 'modo: orchestrator',
|
|
17
|
+
UIUX: 'modo: uiux',
|
|
18
|
+
DEVSECOPS: 'modo: devsecops',
|
|
19
|
+
QA: 'modo: qa',
|
|
20
|
+
SCRUM: 'modo: scrum',
|
|
21
|
+
SRE: 'modo: sre',
|
|
22
|
+
INFRA: 'modo: infra',
|
|
23
|
+
FULL_DEV: 'modo: full-dev'
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
// Definição canônica dos eventos de barramento
|
|
27
|
+
const EVENT_TYPES = {
|
|
28
|
+
EVENT_REQUIREMENTS_READY: 'EVENT_REQUIREMENTS_READY',
|
|
29
|
+
EVENT_DESIGN_READY: 'EVENT_DESIGN_READY',
|
|
30
|
+
EVENT_UI_REVIEW: 'EVENT_UI_REVIEW',
|
|
31
|
+
EVENT_CODE_COMPLETE: 'EVENT_CODE_COMPLETE',
|
|
32
|
+
EVENT_REVIEW_FAILED: 'EVENT_REVIEW_FAILED',
|
|
33
|
+
EVENT_REVIEW_PASSED: 'EVENT_REVIEW_PASSED',
|
|
34
|
+
EVENT_METRIC_ANOMALY: 'EVENT_METRIC_ANOMALY',
|
|
35
|
+
EVENT_REFACTOR_PROPOSAL: 'EVENT_REFACTOR_PROPOSAL',
|
|
36
|
+
EVENT_AGENT_SELF_IMPROVE: 'EVENT_AGENT_SELF_IMPROVE',
|
|
37
|
+
EVENT_KANBAN_DISPATCH: 'EVENT_KANBAN_DISPATCH',
|
|
38
|
+
EVENT_INFRA_PROVISIONED: 'EVENT_INFRA_PROVISIONED'
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
class MultiAgentOrchestrator {
|
|
42
|
+
constructor(options = {}) {
|
|
43
|
+
this.history = [];
|
|
44
|
+
this.subscribers = new Map();
|
|
45
|
+
this.storagePath = typeof options === 'string' ? options : (options?.storagePath || null);
|
|
46
|
+
this.db = null;
|
|
47
|
+
this._initDatabase(this.storagePath);
|
|
48
|
+
this._setupDefaultRoutes();
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
_initDatabase(storagePath) {
|
|
52
|
+
try {
|
|
53
|
+
const { DatabaseSync } = require('node:sqlite');
|
|
54
|
+
if (storagePath) {
|
|
55
|
+
const dir = path.dirname(storagePath);
|
|
56
|
+
if (dir && !fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
57
|
+
this.db = new DatabaseSync(storagePath);
|
|
58
|
+
} else {
|
|
59
|
+
this.db = new DatabaseSync(':memory:');
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
this.db.exec(`
|
|
63
|
+
CREATE TABLE IF NOT EXISTS event_log (
|
|
64
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
65
|
+
event_id TEXT UNIQUE,
|
|
66
|
+
event_type TEXT,
|
|
67
|
+
timestamp TEXT,
|
|
68
|
+
payload_json TEXT,
|
|
69
|
+
result_json TEXT
|
|
70
|
+
);
|
|
71
|
+
CREATE INDEX IF NOT EXISTS idx_event_type ON event_log(event_type);
|
|
72
|
+
`);
|
|
73
|
+
|
|
74
|
+
// Se existir histórico prévio persistido no banco, carrega na memória
|
|
75
|
+
const rows = this.db.prepare('SELECT * FROM event_log ORDER BY id ASC').all();
|
|
76
|
+
for (const row of rows) {
|
|
77
|
+
try {
|
|
78
|
+
this.history.push({
|
|
79
|
+
eventId: row.event_id,
|
|
80
|
+
eventType: row.event_type,
|
|
81
|
+
timestamp: row.timestamp,
|
|
82
|
+
payload: JSON.parse(row.payload_json || '{}'),
|
|
83
|
+
result: JSON.parse(row.result_json || '{}')
|
|
84
|
+
});
|
|
85
|
+
} catch (parseErr) {
|
|
86
|
+
void parseErr;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
} catch (_) {
|
|
90
|
+
// Fallback transparente para armazenamento puramente em memória
|
|
91
|
+
this.db = null;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
_setupDefaultRoutes() {
|
|
96
|
+
// Rota 0A: EVENT_REQUIREMENTS_READY (Orchestrator/Scrum -> UIUX)
|
|
97
|
+
this.on(EVENT_TYPES.EVENT_REQUIREMENTS_READY, (payload) => {
|
|
98
|
+
return {
|
|
99
|
+
handoffTo: AGENT_PERSONAS.UIUX,
|
|
100
|
+
status: 'READY_FOR_DESIGN',
|
|
101
|
+
reason: 'Requisitos funcionais homologados; necessário design visual e acessibilidade.',
|
|
102
|
+
nextAction: 'UIUX elabora jornada, tokens e especificações WCAG 2.1 AA.',
|
|
103
|
+
requiresFix: false
|
|
104
|
+
};
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
// Rota 0B: EVENT_DESIGN_READY (UIUX -> DevSecOps)
|
|
108
|
+
this.on(EVENT_TYPES.EVENT_DESIGN_READY, (payload) => {
|
|
109
|
+
return {
|
|
110
|
+
handoffTo: AGENT_PERSONAS.DEVSECOPS,
|
|
111
|
+
status: 'READY_FOR_IMPLEMENTATION',
|
|
112
|
+
reason: 'Especificações visuais, design tokens e estados de componentes concluídos.',
|
|
113
|
+
nextAction: 'DevSecOps implementa código semântico aderente aos tokens e contratos.',
|
|
114
|
+
requiresFix: false
|
|
115
|
+
};
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
// Rota 0C: EVENT_UI_REVIEW (QA -> UIUX)
|
|
119
|
+
this.on(EVENT_TYPES.EVENT_UI_REVIEW, (payload) => {
|
|
120
|
+
const a11yPassed = payload.a11yPassed !== false;
|
|
121
|
+
return {
|
|
122
|
+
handoffTo: AGENT_PERSONAS.UIUX,
|
|
123
|
+
status: a11yPassed ? 'A11Y_APPROVED' : 'A11Y_REJECTED',
|
|
124
|
+
reason: a11yPassed ? 'Auditoria de acessibilidade WCAG aprovada.' : 'Violação de contraste ou semântica ARIA detectada.',
|
|
125
|
+
nextAction: a11yPassed ? 'Tokens e componentes homologados.' : 'UIUX deve reajustar contraste e hierarquia visual.',
|
|
126
|
+
requiresFix: !a11yPassed
|
|
127
|
+
};
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
// Rota 0D: EVENT_INFRA_PROVISIONED (Infra -> DevSecOps / SRE)
|
|
131
|
+
this.on(EVENT_TYPES.EVENT_INFRA_PROVISIONED, (payload) => {
|
|
132
|
+
return {
|
|
133
|
+
handoffTo: AGENT_PERSONAS.DEVSECOPS,
|
|
134
|
+
status: 'INFRA_READY',
|
|
135
|
+
reason: 'Infraestrutura de CI/CD, containers e OTLP devidamente provisionados.',
|
|
136
|
+
nextAction: 'DevSecOps valida deployment local e SRE conecta monitoramento Prometheus.',
|
|
137
|
+
requiresFix: false
|
|
138
|
+
};
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
// Rota 1: EVENT_CODE_COMPLETE (DevSecOps -> QA)
|
|
142
|
+
this.on(EVENT_TYPES.EVENT_CODE_COMPLETE, (payload) => {
|
|
143
|
+
const codeOrDiff = payload.diff || payload.code || '';
|
|
144
|
+
const hasTests = codeOrDiff.includes('test') || payload.testsPassing === true;
|
|
145
|
+
const hasSecrets = SECURITY_RULES.some(r => r.cwe === 'CWE-798' && r.pattern.test(codeOrDiff));
|
|
146
|
+
|
|
147
|
+
if (hasSecrets) {
|
|
148
|
+
return {
|
|
149
|
+
handoffTo: AGENT_PERSONAS.QA,
|
|
150
|
+
status: 'REJECTED',
|
|
151
|
+
reason: 'Credencial ou segredo em texto plano detectado no diff (Regra 5).',
|
|
152
|
+
nextAction: 'QA emite veto e exige expurgo imediato.',
|
|
153
|
+
requiresFix: true
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
if (!hasTests) {
|
|
158
|
+
return {
|
|
159
|
+
handoffTo: AGENT_PERSONAS.QA,
|
|
160
|
+
status: 'REJECTED',
|
|
161
|
+
reason: 'Entrega de código sem testes automatizados comprovados (Regra 4).',
|
|
162
|
+
nextAction: 'QA exige inclusão de testes unitários antes de qualquer aprovação.',
|
|
163
|
+
requiresFix: true
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return {
|
|
168
|
+
handoffTo: AGENT_PERSONAS.QA,
|
|
169
|
+
status: 'READY_FOR_INSPECTION',
|
|
170
|
+
reason: 'Código submetido à auditoria cética adversária.',
|
|
171
|
+
nextAction: 'QA realiza análise de segurança AST e casos de borda.',
|
|
172
|
+
requiresFix: false
|
|
173
|
+
};
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
// Rota 2: EVENT_REVIEW_FAILED (QA -> DevSecOps)
|
|
177
|
+
this.on(EVENT_TYPES.EVENT_REVIEW_FAILED, (payload) => {
|
|
178
|
+
return {
|
|
179
|
+
handoffTo: AGENT_PERSONAS.DEVSECOPS,
|
|
180
|
+
status: 'CORRECTION_REQUIRED',
|
|
181
|
+
reason: payload.finding || 'Falha apontada pela auditoria adversária.',
|
|
182
|
+
nextAction: 'DevSecOps deve sanar a causa raiz sem contornar testes ou lint.',
|
|
183
|
+
requiresFix: true
|
|
184
|
+
};
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
// Rota 3: EVENT_REVIEW_PASSED (QA -> Orchestrator / CI)
|
|
188
|
+
this.on(EVENT_TYPES.EVENT_REVIEW_PASSED, (payload) => {
|
|
189
|
+
return {
|
|
190
|
+
handoffTo: AGENT_PERSONAS.ORCHESTRATOR,
|
|
191
|
+
status: 'APPROVED',
|
|
192
|
+
reason: 'Auditoria cética concluída com 100% de conformidade.',
|
|
193
|
+
nextAction: 'Liberar Pull Request, validar esteira de CI e efetuar Tríplice Registro.',
|
|
194
|
+
requiresFix: false
|
|
195
|
+
};
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
// Rota 4: EVENT_METRIC_ANOMALY (SRE -> Scrum & SRE)
|
|
199
|
+
this.on(EVENT_TYPES.EVENT_METRIC_ANOMALY, (payload) => {
|
|
200
|
+
const metric = payload.metric || 'unknown';
|
|
201
|
+
const value = payload.value || 0;
|
|
202
|
+
const threshold = payload.threshold || 0;
|
|
203
|
+
|
|
204
|
+
return {
|
|
205
|
+
handoffTo: AGENT_PERSONAS.SCRUM,
|
|
206
|
+
status: 'ANOMALY_TRIGGERED',
|
|
207
|
+
reason: `Métrica ${metric} atingiu ${value} (limiar: ${threshold}).`,
|
|
208
|
+
nextAction: 'Disparar playbook de auto-remediação SRE e iniciar investigação Ishikawa/PDCA.',
|
|
209
|
+
remediation: payload.recommendedPlaybook || 'PLAYBOOK_CIRCUIT_BREAKER_LLM.md'
|
|
210
|
+
};
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
// Rota 5: EVENT_REFACTOR_PROPOSAL (Scrum/DevSecOps -> QA Shift-Left Gate -> Backlog)
|
|
214
|
+
this.on(EVENT_TYPES.EVENT_REFACTOR_PROPOSAL, (payload) => {
|
|
215
|
+
const isAligned = payload.contextAligned !== false;
|
|
216
|
+
const isQaApproved = payload.qaApproved !== false;
|
|
217
|
+
const isOffDomain = payload.isOffDomain === true;
|
|
218
|
+
const isRedundant = payload.isRedundant === true;
|
|
219
|
+
|
|
220
|
+
if (!isAligned || !isQaApproved || isOffDomain || isRedundant) {
|
|
221
|
+
return {
|
|
222
|
+
handoffTo: AGENT_PERSONAS.QA,
|
|
223
|
+
status: 'REJECTED_SANITY_FILTER',
|
|
224
|
+
reason: 'Veto do Quality Architect (Regra 14 / Shift-Left Gate): proposta fora de domínio, overengineering ou arquivos redundantes.',
|
|
225
|
+
nextAction: 'Ideia descartada para evitar inchaço do repositório e preservar foco no produto real.',
|
|
226
|
+
ideaId: payload.ideaId || 'I-REJECTED',
|
|
227
|
+
requiresFix: true
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
return {
|
|
232
|
+
handoffTo: AGENT_PERSONAS.DEVSECOPS,
|
|
233
|
+
status: 'QUEUED',
|
|
234
|
+
reason: 'Proposta de melhoria homologada pelo Quality Architect em conformidade com a Regra 14.',
|
|
235
|
+
nextAction: 'Cadastrar card no backlog e criar branch dedicada.',
|
|
236
|
+
ideaId: payload.ideaId || 'I-NEW',
|
|
237
|
+
requiresFix: false
|
|
238
|
+
};
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
// Rota 6: EVENT_AGENT_SELF_IMPROVE (Suíte Completa -> QA Auditoria Empírica -> Orchestrator)
|
|
242
|
+
this.on(EVENT_TYPES.EVENT_AGENT_SELF_IMPROVE, (payload) => {
|
|
243
|
+
const evalPassed = payload.evalPassed !== false;
|
|
244
|
+
if (!evalPassed) {
|
|
245
|
+
return {
|
|
246
|
+
handoffTo: AGENT_PERSONAS.QA,
|
|
247
|
+
status: 'SELF_IMPROVE_REJECTED',
|
|
248
|
+
reason: 'Veto de Auditoria Empírica de QA: auto-evolução reflexiva reprovada por falta de evidência empírica mensurável.',
|
|
249
|
+
nextAction: 'Descartar hipótese para prevenir alucinação cumulativa de regras.',
|
|
250
|
+
requiresFix: true
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
return {
|
|
255
|
+
handoffTo: AGENT_PERSONAS.ORCHESTRATOR,
|
|
256
|
+
status: 'REFLEXIVE_LOGGED',
|
|
257
|
+
reason: 'Ciclo de auto-evolução reflexiva validado pelo Quality Architect com evidência empírica.',
|
|
258
|
+
nextAction: 'Registrar hipótese validada de domínio em IDEAS.md.',
|
|
259
|
+
tokenBudget: payload.tokenBudget || 'Under 1500 tokens',
|
|
260
|
+
requiresFix: false
|
|
261
|
+
};
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
// Rota 7: EVENT_KANBAN_DISPATCH (Full Dev continuous loop)
|
|
265
|
+
this.on(EVENT_TYPES.EVENT_KANBAN_DISPATCH, (payload) => {
|
|
266
|
+
const { processFullDevPipeline } = require('../integrations/jira_manager.js');
|
|
267
|
+
const pipeline = processFullDevPipeline(payload.tasks || [], payload.projectContext || {});
|
|
268
|
+
return {
|
|
269
|
+
handoffTo: AGENT_PERSONAS.FULL_DEV,
|
|
270
|
+
status: pipeline.activeTask ? 'RESUME_IN_PROGRESS' : (pipeline.nextApprovedTask ? 'START_NEXT_TASK' : 'IDLE_TODO_EMPTY'),
|
|
271
|
+
reason: pipeline.activeTask ? 'Concluir tarefa atualmente em andamento antes de avançar.' : (pipeline.nextApprovedTask ? 'Ideia aprovada pelo filtro de sanidade (Regra 14).' : 'Nenhuma tarefa pendente viável em A fazer.'),
|
|
272
|
+
nextAction: pipeline.lifecyclePlan[0] ? pipeline.lifecyclePlan[0].message : 'Aguardar novas demandas.',
|
|
273
|
+
pipeline
|
|
274
|
+
};
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
// Rota 8: EVENT_INFRA_PROVISIONED (Infra Engineer -> DevSecOps)
|
|
278
|
+
this.on(EVENT_TYPES.EVENT_INFRA_PROVISIONED, (payload) => {
|
|
279
|
+
return {
|
|
280
|
+
handoffTo: AGENT_PERSONAS.DEVSECOPS,
|
|
281
|
+
status: 'INFRA_READY',
|
|
282
|
+
reason: payload.reason || 'Infraestrutura e túneis de rede provisionados com sucesso.',
|
|
283
|
+
nextAction: 'DevSecOps integra código à infraestrutura e CI/CD.',
|
|
284
|
+
requiresFix: false,
|
|
285
|
+
details: payload.details || {}
|
|
286
|
+
};
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
on(eventType, handler) {
|
|
291
|
+
this.subscribers.set(eventType, handler);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
dispatch(eventType, payload = {}) {
|
|
295
|
+
if (!EVENT_TYPES[eventType]) {
|
|
296
|
+
throw new Error(`Evento desconhecido: ${eventType}. Eventos suportados: ${Object.keys(EVENT_TYPES).join(', ')}`);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
const handler = this.subscribers.get(eventType);
|
|
300
|
+
const result = handler ? handler(payload) : { status: 'NO_HANDLER' };
|
|
301
|
+
|
|
302
|
+
const eventRecord = {
|
|
303
|
+
eventId: `EVT-${Date.now()}-${crypto.randomUUID().slice(0, 8)}`,
|
|
304
|
+
eventType,
|
|
305
|
+
timestamp: new Date().toISOString(),
|
|
306
|
+
payload,
|
|
307
|
+
result
|
|
308
|
+
};
|
|
309
|
+
|
|
310
|
+
this.history.push(eventRecord);
|
|
311
|
+
|
|
312
|
+
if (this.db) {
|
|
313
|
+
try {
|
|
314
|
+
const stmt = this.db.prepare(`
|
|
315
|
+
INSERT INTO event_log (event_id, event_type, timestamp, payload_json, result_json)
|
|
316
|
+
VALUES (?, ?, ?, ?, ?)
|
|
317
|
+
`);
|
|
318
|
+
stmt.run(
|
|
319
|
+
eventRecord.eventId,
|
|
320
|
+
eventRecord.eventType,
|
|
321
|
+
eventRecord.timestamp,
|
|
322
|
+
JSON.stringify(eventRecord.payload),
|
|
323
|
+
JSON.stringify(eventRecord.result)
|
|
324
|
+
);
|
|
325
|
+
} catch (insertErr) {
|
|
326
|
+
void insertErr;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
return eventRecord;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
processKanbanPipeline(tasks = [], projectContext = {}) {
|
|
334
|
+
const { processFullDevPipeline } = require('../integrations/jira_manager.js');
|
|
335
|
+
return processFullDevPipeline(tasks, projectContext);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
getHistory(options = {}) {
|
|
339
|
+
if (options && options.eventType) {
|
|
340
|
+
return this.history.filter(h => h.eventType === options.eventType);
|
|
341
|
+
}
|
|
342
|
+
return [...this.history];
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
getEventLog(options = {}) {
|
|
346
|
+
return this.getHistory(options);
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
clearHistory() {
|
|
350
|
+
this.history = [];
|
|
351
|
+
if (this.db) {
|
|
352
|
+
try {
|
|
353
|
+
this.db.exec('DELETE FROM event_log');
|
|
354
|
+
} catch (delErr) {
|
|
355
|
+
void delErr;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
closeDatabase() {
|
|
361
|
+
if (this.db) {
|
|
362
|
+
try {
|
|
363
|
+
this.db.close();
|
|
364
|
+
} catch (closeErr) {
|
|
365
|
+
void closeErr;
|
|
366
|
+
}
|
|
367
|
+
this.db = null;
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
auditToSarif() {
|
|
372
|
+
const history = this.getHistory();
|
|
373
|
+
const reviewFailures = history.filter(h => h.eventType === EVENT_TYPES.EVENT_REVIEW_FAILED);
|
|
374
|
+
const findings = [];
|
|
375
|
+
|
|
376
|
+
if (reviewFailures.length > 0) {
|
|
377
|
+
findings.push({
|
|
378
|
+
ruleId: 'RULE-BUS-001',
|
|
379
|
+
name: 'ReviewFailureEventsDetected',
|
|
380
|
+
severity: 'WARNING',
|
|
381
|
+
message: `Detectados ${reviewFailures.length} eventos de falha de revisão adversária no barramento.`,
|
|
382
|
+
remediation: 'Investigue os bloqueios do AGENT_QA e aplique autocura adaptativa.'
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
return createSarifReport({
|
|
387
|
+
toolName: 'agent-master-orchestrator',
|
|
388
|
+
rules: [
|
|
389
|
+
{
|
|
390
|
+
id: 'RULE-BUS-001',
|
|
391
|
+
name: 'ReviewFailureEventsDetected',
|
|
392
|
+
description: 'Identifica eventos de falha de revisão nos handovers entre agentes',
|
|
393
|
+
severity: 'HIGH',
|
|
394
|
+
cwe: 'CWE-400'
|
|
395
|
+
}
|
|
396
|
+
],
|
|
397
|
+
findings,
|
|
398
|
+
properties: {
|
|
399
|
+
totalEvents: history.length,
|
|
400
|
+
reviewFailuresCount: reviewFailures.length,
|
|
401
|
+
storageEngine: this.db ? 'SQLite WAL' : 'In-Memory'
|
|
402
|
+
}
|
|
403
|
+
});
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
formatReport() {
|
|
407
|
+
const h = this.getHistory();
|
|
408
|
+
return [
|
|
409
|
+
'### Relatório do Barramento de Eventos Multi-Agente',
|
|
410
|
+
`- **Total de Eventos:** ${h.length}`,
|
|
411
|
+
`- **Engine de Armazenamento:** ${this.db ? 'SQLite WAL' : 'In-Memory'}`,
|
|
412
|
+
`- **Personas Homologadas:** ${Object.values(AGENT_PERSONAS).join(', ')}`
|
|
413
|
+
].join('\n');
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
module.exports = {
|
|
418
|
+
MultiAgentOrchestrator,
|
|
419
|
+
AGENT_PERSONAS,
|
|
420
|
+
EVENT_TYPES
|
|
421
|
+
};
|