@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/README.md +3 -3
- package/SEMA_BRIEF.curto.txt +3 -3
- package/SEMA_BRIEF.md +12 -12
- package/SEMA_BRIEF.micro.txt +2 -2
- package/SEMA_INDEX.json +208 -140
- package/dist/index.js +564 -13
- package/dist/index.js.map +1 -1
- package/docs/cli.md +4 -4
- package/docs/env.md +3 -3
- package/docs/instalacao-e-primeiro-uso.md +5 -5
- package/docs/persistencia-vendor-first.md +1 -1
- package/docs/rollback.md +1 -1
- package/node_modules/@sema/gerador-css/package.json +1 -1
- package/node_modules/@sema/gerador-dart/package.json +1 -1
- package/node_modules/@sema/gerador-html/package.json +1 -1
- package/node_modules/@sema/gerador-javascript/package.json +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/package.json +1 -1
- package/node_modules/@sema/padroes/package.json +1 -1
- package/package.json +10 -10
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
|
-
|
|
4317
|
-
|
|
4318
|
-
|
|
4319
|
-
|
|
4320
|
-
|
|
4321
|
-
|
|
4322
|
-
|
|
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
|
-
|
|
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])
|