@semacode/cli 1.5.19 → 1.5.26

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/dist/index.js CHANGED
@@ -479,6 +479,8 @@ function ajuda() {
479
479
  "sema profile validar workflow contratos/sema/workflow_ops.sema --maturidade production --preset webhook --artefato-arquivo workflow.md --json",
480
480
  "sema profile validar ops contratos/sema/workflow_ops.sema --maturidade critical --preset deploy --artefato-arquivo runbook.md --json",
481
481
  "sema profile validar game contratos/sema/game.sema --maturidade prototype --preset playtest --artefato-arquivo playtest.md --json",
482
+ "sema profile capabilities --json",
483
+ "sema rule-packs --profile legal --json",
482
484
  "",
483
485
  "[5] Adotar Sema em projeto que ainda nao usa",
484
486
  "sema importar <fonte> <diretorio> --saida <diretorio> --json",
@@ -507,6 +509,8 @@ function ajuda() {
507
509
  "formatacao: sema formatar <arquivo-ou-pasta> [--check] [--json]",
508
510
  "author: sema author <iniciar|validar|briefing|revisar-cliches|validar-narrativa|validar-proibicoes> [arquivo] [--tema-sensivel] [--preset conto|romance|roteiro|lore|campanha] [--saida <arquivo>] [--texto <texto>] [--json]",
509
511
  "profile: sema profile validar <software|workflow|ops|game|legal|research> <arquivo-ou-pasta> [--maturidade draft|prototype|production|critical] [--preset <preset>] [--artefato <texto>|--artefato-arquivo <arquivo>] [--json]",
512
+ "capabilities: sema profile capabilities [--json]",
513
+ "rule packs: sema rule-packs [--profile <author|software|workflow|ops|game|legal|research>] [--json]",
510
514
  ]),
511
515
  "",
