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.
Files changed (82) hide show
  1. package/README.md +205 -371
  2. package/agents/AGENT_DEVSECOPS.md +32 -417
  3. package/agents/AGENT_INFRA.md +31 -0
  4. package/agents/AGENT_ORCHESTRATOR.md +39 -264
  5. package/agents/AGENT_QA.md +58 -186
  6. package/agents/AGENT_SCRUM.md +23 -190
  7. package/agents/AGENT_SRE.md +22 -173
  8. package/agents/AGENT_UIUX.md +26 -162
  9. package/docs/ARCHITECTURE.md +152 -148
  10. package/docs/CALCULATIONS.md +17 -17
  11. package/docs/CHANGELOG.md +112 -49
  12. package/docs/ENGINEERING_RULES.md +56 -252
  13. package/docs/IDEAS.md +17 -17
  14. package/docs/LOCAL_BACKLOG.md +20 -0
  15. package/docs/STATE.md +111 -43
  16. package/docs/playbooks/PLAYBOOK_CIRCUIT_BREAKER_LLM.md +58 -58
  17. package/docs/playbooks/PLAYBOOK_OPENTELEMETRY_TRACING.md +58 -58
  18. package/package.json +59 -47
  19. package/scripts/auditors/a11y_auditor.js +462 -0
  20. package/scripts/auditors/code_quality_auditor.js +444 -0
  21. package/scripts/auditors/contract_test_validator.js +396 -0
  22. package/scripts/auditors/eval_harness.js +213 -0
  23. package/scripts/auditors/git_hygiene_linter.js +391 -0
  24. package/scripts/auditors/pr_reviewer.js +627 -0
  25. package/scripts/auditors/sast_scanner.js +442 -0
  26. package/scripts/auditors/sca_dependency_auditor.js +673 -0
  27. package/scripts/{bootstrap_cli.js → bin/bootstrap_cli.js} +597 -468
  28. package/scripts/bin/domain_idea_miner.js +658 -0
  29. package/scripts/bin/smart_onboarding.js +905 -0
  30. package/scripts/{web_inspector.js → bin/web_inspector.js} +578 -355
  31. package/scripts/core/architecture_advisor.js +378 -0
  32. package/scripts/core/ast_skeletonizer.js +413 -0
  33. package/scripts/core/autonomous_remediation_engine.js +305 -0
  34. package/scripts/{circuit_breaker.js → core/circuit_breaker.js} +546 -330
  35. package/scripts/core/context_compressor.js +237 -0
  36. package/scripts/core/fast_feature_scaffold.js +840 -0
  37. package/scripts/core/hot_state_cache.js +238 -0
  38. package/scripts/core/knowledge_gateway.js +888 -0
  39. package/scripts/{magic_prompt_generator.js → core/magic_prompt_generator.js} +250 -205
  40. package/scripts/{multi_agent_orchestrator.js → core/multi_agent_orchestrator.js} +421 -258
  41. package/scripts/{otel_tracer.js → core/otel_tracer.js} +335 -228
  42. package/scripts/{perf_benchmark.js → core/perf_benchmark.js} +212 -153
  43. package/scripts/core/sarif_engine.js +299 -0
  44. package/scripts/{sre_remediation_engine.js → core/sre_remediation_engine.js} +236 -174
  45. package/scripts/{universal_packager.js → core/universal_packager.js} +357 -313
  46. package/scripts/integrations/atlassian_client.js +600 -0
  47. package/scripts/integrations/atlassian_sync_action.js +576 -0
  48. package/scripts/integrations/confluence_sync.js +684 -0
  49. package/scripts/integrations/credentials_guard.js +500 -0
  50. package/scripts/integrations/jira_manager.js +722 -0
  51. package/scripts/mcp/handlers/atlassian_handlers.js +300 -0
  52. package/scripts/mcp/handlers/core_handlers.js +419 -0
  53. package/scripts/mcp/handlers/qa_handlers.js +502 -0
  54. package/scripts/mcp/handlers/rules_handlers.js +379 -0
  55. package/scripts/mcp/handlers/scaffold_handlers.js +334 -0
  56. package/scripts/mcp/handlers/sre_handlers.js +443 -0
  57. package/scripts/mcp/resources_registry.js +453 -0
  58. package/scripts/mcp/server.js +408 -0
  59. package/scripts/mcp/tool_handlers.js +444 -0
  60. package/scripts/mcp/tools_registry.js +1123 -0
  61. package/scripts/mcp_server.js +236 -1884
  62. package/.cursorignore +0 -23
  63. package/agents/compact/AGENT_ORCHESTRATOR_COMPACTO.md +0 -53
  64. package/scripts/a11y_auditor.js +0 -187
  65. package/scripts/ast_skeletonizer.js +0 -220
  66. package/scripts/atlassian_client.js +0 -238
  67. package/scripts/atlassian_sync_action.js +0 -269
  68. package/scripts/code_quality_auditor.js +0 -142
  69. package/scripts/confluence_sync.js +0 -337
  70. package/scripts/context_compressor.js +0 -139
  71. package/scripts/contract_test_validator.js +0 -166
  72. package/scripts/credentials_guard.js +0 -216
  73. package/scripts/domain_idea_miner.js +0 -364
  74. package/scripts/eval_harness.js +0 -100
  75. package/scripts/fast_feature_scaffold.js +0 -338
  76. package/scripts/git_hygiene_linter.js +0 -186
  77. package/scripts/hot_state_cache.js +0 -95
  78. package/scripts/jira_manager.js +0 -408
  79. package/scripts/pr_reviewer.js +0 -373
  80. package/scripts/sast_scanner.js +0 -180
  81. package/scripts/sca_dependency_auditor.js +0 -167
  82. 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 { SECURITY_RULES } = require('./sast_scanner.js');
