@semacode/cli 1.2.0 → 1.2.11
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 +2 -2
- package/SEMA_BRIEF.curto.txt +9 -9
- package/SEMA_BRIEF.md +49 -49
- package/SEMA_BRIEF.micro.txt +7 -7
- package/SEMA_INDEX.json +501 -546
- package/dist/drift.d.ts +3 -3
- package/dist/drift.js +213 -22
- package/dist/drift.js.map +1 -1
- package/dist/importador.d.ts +1 -1
- package/dist/importador.js +0 -60
- package/dist/importador.js.map +1 -1
- package/dist/index.js +1334 -1360
- package/dist/index.js.map +1 -1
- package/dist/projeto.js +0 -6
- package/dist/projeto.js.map +1 -1
- package/dist/tipos.d.ts +1 -1
- package/docs/AGENT_STARTER.md +102 -102
- package/docs/instalacao-e-primeiro-uso.md +196 -198
- package/docs/sintaxe.md +95 -1
- package/node_modules/@sema/gerador-dart/package.json +1 -1
- package/node_modules/@sema/gerador-lua/dist/index.js +49 -81
- package/node_modules/@sema/gerador-lua/dist/index.js.map +1 -1
- package/node_modules/@sema/gerador-lua/package.json +1 -1
- package/node_modules/@sema/gerador-python/package.json +1 -1
- package/node_modules/@sema/gerador-typescript/package.json +1 -1
- package/node_modules/@sema/nucleo/dist/ast/tipos.d.ts +8 -2
- package/node_modules/@sema/nucleo/dist/formatador/index.js +65 -21
- package/node_modules/@sema/nucleo/dist/formatador/index.js.map +1 -1
- package/node_modules/@sema/nucleo/dist/ir/conversor.js +91 -5
- package/node_modules/@sema/nucleo/dist/ir/conversor.js.map +1 -1
- package/node_modules/@sema/nucleo/dist/ir/modelos.d.ts +74 -3
- package/node_modules/@sema/nucleo/dist/lexer/tokens.js +6 -0
- package/node_modules/@sema/nucleo/dist/lexer/tokens.js.map +1 -1
- package/node_modules/@sema/nucleo/dist/parser/parser.js +12 -2
- package/node_modules/@sema/nucleo/dist/parser/parser.js.map +1 -1
- package/node_modules/@sema/nucleo/dist/semantico/analisador.d.ts +2 -2
- package/node_modules/@sema/nucleo/dist/semantico/analisador.js +410 -11
- package/node_modules/@sema/nucleo/dist/semantico/analisador.js.map +1 -1
- package/node_modules/@sema/nucleo/dist/semantico/estruturas.d.ts +6 -1
- package/node_modules/@sema/nucleo/dist/semantico/estruturas.js +63 -13
- package/node_modules/@sema/nucleo/dist/semantico/estruturas.js.map +1 -1
- package/node_modules/@sema/nucleo/dist/semantico/seguranca.d.ts +91 -0
- package/node_modules/@sema/nucleo/dist/semantico/seguranca.js +258 -0
- package/node_modules/@sema/nucleo/dist/semantico/seguranca.js.map +1 -0
- package/node_modules/@sema/nucleo/package.json +1 -1
- package/node_modules/@sema/padroes/dist/index.js +18 -1
- package/node_modules/@sema/padroes/dist/index.js.map +1 -1
- package/node_modules/@sema/padroes/package.json +1 -1
- package/package.json +7 -7
package/dist/drift.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ interface RegistroConsumerBridgeDrift {
|
|
|
12
12
|
simbolo: string;
|
|
13
13
|
}
|
|
14
14
|
export interface DiagnosticoDrift {
|
|
15
|
-
tipo: "impl_quebrado" | "task_sem_impl" | "rota_divergente" | "recurso_divergente" | "vinculo_quebrado";
|
|
15
|
+
tipo: "impl_quebrado" | "task_sem_impl" | "rota_divergente" | "recurso_divergente" | "vinculo_quebrado" | "seguranca_frouxa";
|
|
16
16
|
modulo: string;
|
|
17
17
|
task?: string;
|
|
18
18
|
route?: string;
|
|
@@ -21,7 +21,7 @@ export interface DiagnosticoDrift {
|
|
|
21
21
|
interface RegistroImplDrift {
|
|
22
22
|
modulo: string;
|
|
23
23
|
task: string;
|
|
24
|
-
origem: "ts" | "py" | "dart" | "
|
|
24
|
+
origem: "ts" | "py" | "dart" | "cs" | "java" | "go" | "rust" | "cpp";
|
|
25
25
|
caminho: string;
|
|
26
26
|
arquivo?: string;
|
|
27
27
|
simbolo?: string;
|
|
@@ -47,7 +47,7 @@ interface RegistroRecursoDrift {
|
|
|
47
47
|
status: "resolvido" | "divergente";
|
|
48
48
|
}
|
|
49
49
|
interface SimboloCandidatoDrift {
|
|
50
|
-
origem: "ts" | "py" | "dart" | "
|
|
50
|
+
origem: "ts" | "py" | "dart" | "cs" | "java" | "go" | "rust" | "cpp";
|
|
51
51
|
caminho: string;
|
|
52
52
|
arquivo: string;
|
|
53
53
|
simbolo: string;
|
package/dist/drift.js
CHANGED
|
@@ -5,7 +5,6 @@ import { extrairSimbolosCpp } from "./cpp-symbols.js";
|
|
|
5
5
|
import { extrairRotasDotnet, extrairSimbolosDotnet } from "./dotnet-http.js";
|
|
6
6
|
import { extrairRotasGo, extrairSimbolosGo } from "./go-http.js";
|
|
7
7
|
import { extrairRotasJava, extrairSimbolosJava } from "./java-http.js";
|
|
8
|
-
import { extrairSimbolosLua } from "./lua-symbols.js";
|
|
9
8
|
import { contarIndentacaoPython, extrairRotasFlaskDecoradas, normalizarCaminhoFlask } from "./python-http.js";
|
|
10
9
|
import { extrairRotasRust, extrairSimbolosRust } from "./rust-http.js";
|
|
11
10
|
import { extrairRotasTypeScriptHttp } from "./typescript-http.js";
|
|
@@ -118,8 +117,14 @@ function encontrarAncoraSuperficie(ir, superficie, simbolos, mapaImpl, arquivos)
|
|
|
118
117
|
return undefined;
|
|
119
118
|
}
|
|
120
119
|
function calcularRiscoOperacional(task) {
|
|
120
|
+
const dadosSensiveis = Boolean(task.dados.classificacaoPadrao && ["pii", "financeiro", "credencial", "segredo"].includes(task.dados.classificacaoPadrao)
|
|
121
|
+
|| task.dados.campos.some((campo) => ["pii", "financeiro", "credencial", "segredo"].includes(campo.classificacao)));
|
|
122
|
+
const efeitoPrivilegiado = task.efeitosEstruturados.some((efeito) => ["db.read", "db.write", "queue.publish", "queue.consume", "fs.read", "fs.write", "network.egress", "secret.read", "shell.exec"].includes(efeito.categoria)
|
|
123
|
+
|| ["alta", "critica"].includes(efeito.criticidade ?? ""));
|
|
121
124
|
if (task.execucao.criticidadeOperacional === "alta"
|
|
122
125
|
|| task.execucao.criticidadeOperacional === "critica"
|
|
126
|
+
|| dadosSensiveis
|
|
127
|
+
|| efeitoPrivilegiado
|
|
123
128
|
|| task.efeitosEstruturados.some((efeito) => efeito.categoria === "persistencia" || efeito.criticidade === "critica")) {
|
|
124
129
|
return "alto";
|
|
125
130
|
}
|
|
@@ -154,7 +159,7 @@ function calcularScoreTask(task, implsValidos, implsQuebrados, vinculosValidos,
|
|
|
154
159
|
}
|
|
155
160
|
return Math.max(0, Math.min(100, score));
|
|
156
161
|
}
|
|
157
|
-
function resumirLacunasTask(task, semImplementacao, implsQuebrados, vinculosQuebrados) {
|
|
162
|
+
function resumirLacunasTask(task, semImplementacao, implsQuebrados, vinculosQuebrados, guardrails) {
|
|
158
163
|
const lacunas = [];
|
|
159
164
|
if (semImplementacao) {
|
|
160
165
|
lacunas.push("sem_impl");
|
|
@@ -171,6 +176,33 @@ function resumirLacunasTask(task, semImplementacao, implsQuebrados, vinculosQueb
|
|
|
171
176
|
if (!task.execucao.explicita) {
|
|
172
177
|
lacunas.push("execucao_implicita");
|
|
173
178
|
}
|
|
179
|
+
if (guardrails.publica && !task.execucao.explicita) {
|
|
180
|
+
lacunas.push("superficie_publica_sem_execucao");
|
|
181
|
+
}
|
|
182
|
+
if (guardrails.sensivel && !task.execucao.explicita) {
|
|
183
|
+
lacunas.push("execucao_critica_sem_bloco");
|
|
184
|
+
}
|
|
185
|
+
if ((guardrails.publica || guardrails.sensivel) && semImplementacao && task.vinculos.length === 0) {
|
|
186
|
+
lacunas.push("rastreabilidade_fraca");
|
|
187
|
+
}
|
|
188
|
+
if (guardrails.publica && !guardrails.auth) {
|
|
189
|
+
lacunas.push("auth_ausente");
|
|
190
|
+
}
|
|
191
|
+
if ((guardrails.publica || guardrails.sensivel || guardrails.efeitoPrivilegiado || guardrails.dadosSensiveis) && !guardrails.authz) {
|
|
192
|
+
lacunas.push("authz_frouxa");
|
|
193
|
+
}
|
|
194
|
+
if ((guardrails.publica || guardrails.sensivel || guardrails.efeitoPrivilegiado) && !guardrails.dados) {
|
|
195
|
+
lacunas.push("dados_nao_classificados");
|
|
196
|
+
}
|
|
197
|
+
if ((guardrails.publica || guardrails.sensivel || guardrails.efeitoPrivilegiado || guardrails.dadosSensiveis) && !guardrails.audit) {
|
|
198
|
+
lacunas.push("audit_ausente");
|
|
199
|
+
}
|
|
200
|
+
if (guardrails.exigeSegredos && !guardrails.segredos) {
|
|
201
|
+
lacunas.push("segredo_sem_governanca");
|
|
202
|
+
}
|
|
203
|
+
if ((guardrails.efeitoPrivilegiado || guardrails.dadosSensiveis) && !guardrails.forbidden) {
|
|
204
|
+
lacunas.push("proibicoes_ausentes");
|
|
205
|
+
}
|
|
174
206
|
return lacunas;
|
|
175
207
|
}
|
|
176
208
|
function resumirOperacional(resultado) {
|
|
@@ -979,22 +1011,6 @@ async function indexarDart(diretorios) {
|
|
|
979
1011
|
|| a.arquivo.localeCompare(b.arquivo, "pt-BR")),
|
|
980
1012
|
};
|
|
981
1013
|
}
|
|
982
|
-
async function indexarLua(diretorios) {
|
|
983
|
-
const simbolos = new Map();
|
|
984
|
-
for (const diretorio of diretorios) {
|
|
985
|
-
const arquivos = (await listarArquivosRecursivos(diretorio, [".lua"]))
|
|
986
|
-
.filter((arquivo) => !/(^|[\\/])(spec|specs|test|tests)([\\/]|$)/i.test(arquivo))
|
|
987
|
-
.filter((arquivo) => !/[_-](spec|test)\.lua$/i.test(arquivo));
|
|
988
|
-
for (const arquivo of arquivos) {
|
|
989
|
-
const texto = await readFile(arquivo, "utf8");
|
|
990
|
-
const basesSimbolicas = caminhosSimbolicos(diretorio, arquivo);
|
|
991
|
-
for (const simbolo of extrairSimbolosLua(texto)) {
|
|
992
|
-
registrarSimboloGenerico(simbolos, "lua", basesSimbolicas, arquivo, simbolo.simbolo);
|
|
993
|
-
}
|
|
994
|
-
}
|
|
995
|
-
}
|
|
996
|
-
return { simbolos: [...simbolos.values()], rotas: [] };
|
|
997
|
-
}
|
|
998
1014
|
function registrarSimboloGenerico(simbolos, origem, basesSimbolicas, arquivo, simbolo) {
|
|
999
1015
|
for (const baseSimbolica of basesSimbolicas) {
|
|
1000
1016
|
const caminho = `${baseSimbolica}.${simbolo}`;
|
|
@@ -1345,7 +1361,6 @@ export async function analisarDriftLegado(contexto) {
|
|
|
1345
1361
|
const indexTs = await indexarTypeScript(contexto.diretoriosCodigo);
|
|
1346
1362
|
const indexPy = await indexarPython(contexto.diretoriosCodigo);
|
|
1347
1363
|
const indexDart = await indexarDart(contexto.diretoriosCodigo);
|
|
1348
|
-
const indexLua = await indexarLua(contexto.diretoriosCodigo);
|
|
1349
1364
|
const indexDotnet = await indexarDotnet(contexto.diretoriosCodigo);
|
|
1350
1365
|
const indexJava = await indexarJava(contexto.diretoriosCodigo);
|
|
1351
1366
|
const indexGo = await indexarGo(contexto.diretoriosCodigo);
|
|
@@ -1355,7 +1370,6 @@ export async function analisarDriftLegado(contexto) {
|
|
|
1355
1370
|
...indexTs.simbolos,
|
|
1356
1371
|
...indexPy.simbolos,
|
|
1357
1372
|
...indexDart.simbolos,
|
|
1358
|
-
...indexLua.simbolos,
|
|
1359
1373
|
...indexDotnet.simbolos,
|
|
1360
1374
|
...indexJava.simbolos,
|
|
1361
1375
|
...indexGo.simbolos,
|
|
@@ -1366,7 +1380,6 @@ export async function analisarDriftLegado(contexto) {
|
|
|
1366
1380
|
...indexTs.simbolos.map((item) => [item.caminho, item]),
|
|
1367
1381
|
...indexPy.simbolos.map((item) => [item.caminho, item]),
|
|
1368
1382
|
...indexDart.simbolos.map((item) => [item.caminho, item]),
|
|
1369
|
-
...indexLua.simbolos.map((item) => [item.caminho, item]),
|
|
1370
1383
|
...indexDotnet.simbolos.map((item) => [item.caminho, item]),
|
|
1371
1384
|
...indexJava.simbolos.map((item) => [item.caminho, item]),
|
|
1372
1385
|
...indexGo.simbolos.map((item) => [item.caminho, item]),
|
|
@@ -1398,6 +1411,7 @@ export async function analisarDriftLegado(contexto) {
|
|
|
1398
1411
|
const diagnosticos = [];
|
|
1399
1412
|
const tasksResumo = [];
|
|
1400
1413
|
const taskPorChave = new Map();
|
|
1414
|
+
const guardrailsPorTask = new Map();
|
|
1401
1415
|
const resumoVinculosPorTask = new Map();
|
|
1402
1416
|
for (const item of contexto.modulosSelecionados) {
|
|
1403
1417
|
const ir = item.resultado.ir;
|
|
@@ -1405,6 +1419,69 @@ export async function analisarDriftLegado(contexto) {
|
|
|
1405
1419
|
continue;
|
|
1406
1420
|
}
|
|
1407
1421
|
const superficiesPorChave = new Map(ir.superficies.map((superficie) => [`${superficie.tipo}:${superficie.nome}`, superficie]));
|
|
1422
|
+
for (const task of ir.tasks) {
|
|
1423
|
+
guardrailsPorTask.set(`${ir.nome}:${task.nome}`, {
|
|
1424
|
+
publica: false,
|
|
1425
|
+
sensivel: calcularRiscoOperacional(task) === "alto",
|
|
1426
|
+
auth: task.auth.explicita,
|
|
1427
|
+
authz: task.authz.explicita,
|
|
1428
|
+
dados: task.dados.explicita,
|
|
1429
|
+
audit: task.audit.explicita,
|
|
1430
|
+
segredos: task.segredos.explicita,
|
|
1431
|
+
forbidden: task.forbidden.explicita,
|
|
1432
|
+
dadosSensiveis: Boolean(task.dados.classificacaoPadrao && ["pii", "financeiro", "credencial", "segredo"].includes(task.dados.classificacaoPadrao)
|
|
1433
|
+
|| task.dados.campos.some((campo) => ["pii", "financeiro", "credencial", "segredo"].includes(campo.classificacao))),
|
|
1434
|
+
efeitoPrivilegiado: task.efeitosEstruturados.some((efeito) => ["db.read", "db.write", "queue.publish", "queue.consume", "fs.read", "fs.write", "network.egress", "secret.read", "shell.exec"].includes(efeito.categoria)
|
|
1435
|
+
|| ["alta", "critica"].includes(efeito.criticidade ?? "")),
|
|
1436
|
+
exigeSegredos: task.efeitosEstruturados.some((efeito) => efeito.categoria === "secret.read")
|
|
1437
|
+
|| Boolean(task.dados.classificacaoPadrao && ["credencial", "segredo"].includes(task.dados.classificacaoPadrao)
|
|
1438
|
+
|| task.dados.campos.some((campo) => ["credencial", "segredo"].includes(campo.classificacao))),
|
|
1439
|
+
});
|
|
1440
|
+
}
|
|
1441
|
+
for (const route of ir.routes) {
|
|
1442
|
+
if (!route.task || route.perfilCompatibilidade !== "publico") {
|
|
1443
|
+
continue;
|
|
1444
|
+
}
|
|
1445
|
+
const guardrails = guardrailsPorTask.get(`${ir.nome}:${route.task}`);
|
|
1446
|
+
if (guardrails) {
|
|
1447
|
+
guardrails.publica = true;
|
|
1448
|
+
guardrails.auth = guardrails.auth || route.auth.explicita;
|
|
1449
|
+
guardrails.authz = guardrails.authz || route.authz.explicita;
|
|
1450
|
+
guardrails.dados = guardrails.dados || route.dados.explicita;
|
|
1451
|
+
guardrails.audit = guardrails.audit || route.audit.explicita;
|
|
1452
|
+
guardrails.segredos = guardrails.segredos || route.segredos.explicita;
|
|
1453
|
+
guardrails.forbidden = guardrails.forbidden || route.forbidden.explicita;
|
|
1454
|
+
guardrails.dadosSensiveis = guardrails.dadosSensiveis || Boolean(route.dados.classificacaoPadrao && ["pii", "financeiro", "credencial", "segredo"].includes(route.dados.classificacaoPadrao)
|
|
1455
|
+
|| route.dados.campos.some((campo) => ["pii", "financeiro", "credencial", "segredo"].includes(campo.classificacao)));
|
|
1456
|
+
guardrails.efeitoPrivilegiado = guardrails.efeitoPrivilegiado || route.efeitosPublicos.some((efeito) => ["db.read", "db.write", "queue.publish", "queue.consume", "fs.read", "fs.write", "network.egress", "secret.read", "shell.exec"].includes(efeito.categoria)
|
|
1457
|
+
|| ["alta", "critica"].includes(efeito.criticidade ?? ""));
|
|
1458
|
+
guardrails.exigeSegredos = guardrails.exigeSegredos || route.efeitosPublicos.some((efeito) => efeito.categoria === "secret.read")
|
|
1459
|
+
|| Boolean(route.dados.classificacaoPadrao && ["credencial", "segredo"].includes(route.dados.classificacaoPadrao)
|
|
1460
|
+
|| route.dados.campos.some((campo) => ["credencial", "segredo"].includes(campo.classificacao)));
|
|
1461
|
+
}
|
|
1462
|
+
}
|
|
1463
|
+
for (const superficie of ir.superficies) {
|
|
1464
|
+
if (!superficie.task || superficie.perfilCompatibilidade !== "publico") {
|
|
1465
|
+
continue;
|
|
1466
|
+
}
|
|
1467
|
+
const guardrails = guardrailsPorTask.get(`${ir.nome}:${superficie.task}`);
|
|
1468
|
+
if (guardrails) {
|
|
1469
|
+
guardrails.publica = true;
|
|
1470
|
+
guardrails.auth = guardrails.auth || superficie.auth.explicita;
|
|
1471
|
+
guardrails.authz = guardrails.authz || superficie.authz.explicita;
|
|
1472
|
+
guardrails.dados = guardrails.dados || superficie.dados.explicita;
|
|
1473
|
+
guardrails.audit = guardrails.audit || superficie.audit.explicita;
|
|
1474
|
+
guardrails.segredos = guardrails.segredos || superficie.segredos.explicita;
|
|
1475
|
+
guardrails.forbidden = guardrails.forbidden || superficie.forbidden.explicita;
|
|
1476
|
+
guardrails.dadosSensiveis = guardrails.dadosSensiveis || Boolean(superficie.dados.classificacaoPadrao && ["pii", "financeiro", "credencial", "segredo"].includes(superficie.dados.classificacaoPadrao)
|
|
1477
|
+
|| superficie.dados.campos.some((campo) => ["pii", "financeiro", "credencial", "segredo"].includes(campo.classificacao)));
|
|
1478
|
+
guardrails.efeitoPrivilegiado = guardrails.efeitoPrivilegiado || superficie.effects.some((efeito) => ["db.read", "db.write", "queue.publish", "queue.consume", "fs.read", "fs.write", "network.egress", "secret.read", "shell.exec"].includes(efeito.categoria)
|
|
1479
|
+
|| ["alta", "critica"].includes(efeito.criticidade ?? ""));
|
|
1480
|
+
guardrails.exigeSegredos = guardrails.exigeSegredos || superficie.effects.some((efeito) => efeito.categoria === "secret.read")
|
|
1481
|
+
|| Boolean(superficie.dados.classificacaoPadrao && ["credencial", "segredo"].includes(superficie.dados.classificacaoPadrao)
|
|
1482
|
+
|| superficie.dados.campos.some((campo) => ["credencial", "segredo"].includes(campo.classificacao)));
|
|
1483
|
+
}
|
|
1484
|
+
}
|
|
1408
1485
|
for (const task of ir.tasks) {
|
|
1409
1486
|
taskPorChave.set(`${ir.nome}:${task.nome}`, task);
|
|
1410
1487
|
let validos = 0;
|
|
@@ -1520,6 +1597,29 @@ export async function analisarDriftLegado(contexto) {
|
|
|
1520
1597
|
criticidadeOperacional: "media",
|
|
1521
1598
|
explicita: false,
|
|
1522
1599
|
},
|
|
1600
|
+
auth: {
|
|
1601
|
+
explicita: false,
|
|
1602
|
+
},
|
|
1603
|
+
authz: {
|
|
1604
|
+
explicita: false,
|
|
1605
|
+
papeis: [],
|
|
1606
|
+
escopos: [],
|
|
1607
|
+
},
|
|
1608
|
+
dados: {
|
|
1609
|
+
explicita: false,
|
|
1610
|
+
campos: [],
|
|
1611
|
+
},
|
|
1612
|
+
audit: {
|
|
1613
|
+
explicita: false,
|
|
1614
|
+
},
|
|
1615
|
+
segredos: {
|
|
1616
|
+
explicita: false,
|
|
1617
|
+
itens: [],
|
|
1618
|
+
},
|
|
1619
|
+
forbidden: {
|
|
1620
|
+
explicita: false,
|
|
1621
|
+
regras: [],
|
|
1622
|
+
},
|
|
1523
1623
|
guarantees: [],
|
|
1524
1624
|
garantiasEstruturadas: [],
|
|
1525
1625
|
errors: {},
|
|
@@ -1664,6 +1764,19 @@ export async function analisarDriftLegado(contexto) {
|
|
|
1664
1764
|
for (const resumo of tasksResumo) {
|
|
1665
1765
|
const chaveTask = `${resumo.modulo}:${resumo.task}`;
|
|
1666
1766
|
const task = taskPorChave.get(chaveTask);
|
|
1767
|
+
const guardrails = guardrailsPorTask.get(chaveTask) ?? {
|
|
1768
|
+
publica: false,
|
|
1769
|
+
sensivel: false,
|
|
1770
|
+
auth: false,
|
|
1771
|
+
authz: false,
|
|
1772
|
+
dados: false,
|
|
1773
|
+
audit: false,
|
|
1774
|
+
segredos: false,
|
|
1775
|
+
forbidden: false,
|
|
1776
|
+
dadosSensiveis: false,
|
|
1777
|
+
efeitoPrivilegiado: false,
|
|
1778
|
+
exigeSegredos: false,
|
|
1779
|
+
};
|
|
1667
1780
|
const resumoVinculos = resumoVinculosPorTask.get(chaveTask) ?? {
|
|
1668
1781
|
validos: 0,
|
|
1669
1782
|
quebrados: 0,
|
|
@@ -1674,7 +1787,7 @@ export async function analisarDriftLegado(contexto) {
|
|
|
1674
1787
|
}
|
|
1675
1788
|
resumo.confiancaVinculo = calcularConfiancaTask(task, resumo.implsValidos, resumo.implsQuebrados, resumoVinculos.validos, resumoVinculos.quebrados);
|
|
1676
1789
|
resumo.riscoOperacional = calcularRiscoOperacional(task);
|
|
1677
|
-
resumo.lacunas = resumirLacunasTask(task, resumo.semImplementacao, resumo.implsQuebrados, resumoVinculos.quebrados);
|
|
1790
|
+
resumo.lacunas = resumirLacunasTask(task, resumo.semImplementacao, resumo.implsQuebrados, resumoVinculos.quebrados, guardrails);
|
|
1678
1791
|
resumo.scoreSemantico = calcularScoreTask(task, resumo.implsValidos, resumo.implsQuebrados, resumoVinculos.validos, resumoVinculos.quebrados, resumo.semImplementacao);
|
|
1679
1792
|
resumo.arquivosProvaveisEditar = [...new Set([
|
|
1680
1793
|
...resumo.arquivosReferenciados,
|
|
@@ -1685,7 +1798,85 @@ export async function analisarDriftLegado(contexto) {
|
|
|
1685
1798
|
...task.resumoAgente.checks,
|
|
1686
1799
|
resumo.riscoOperacional !== "baixo" ? "revisar efeitos operacionais" : "",
|
|
1687
1800
|
resumo.lacunas.includes("vinculo_quebrado") ? "corrigir vinculos rastreaveis" : "",
|
|
1801
|
+
resumo.lacunas.some((lacuna) => ["superficie_publica_sem_execucao", "execucao_critica_sem_bloco", "rastreabilidade_fraca"].includes(lacuna))
|
|
1802
|
+
? "endurecer execucao e rastreabilidade para producao"
|
|
1803
|
+
: "",
|
|
1804
|
+
resumo.lacunas.some((lacuna) => ["auth_ausente", "authz_frouxa", "dados_nao_classificados", "audit_ausente", "segredo_sem_governanca", "proibicoes_ausentes"].includes(lacuna))
|
|
1805
|
+
? "explicitar contratos de seguranca semantica"
|
|
1806
|
+
: "",
|
|
1688
1807
|
].filter(Boolean))];
|
|
1808
|
+
if (resumo.lacunas.includes("superficie_publica_sem_execucao")) {
|
|
1809
|
+
diagnosticos.push({
|
|
1810
|
+
tipo: "seguranca_frouxa",
|
|
1811
|
+
modulo: resumo.modulo,
|
|
1812
|
+
task: resumo.task,
|
|
1813
|
+
mensagem: `Task "${resumo.task}" alimenta superficie publica, mas ainda depende de execucao implicita.`,
|
|
1814
|
+
});
|
|
1815
|
+
}
|
|
1816
|
+
if (resumo.lacunas.includes("execucao_critica_sem_bloco")) {
|
|
1817
|
+
diagnosticos.push({
|
|
1818
|
+
tipo: "seguranca_frouxa",
|
|
1819
|
+
modulo: resumo.modulo,
|
|
1820
|
+
task: resumo.task,
|
|
1821
|
+
mensagem: `Task "${resumo.task}" opera com risco alto, mas ainda nao declarou execucao explicita.`,
|
|
1822
|
+
});
|
|
1823
|
+
}
|
|
1824
|
+
if (resumo.lacunas.includes("rastreabilidade_fraca")) {
|
|
1825
|
+
diagnosticos.push({
|
|
1826
|
+
tipo: "seguranca_frouxa",
|
|
1827
|
+
modulo: resumo.modulo,
|
|
1828
|
+
task: resumo.task,
|
|
1829
|
+
mensagem: `Task "${resumo.task}" exige producao mais rastreavel, mas ainda nao declara impl nem vinculos.`,
|
|
1830
|
+
});
|
|
1831
|
+
}
|
|
1832
|
+
if (resumo.lacunas.includes("auth_ausente")) {
|
|
1833
|
+
diagnosticos.push({
|
|
1834
|
+
tipo: "seguranca_frouxa",
|
|
1835
|
+
modulo: resumo.modulo,
|
|
1836
|
+
task: resumo.task,
|
|
1837
|
+
mensagem: `Task "${resumo.task}" chega em superficie publica sem auth explicita em task, route ou superficie associada.`,
|
|
1838
|
+
});
|
|
1839
|
+
}
|
|
1840
|
+
if (resumo.lacunas.includes("authz_frouxa")) {
|
|
1841
|
+
diagnosticos.push({
|
|
1842
|
+
tipo: "seguranca_frouxa",
|
|
1843
|
+
modulo: resumo.modulo,
|
|
1844
|
+
task: resumo.task,
|
|
1845
|
+
mensagem: `Task "${resumo.task}" opera com risco ou exposicao, mas ainda nao explicita authz suficiente.`,
|
|
1846
|
+
});
|
|
1847
|
+
}
|
|
1848
|
+
if (resumo.lacunas.includes("dados_nao_classificados")) {
|
|
1849
|
+
diagnosticos.push({
|
|
1850
|
+
tipo: "seguranca_frouxa",
|
|
1851
|
+
modulo: resumo.modulo,
|
|
1852
|
+
task: resumo.task,
|
|
1853
|
+
mensagem: `Task "${resumo.task}" ainda nao classifica dados de entrada/saida de forma semantica.`,
|
|
1854
|
+
});
|
|
1855
|
+
}
|
|
1856
|
+
if (resumo.lacunas.includes("audit_ausente")) {
|
|
1857
|
+
diagnosticos.push({
|
|
1858
|
+
tipo: "seguranca_frouxa",
|
|
1859
|
+
modulo: resumo.modulo,
|
|
1860
|
+
task: resumo.task,
|
|
1861
|
+
mensagem: `Task "${resumo.task}" ainda nao declara audit explicita para operacao sensivel ou publica.`,
|
|
1862
|
+
});
|
|
1863
|
+
}
|
|
1864
|
+
if (resumo.lacunas.includes("segredo_sem_governanca")) {
|
|
1865
|
+
diagnosticos.push({
|
|
1866
|
+
tipo: "seguranca_frouxa",
|
|
1867
|
+
modulo: resumo.modulo,
|
|
1868
|
+
task: resumo.task,
|
|
1869
|
+
mensagem: `Task "${resumo.task}" toca segredo ou credencial sem bloco segredos governando origem, escopo e rotacao.`,
|
|
1870
|
+
});
|
|
1871
|
+
}
|
|
1872
|
+
if (resumo.lacunas.includes("proibicoes_ausentes")) {
|
|
1873
|
+
diagnosticos.push({
|
|
1874
|
+
tipo: "seguranca_frouxa",
|
|
1875
|
+
modulo: resumo.modulo,
|
|
1876
|
+
task: resumo.task,
|
|
1877
|
+
mensagem: `Task "${resumo.task}" opera com efeito privilegiado ou dado sensivel sem forbidden explicito para conter abuso e vazamento.`,
|
|
1878
|
+
});
|
|
1879
|
+
}
|
|
1689
1880
|
}
|
|
1690
1881
|
const consumerSurfaces = [...indexTs.consumerSurfaces, ...indexDart.consumerSurfaces].sort((a, b) => a.rota.localeCompare(b.rota, "pt-BR")
|
|
1691
1882
|
|| a.tipoArquivo.localeCompare(b.tipoArquivo, "pt-BR")
|