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
@@ -0,0 +1,391 @@
1
+ /**
2
+ * scripts/auditors/git_hygiene_linter.js
3
+ * Auditor Local de Commits & Branches — Regra 11 de Engenharia & Princípio 3 (v5.1 Enterprise)
4
+ *
5
+ * Implementa validação estrita de nomenclatura de branches e sintaxe de commits:
6
+ * - Commit Canônico: [<TICKET>] - <Ação em português>
7
+ * - Proibição total de Conventional Commits (feat:, fix:, chore:, etc.)
8
+ * - Proibição de prefixos legados em branches (feature/**, fix/**, hotfix/**)
9
+ * - Emissão de relatórios oficiais no padrão OASIS SARIF v2.1.0 (auditToSarif)
10
+ * - Instalação de hooks locais nativos (.git/hooks/commit-msg) sem dependências externas.
11
+ */
12
+ 'use strict';
13
+
14
+ const fs = require('node:fs');
15
+ const path = require('node:path');
16
+ const { execFileSync } = require('node:child_process');
17
+ const { createSarifReport } = require('../core/sarif_engine.js');
18
+
19
+ const TICKET_REGEX = /^[A-Z][A-Z0-9_]+-\d+$/;
20
+ const BRANCH_CANONICAL_REGEX = /^([A-Z][A-Z0-9_]+-\d+)(?:-[a-z0-9-]+)?$/;
21
+ const COMMIT_REGEX = /^\[([A-Z][A-Z0-9_]+-\d+|GOV|CD|SETUP|RELEASE|INIT)\]\s*-\s*(.+)$/;
22
+ const FORBIDDEN_COMMIT_PREFIXES = /^(feat|fix|chore|docs|style|refactor|perf|test|build|ci|wip)(\(.*\))?:\s*/i;
23
+ const FORBIDDEN_BRANCH_PREFIXES = /^(feature|feat|fix|bugfix|hotfix|chore|refactor)\//i;
24
+
25
+ /**
26
+ * Classe principal do Auditor de Higiene de Git e Rastreabilidade.
27
+ */
28
+ class GitHygieneLinter {
29
+ constructor(options = {}) {
30
+ this.options = options;
31
+ }
32
+
33
+ /**
34
+ * Valida sintaxe da mensagem de commit contra a Regra 11 e Princípio 3.
35
+ *
36
+ * @param {string} message
37
+ * @returns {{ valid: boolean, ticket?: string, action?: string, cleanMessage?: string, reason?: string }}
38
+ */
39
+ lintCommitMessage(message) {
40
+ if (!message || typeof message !== 'string') {
41
+ return { valid: false, reason: 'Mensagem de commit vazia ou indefinida.' };
42
+ }
43
+
44
+ const cleanMsg = message.trim().split('\n')[0].trim();
45
+ if (!cleanMsg) {
46
+ return { valid: false, reason: 'Mensagem de commit vazia ou em branco.' };
47
+ }
48
+
49
+ // 0. Permitir commits de Merge/Revert gerados pelo Git/GitHub
50
+ if (/^(Merge\b|Revert\b)/i.test(cleanMsg)) {
51
+ return { valid: true, ticket: 'MERGE', cleanMessage: cleanMsg };
52
+ }
53
+
54
+ // 1. Proibir Conventional Commits
55
+ if (FORBIDDEN_COMMIT_PREFIXES.test(cleanMsg)) {
56
+ return {
57
+ valid: false,
58
+ reason: 'Violação da Regra 11: Conventional Commits (feat:, fix:, chore:, etc.) são terminantemente proibidos. Use exclusivamente [<TICKET>] - <Ação em português>.'
59
+ };
60
+ }
61
+
62
+ // 2. Verificar formato canônico [<TICKET>] - <Ação>
63
+ const match = cleanMsg.match(COMMIT_REGEX);
64
+ if (!match) {
65
+ return {
66
+ valid: false,
67
+ reason: 'Violação da Regra 11: A mensagem de commit deve seguir estritamente o formato: [<TICKET>] - <Ação em português>. Ex: [PROJ-123] - Implementar rate limit defensivo'
68
+ };
69
+ }
70
+
71
+ const ticket = match[1];
72
+ const action = match[2].trim();
73
+
74
+ if (action.length < 3) {
75
+ return {
76
+ valid: false,
77
+ reason: 'Violação da Regra 11: A descrição da ação no commit deve conter pelo menos 3 caracteres substantivos.'
78
+ };
79
+ }
80
+
81
+ return {
82
+ valid: true,
83
+ ticket,
84
+ action,
85
+ cleanMessage: cleanMsg
86
+ };
87
+ }
88
+
89
+ /**
90
+ * Valida a nomenclatura de uma branch contra a Regra 11 e Princípio 3.
91
+ *
92
+ * @param {string} branchName
93
+ * @returns {{ valid: boolean, branch?: string, ticket?: string, reason?: string }}
94
+ */
95
+ lintBranchName(branchName) {
96
+ if (!branchName || typeof branchName !== 'string') {
97
+ return { valid: false, reason: 'Nome de branch vazio ou indefinido.' };
98
+ }
99
+
100
+ const branch = branchName.trim().replace(/^refs\/heads\//, '');
101
+ if (!branch) {
102
+ return { valid: false, reason: 'Nome de branch vazio após sanitização.' };
103
+ }
104
+
105
+ // Permitir branches primárias canônicas
106
+ if (['main', 'master', 'develop'].includes(branch)) {
107
+ return { valid: true, branch, ticket: null };
108
+ }
109
+
110
+ // Proibir prefixos legados
111
+ if (FORBIDDEN_BRANCH_PREFIXES.test(branch)) {
112
+ return {
113
+ valid: false,
114
+ reason: `Violação da Regra 11: Prefixos legados (feature/**, fix/**, etc.) são proibidos. A branch deve conter a chave do ticket (ex: PROJ-123 ou PROJ-123-descricao). Recebido: "${branch}".`
115
+ };
116
+ }
117
+
118
+ // A branch de tarefa deve se chamar o Ticket ou Ticket com slug descritivo
119
+ const match = branch.match(BRANCH_CANONICAL_REGEX);
120
+ if (!match) {
121
+ return {
122
+ valid: false,
123
+ reason: `Violação da Regra 11: O nome da branch de tarefa deve conter a chave do ticket (ex: PROJ-123 ou PROJ-123-descricao-semantica). Recebido: "${branch}".`
124
+ };
125
+ }
126
+
127
+ const ticket = match[1];
128
+ return {
129
+ valid: true,
130
+ branch,
131
+ ticket
132
+ };
133
+ }
134
+
135
+ /**
136
+ * Inspeciona o estado atual do repositório Git local com timeouts seguros.
137
+ *
138
+ * @param {string} [repoDir=process.cwd()]
139
+ * @returns {{ compliant: boolean, currentBranch: string, lastCommit: string, branchAudit: object, commitAudit: object }}
140
+ */
141
+ auditGitState(repoDir = process.cwd()) {
142
+ let currentBranch = 'unknown';
143
+ let lastCommit = '';
144
+
145
+ if (process.env.GITHUB_HEAD_REF) {
146
+ currentBranch = process.env.GITHUB_HEAD_REF;
147
+ } else {
148
+ try {
149
+ currentBranch = execFileSync('git', ['rev-parse', '--abbrev-ref', 'HEAD'], {
150
+ cwd: repoDir,
151
+ encoding: 'utf8',
152
+ timeout: 3000,
153
+ stdio: ['pipe', 'pipe', 'ignore']
154
+ }).trim();
155
+ } catch (_err) {
156
+ currentBranch = '';
157
+ }
158
+ if (currentBranch === 'HEAD' && process.env.GITHUB_REF_NAME) {
159
+ currentBranch = process.env.GITHUB_REF_NAME;
160
+ }
161
+ }
162
+
163
+ try {
164
+ lastCommit = execFileSync('git', ['log', '-1', '--pretty=%B'], {
165
+ cwd: repoDir,
166
+ encoding: 'utf8',
167
+ timeout: 3000,
168
+ stdio: ['pipe', 'pipe', 'ignore']
169
+ }).trim();
170
+ } catch (_err) {
171
+ lastCommit = '';
172
+ }
173
+
174
+ const branchAudit = this.lintBranchName(currentBranch);
175
+ const commitAudit = lastCommit ? this.lintCommitMessage(lastCommit) : { valid: true, reason: 'Nenhum commit encontrado no histórico.' };
176
+ const compliant = branchAudit.valid && commitAudit.valid;
177
+
178
+ return {
179
+ compliant,
180
+ currentBranch,
181
+ lastCommit,
182
+ branchAudit,
183
+ commitAudit
184
+ };
185
+ }
186
+
187
+ /**
188
+ * Exporta os apontamentos de higiene Git em OASIS SARIF v2.1.0 oficial.
189
+ *
190
+ * @param {object} params
191
+ * @param {string} [params.branchName]
192
+ * @param {string} [params.commitMessage]
193
+ * @param {string} [params.repoDir]
194
+ * @returns {object} SARIF v2.1.0 JSON object
195
+ */
196
+ auditToSarif(params = {}) {
197
+ const findings = [];
198
+ let branchAudit;
199
+ let commitAudit;
200
+
201
+ if (params.branchName) {
202
+ branchAudit = this.lintBranchName(params.branchName);
203
+ if (!branchAudit.valid) {
204
+ findings.push({
205
+ ruleId: 'GIT-HYGIENE-BRANCH',
206
+ name: 'Nome de Branch Fora do Padrão Canônico',
207
+ severity: 'HIGH',
208
+ filename: '.git/HEAD',
209
+ line: 1,
210
+ column: 1,
211
+ snippet: params.branchName,
212
+ message: branchAudit.reason,
213
+ remediation: 'Renomeie a branch para seguir o padrão: <TICKET> ou <TICKET>-slug (ex: git branch -m PROJ-123-descricao).'
214
+ });
215
+ }
216
+ }
217
+
218
+ if (params.commitMessage) {
219
+ commitAudit = this.lintCommitMessage(params.commitMessage);
220
+ if (!commitAudit.valid) {
221
+ findings.push({
222
+ ruleId: 'GIT-HYGIENE-COMMIT',
223
+ name: 'Mensagem de Commit Não Rastreável ou Conventional Commit Proibido',
224
+ severity: 'HIGH',
225
+ filename: '.git/COMMIT_EDITMSG',
226
+ line: 1,
227
+ column: 1,
228
+ snippet: params.commitMessage.split('\n')[0],
229
+ message: commitAudit.reason,
230
+ remediation: 'Formate a mensagem do commit seguindo estritamente: [<TICKET>] - <Ação em português>.'
231
+ });
232
+ }
233
+ }
234
+
235
+ if (!params.branchName && !params.commitMessage) {
236
+ const state = this.auditGitState(params.repoDir);
237
+ if (!state.branchAudit.valid) {
238
+ findings.push({
239
+ ruleId: 'GIT-HYGIENE-BRANCH',
240
+ name: 'Nome de Branch Atual Fora do Padrão Canônico',
241
+ severity: 'HIGH',
242
+ filename: '.git/HEAD',
243
+ line: 1,
244
+ column: 1,
245
+ snippet: state.currentBranch,
246
+ message: state.branchAudit.reason,
247
+ remediation: 'Renomeie a branch para o padrão: <TICKET> ou <TICKET>-slug.'
248
+ });
249
+ }
250
+ if (!state.commitAudit.valid) {
251
+ findings.push({
252
+ ruleId: 'GIT-HYGIENE-COMMIT',
253
+ name: 'Último Commit Fora do Padrão Canônico',
254
+ severity: 'HIGH',
255
+ filename: '.git/COMMIT_EDITMSG',
256
+ line: 1,
257
+ column: 1,
258
+ snippet: state.lastCommit.split('\n')[0],
259
+ message: state.commitAudit.reason,
260
+ remediation: 'Reescreva a mensagem com git commit --amend.'
261
+ });
262
+ }
263
+ }
264
+
265
+ return createSarifReport({
266
+ toolName: 'agent-master-git-hygiene-linter',
267
+ toolVersion: '5.1.0',
268
+ findings,
269
+ properties: {
270
+ compliant: findings.length === 0,
271
+ branchAudit: branchAudit || null,
272
+ commitAudit: commitAudit || null
273
+ }
274
+ });
275
+ }
276
+
277
+ /**
278
+ * Formata relatório executivo em Markdown para os Agentes e PR Reviewer.
279
+ *
280
+ * @param {object} auditResult
281
+ * @returns {string}
282
+ */
283
+ formatReport(auditResult) {
284
+ let md = `## 🌿 Relatório de Higiene de Git & Rastreabilidade (Regra 11 — Princípio 3)\n\n`;
285
+ const isCompliant = (auditResult.commitAudit ? auditResult.commitAudit.valid : true) &&
286
+ (auditResult.branchAudit ? auditResult.branchAudit.valid : true) &&
287
+ (auditResult.compliant !== false);
288
+
289
+ md += `**Status de Conformidade:** ${isCompliant ? '✅ CONFORME' : '❌ VIOLAÇÃO DETECTADA'}\n\n`;
290
+
291
+ if (auditResult.branchAudit) {
292
+ md += `### 📌 Auditoria de Branch\n`;
293
+ md += `- **Branch:** \`${auditResult.currentBranch || auditResult.branchAudit.branch || 'N/A'}\`\n`;
294
+ md += `- **Válida:** ${auditResult.branchAudit.valid ? '✅ SIM' : '❌ NÃO'}\n`;
295
+ if (!auditResult.branchAudit.valid) {
296
+ md += `- **Motivo:** ${auditResult.branchAudit.reason}\n`;
297
+ } else if (auditResult.branchAudit.ticket) {
298
+ md += `- **Ticket Vinculado:** \`${auditResult.branchAudit.ticket}\`\n`;
299
+ }
300
+ md += '\n';
301
+ }
302
+
303
+ if (auditResult.commitAudit) {
304
+ md += `### 📝 Auditoria de Commit\n`;
305
+ md += `- **Válido:** ${auditResult.commitAudit.valid ? '✅ SIM' : '❌ NÃO'}\n`;
306
+ if (!auditResult.commitAudit.valid) {
307
+ md += `- **Motivo:** ${auditResult.commitAudit.reason}\n`;
308
+ } else if (auditResult.commitAudit.ticket) {
309
+ md += `- **Ticket Vinculado:** \`${auditResult.commitAudit.ticket}\`\n`;
310
+ md += `- **Mensagem Limpa:** \`${auditResult.commitAudit.cleanMessage}\`\n`;
311
+ }
312
+ md += '\n';
313
+ }
314
+
315
+ return md;
316
+ }
317
+ }
318
+
319
+ const defaultLinter = new GitHygieneLinter();
320
+
321
+ function lintCommitMessage(message) {
322
+ return defaultLinter.lintCommitMessage(message);
323
+ }
324
+
325
+ function lintBranchName(branchName) {
326
+ return defaultLinter.lintBranchName(branchName);
327
+ }
328
+
329
+ function auditGitState(repoDir) {
330
+ return defaultLinter.auditGitState(repoDir);
331
+ }
332
+
333
+ /**
334
+ * Instala hooks nativos de Git (.git/hooks/commit-msg) sem dependências externas.
335
+ *
336
+ * @param {string} [repoDir=process.cwd()]
337
+ * @returns {{ installed: boolean, hooksPath?: string, message: string }}
338
+ */
339
+ function installGitHooks(repoDir = process.cwd()) {
340
+ const hooksDir = path.join(repoDir, '.git', 'hooks');
341
+ if (!fs.existsSync(path.join(repoDir, '.git'))) {
342
+ return { installed: false, message: 'Diretório .git não encontrado. Repositório não inicializado.' };
343
+ }
344
+
345
+ if (!fs.existsSync(hooksDir)) {
346
+ fs.mkdirSync(hooksDir, { recursive: true });
347
+ }
348
+
349
+ const commitMsgHook = path.join(hooksDir, 'commit-msg');
350
+ const hookScript = `#!/usr/bin/env node
351
+ 'use strict';
352
+ const fs = require('fs');
353
+ const msgFile = process.argv[2];
354
+ if (!msgFile) process.exit(0);
355
+
356
+ const msg = fs.readFileSync(msgFile, 'utf8');
357
+ const COMMIT_REGEX = /^\\[([A-Z][A-Z0-9_]+-\\d+|GOV|CD|SETUP|RELEASE|INIT)\\]\\s*-\\s*.+$/;
358
+ const FORBIDDEN = /^(feat|fix|chore|docs|style|refactor|perf|test|build|ci|wip)(\\(.*\\))?:\\s*/i;
359
+
360
+ const firstLine = msg.trim().split('\\n')[0].trim();
361
+ if (FORBIDDEN.test(firstLine)) {
362
+ console.error('\\n❌ [REGRA 11] ERRO NO COMMIT: Conventional Commits são proibidos!');
363
+ console.error('Use estritamente: [<TICKET>] - <Ação em português>\\n');
364
+ process.exit(1);
365
+ }
366
+
367
+ if (!COMMIT_REGEX.test(firstLine)) {
368
+ console.error('\\n❌ [REGRA 11] ERRO NO COMMIT: Formato inválido!');
369
+ console.error('Esperado: [<TICKET>] - <Ação em português>');
370
+ console.error('Recebido: ' + firstLine + '\\n');
371
+ process.exit(1);
372
+ }
373
+ `;
374
+
375
+ fs.writeFileSync(commitMsgHook, hookScript, { mode: 0o755 });
376
+ return {
377
+ installed: true,
378
+ hooksPath: commitMsgHook,
379
+ message: 'Git hook commit-msg instalado com sucesso para conformidade da Regra 11.'
380
+ };
381
+ }
382
+
383
+ module.exports = {
384
+ GitHygieneLinter,
385
+ lintCommitMessage,
386
+ lintBranchName,
387
+ auditGitState,
388
+ installGitHooks,
389
+ TICKET_REGEX,
390
+ COMMIT_REGEX
391
+ };