512
516
  renderizarSecaoAscii("Ajuda IA-first", [
@@ -530,6 +534,8 @@ function ajuda() {
530
534
  "sema author validar-narrativa <arquivo.sema> [--texto <texto>|--texto-arquivo <arquivo>] [--json]",
531
535
  "sema author validar-proibicoes <arquivo.sema> [--texto <texto>|--texto-arquivo <arquivo>] [--json]",
532
536
  "sema profile validar <profile> <arquivo.sema> [--maturidade draft|prototype|production|critical] [--preset <preset>] [--artefato <texto>|--artefato-arquivo <arquivo>] [--json]",
537
+ "sema profile capabilities [--json]",
538
+ "sema rule-packs [--profile <profile>] [--json]",
533
539
  ]),
534
540
  "",
535
541
  renderizarSecaoAscii("Operacional", [
@@ -590,6 +596,7 @@ const OPCOES_COM_VALOR = new Set([
590
596
  "--endpoint",
591
597
  "--maturidade",
592
598
  "--preset",
599
+ "--profile",
593
600
  "--artefato",
594
601
  "--artifact",
595
602
  "--artefato-arquivo",
@@ -4208,6 +4215,335 @@ const PRESETS_PROFILE = {
4208
4215
  research: ["rapida", "tecnica", "decisoria", "critica"],
4209
4216
  game: ["casual", "arcade", "rpg", "economia", "playtest"],
4210
4217
  };
4218
+ const CAPABILITY_MATRIX_GOVERNANCA = {
4219
+ author: {
4220
+ profile: "author",
4221
+ detectaLiteral: true,
4222
+ detectaSemantico: "parcial",
4223
+ detectaOrdemExecucao: false,
4224
+ detectaDriftReal: "parcial",
4225
+ validaArtefatoReal: true,
4226
+ interpretaNegacao: true,
4227
+ confianca: "media",
4228
+ limites: [
4229
+ "validacao semantica profunda segue heuristica e precisa de texto alvo",
4230
+ "continuidade longa depende de texto anterior ou memoria canonica fornecida",
4231
+ ],
4232
+ rulePacksSugeridos: ["author-quality", "brand-voice", "campaign-continuity"],
4233
+ },
4234
+ software: {
4235
+ profile: "software",
4236
+ detectaLiteral: true,
4237
+ detectaSemantico: "parcial",
4238
+ detectaOrdemExecucao: "parcial",
4239
+ detectaDriftReal: "parcial",
4240
+ validaArtefatoReal: true,
4241
+ interpretaNegacao: true,
4242
+ confianca: "media",
4243
+ limites: [
4244
+ "artefato inline nao substitui SAST completo",
4245
+ "drift real melhora quando contrato e codigo vivo estao vinculados",
4246
+ ],
4247
+ rulePacksSugeridos: ["owasp", "openapi", "saas"],
4248
+ },
4249
+ workflow: {
4250
+ profile: "workflow",
4251
+ detectaLiteral: true,
4252
+ detectaSemantico: "parcial",
4253
+ detectaOrdemExecucao: true,
4254
+ detectaDriftReal: "parcial",
4255
+ validaArtefatoReal: true,
4256
+ interpretaNegacao: true,
4257
+ confianca: "media",
4258
+ limites: [
4259
+ "ordem real exige etapas nomeadas no contrato e no artefato",
4260
+ "adaptadores de runtime ainda devem declarar lacunas honestas",
4261
+ ],
4262
+ rulePacksSugeridos: ["n8n", "event-driven", "approval-flow"],
4263
+ },
4264
+ ops: {
4265
+ profile: "ops",
4266
+ detectaLiteral: true,
4267
+ detectaSemantico: "parcial",
4268
+ detectaOrdemExecucao: "parcial",
4269
+ detectaDriftReal: "parcial",
4270
+ validaArtefatoReal: true,
4271
+ interpretaNegacao: true,
4272
+ confianca: "media",
4273
+ limites: [
4274
+ "validacao nao executa rollback real sem comandos externos",
4275
+ "modo critical deve escalar humano quando falta runbook ou reversibilidade",
4276
+ ],
4277
+ rulePacksSugeridos: ["kubernetes", "sre", "incident-response"],
4278
+ },
4279
+ legal: {
4280
+ profile: "legal",
4281
+ detectaLiteral: true,
4282
+ detectaSemantico: "parcial",
4283
+ detectaOrdemExecucao: false,
4284
+ detectaDriftReal: "parcial",
4285
+ validaArtefatoReal: true,
4286
+ interpretaNegacao: true,
4287
+ confianca: "media",
4288
+ limites: [
4289
+ "nao substitui revisao humana por profissional habilitado",
4290
+ "fontes normativas devem ser fornecidas ou citadas pelo agente",
4291
+ ],
4292
+ rulePacksSugeridos: ["lgpd", "dpa", "privacy-policy", "soc2"],
4293
+ },
4294
+ research: {
4295
+ profile: "research",
4296
+ detectaLiteral: true,
4297
+ detectaSemantico: "parcial",
4298
+ detectaOrdemExecucao: false,
4299
+ detectaDriftReal: "parcial",
4300
+ validaArtefatoReal: true,
4301
+ interpretaNegacao: true,
4302
+ confianca: "media",
4303
+ limites: [
4304
+ "nao verifica fontes externas sem ferramenta de busca ou dataset anexado",
4305
+ "confianca aumenta quando evidencia, metodo e incerteza estao separados",
4306
+ ],
4307
+ rulePacksSugeridos: ["decision-research", "contradictory-review", "evidence-matrix"],
4308
+ },
4309
+ game: {
4310
+ profile: "game",
4311
+ detectaLiteral: true,
4312
+ detectaSemantico: "parcial",
4313
+ detectaOrdemExecucao: "parcial",
4314
+ detectaDriftReal: "parcial",
4315
+ validaArtefatoReal: true,
4316
+ interpretaNegacao: true,
4317
+ confianca: "media",
4318
+ limites: [
4319
+ "playtest simulado nao substitui telemetria de jogador real",
4320
+ "balanceamento numerico profundo depende de parametros e sessoes",
4321
+ ],
4322
+ rulePacksSugeridos: ["playtest", "economy-balance", "progression"],
4323
+ },
4324
+ };
4325
+ const RULE_PACKS_SEMA = [
4326
+ {
4327
+ id: "owasp",
4328
+ nome: "OWASP Application Security",
4329
+ categoria: "premium",
4330
+ profiles: ["software"],
4331
+ maturidadeMinima: "production",
4332
+ controles: ["input_validation", "safe_output", "no_eval", "no_dynamic_sql", "secret_handling"],
4333
+ monetizacao: "cloud",
4334
+ status: "premium",
4335
+ },
4336
+ {
4337
+ id: "openapi",
4338
+ nome: "OpenAPI Contract Surface",
4339
+ categoria: "oss",
4340
+ profiles: ["software", "workflow"],
4341
+ maturidadeMinima: "prototype",
4342
+ controles: ["endpoint_shape", "request_response", "auth_surface", "error_contract"],
4343
+ monetizacao: "aberto",
4344
+ status: "base",
4345
+ },
4346
+ {
4347
+ id: "lgpd",
4348
+ nome: "LGPD Privacy Governance",
4349
+ categoria: "premium",
4350
+ profiles: ["legal", "ops", "workflow"],
4351
+ maturidadeMinima: "production",
4352
+ controles: ["data_inventory", "legal_basis", "retention", "data_subject_rights", "human_review"],
4353
+ monetizacao: "cloud",
4354
+ status: "premium",
4355
+ },
4356
+ {
4357
+ id: "dpa",
4358
+ nome: "Data Processing Agreement",
4359
+ categoria: "premium",
4360
+ profiles: ["legal"],
4361
+ maturidadeMinima: "production",
4362
+ controles: ["controller_processor", "subprocessors", "transfer", "security_measures", "audit"],
4363
+ monetizacao: "cloud",
4364
+ status: "premium",
4365
+ },
4366
+ {
4367
+ id: "soc2",
4368
+ nome: "SOC2 Operational Evidence",
4369
+ categoria: "enterprise",
4370
+ profiles: ["ops", "workflow", "software", "legal"],
4371
+ maturidadeMinima: "critical",
4372
+ controles: ["audit_trail", "approval_gate", "incident_evidence", "access_review"],
4373
+ monetizacao: "enterprise",
4374
+ status: "planejado",
4375
+ },
4376
+ {
4377
+ id: "kubernetes",
4378
+ nome: "Kubernetes Change Safety",
4379
+ categoria: "premium",
4380
+ profiles: ["ops"],
4381
+ maturidadeMinima: "production",
4382
+ controles: ["deployment_healthcheck", "rollback", "migration_guard", "resource_limits"],
4383
+ monetizacao: "cloud",
4384
+ status: "planejado",
4385
+ },
4386
+ {
4387
+ id: "n8n",
4388
+ nome: "n8n Workflow Runtime",
4389
+ categoria: "premium",
4390
+ profiles: ["workflow"],
4391
+ maturidadeMinima: "prototype",
4392
+ controles: ["node_surface", "credential_boundary", "retry", "idempotency", "dlq"],
4393
+ monetizacao: "cloud",
4394
+ status: "planejado",
4395
+ },
4396
+ {
4397
+ id: "saas",
4398
+ nome: "Startup SaaS Governance",
4399
+ categoria: "premium",
4400
+ profiles: ["software", "workflow", "ops", "legal", "research"],
4401
+ maturidadeMinima: "production",
4402
+ controles: ["authz", "billing_risk", "data_retention", "release_gate", "audit"],
4403
+ monetizacao: "cloud",
4404
+ status: "planejado",
4405
+ },
4406
+ {
4407
+ id: "author-quality",
4408
+ nome: "Author Quality Gate",
4409
+ categoria: "oss",
4410
+ profiles: ["author"],
4411
+ maturidadeMinima: "draft",
4412
+ controles: ["forbidden_literals", "cliche_review", "narrative_conflict", "tone_drift"],
4413
+ monetizacao: "aberto",
4414
+ status: "base",
4415
+ },
4416
+ {
4417
+ id: "brand-voice",
4418
+ nome: "Brand Voice Guardrails",
4419
+ categoria: "premium",
4420
+ profiles: ["author", "legal", "research"],
4421
+ maturidadeMinima: "prototype",
4422
+ controles: ["tone_drift", "style_policy", "forbidden_claims", "approval_review"],
4423
+ monetizacao: "cloud",
4424
+ status: "planejado",
4425
+ },
4426
+ {
4427
+ id: "campaign-continuity",
4428
+ nome: "Campaign Continuity",
4429
+ categoria: "premium",
4430
+ profiles: ["author", "game"],
4431
+ maturidadeMinima: "production",
4432
+ controles: ["canon_memory", "character_state", "promise_tracking", "chapter_drift"],
4433
+ monetizacao: "cloud",
4434
+ status: "planejado",
4435
+ },
4436
+ {
4437
+ id: "event-driven",
4438
+ nome: "Event Driven Workflow",
4439
+ categoria: "premium",
4440
+ profiles: ["workflow", "ops"],
4441
+ maturidadeMinima: "production",
4442
+ controles: ["event_schema", "idempotency", "retry_policy", "dlq", "compensation"],
4443
+ monetizacao: "cloud",
4444
+ status: "planejado",
4445
+ },
4446
+ {
4447
+ id: "approval-flow",
4448
+ nome: "Human Approval Flow",
4449
+ categoria: "enterprise",
4450
+ profiles: ["workflow", "ops", "legal"],
4451
+ maturidadeMinima: "critical",
4452
+ controles: ["human_gate", "rbac", "audit_trail", "decision_retention"],
4453
+ monetizacao: "enterprise",
4454
+ status: "planejado",
4455
+ },
4456
+ {
4457
+ id: "sre",
4458
+ nome: "SRE Operational Gate",
4459
+ categoria: "premium",
4460
+ profiles: ["ops"],
4461
+ maturidadeMinima: "production",
4462
+ controles: ["slo", "error_budget", "runbook", "rollback", "oncall"],
4463
+ monetizacao: "cloud",
4464
+ status: "planejado",
4465
+ },
4466
+ {
4467
+ id: "incident-response",
4468
+ nome: "Incident Response",
4469
+ categoria: "enterprise",
4470
+ profiles: ["ops", "legal"],
4471
+ maturidadeMinima: "critical",
4472
+ controles: ["severity", "communication", "owner", "postmortem", "evidence_retention"],
4473
+ monetizacao: "enterprise",
4474
+ status: "planejado",
4475
+ },
4476
+ {
4477
+ id: "privacy-policy",
4478
+ nome: "Privacy Policy Review",
4479
+ categoria: "premium",
4480
+ profiles: ["legal"],
4481
+ maturidadeMinima: "production",
4482
+ controles: ["data_purpose", "legal_basis", "retention", "dpo_contact", "subject_rights"],
4483
+ monetizacao: "cloud",
4484
+ status: "premium",
4485
+ },
4486
+ {
4487
+ id: "decision-research",
4488
+ nome: "Decision Research",
4489
+ categoria: "oss",
4490
+ profiles: ["research"],
4491
+ maturidadeMinima: "prototype",
4492
+ controles: ["question", "method", "criteria", "weights", "alternatives"],
4493
+ monetizacao: "aberto",
4494
+ status: "base",
4495
+ },
4496
+ {
4497
+ id: "contradictory-review",
4498
+ nome: "Contradictory Evidence Review",
4499
+ categoria: "premium",
4500
+ profiles: ["research", "legal"],
4501
+ maturidadeMinima: "production",
4502
+ controles: ["counter_evidence", "uncertainty", "source_rejection", "confidence_level"],
4503
+ monetizacao: "cloud",
4504
+ status: "planejado",
4505
+ },
4506
+ {
4507
+ id: "evidence-matrix",
4508
+ nome: "Evidence Matrix",
4509
+ categoria: "premium",
4510
+ profiles: ["research", "legal"],
4511
+ maturidadeMinima: "production",
4512
+ controles: ["source_weight", "fact_inference", "reproducibility", "decision_trace"],
4513
+ monetizacao: "cloud",
4514
+ status: "planejado",
4515
+ },
4516
+ {
4517
+ id: "playtest",
4518
+ nome: "Simulated Playtest",
4519
+ categoria: "oss",
4520
+ profiles: ["game"],
4521
+ maturidadeMinima: "prototype",
4522
+ controles: ["first_10_seconds", "first_minute", "tension_point", "reward", "retry_reason"],
4523
+ monetizacao: "aberto",
4524
+ status: "base",
4525
+ },
4526
+ {
4527
+ id: "economy-balance",
4528
+ nome: "Game Economy Balance",
4529
+ categoria: "premium",
4530
+ profiles: ["game"],
4531
+ maturidadeMinima: "production",
4532
+ controles: ["currency_source", "sink", "soft_cap", "exploit", "session_curve"],
4533
+ monetizacao: "cloud",
4534
+ status: "planejado",
4535
+ },
4536
+ {
4537
+ id: "progression",
4538
+ nome: "Progression And Pacing",
4539
+ categoria: "premium",
4540
+ profiles: ["game", "author"],
4541
+ maturidadeMinima: "production",
4542
+ controles: ["difficulty_curve", "session_time", "mastery", "frustration", "reward_cadence"],
4543
+ monetizacao: "cloud",
4544
+ status: "planejado",
4545
+ },
4546
+ ];
4211
4547
  const REQUISITOS_PRESET_PROFILE = {
4212
4548
  security: [
4213
4549
  { id: "security_entrada_saida", descricao: "declara validacao de entrada e saida segura", termos: [/entrada|input/i, /saida|output|retorno/i, /segur|sanitiz|valid/i], obrigatorio: true, severidade: "blocking" },
@@ -4311,16 +4647,33 @@ function severidadeRequisitoProfile(requisito, profile, maturidade) {
4311
4647
  }
4312
4648
  return maturidade === "draft" ? "warning" : "blocking";
4313
4649
  }
4650
+ function riscoAchadoProfile(severidade, fonte) {
4651
+ if (severidade === "critical")
4652
+ return fonte === "artefato" ? "violacao_critica_no_artefato" : "risco_critico_de_governanca";
4653
+ if (severidade === "blocking")
4654
+ return fonte === "artefato" ? "artefato_nao_aderente" : "contrato_nao_pronto";
4655
+ if (severidade === "warning")
4656
+ return "ressalva_operacional";
4657
+ return "informativo";
4658
+ }
4314
4659
  function avaliarRequisitosProfile(conteudo, requisitos, profile, maturidade, fonte = "contrato") {
4315
- return requisitos.map((requisito) => ({
4316
- id: requisito.id,
4317
- descricao: requisito.descricao,
4318
- obrigatorio: requisito.obrigatorio,
4319
- atendido: requisito.termos.every((termo) => termo.test(conteudo)),
4320
- severidade: severidadeRequisitoProfile(requisito, profile, maturidade),
4321
- termos: requisito.termos.map((termo) => termo.source),
4322
- fonte,
4323
- }));
4660
+ return requisitos.map((requisito) => {
4661
+ const severidade = severidadeRequisitoProfile(requisito, profile, maturidade);
4662
+ const atendido = requisito.termos.every((termo) => termo.test(conteudo));
4663
+ return {
4664
+ id: requisito.id,
4665
+ descricao: requisito.descricao,
4666
+ obrigatorio: requisito.obrigatorio,
4667
+ atendido,
4668
+ severidade,
4669
+ termos: requisito.termos.map((termo) => termo.source),
4670
+ fonte,
4671
+ regra: requisito.id,
4672
+ motivo: atendido ? undefined : `requisito ${fonte} nao foi demonstrado no contrato.`,
4673
+ risco: atendido ? undefined : riscoAchadoProfile(severidade, fonte),
4674
+ sugestao: atendido ? undefined : "declare o requisito com entradas, efeitos, garantias e checks rastreaveis.",
4675
+ };
4676
+ });
4324
4677
  }
4325
4678
  function decidirAcaoAgenteProfile(contratoValido, achados) {
4326
4679
  if (!contratoValido)
@@ -4353,6 +4706,62 @@ function penalidadeAchadoProfile(achado) {
4353
4706
  function calcularScoreAchadosProfile(base, achados) {
4354
4707
  return Math.max(0, base - achados.reduce((total, achado) => total + penalidadeAchadoProfile(achado), 0));
4355
4708
  }
4709
+ function calcularScoreRiscoProfile(achados) {
4710
+ const pendentes = achados.filter((achado) => !achado.atendido);
4711
+ return Math.min(100, pendentes.reduce((total, achado) => {
4712
+ if (achado.severidade === "critical")
4713
+ return total + 35;
4714
+ if (achado.severidade === "blocking")
4715
+ return total + 22;
4716
+ if (achado.severidade === "warning")
4717
+ return total + 8;
4718
+ return total + 2;
4719
+ }, 0));
4720
+ }
4721
+ function severidadeMaximaProfile(achados) {
4722
+ const pendentes = achados.filter((achado) => !achado.atendido);
4723
+ if (pendentes.some((achado) => achado.severidade === "critical"))
4724
+ return "critical";
4725
+ if (pendentes.some((achado) => achado.severidade === "blocking"))
4726
+ return "blocking";
4727
+ if (pendentes.some((achado) => achado.severidade === "warning"))
4728
+ return "warning";
4729
+ if (pendentes.some((achado) => achado.severidade === "info"))
4730
+ return "info";
4731
+ return null;
4732
+ }
4733
+ function calcularConfiancaValidacaoProfile(artefatoRecebido, achadosArtefato, scoreRisco) {
4734
+ if (!artefatoRecebido)
4735
+ return "parcial";
4736
+ if (scoreRisco >= 70)
4737
+ return "media";
4738
+ if (achadosArtefato.some((achado) => !achado.atendido && achado.trecho && achado.linha))
4739
+ return "alta";
4740
+ if (achadosArtefato.length > 0)
4741
+ return "media";
4742
+ return "media";
4743
+ }
4744
+ function criarRuntimeGateProfile(decisao, maturidade, achados, scoreRisco) {
4745
+ const severidadeMaxima = severidadeMaximaProfile(achados);
4746
+ const exigeHumano = decisao === "chamar_humano" || severidadeMaxima === "critical";
4747
+ const podeExecutar = decisao === "continuar" || decisao === "continuar_com_ressalva";
4748
+ return {
4749
+ decisao,
4750
+ maturidade,
4751
+ podeExecutar,
4752
+ exigeHumano,
4753
+ scoreRisco,
4754
+ severidadeMaxima,
4755
+ motivo: podeExecutar
4756
+ ? "gate permite continuidade com as ressalvas declaradas."
4757
+ : exigeHumano
4758
+ ? "gate bloqueia e exige humano por risco critico ou maturidade critica."
4759
+ : "gate bloqueia ate resolver requisitos obrigatorios.",
4760
+ };
4761
+ }
4762
+ function selecionarRulePacksProfile(profile) {
4763
+ return RULE_PACKS_SEMA.filter((pack) => pack.profiles.includes(profile));
4764
+ }
4356
4765
  function contratoProibeTermoProfile(contrato, termo) {
4357
4766
  const escaped = termo.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
4358
4767
  const padroes = [
@@ -4361,7 +4770,7 @@ function contratoProibeTermoProfile(contrato, termo) {
4361
4770
  ];
4362
4771
  return padroes.some((padrao) => padrao.test(contrato));
4363
4772
  }
4364
- function criarAchadoArtefatoProfile(id, descricao, atendido, severidade, trecho, sugestao, motivo) {
4773
+ function criarAchadoArtefatoProfile(id, descricao, atendido, severidade, trecho, sugestao, motivo, detalhes) {
4365
4774
  return {
4366
4775
  id,
4367
4776
  descricao,
@@ -4370,8 +4779,14 @@ function criarAchadoArtefatoProfile(id, descricao, atendido, severidade, trecho,
4370
4779
  severidade,
4371
4780
  termos: [],
4372
4781
  fonte: "artefato",
4782
+ regra: detalhes?.regra ?? id,
4373
4783
  trecho,
4784
+ linha: detalhes?.linha,
4785
+ coluna: detalhes?.coluna,
4786
+ inicio: detalhes?.inicio,
4787
+ fim: detalhes?.fim,
4374
4788
  motivo,
4789
+ risco: detalhes?.risco ?? (atendido ? undefined : riscoAchadoProfile(severidade, "artefato")),
4375
4790
  sugestao,
4376
4791
  };
4377
4792
  }
@@ -4396,6 +4811,25 @@ function trechoDoMatchProfile(texto, indice, tamanho) {
4396
4811
  const fim = Math.min(texto.length, indice + tamanho + 60);
4397
4812
  return texto.slice(inicio, fim).replace(/\s+/g, " ").trim();
4398
4813
  }
4814
+ function localizacaoDoMatchProfile(texto, indice, tamanho) {
4815
+ const antes = texto.slice(0, indice);
4816
+ const linhas = antes.split(/\r?\n/);
4817
+ return {
4818
+ trecho: trechoDoMatchProfile(texto, indice, tamanho),
4819
+ linha: linhas.length,
4820
+ coluna: (linhas.at(-1) ?? "").length + 1,
4821
+ inicio: indice,
4822
+ fim: indice + tamanho,
4823
+ };
4824
+ }
4825
+ function localizarRegexProfile(texto, regex) {
4826
+ const flags = regex.flags.replace(/g/g, "");
4827
+ const busca = new RegExp(regex.source, flags);
4828
+ const match = busca.exec(texto);
4829
+ if (!match)
4830
+ return undefined;
4831
+ return localizacaoDoMatchProfile(texto, match.index, match[0].length);
4832
+ }
4399
4833
  function termoNegadoNoArtefato(texto, indice, tamanho) {
4400
4834
  const antes = texto.slice(Math.max(0, indice - 90), indice);
4401
4835
  const depois = texto.slice(indice + tamanho, Math.min(texto.length, indice + tamanho + 90));
@@ -4420,7 +4854,7 @@ function avaliarPresencaPositivaArtefato(texto, regex) {
4420
4854
  if (primeiroNegado) {
4421
4855
  return {
4422
4856
  atendido: false,
4423
- trecho: trechoDoMatchProfile(texto, primeiroNegado.indice, primeiroNegado.tamanho),
4857
+ ...localizacaoDoMatchProfile(texto, primeiroNegado.indice, primeiroNegado.tamanho),
4424
4858
  motivo: "termo encontrado em contexto de negacao/ausencia; mencao negativa nao satisfaz requisito.",
4425
4859
  };
4426
4860
  }
@@ -4429,7 +4863,13 @@ function avaliarPresencaPositivaArtefato(texto, regex) {
4429
4863
  function validarTermosObrigatoriosArtefato(texto, checks) {
4430
4864
  return checks.map((check) => {
4431
4865
  const presenca = avaliarPresencaPositivaArtefato(texto, check.regex);
4432
- return criarAchadoArtefatoProfile(check.id, check.descricao, presenca.atendido, check.severidade ?? "blocking", presenca.trecho, check.sugestao, presenca.motivo);
4866
+ return criarAchadoArtefatoProfile(check.id, check.descricao, presenca.atendido, check.severidade ?? "blocking", presenca.trecho, check.sugestao, presenca.motivo, {
4867
+ linha: presenca.linha,
4868
+ coluna: presenca.coluna,
4869
+ inicio: presenca.inicio,
4870
+ fim: presenca.fim,
4871
+ regra: check.id,
4872
+ });
4433
4873
  });
4434
4874
  }
4435
4875
  function avaliarArtefatoSoftwareProfile(contrato, artefato, maturidade, preset) {
@@ -4589,6 +5029,21 @@ async function validarProfileSemantico(entrada, profile, opcoes) {
4589
5029
  const decisaoAgente = decidirAcaoAgenteProfile(contratoValido, achados);
4590
5030
  const aprovado = contratoValido && obrigatoriosPendentes.length === 0 && scoreProntoParaAcao >= 80;
4591
5031
  const podeContinuar = decisaoAgente === "continuar" || decisaoAgente === "continuar_com_ressalva";
5032
+ const scoreRisco = calcularScoreRiscoProfile(achados);
5033
+ const confiancaValidacao = calcularConfiancaValidacaoProfile(Boolean(opcoes.artefatoTexto), achadosArtefato, scoreRisco);
5034
+ const prontoParaAcao = aprovado && podeContinuar;
5035
+ const confidenceEngine = {
5036
+ scoreContratoFormal: scoreContrato,
5037
+ scoreAderenciaSemantica: scoreArtefato,
5038
+ scoreRisco,
5039
+ prontoParaAcao,
5040
+ confiancaValidacao,
5041
+ comparacaoArtefatoReal: Boolean(opcoes.artefatoTexto),
5042
+ heuristicaParcial: confiancaValidacao === "parcial" || confiancaValidacao === "baixa",
5043
+ };
5044
+ const runtimeGate = criarRuntimeGateProfile(decisaoAgente, maturidade, achados, scoreRisco);
5045
+ const capabilityMatrix = CAPABILITY_MATRIX_GOVERNANCA[profile];
5046
+ const rulePacksSugeridos = selecionarRulePacksProfile(profile);
4592
5047
  return {
4593
5048
  comando: "profile validar",
4594
5049
  sucesso: aprovado,
@@ -4608,6 +5063,15 @@ async function validarProfileSemantico(entrada, profile, opcoes) {
4608
5063
  scoreContrato,
4609
5064
  scoreArtefato,
4610
5065
  scoreProntoParaAcao,
5066
+ scoreContratoFormal: scoreContrato,
5067
+ scoreAderenciaSemantica: scoreArtefato,
5068
+ scoreRisco,
5069
+ prontoParaAcao,
5070
+ confiancaValidacao,
5071
+ confidenceEngine,
5072
+ capabilityMatrix,
5073
+ runtimeGate,
5074
+ rulePacksSugeridos,
4611
5075
  achados,
4612
5076
  achadosArtefato,
4613
5077
  requisitosAtendidos: achados.filter((achado) => achado.atendido).map((achado) => achado.id),
@@ -4636,31 +5100,110 @@ function renderizarProfileValidarTexto(resultado) {
4636
5100
  `SCORE_CONTRATO: ${resultado.scoreContrato}`,
4637
5101
  `SCORE_ARTEFATO: ${resultado.scoreArtefato ?? "nao_avaliado"}`,
4638
5102
  `SCORE_PRONTO_PARA_ACAO: ${resultado.scoreProntoParaAcao}`,
5103
+ `SCORE_RISCO: ${resultado.scoreRisco}`,
5104
+ `CONFIANCA_VALIDACAO: ${resultado.confiancaValidacao}`,
5105
+ `RUNTIME_GATE: ${resultado.runtimeGate.decisao}`,
4639
5106
  ];
4640
5107
  for (const achado of resultado.achados) {
4641
5108
  linhas.push(`- ${achado.id}: ${achado.atendido ? "ok" : "pendente"} ${achado.severidade}${achado.obrigatorio ? " obrigatorio" : " recomendado"} ${achado.fonte} - ${achado.descricao}`);
5109
+ if (achado.linha && achado.coluna)
5110
+ linhas.push(` posicao: linha ${achado.linha}, coluna ${achado.coluna}`);
4642
5111
  if (achado.trecho)
4643
5112
  linhas.push(` trecho: ${achado.trecho}`);
4644
5113
  if (achado.motivo)
4645
5114
  linhas.push(` motivo: ${achado.motivo}`);
5115
+ if (achado.risco)
5116
+ linhas.push(` risco: ${achado.risco}`);
4646
5117
  if (achado.sugestao)
4647
5118
  linhas.push(` sugestao: ${achado.sugestao}`);
4648
5119
  }
4649
5120
  return linhas.join("\n");
4650
5121
  }
5122
+ function criarPayloadCapabilityMatrix() {
5123
+ const profiles = Object.values(CAPABILITY_MATRIX_GOVERNANCA);
5124
+ return {
5125
+ comando: "profile capabilities",
5126
+ sucesso: true,
5127
+ profiles,
5128
+ resumo: {
5129
+ profiles: profiles.length,
5130
+ validaArtefatoReal: profiles.filter((profile) => profile.validaArtefatoReal).map((profile) => profile.profile),
5131
+ interpretaNegacao: profiles.filter((profile) => profile.interpretaNegacao).map((profile) => profile.profile),
5132
+ },
5133
+ };
5134
+ }
5135
+ function renderizarCapabilityMatrixTexto(payload) {
5136
+ return [
5137
+ "CAPABILITY_MATRIX",
5138
+ ...payload.profiles.map((profile) => [
5139
+ `- ${profile.profile}: confianca=${profile.confianca}`,
5140
+ ` literal=${profile.detectaLiteral ? "sim" : "nao"} semantico=${profile.detectaSemantico} ordem=${profile.detectaOrdemExecucao} artefato=${profile.validaArtefatoReal} negacao=${profile.interpretaNegacao ? "sim" : "nao"}`,
5141
+ ` packs=${profile.rulePacksSugeridos.join(", ")}`,
5142
+ ` limites=${profile.limites.join(" | ")}`,
5143
+ ].join("\n")).join("\n"),
5144
+ ].join("\n");
5145
+ }
5146
+ function criarPayloadRulePacks(profileFiltro = null) {
5147
+ const packs = profileFiltro
5148
+ ? RULE_PACKS_SEMA.filter((pack) => pack.profiles.includes(profileFiltro))
5149
+ : RULE_PACKS_SEMA;
5150
+ return {
5151
+ comando: "rule-packs",
5152
+ sucesso: true,
5153
+ profile: profileFiltro,
5154
+ packs,
5155
+ resumo: {
5156
+ total: packs.length,
5157
+ abertos: packs.filter((pack) => pack.monetizacao === "aberto").map((pack) => pack.id),
5158
+ pagos: packs.filter((pack) => pack.monetizacao !== "aberto").map((pack) => pack.id),
5159
+ enterprise: packs.filter((pack) => pack.categoria === "enterprise").map((pack) => pack.id),
5160
+ },
5161
+ };
5162
+ }
5163
+ function renderizarRulePacksTexto(payload) {
5164
+ return [
5165
+ "RULE_PACKS",
5166
+ ...payload.packs.map((pack) => [
5167
+ `- ${pack.id}: ${pack.nome}`,
5168
+ ` profiles=${pack.profiles.join(", ")} maturidade_minima=${pack.maturidadeMinima} monetizacao=${pack.monetizacao} status=${pack.status}`,
5169
+ ` controles=${pack.controles.join(", ")}`,
5170
+ ].join("\n")),
5171
+ ].join("\n");
5172
+ }
5173
+ function normalizarProfileGovernanca(valor) {
5174
+ if (!valor)
5175
+ return null;
5176
+ const chave = valor.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
5177
+ if (chave === "author" || chave === "autor" || chave === "escrita")
5178
+ return "author";
5179
+ return normalizarProfileSemantico(valor);
5180
+ }
4651
5181
  async function comandoProfile(posicionais, args, emJson) {
4652
5182
  const subcomando = posicionais[0];
4653
5183
  if (!subcomando || subcomando === "help" || subcomando === "ajuda") {
4654
5184
  console.log([
4655
- "Uso: sema profile <validar>",
5185
+ "Uso: sema profile <validar|capabilities|rule-packs>",
4656
5186
  "",
4657
5187
  "Comandos:",
4658
5188
  " sema profile validar <software|workflow|ops|game|legal|research> <arquivo-ou-pasta> [--maturidade draft|prototype|production|critical] [--preset <preset>] [--artefato <texto>|--artefato-arquivo <arquivo>] [--json]",
5189
+ " sema profile capabilities [--json]",
5190
+ " sema profile rule-packs [--profile <author|software|workflow|ops|game|legal|research>] [--json]",
4659
5191
  "",
4660
5192
  "O profile e um gate semantico: se requisito obrigatorio faltar, a saida bloqueia.",
4661
5193
  ].join("\n"));
4662
5194
  return subcomando ? 0 : 1;
4663
5195
  }
5196
+ if (subcomando === "capabilities" || subcomando === "capability-matrix" || subcomando === "matrix") {
5197
+ const payload = criarPayloadCapabilityMatrix();
5198
+ console.log(emJson ? JSON.stringify(payload, null, 2) : renderizarCapabilityMatrixTexto(payload));
5199
+ return 0;
5200
+ }
5201
+ if (subcomando === "rule-packs" || subcomando === "packs") {
5202
+ const profileFiltro = normalizarProfileGovernanca(obterOpcao(args, "--profile"));
5203
+ const payload = criarPayloadRulePacks(profileFiltro);
5204
+ console.log(emJson ? JSON.stringify(payload, null, 2) : renderizarRulePacksTexto(payload));
5205
+ return 0;
5206
+ }
4664
5207
  if (subcomando !== "validar") {
4665
5208
  console.error(`Subcomando profile desconhecido: ${subcomando}`);
4666
5209
  return 1;
@@ -6169,6 +6712,14 @@ async function principal() {
6169
6712
  case "profile":
6170
6713
  codigoSaida = await comandoProfile(posicionais, resto, possuiFlag(resto, "--json"));
6171
6714
  break;
6715
+ case "rule-packs":
6716
+ {
6717
+ const profileFiltro = normalizarProfileGovernanca(obterOpcao(resto, "--profile") ?? posicionais[0]);
6718
+ const payload = criarPayloadRulePacks(profileFiltro);
6719
+ console.log(possuiFlag(resto, "--json") ? JSON.stringify(payload, null, 2) : renderizarRulePacksTexto(payload));
6720
+ codigoSaida = 0;
6721
+ }
6722
+ break;
6172
6723
  case "validar":
6173
6724
  codigoSaida = possuiFlag(resto, "--json")
6174
6725
  ? await comandoValidarJson(posicionais[0])