11
-
12
- // Definição canônica dos 6 modos / personas oficiais
13
- const AGENT_PERSONAS = {
14
- ORCHESTRATOR: 'modo: orchestrator',
15
- UIUX: 'modo: uiux',
16
- DEVSECOPS: 'modo: devsecops',
17
- QA: 'modo: qa',
18
- SCRUM: 'modo: scrum',
19
- SRE: 'modo: sre',
20
- FULL_DEV: 'modo: full-dev'
21
- };
22
-
23
- // Definição canônica dos eventos de barramento
24
- const EVENT_TYPES = {
25
- EVENT_REQUIREMENTS_READY: 'EVENT_REQUIREMENTS_READY',
26
- EVENT_DESIGN_READY: 'EVENT_DESIGN_READY',
27
- EVENT_UI_REVIEW: 'EVENT_UI_REVIEW',
28
- EVENT_CODE_COMPLETE: 'EVENT_CODE_COMPLETE',
29
- EVENT_REVIEW_FAILED: 'EVENT_REVIEW_FAILED',
30
- EVENT_REVIEW_PASSED: 'EVENT_REVIEW_PASSED',
31
- EVENT_METRIC_ANOMALY: 'EVENT_METRIC_ANOMALY',
32
- EVENT_REFACTOR_PROPOSAL: 'EVENT_REFACTOR_PROPOSAL',
33
- EVENT_AGENT_SELF_IMPROVE: 'EVENT_AGENT_SELF_IMPROVE',
34
- EVENT_KANBAN_DISPATCH: 'EVENT_KANBAN_DISPATCH'
35
- };
36
-
37
- class MultiAgentOrchestrator {
38
- constructor() {
39
- this.history = [];
40
- this.subscribers = new Map();
41
- this._setupDefaultRoutes();
42
- }
43
-
44
- _setupDefaultRoutes() {
45
- // Rota 0A: EVENT_REQUIREMENTS_READY (Orchestrator/Scrum -> UIUX)
46
- this.on(EVENT_TYPES.EVENT_REQUIREMENTS_READY, (payload) => {
47
- return {
48
- handoffTo: AGENT_PERSONAS.UIUX,
49
- status: 'READY_FOR_DESIGN',
50
- reason: 'Requisitos funcionais homologados; necessário design visual e acessibilidade.',
51
- nextAction: 'UIUX elabora jornada, tokens e especificações WCAG 2.1 AA.',
52
- requiresFix: false
53
- };
54
- });
55
-
56
- // Rota 0B: EVENT_DESIGN_READY (UIUX -> DevSecOps)
57
- this.on(EVENT_TYPES.EVENT_DESIGN_READY, (payload) => {
58
- return {
59
- handoffTo: AGENT_PERSONAS.DEVSECOPS,
60
- status: 'READY_FOR_IMPLEMENTATION',
61
- reason: 'Especificações visuais, design tokens e estados de componentes concluídos.',
62
- nextAction: 'DevSecOps implementa código semântico aderente aos tokens e contratos.',
63
- requiresFix: false
64
- };
65
- });
66
-
67
- // Rota 0C: EVENT_UI_REVIEW (QA -> UIUX)
68
- this.on(EVENT_TYPES.EVENT_UI_REVIEW, (payload) => {
69
- const a11yPassed = payload.a11yPassed !== false;
70
- return {
71
- handoffTo: AGENT_PERSONAS.UIUX,
72
- status: a11yPassed ? 'A11Y_APPROVED' : 'A11Y_REJECTED',
73
- reason: a11yPassed ? 'Auditoria de acessibilidade WCAG aprovada.' : 'Violação de contraste ou semântica ARIA detectada.',
74
- nextAction: a11yPassed ? 'Tokens e componentes homologados.' : 'UIUX deve reajustar contraste e hierarquia visual.',
75
- requiresFix: !a11yPassed
76
- };
77
- });
78
-
79
- // Rota 1: EVENT_CODE_COMPLETE (DevSecOps -> QA)
80
- this.on(EVENT_TYPES.EVENT_CODE_COMPLETE, (payload) => {
81
- const codeOrDiff = payload.diff || payload.code || '';
82
- const hasTests = codeOrDiff.includes('test') || payload.testsPassing === true;
83
- const hasSecrets = SECURITY_RULES.some(r => r.cwe === 'CWE-798' && r.pattern.test(codeOrDiff));
84
-
85
- if (hasSecrets) {
86
- return {
87
- handoffTo: AGENT_PERSONAS.QA,
88
- status: 'REJECTED',
89
- reason: 'Credencial ou segredo em texto plano detectado no diff (Regra 5).',
90
- nextAction: 'QA emite veto e exige expurgo imediato.',
91
- requiresFix: true
92
- };
93
- }
94
-
95
- if (!hasTests) {
96
- return {
97
- handoffTo: AGENT_PERSONAS.QA,
98
- status: 'REJECTED',
99
- reason: 'Entrega de código sem testes automatizados comprovados (Regra 4).',
100
- nextAction: 'QA exige inclusão de testes unitários antes de qualquer aprovação.',
101
- requiresFix: true
102
- };
103
- }
104
-
105
- return {
106
- handoffTo: AGENT_PERSONAS.QA,
107
- status: 'READY_FOR_INSPECTION',
108
- reason: 'Código submetido à auditoria cética adversária.',
109
- nextAction: 'QA realiza análise de segurança AST e casos de borda.',
110
- requiresFix: false
111
- };
112
- });
113
-
114
- // Rota 2: EVENT_REVIEW_FAILED (QA -> DevSecOps)
115
- this.on(EVENT_TYPES.EVENT_REVIEW_FAILED, (payload) => {
116
- return {
117
- handoffTo: AGENT_PERSONAS.DEVSECOPS,
118
- status: 'CORRECTION_REQUIRED',
119
- reason: payload.finding || 'Falha apontada pela auditoria adversária.',
120
- nextAction: 'DevSecOps deve sanar a causa raiz sem contornar testes ou lint.',
121
- requiresFix: true
122
- };
123
- });
124
-
125
- // Rota 3: EVENT_REVIEW_PASSED (QA -> Orchestrator / CI)
126
- this.on(EVENT_TYPES.EVENT_REVIEW_PASSED, (payload) => {
127
- return {
128
- handoffTo: AGENT_PERSONAS.ORCHESTRATOR,
129
- status: 'APPROVED',
130
- reason: 'Auditoria cética concluída com 100% de conformidade.',
131
- nextAction: 'Liberar Pull Request, validar esteira de CI e efetuar Tríplice Registro.',
132
- requiresFix: false
133
- };
134
- });
135
-
136
- // Rota 4: EVENT_METRIC_ANOMALY (SRE -> Scrum & SRE)
137
- this.on(EVENT_TYPES.EVENT_METRIC_ANOMALY, (payload) => {
138
- const metric = payload.metric || 'unknown';
139
- const value = payload.value || 0;
140
- const threshold = payload.threshold || 0;
141
-
142
- return {
143
- handoffTo: AGENT_PERSONAS.SCRUM,
144
- status: 'ANOMALY_TRIGGERED',
145
- reason: `Métrica ${metric} atingiu ${value} (limiar: ${threshold}).`,
146
- nextAction: 'Disparar playbook de auto-remediação SRE e iniciar investigação Ishikawa/PDCA.',
147
- remediation: payload.recommendedPlaybook || 'PLAYBOOK_CIRCUIT_BREAKER_LLM.md'
148
- };
149
- });
150
-
151
- // Rota 5: EVENT_REFACTOR_PROPOSAL (Scrum/DevSecOps -> QA Shift-Left Gate -> Backlog)
152
- this.on(EVENT_TYPES.EVENT_REFACTOR_PROPOSAL, (payload) => {
153
- const isAligned = payload.contextAligned !== false;
154
- const isQaApproved = payload.qaApproved !== false;
155
- const isOffDomain = payload.isOffDomain === true;
156
- const isRedundant = payload.isRedundant === true;
157
-
158
- if (!isAligned || !isQaApproved || isOffDomain || isRedundant) {
159
- return {
160
- handoffTo: AGENT_PERSONAS.QA,
161
- status: 'REJECTED_SANITY_FILTER',
162
- reason: 'Veto do Quality Architect (Regra 14 / Shift-Left Gate): proposta fora de domínio, overengineering ou arquivos redundantes.',
163
- nextAction: 'Ideia descartada para evitar inchaço do repositório e preservar foco no produto real.',
164
- ideaId: payload.ideaId || 'I-REJECTED',
165
- requiresFix: true
166
- };
167
- }
168
-
169
- return {
170
- handoffTo: AGENT_PERSONAS.DEVSECOPS,
171
- status: 'QUEUED',
172
- reason: 'Proposta de melhoria homologada pelo Quality Architect em conformidade com a Regra 14.',
173
- nextAction: 'Cadastrar card no backlog e criar branch dedicada.',
174
- ideaId: payload.ideaId || 'I-NEW',
175
- requiresFix: false
176
- };
177
- });
178
-
179
- // Rota 6: EVENT_AGENT_SELF_IMPROVE (Suíte Completa -> QA Auditoria Empírica -> Orchestrator)
180
- this.on(EVENT_TYPES.EVENT_AGENT_SELF_IMPROVE, (payload) => {
181
- const evalPassed = payload.evalPassed !== false;
182
- if (!evalPassed) {
183
- return {
184
- handoffTo: AGENT_PERSONAS.QA,
185
- status: 'SELF_IMPROVE_REJECTED',
186
- reason: 'Veto de Auditoria Empírica de QA: auto-evolução reflexiva reprovada por falta de evidência empírica mensurável.',
187
- nextAction: 'Descartar hipótese para prevenir alucinação cumulativa de regras.',
188
- requiresFix: true
189
- };
190
- }
191
-
192
- return {
193
- handoffTo: AGENT_PERSONAS.ORCHESTRATOR,
194
- status: 'REFLEXIVE_LOGGED',
195
- reason: 'Ciclo de auto-evolução reflexiva validado pelo Quality Architect com evidência empírica.',
196
- nextAction: 'Registrar hipótese validada de domínio em IDEAS.md.',
197
- tokenBudget: payload.tokenBudget || 'Under 1500 tokens',
198
- requiresFix: false
199
- };
200
- });
201
-
202
- // Rota 7: EVENT_KANBAN_DISPATCH (Full Dev continuous loop)
203
- this.on(EVENT_TYPES.EVENT_KANBAN_DISPATCH, (payload) => {
204
- const { processFullDevPipeline } = require('./jira_manager.js');
205
- const pipeline = processFullDevPipeline(payload.tasks || [], payload.projectContext || {});
206
- return {
207
- handoffTo: AGENT_PERSONAS.FULL_DEV,
208
- status: pipeline.activeTask ? 'RESUME_IN_PROGRESS' : (pipeline.nextApprovedTask ? 'START_NEXT_TASK' : 'IDLE_TODO_EMPTY'),
209
- 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.'),
210
- nextAction: pipeline.lifecyclePlan[0] ? pipeline.lifecyclePlan[0].message : 'Aguardar novas demandas.',
211
- pipeline
212
- };
213
- });
214
- }
215
-
216
- on(eventType, handler) {
217
- this.subscribers.set(eventType, handler);
218
- }
219
-
220
- dispatch(eventType, payload = {}) {
221
- if (!EVENT_TYPES[eventType]) {
222
- throw new Error(`Evento desconhecido: ${eventType}. Eventos suportados: ${Object.keys(EVENT_TYPES).join(', ')}`);
223
- }
224
-
225
- const handler = this.subscribers.get(eventType);
226
- const result = handler ? handler(payload) : { status: 'NO_HANDLER' };
227
-
228
- const eventRecord = {
229
- eventId: `EVT-${Date.now()}-${Math.floor(Math.random() * 1000)}`,
230
- eventType,
231
- timestamp: new Date().toISOString(),
232
- payload,
233
- result
234
- };
235
-
236
- this.history.push(eventRecord);
237
- return eventRecord;
238
- }
239
-
240
- processKanbanPipeline(tasks = [], projectContext = {}) {
241
- const { processFullDevPipeline } = require('./jira_manager.js');
242
- return processFullDevPipeline(tasks, projectContext);
243
- }
244
-
245
- getHistory() {
246
- return [...this.history];
247
- }
248
-
249
- clearHistory() {
250
- this.history = [];
251
- }
252
- }
253
-
254
- module.exports = {
255
- MultiAgentOrchestrator,
256
- AGENT_PERSONAS,
257
- EVENT_TYPES
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
+ };