@semacode/cli 2.1.0 → 2.3.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 (154) hide show
  1. package/README.md +107 -4
  2. package/dist/agentContext.d.ts +1 -1
  3. package/dist/agentContextPack.js +6 -1
  4. package/dist/agentContextTipos.d.ts +4 -2
  5. package/dist/agentContextTipos.js +7 -0
  6. package/dist/agentEntryPoints.js +70 -19
  7. package/dist/comandos.js +6 -0
  8. package/dist/discovery/catalog.d.ts +11 -0
  9. package/dist/discovery/catalog.js +521 -0
  10. package/dist/discovery/command.d.ts +11 -0
  11. package/dist/discovery/command.js +226 -0
  12. package/dist/discovery/index.d.ts +5 -0
  13. package/dist/discovery/index.js +8 -0
  14. package/dist/discovery/ranker.d.ts +3 -0
  15. package/dist/discovery/ranker.js +310 -0
  16. package/dist/discovery/redaction.d.ts +2 -0
  17. package/dist/discovery/redaction.js +21 -0
  18. package/dist/discovery/render.d.ts +2 -0
  19. package/dist/discovery/render.js +100 -0
  20. package/dist/discovery/types.d.ts +119 -0
  21. package/dist/discovery/types.js +13 -0
  22. package/dist/execucoesExternas.js +19 -5
  23. package/dist/exemplosOficiais.js +29 -8
  24. package/dist/iaPrompts.d.ts +1 -1
  25. package/dist/iaPrompts.js +3 -0
  26. package/dist/index.d.ts +3 -0
  27. package/dist/index.js +24 -5
  28. package/dist/index.part01.d.ts +1 -1
  29. package/dist/index.part01.js +47 -3
  30. package/dist/index.part06.js +3 -0
  31. package/dist/initTemplatesBase.js +3 -2
  32. package/dist/pipelineConteudo/adapters.d.ts +84 -0
  33. package/dist/pipelineConteudo/adapters.js +449 -0
  34. package/dist/pipelineConteudo/canonical.d.ts +18 -0
  35. package/dist/pipelineConteudo/canonical.js +107 -0
  36. package/dist/pipelineConteudo/command.d.ts +3 -0
  37. package/dist/pipelineConteudo/command.js +572 -0
  38. package/dist/pipelineConteudo/index.d.ts +9 -0
  39. package/dist/pipelineConteudo/index.js +12 -0
  40. package/dist/pipelineConteudo/ledger.d.ts +68 -0
  41. package/dist/pipelineConteudo/ledger.js +732 -0
  42. package/dist/pipelineConteudo/planner.d.ts +12 -0
  43. package/dist/pipelineConteudo/planner.js +366 -0
  44. package/dist/pipelineConteudo/projection.d.ts +16 -0
  45. package/dist/pipelineConteudo/projection.js +57 -0
  46. package/dist/pipelineConteudo/state.d.ts +23 -0
  47. package/dist/pipelineConteudo/state.js +615 -0
  48. package/dist/pipelineConteudo/trust.d.ts +17 -0
  49. package/dist/pipelineConteudo/trust.js +750 -0
  50. package/dist/pipelineConteudo/types.d.ts +331 -0
  51. package/dist/pipelineConteudo/types.js +4 -0
  52. package/dist/profileArtefatoValidadores.d.ts +3 -2
  53. package/dist/profileArtefatoValidadores.js +81 -0
  54. package/dist/profileAuthorTipos.d.ts +4 -3
  55. package/dist/profileCatalogo.d.ts +5 -5
  56. package/dist/profileCatalogo.js +30 -0
  57. package/dist/profileCommand.d.ts +8 -2
  58. package/dist/profileCommand.js +15 -5
  59. package/dist/profileRegras.d.ts +5 -5
  60. package/dist/profileRegras.js +13 -1
  61. package/dist/profileRulePacks.js +68 -0
  62. package/dist/sistemasInterativos/adapterProtocol.d.ts +3 -0
  63. package/dist/sistemasInterativos/adapterProtocol.js +240 -0
  64. package/dist/sistemasInterativos/advancedCatalog.d.ts +5 -0
  65. package/dist/sistemasInterativos/advancedCatalog.js +442 -0
  66. package/dist/sistemasInterativos/autonomy.d.ts +230 -0
  67. package/dist/sistemasInterativos/autonomy.js +753 -0
  68. package/dist/sistemasInterativos/canonical.d.ts +3 -0
  69. package/dist/sistemasInterativos/canonical.js +43 -0
  70. package/dist/sistemasInterativos/catalog.d.ts +116 -0
  71. package/dist/sistemasInterativos/catalog.js +543 -0
  72. package/dist/sistemasInterativos/command.d.ts +7 -0
  73. package/dist/sistemasInterativos/command.js +311 -0
  74. package/dist/sistemasInterativos/controlRun.d.ts +56 -0
  75. package/dist/sistemasInterativos/controlRun.js +391 -0
  76. package/dist/sistemasInterativos/evidence.d.ts +5 -0
  77. package/dist/sistemasInterativos/evidence.js +306 -0
  78. package/dist/sistemasInterativos/experienceIr.d.ts +12 -0
  79. package/dist/sistemasInterativos/experienceIr.js +895 -0
  80. package/dist/sistemasInterativos/experienceIrSemantics.d.ts +30 -0
  81. package/dist/sistemasInterativos/experienceIrSemantics.js +368 -0
  82. package/dist/sistemasInterativos/experienceIrTypes.d.ts +370 -0
  83. package/dist/sistemasInterativos/experienceIrTypes.js +5 -0
  84. package/dist/sistemasInterativos/extensionCommand.d.ts +391 -0
  85. package/dist/sistemasInterativos/extensionCommand.js +383 -0
  86. package/dist/sistemasInterativos/index.d.ts +19 -0
  87. package/dist/sistemasInterativos/index.js +22 -0
  88. package/dist/sistemasInterativos/operations.d.ts +40 -0
  89. package/dist/sistemasInterativos/operations.js +1167 -0
  90. package/dist/sistemasInterativos/operationsTypes.d.ts +297 -0
  91. package/dist/sistemasInterativos/operationsTypes.js +11 -0
  92. package/dist/sistemasInterativos/planner.d.ts +2 -0
  93. package/dist/sistemasInterativos/planner.js +159 -0
  94. package/dist/sistemasInterativos/portability.d.ts +164 -0
  95. package/dist/sistemasInterativos/portability.js +539 -0
  96. package/dist/sistemasInterativos/render.d.ts +3 -0
  97. package/dist/sistemasInterativos/render.js +179 -0
  98. package/dist/sistemasInterativos/temporal.d.ts +183 -0
  99. package/dist/sistemasInterativos/temporal.js +543 -0
  100. package/dist/sistemasInterativos/types.d.ts +215 -0
  101. package/dist/sistemasInterativos/types.js +4 -0
  102. package/dist/sistemasInterativos/validator.d.ts +2 -0
  103. package/dist/sistemasInterativos/validator.js +305 -0
  104. package/docs/README.md +9 -0
  105. package/docs/ai-integration.md +7 -1
  106. package/docs/ai-workflow.md +5 -4
  107. package/docs/commands.md +43 -1
  108. package/docs/descoberta-capacidades.md +106 -0
  109. package/docs/documentation.md +11 -2
  110. package/docs/pipeline-conteudo.md +246 -0
  111. package/docs/profiles.md +11 -2
  112. package/docs/sistemas-interativos.md +381 -0
  113. package/docs/testing.md +11 -2
  114. package/exemplos/pipeline-conteudo/README.md +44 -0
  115. package/exemplos/pipeline-conteudo/alvos.json +23 -0
  116. package/exemplos/pipeline-conteudo/definicao.json +136 -0
  117. package/exemplos/profile_simulation.sema +211 -0
  118. package/exemplos/sistemas-interativos/README.md +100 -0
  119. package/exemplos/sistemas-interativos/advanced/acceptance-context-evaluate-valid.json +5 -0
  120. package/exemplos/sistemas-interativos/advanced/acceptance-lock-valid.json +16 -0
  121. package/exemplos/sistemas-interativos/advanced/asset-provenance-valid.json +32 -0
  122. package/exemplos/sistemas-interativos/advanced/autonomy-repair-valid.json +93 -0
  123. package/exemplos/sistemas-interativos/advanced/control-run-definition-valid.json +78 -0
  124. package/exemplos/sistemas-interativos/advanced/control-run-valid.json +27 -0
  125. package/exemplos/sistemas-interativos/advanced/distributed-workers-valid.json +79 -0
  126. package/exemplos/sistemas-interativos/advanced/editor-state-valid.json +42 -0
  127. package/exemplos/sistemas-interativos/advanced/engine-snapshot-after-valid.json +32 -0
  128. package/exemplos/sistemas-interativos/advanced/engine-snapshot-before-valid.json +23 -0
  129. package/exemplos/sistemas-interativos/advanced/job-orchestration-valid.json +39 -0
  130. package/exemplos/sistemas-interativos/advanced/multimodal-evidence-valid.json +46 -0
  131. package/exemplos/sistemas-interativos/advanced/multiplayer-authority-valid.json +39 -0
  132. package/exemplos/sistemas-interativos/advanced/playtest-fuzz-valid.json +37 -0
  133. package/exemplos/sistemas-interativos/advanced/portability-valid.json +104 -0
  134. package/exemplos/sistemas-interativos/advanced/temporal-evidence-valid.json +27 -0
  135. package/exemplos/sistemas-interativos/advanced/temporal-valid.json +118 -0
  136. package/exemplos/sistemas-interativos/experience-ir-valid.json +459 -0
  137. package/exemplos/sistemas-interativos/game-2d.json +83 -0
  138. package/exemplos/sistemas-interativos/game-3d-human.json +81 -0
  139. package/exemplos/sistemas-interativos/game-pixel-16-bit.json +97 -0
  140. package/exemplos/sistemas-interativos/game-pixel-8-bit.json +94 -0
  141. package/exemplos/sistemas-interativos/game-xr-human.json +80 -0
  142. package/exemplos/sistemas-interativos/hybrid-2-5d.json +108 -0
  143. package/exemplos/sistemas-interativos/protocol-mutating-rollback-valid.json +75 -0
  144. package/exemplos/sistemas-interativos/protocol-read-only-valid.json +58 -0
  145. package/exemplos/sistemas-interativos/simulation-2d-controlled.json +97 -0
  146. package/exemplos/sistemas-interativos/simulation-3d-calibrated-autonomous.json +141 -0
  147. package/exemplos/sistemas-interativos/simulation-headless-autonomous-batch.json +112 -0
  148. package/exemplos/sistemas-interativos/simulation-pixel-16-bit.json +103 -0
  149. package/exemplos/sistemas-interativos/simulation-text-controlled.json +95 -0
  150. package/node_modules/@sema/gerador-lua/dist/index.js +78 -4
  151. package/node_modules/@sema/gerador-lua/dist/index.js.map +1 -1
  152. package/node_modules/@sema/gerador-php/dist/index.js +8 -0
  153. package/node_modules/@sema/gerador-php/dist/index.js.map +1 -1
  154. package/package.json +8 -1
@@ -0,0 +1,750 @@
1
+ // SEMA-GOVERNED: sema.produto.pipeline_conteudo.confianca
2
+ // Descricao: verifica envelopes contra raiz publica e deriva gates sem transformar recibo do executor em evidencia.
3
+ import { createPublicKey } from "node:crypto";
4
+ import { digestEnvelopeConteudo, digestJsonCanonico, digestSha256, verificarAssinaturaEnvelopeConteudo, } from "./canonical.js";
5
+ const IDADE_MAXIMA_PADRAO_MS = 5 * 60 * 1000;
6
+ const DESVIO_FUTURO_PADRAO_MS = 30 * 1000;
7
+ const CAMPOS_CONFIANCA = new Set([
8
+ "trustDomainId", "principals", "revokedKeyIds", "maxEnvelopeAgeMs", "maxFutureSkewMs", "schemaVersionsAceitas",
9
+ ]);
10
+ const CAMPOS_PRINCIPAL = new Set([
11
+ "principalId", "keyId", "controlDomain", "papeis", "capabilities", "scopes", "publicKeyPem",
12
+ ]);
13
+ const CAMPOS_ENVELOPE = new Set([
14
+ "schemaVersion", "payloadType", "payload", "principalId", "keyId", "issuedAt", "nonce",
15
+ "signatureAlgorithm", "signature",
16
+ ]);
17
+ function adicionarBloqueio(bloqueios, bloqueio) {
18
+ if (!bloqueios.includes(bloqueio))
19
+ bloqueios.push(bloqueio);
20
+ }
21
+ function textoNaoVazio(valor) {
22
+ return typeof valor === "string" && valor.trim().length > 0;
23
+ }
24
+ function textoOpacoNormalizado(valor) {
25
+ return typeof valor === "string" &&
26
+ valor.length > 0 &&
27
+ valor === valor.trim() &&
28
+ !/[\s\u0000-\u001f\u007f]/u.test(valor);
29
+ }
30
+ function listaOpacaUnica(valor) {
31
+ return Array.isArray(valor) && valor.every(textoOpacoNormalizado) && new Set(valor).size === valor.length;
32
+ }
33
+ function timestampMs(valor) {
34
+ if (valor instanceof Date)
35
+ return valor.getTime();
36
+ if (typeof valor === "number")
37
+ return valor;
38
+ return valor === undefined ? Date.now() : Date.parse(valor);
39
+ }
40
+ function limiteSeguro(valorConfigurado, valorDaChamada, padrao) {
41
+ if (valorConfigurado === undefined)
42
+ return valorDaChamada ?? padrao;
43
+ if (valorDaChamada === undefined)
44
+ return valorConfigurado;
45
+ return Math.min(valorConfigurado, valorDaChamada);
46
+ }
47
+ function valoresOrdenados(valores) {
48
+ return [...valores].sort();
49
+ }
50
+ function configuracaoConfiancaCanonica(confianca) {
51
+ // Revogacoes sao overlay operacional mutavel. O digest pina o snapshot
52
+ // imutavel de principals, papeis, scopes, dominios e parametros de verificacao.
53
+ const raiz = {
54
+ trustDomainId: confianca.trustDomainId,
55
+ principals: [...confianca.principals]
56
+ .map((principal) => ({
57
+ principalId: principal.principalId,
58
+ keyId: principal.keyId,
59
+ controlDomain: principal.controlDomain,
60
+ papeis: valoresOrdenados(principal.papeis),
61
+ capabilities: valoresOrdenados(principal.capabilities),
62
+ scopes: valoresOrdenados(principal.scopes),
63
+ publicKeyPem: principal.publicKeyPem,
64
+ }))
65
+ .sort((a, b) => {
66
+ const chaveA = `${a.principalId}\u0000${a.keyId}`;
67
+ const chaveB = `${b.principalId}\u0000${b.keyId}`;
68
+ return chaveA < chaveB ? -1 : chaveA > chaveB ? 1 : 0;
69
+ }),
70
+ };
71
+ if (confianca.maxEnvelopeAgeMs !== undefined)
72
+ raiz.maxEnvelopeAgeMs = confianca.maxEnvelopeAgeMs;
73
+ if (confianca.maxFutureSkewMs !== undefined)
74
+ raiz.maxFutureSkewMs = confianca.maxFutureSkewMs;
75
+ if (confianca.schemaVersionsAceitas !== undefined) {
76
+ raiz.schemaVersionsAceitas = valoresOrdenados(confianca.schemaVersionsAceitas);
77
+ }
78
+ return raiz;
79
+ }
80
+ export function digestConfiguracaoConfiancaConteudo(confianca) {
81
+ return digestJsonCanonico(configuracaoConfiancaCanonica(confianca));
82
+ }
83
+ export function digestRevogacoesConfiancaConteudo(confianca) {
84
+ return digestJsonCanonico({
85
+ trustDomainId: confianca.trustDomainId,
86
+ revokedKeyIds: valoresOrdenados(confianca.revokedKeyIds),
87
+ });
88
+ }
89
+ export function validarConfiguracaoConfiancaConteudo(confianca, trustRootDigestEsperado, revocationDigestEsperado) {
90
+ const bloqueios = [];
91
+ const fingerprints = [];
92
+ const trustRootDigest = digestConfiguracaoConfiancaConteudo(confianca);
93
+ const revocationDigest = digestRevogacoesConfiancaConteudo(confianca);
94
+ if (Object.keys(confianca).some((chave) => /private.?key/i.test(chave))) {
95
+ adicionarBloqueio(bloqueios, "chave_privada_na_configuracao");
96
+ }
97
+ for (const campo of Object.keys(confianca)) {
98
+ if (!CAMPOS_CONFIANCA.has(campo))
99
+ adicionarBloqueio(bloqueios, "campo_confianca_nao_permitido");
100
+ }
101
+ if (!textoOpacoNormalizado(confianca.trustDomainId))
102
+ adicionarBloqueio(bloqueios, "trust_domain_id_invalido");
103
+ if (confianca.principals.length === 0)
104
+ adicionarBloqueio(bloqueios, "principals_ausentes");
105
+ const principalIds = new Set();
106
+ const keyIds = new Set();
107
+ const fingerprintsVistos = new Map();
108
+ for (const principal of confianca.principals) {
109
+ for (const campo of Object.keys(principal)) {
110
+ if (!CAMPOS_PRINCIPAL.has(campo)) {
111
+ adicionarBloqueio(bloqueios, "campo_principal_nao_permitido");
112
+ }
113
+ }
114
+ if (!textoOpacoNormalizado(principal.principalId))
115
+ adicionarBloqueio(bloqueios, "principal_id_invalido");
116
+ if (!textoOpacoNormalizado(principal.keyId))
117
+ adicionarBloqueio(bloqueios, "key_id_invalido");
118
+ if (!textoOpacoNormalizado(principal.controlDomain) ||
119
+ principal.controlDomain !== principal.controlDomain.toLowerCase())
120
+ adicionarBloqueio(bloqueios, "control_domain_invalido");
121
+ if (!listaOpacaUnica(principal.papeis))
122
+ adicionarBloqueio(bloqueios, "papeis_invalidos");
123
+ if (!listaOpacaUnica(principal.capabilities))
124
+ adicionarBloqueio(bloqueios, "capabilities_invalidas");
125
+ if (!listaOpacaUnica(principal.scopes))
126
+ adicionarBloqueio(bloqueios, "scopes_invalidos");
127
+ if (principalIds.has(principal.principalId))
128
+ adicionarBloqueio(bloqueios, "principal_id_duplicado");
129
+ if (keyIds.has(principal.keyId))
130
+ adicionarBloqueio(bloqueios, "key_id_duplicado");
131
+ principalIds.add(principal.principalId);
132
+ keyIds.add(principal.keyId);
133
+ if (Object.keys(principal).some((chave) => /private.?key/i.test(chave))) {
134
+ adicionarBloqueio(bloqueios, "chave_privada_na_configuracao");
135
+ }
136
+ if (typeof principal.publicKeyPem !== "string" ||
137
+ !/^-----BEGIN PUBLIC KEY-----\r?\n[\s\S]+\r?\n-----END PUBLIC KEY-----\r?\n?$/u.test(principal.publicKeyPem) ||
138
+ /PRIVATE KEY/u.test(principal.publicKeyPem)) {
139
+ adicionarBloqueio(bloqueios, "public_key_pem_nao_spki_publica");
140
+ continue;
141
+ }
142
+ try {
143
+ const publicKey = createPublicKey(principal.publicKeyPem);
144
+ if (publicKey.asymmetricKeyType !== "ed25519") {
145
+ adicionarBloqueio(bloqueios, "chave_publica_nao_ed25519");
146
+ continue;
147
+ }
148
+ const spki = publicKey.export({ type: "spki", format: "der" });
149
+ const fingerprint = digestSha256(spki);
150
+ fingerprints.push(fingerprint);
151
+ const anterior = fingerprintsVistos.get(fingerprint);
152
+ if (anterior !== undefined) {
153
+ adicionarBloqueio(bloqueios, "fingerprint_duplicado");
154
+ }
155
+ else {
156
+ fingerprintsVistos.set(fingerprint, principal);
157
+ }
158
+ }
159
+ catch {
160
+ adicionarBloqueio(bloqueios, "chave_publica_invalida");
161
+ }
162
+ }
163
+ const revogadasVistas = new Set();
164
+ for (const keyId of confianca.revokedKeyIds) {
165
+ if (!keyIds.has(keyId))
166
+ adicionarBloqueio(bloqueios, "chave_revogada_desconhecida");
167
+ if (revogadasVistas.has(keyId))
168
+ adicionarBloqueio(bloqueios, "chave_revogada_duplicada");
169
+ revogadasVistas.add(keyId);
170
+ }
171
+ if (!textoNaoVazio(trustRootDigestEsperado) || trustRootDigest !== trustRootDigestEsperado) {
172
+ adicionarBloqueio(bloqueios, "trust_root_digest_divergente");
173
+ }
174
+ if (!textoNaoVazio(revocationDigestEsperado) || revocationDigest !== revocationDigestEsperado) {
175
+ adicionarBloqueio(bloqueios, "revocation_digest_divergente");
176
+ }
177
+ return { valida: bloqueios.length === 0, trustRootDigest, revocationDigest, fingerprints, bloqueios };
178
+ }
179
+ function digestInvalido(envelope) {
180
+ const partes = [
181
+ envelope.schemaVersion,
182
+ envelope.payloadType,
183
+ envelope.principalId,
184
+ envelope.keyId,
185
+ envelope.issuedAt,
186
+ envelope.nonce,
187
+ envelope.signature,
188
+ ].map((parte) => (typeof parte === "string" ? parte : String(parte)));
189
+ return digestSha256(`envelope-nao-canonico\u0000${partes.join("\u0000")}`);
190
+ }
191
+ function verificarEnvelopeAssinadoConteudoComRaizValidada(envelope, confianca, opcoes, bloqueiosRaiz) {
192
+ const bloqueios = [...bloqueiosRaiz];
193
+ let digest;
194
+ for (const campo of Object.keys(envelope)) {
195
+ if (!CAMPOS_ENVELOPE.has(campo))
196
+ adicionarBloqueio(bloqueios, "campo_envelope_nao_permitido");
197
+ }
198
+ try {
199
+ digest = digestEnvelopeConteudo(envelope);
200
+ }
201
+ catch {
202
+ digest = digestInvalido(envelope);
203
+ adicionarBloqueio(bloqueios, "payload_nao_canonico");
204
+ }
205
+ if (!textoNaoVazio(envelope.schemaVersion) ||
206
+ !textoNaoVazio(envelope.payloadType) ||
207
+ !textoNaoVazio(envelope.principalId) ||
208
+ !textoNaoVazio(envelope.keyId) ||
209
+ !textoNaoVazio(envelope.issuedAt) ||
210
+ !textoNaoVazio(envelope.nonce) ||
211
+ !textoNaoVazio(envelope.signature)) {
212
+ adicionarBloqueio(bloqueios, "envelope_incompleto");
213
+ }
214
+ if (envelope.signatureAlgorithm !== "Ed25519") {
215
+ adicionarBloqueio(bloqueios, "algoritmo_assinatura_invalido");
216
+ }
217
+ if (envelope.payloadType !== opcoes.payloadTypeEsperado) {
218
+ adicionarBloqueio(bloqueios, "payload_type_incompativel");
219
+ }
220
+ if (confianca.schemaVersionsAceitas !== undefined &&
221
+ !confianca.schemaVersionsAceitas.includes(envelope.schemaVersion)) {
222
+ adicionarBloqueio(bloqueios, "schema_version_nao_aceita");
223
+ }
224
+ if (confianca.revokedKeyIds.includes(envelope.keyId)) {
225
+ adicionarBloqueio(bloqueios, "chave_revogada");
226
+ }
227
+ const candidatos = confianca.principals.filter((item) => item.principalId === envelope.principalId && item.keyId === envelope.keyId);
228
+ const principal = candidatos.length === 1 ? candidatos[0] : undefined;
229
+ if (candidatos.length === 0)
230
+ adicionarBloqueio(bloqueios, "principal_nao_encontrado");
231
+ if (candidatos.length > 1)
232
+ adicionarBloqueio(bloqueios, "principal_ambiguo");
233
+ if (principal !== undefined) {
234
+ if (opcoes.capabilityRequerida !== undefined &&
235
+ !principal.capabilities.includes(opcoes.capabilityRequerida)) {
236
+ adicionarBloqueio(bloqueios, "capability_ausente");
237
+ }
238
+ if (opcoes.scopeRequerido !== undefined && !principal.scopes.includes(opcoes.scopeRequerido)) {
239
+ adicionarBloqueio(bloqueios, "scope_ausente");
240
+ }
241
+ if (opcoes.papelRequerido !== undefined && !principal.papeis.includes(opcoes.papelRequerido)) {
242
+ adicionarBloqueio(bloqueios, "papel_ausente");
243
+ }
244
+ if (opcoes.papeisPermitidos !== undefined &&
245
+ !opcoes.papeisPermitidos.some((papel) => principal.papeis.includes(papel))) {
246
+ adicionarBloqueio(bloqueios, "papel_nao_permitido");
247
+ }
248
+ }
249
+ const agora = timestampMs(opcoes.agora);
250
+ const emitidoEm = Date.parse(envelope.issuedAt);
251
+ const idadeMaxima = limiteSeguro(confianca.maxEnvelopeAgeMs, opcoes.maxEnvelopeAgeMs, IDADE_MAXIMA_PADRAO_MS);
252
+ const desvioFuturo = limiteSeguro(confianca.maxFutureSkewMs, opcoes.maxFutureSkewMs, DESVIO_FUTURO_PADRAO_MS);
253
+ if (!Number.isFinite(agora) ||
254
+ !Number.isFinite(idadeMaxima) ||
255
+ !Number.isFinite(desvioFuturo) ||
256
+ idadeMaxima < 0 ||
257
+ desvioFuturo < 0) {
258
+ adicionarBloqueio(bloqueios, "configuracao_frescura_invalida");
259
+ }
260
+ if (!Number.isFinite(emitidoEm)) {
261
+ adicionarBloqueio(bloqueios, "issued_at_invalido");
262
+ }
263
+ else if (Number.isFinite(agora) && Number.isFinite(desvioFuturo) && emitidoEm > agora + desvioFuturo) {
264
+ adicionarBloqueio(bloqueios, "issued_at_no_futuro");
265
+ }
266
+ else if (Number.isFinite(agora) && Number.isFinite(idadeMaxima) && agora - emitidoEm > idadeMaxima) {
267
+ adicionarBloqueio(bloqueios, "envelope_expirado");
268
+ }
269
+ if (opcoes.noncesUsados?.has(envelope.nonce)) {
270
+ adicionarBloqueio(bloqueios, "nonce_reutilizado");
271
+ }
272
+ if (principal !== undefined && !confianca.revokedKeyIds.includes(envelope.keyId)) {
273
+ try {
274
+ const publicKey = createPublicKey(principal.publicKeyPem);
275
+ if (publicKey.asymmetricKeyType !== "ed25519") {
276
+ adicionarBloqueio(bloqueios, "chave_publica_nao_ed25519");
277
+ }
278
+ else if (!verificarAssinaturaEnvelopeConteudo(envelope, publicKey)) {
279
+ adicionarBloqueio(bloqueios, "assinatura_invalida");
280
+ }
281
+ }
282
+ catch {
283
+ adicionarBloqueio(bloqueios, "chave_publica_invalida");
284
+ }
285
+ }
286
+ if (bloqueios.length > 0 || principal === undefined) {
287
+ return { valido: false, digest, principal, bloqueios };
288
+ }
289
+ const envelopeVerificado = {
290
+ estado: "ACEITA",
291
+ digest,
292
+ principal,
293
+ envelope,
294
+ payload: envelope.payload,
295
+ };
296
+ return { valido: true, digest, principal, envelopeVerificado, bloqueios };
297
+ }
298
+ function validarPinsExternosDaRaiz(confianca, opcoes) {
299
+ const estruturaConfianca = validarConfiguracaoConfiancaConteudo(confianca, opcoes.trustRootDigestEsperado, opcoes.revocationDigestEsperado);
300
+ return estruturaConfianca.bloqueios.map((bloqueio) => `raiz_confianca_invalida:${bloqueio}`);
301
+ }
302
+ /** Verificacao publica: a autoridade so existe quando os dois pins externos conferem. */
303
+ export function verificarEnvelopeAssinadoConteudo(envelope, confianca, opcoes) {
304
+ return verificarEnvelopeAssinadoConteudoComRaizValidada(envelope, confianca, opcoes, validarPinsExternosDaRaiz(confianca, opcoes));
305
+ }
306
+ /**
307
+ * Replay historico interno: valida os pins contra o overlay atual antes de
308
+ * ignorar revogacoes somente para provar assinaturas historicas. Nao exportar
309
+ * este simbolo pela superficie publica do pacote.
310
+ */
311
+ export function verificarEnvelopeAssinadoConteudoHistoricoInterno(envelope, confiancaAtual, opcoes) {
312
+ const bloqueiosRaiz = validarPinsExternosDaRaiz(confiancaAtual, opcoes);
313
+ const confiancaHistorica = {
314
+ ...confiancaAtual,
315
+ revokedKeyIds: [],
316
+ };
317
+ return verificarEnvelopeAssinadoConteudoComRaizValidada(envelope, confiancaHistorica, opcoes, bloqueiosRaiz);
318
+ }
319
+ function alvoExato(recebido, esperado) {
320
+ return recebido === esperado;
321
+ }
322
+ function principalPorId(principals, principalId) {
323
+ const encontrados = principals.filter((item) => item.principalId === principalId);
324
+ if (encontrados.length === 0)
325
+ return undefined;
326
+ const dominios = new Set(encontrados.map((item) => item.controlDomain));
327
+ return dominios.size === 1 ? encontrados[0] : undefined;
328
+ }
329
+ function contextoGateDaEntrada(entrada) {
330
+ return {
331
+ trustDomainId: entrada.trustDomainId,
332
+ trustRootDigest: entrada.trustRootDigest,
333
+ ledgerId: entrada.ledgerId,
334
+ policyDigest: entrada.policyDigest,
335
+ definitionDigest: entrada.definitionDigest,
336
+ };
337
+ }
338
+ function conferirContextoGate(payload, entrada, referencia, prefixo, bloqueios) {
339
+ let valido = true;
340
+ const bloquear = (codigo) => {
341
+ adicionarBloqueio(bloqueios, `${prefixo}:${codigo}`);
342
+ valido = false;
343
+ };
344
+ if (payload.runId !== entrada.runId)
345
+ bloquear("run_divergente");
346
+ if (payload.authorizationScope !== entrada.authorizationScope)
347
+ bloquear("authorization_scope_divergente");
348
+ if (!textoNaoVazio(payload.trustDomainId))
349
+ bloquear("trust_domain_id_ausente");
350
+ if (!textoNaoVazio(payload.ledgerId))
351
+ bloquear("ledger_id_ausente");
352
+ if (!textoNaoVazio(payload.policyDigest))
353
+ bloquear("policy_digest_ausente");
354
+ if (!textoNaoVazio(payload.definitionDigest))
355
+ bloquear("definition_digest_ausente");
356
+ if (payload.trustDomainId !== referencia.trustDomainId)
357
+ bloquear("trust_domain_divergente");
358
+ if (payload.trustRootDigest !== referencia.trustRootDigest)
359
+ bloquear("trust_root_digest_divergente");
360
+ if (payload.ledgerId !== referencia.ledgerId)
361
+ bloquear("ledger_divergente");
362
+ if (payload.policyDigest !== referencia.policyDigest)
363
+ bloquear("policy_digest_divergente");
364
+ if (payload.definitionDigest !== referencia.definitionDigest)
365
+ bloquear("definition_digest_divergente");
366
+ return valido;
367
+ }
368
+ function conferirCamposAtestado(payload, entrada, principal, principalsDaLinhagem, dominiosDaLinhagem, bloqueios) {
369
+ const prefixo = `evidencia:${payload.evidenceId || "sem_id"}`;
370
+ let valido = true;
371
+ const bloquear = (codigo) => {
372
+ adicionarBloqueio(bloqueios, `${prefixo}:${codigo}`);
373
+ valido = false;
374
+ };
375
+ if (payload.kind !== "EVIDENCE_ATTESTED")
376
+ bloquear("tipo_invalido");
377
+ if (!textoNaoVazio(payload.evidenceId))
378
+ bloquear("id_ausente");
379
+ if (payload.gateId !== entrada.gate.gateId)
380
+ bloquear("gate_divergente");
381
+ if (payload.artifactDigest !== entrada.artifactDigest)
382
+ bloquear("artifact_digest_divergente");
383
+ if (!alvoExato(payload.targetId, entrada.targetId))
384
+ bloquear("target_divergente");
385
+ if (payload.producerId !== entrada.producerId)
386
+ bloquear("produtor_divergente");
387
+ if (payload.attesterId !== principal.principalId)
388
+ bloquear("atestador_divergente");
389
+ const capabilityEspecifica = entrada.attesterCapabilitiesAdicionais?.[payload.evidenceType] ??
390
+ `content.evidence.attest:${payload.evidenceType}`;
391
+ const capabilityAutorizada = principal.capabilities.includes(capabilityEspecifica);
392
+ if (!capabilityAutorizada)
393
+ bloquear("capability_ausente");
394
+ const papelAutorizado = principal.papeis.includes("EVIDENCE_ATTESTER") ||
395
+ principal.papeis.includes("ADAPTER") ||
396
+ (principal.papeis.includes("AI_AGENT") && capabilityAutorizada);
397
+ if (!papelAutorizado)
398
+ bloquear("papel_nao_permitido");
399
+ if (entrada.gate.producerDisjoint) {
400
+ if (principalsDaLinhagem.has(principal.principalId) || dominiosDaLinhagem.has(principal.controlDomain)) {
401
+ bloquear("produtor_ou_ancestral_e_atestador_nao_disjuntos");
402
+ }
403
+ }
404
+ if (!["APROVADO", "REPROVADO", "INCONCLUSIVO"].includes(payload.result))
405
+ bloquear("resultado_invalido");
406
+ return valido;
407
+ }
408
+ function conferirCamposParecer(payload, entrada, principal, principalsDaLinhagem, dominiosDaLinhagem, bloqueios) {
409
+ const prefixo = `parecer:${payload.assessmentId || "sem_id"}`;
410
+ let valido = true;
411
+ const bloquear = (codigo) => {
412
+ adicionarBloqueio(bloqueios, `${prefixo}:${codigo}`);
413
+ valido = false;
414
+ };
415
+ if (payload.kind !== "AI_ASSESSMENT")
416
+ bloquear("tipo_invalido");
417
+ if (!textoNaoVazio(payload.assessmentId))
418
+ bloquear("id_ausente");
419
+ if (payload.gateId !== entrada.gate.gateId)
420
+ bloquear("gate_divergente");
421
+ if (payload.artifactDigest !== entrada.artifactDigest)
422
+ bloquear("artifact_digest_divergente");
423
+ if (!alvoExato(payload.targetId, entrada.targetId))
424
+ bloquear("target_divergente");
425
+ if (payload.rubricDigest !== entrada.gate.rubricDigest)
426
+ bloquear("rubric_digest_divergente");
427
+ if (payload.evaluatorId !== principal.principalId)
428
+ bloquear("avaliador_divergente");
429
+ if (!["APROVADO", "REPROVADO", "INCONCLUSIVO"].includes(payload.result))
430
+ bloquear("resultado_invalido");
431
+ const capabilityAutorizada = textoNaoVazio(payload.capability) &&
432
+ entrada.gate.evaluatorCapabilities.includes(payload.capability) &&
433
+ principal.capabilities.includes(payload.capability);
434
+ if (!capabilityAutorizada) {
435
+ bloquear("capability_ausente");
436
+ }
437
+ const papelAutorizado = principal.papeis.includes("EVALUATOR") ||
438
+ (principal.papeis.includes("AI_AGENT") && capabilityAutorizada);
439
+ if (!papelAutorizado)
440
+ bloquear("papel_nao_permitido");
441
+ if (entrada.gate.producerDisjoint) {
442
+ if (principalsDaLinhagem.has(principal.principalId) || dominiosDaLinhagem.has(principal.controlDomain)) {
443
+ bloquear("produtor_ou_ancestral_e_avaliador_nao_disjuntos");
444
+ }
445
+ }
446
+ return valido;
447
+ }
448
+ /**
449
+ * @internal O chamador deve fornecer contexto derivado pelo replay canonico.
450
+ * A unica superficie publica autoritativa para gates e derivarEstadoPipelineConteudo.
451
+ */
452
+ export function avaliarGateConteudoInterno(entrada) {
453
+ const bloqueios = [];
454
+ const requisitosAdicionais = entrada.requiredEvidenceAdicional ?? [];
455
+ const requisitosAdicionaisValidos = Array.isArray(requisitosAdicionais) &&
456
+ requisitosAdicionais.every(textoOpacoNormalizado) &&
457
+ new Set(requisitosAdicionais).size === requisitosAdicionais.length;
458
+ const attesterCapabilitiesAdicionais = entrada.attesterCapabilitiesAdicionais ?? {};
459
+ const attesterCapabilitiesAdicionaisValidas = attesterCapabilitiesAdicionais !== null &&
460
+ typeof attesterCapabilitiesAdicionais === "object" &&
461
+ !Array.isArray(attesterCapabilitiesAdicionais) &&
462
+ Object.entries(attesterCapabilitiesAdicionais).every(([evidenceType, capability]) => textoOpacoNormalizado(evidenceType) && textoOpacoNormalizado(capability));
463
+ const requiredEvidenceEfetiva = [...new Set([
464
+ ...entrada.gate.requiredEvidence,
465
+ ...requisitosAdicionais,
466
+ ])];
467
+ const entradaValida = textoNaoVazio(entrada.runId) &&
468
+ textoNaoVazio(entrada.trustDomainId) &&
469
+ entrada.trustDomainId === entrada.configuracaoConfianca.trustDomainId &&
470
+ textoNaoVazio(entrada.trustRootDigest) &&
471
+ textoNaoVazio(entrada.revocationDigestEsperado) &&
472
+ textoNaoVazio(entrada.ledgerId) &&
473
+ textoNaoVazio(entrada.policyDigest) &&
474
+ textoNaoVazio(entrada.definitionDigest) &&
475
+ textoNaoVazio(entrada.authorizationScope) &&
476
+ Array.isArray(entrada.producerLineageIds) &&
477
+ entrada.producerLineageIds.length > 0 &&
478
+ entrada.producerLineageIds.includes(entrada.producerId) &&
479
+ (entrada.gate.scope === "GLOBAL"
480
+ ? entrada.targetId === undefined
481
+ : textoOpacoNormalizado(entrada.targetId));
482
+ if (!entradaValida)
483
+ adicionarBloqueio(bloqueios, "contexto_avaliacao_invalido");
484
+ let politicaValida = entradaValida &&
485
+ textoNaoVazio(entrada.gate.gateId) &&
486
+ textoNaoVazio(entrada.gate.stageId) &&
487
+ ["GLOBAL", "POR_ALVO"].includes(entrada.gate.scope) &&
488
+ textoNaoVazio(entrada.gate.rubricDigest) &&
489
+ requisitosAdicionaisValidos &&
490
+ attesterCapabilitiesAdicionaisValidas &&
491
+ listaOpacaUnica(entrada.gate.requiredEvidence) &&
492
+ listaOpacaUnica(entrada.gate.evaluatorCapabilities) &&
493
+ ["DETERMINISTICA", "IA_ESPECIALIZADA", "HIBRIDA"].includes(entrada.gate.evaluationMode) &&
494
+ Number.isInteger(entrada.gate.minApprovals) &&
495
+ entrada.gate.minApprovals >= 1 &&
496
+ Number.isInteger(entrada.gate.minAttestationsPerEvidence) &&
497
+ entrada.gate.minAttestationsPerEvidence >= 1 &&
498
+ Number.isInteger(entrada.gate.minDistinctAttesterControlDomains) &&
499
+ entrada.gate.minDistinctAttesterControlDomains >= 1 &&
500
+ entrada.gate.minDistinctAttesterControlDomains <= entrada.gate.minAttestationsPerEvidence &&
501
+ typeof entrada.gate.producerDisjoint === "boolean" &&
502
+ typeof entrada.gate.rejectionIsBinding === "boolean" &&
503
+ Number.isInteger(entrada.gate.minDistinctControlDomains) &&
504
+ entrada.gate.minDistinctControlDomains >= 1 &&
505
+ (entrada.gate.evaluationMode === "IA_ESPECIALIZADA" ||
506
+ entrada.gate.requiredEvidence.length > 0) &&
507
+ (entrada.gate.evaluationMode === "DETERMINISTICA" ||
508
+ entrada.gate.evaluatorCapabilities.length > 0);
509
+ if (!politicaValida)
510
+ adicionarBloqueio(bloqueios, "politica_gate_invalida");
511
+ const confianca = entrada.configuracaoConfianca;
512
+ const revokedKeyIds = confianca.revokedKeyIds;
513
+ const raizConfianca = validarConfiguracaoConfiancaConteudo(confianca, entrada.trustRootDigest, entrada.revocationDigestEsperado);
514
+ if (!raizConfianca.valida) {
515
+ politicaValida = false;
516
+ for (const bloqueio of raizConfianca.bloqueios)
517
+ adicionarBloqueio(bloqueios, `raiz_confianca_invalida:${bloqueio}`);
518
+ }
519
+ const politica = entrada.envelopePolitica?.payload;
520
+ const verificacaoPolitica = verificarEnvelopeAssinadoConteudo(entrada.envelopePolitica, confianca, {
521
+ trustRootDigestEsperado: entrada.trustRootDigest,
522
+ revocationDigestEsperado: entrada.revocationDigestEsperado,
523
+ payloadTypeEsperado: "TRUST_POLICY",
524
+ papelRequerido: "POLICY_AUTHORITY",
525
+ agora: politica?.issuedAt,
526
+ });
527
+ let politicaAssinadaValida = verificacaoPolitica.valido;
528
+ if (!verificacaoPolitica.valido) {
529
+ for (const bloqueio of verificacaoPolitica.bloqueios) {
530
+ adicionarBloqueio(bloqueios, `politica_assinada:${bloqueio}`);
531
+ }
532
+ }
533
+ try {
534
+ const gatesCorrespondentes = Array.isArray(politica?.gates)
535
+ ? politica.gates.filter((gate) => gate.gateId === entrada.gate.gateId)
536
+ : [];
537
+ if (politica === undefined ||
538
+ digestJsonCanonico(politica) !== entrada.policyDigest ||
539
+ politica.runId !== entrada.runId ||
540
+ politica.trustDomainId !== entrada.trustDomainId ||
541
+ politica.trustRootDigest !== entrada.trustRootDigest ||
542
+ politica.ledgerId !== entrada.ledgerId ||
543
+ politica.definitionDigest !== entrada.definitionDigest ||
544
+ !textoOpacoNormalizado(politica.targetSetDigest) ||
545
+ entrada.envelopePolitica.issuedAt !== politica.issuedAt ||
546
+ !Number.isFinite(Date.parse(politica.issuedAt)) ||
547
+ !Number.isFinite(Date.parse(politica.expiresAt)) ||
548
+ Date.parse(politica.expiresAt) <= Date.parse(politica.issuedAt) ||
549
+ gatesCorrespondentes.length !== 1 ||
550
+ digestJsonCanonico(gatesCorrespondentes[0]) !== digestJsonCanonico(entrada.gate)) {
551
+ politicaAssinadaValida = false;
552
+ adicionarBloqueio(bloqueios, "politica_assinada_contexto_ou_gate_divergente");
553
+ }
554
+ }
555
+ catch {
556
+ politicaAssinadaValida = false;
557
+ adicionarBloqueio(bloqueios, "politica_assinada_payload_invalido");
558
+ }
559
+ politicaValida &&= politicaAssinadaValida;
560
+ const noncesUsados = new Set();
561
+ const evidenciasValidas = [];
562
+ const pareceresValidos = [];
563
+ const evidenceIds = new Set();
564
+ const assessmentIds = new Set();
565
+ const principalsDaLinhagem = new Set(entrada.producerLineageIds);
566
+ principalsDaLinhagem.add(entrada.producerId);
567
+ const dominiosDaLinhagem = new Set();
568
+ for (const principalId of principalsDaLinhagem) {
569
+ const principal = principalPorId(confianca.principals, principalId);
570
+ if (principal === undefined) {
571
+ adicionarBloqueio(bloqueios, `principal_linhagem_nao_encontrado:${principalId}`);
572
+ politicaValida = false;
573
+ }
574
+ else {
575
+ dominiosDaLinhagem.add(principal.controlDomain);
576
+ }
577
+ }
578
+ const contextoReferencia = contextoGateDaEntrada(entrada);
579
+ for (const registro of entrada.evidenciasAceitas) {
580
+ const payload = registro.envelope.payload;
581
+ if (typeof payload !== "object" || payload === null || Array.isArray(payload)) {
582
+ adicionarBloqueio(bloqueios, "evidencia:payload_invalido");
583
+ continue;
584
+ }
585
+ const verificacao = verificarEnvelopeAssinadoConteudo(registro.envelope, confianca, {
586
+ trustRootDigestEsperado: entrada.trustRootDigest,
587
+ revocationDigestEsperado: entrada.revocationDigestEsperado,
588
+ payloadTypeEsperado: "EVIDENCE_ATTESTED",
589
+ scopeRequerido: entrada.authorizationScope,
590
+ agora: typeof payload === "object" && payload !== null && "observedAt" in payload
591
+ ? String(payload.observedAt)
592
+ : undefined,
593
+ noncesUsados,
594
+ });
595
+ noncesUsados.add(registro.envelope.nonce);
596
+ if (!verificacao.valido || verificacao.principal === undefined) {
597
+ for (const bloqueio of verificacao.bloqueios)
598
+ adicionarBloqueio(bloqueios, `evidencia_envelope:${bloqueio}`);
599
+ continue;
600
+ }
601
+ const atestado = payload;
602
+ if (!conferirContextoGate(atestado, entrada, contextoReferencia, `evidencia:${atestado.evidenceId || "sem_id"}`, bloqueios))
603
+ continue;
604
+ if (!conferirCamposAtestado(atestado, entrada, verificacao.principal, principalsDaLinhagem, dominiosDaLinhagem, bloqueios))
605
+ continue;
606
+ if (evidenceIds.has(atestado.evidenceId)) {
607
+ adicionarBloqueio(bloqueios, `evidencia:${atestado.evidenceId}:id_duplicado`);
608
+ continue;
609
+ }
610
+ evidenceIds.add(atestado.evidenceId);
611
+ evidenciasValidas.push({ payload: atestado, principal: verificacao.principal });
612
+ }
613
+ for (const registro of entrada.pareceresIa) {
614
+ const payload = registro.envelope.payload;
615
+ if (typeof payload !== "object" || payload === null || Array.isArray(payload)) {
616
+ adicionarBloqueio(bloqueios, "parecer:payload_invalido");
617
+ continue;
618
+ }
619
+ const verificacao = verificarEnvelopeAssinadoConteudo(registro.envelope, confianca, {
620
+ trustRootDigestEsperado: entrada.trustRootDigest,
621
+ revocationDigestEsperado: entrada.revocationDigestEsperado,
622
+ payloadTypeEsperado: "AI_ASSESSMENT",
623
+ scopeRequerido: entrada.authorizationScope,
624
+ agora: typeof payload === "object" && payload !== null && "assessedAt" in payload
625
+ ? String(payload.assessedAt)
626
+ : undefined,
627
+ noncesUsados,
628
+ });
629
+ noncesUsados.add(registro.envelope.nonce);
630
+ if (!verificacao.valido || verificacao.principal === undefined) {
631
+ for (const bloqueio of verificacao.bloqueios)
632
+ adicionarBloqueio(bloqueios, `parecer_envelope:${bloqueio}`);
633
+ continue;
634
+ }
635
+ const parecer = payload;
636
+ if (!conferirContextoGate(parecer, entrada, contextoReferencia, `parecer:${parecer.assessmentId || "sem_id"}`, bloqueios))
637
+ continue;
638
+ if (!conferirCamposParecer(parecer, entrada, verificacao.principal, principalsDaLinhagem, dominiosDaLinhagem, bloqueios))
639
+ continue;
640
+ if (assessmentIds.has(parecer.assessmentId)) {
641
+ adicionarBloqueio(bloqueios, `parecer:${parecer.assessmentId}:id_duplicado`);
642
+ continue;
643
+ }
644
+ assessmentIds.add(parecer.assessmentId);
645
+ pareceresValidos.push({ payload: parecer, principal: verificacao.principal });
646
+ }
647
+ const evidenciasPorTipo = new Map();
648
+ for (const evidencia of evidenciasValidas) {
649
+ const { payload } = evidencia;
650
+ const atuais = evidenciasPorTipo.get(payload.evidenceType) ?? [];
651
+ atuais.push(evidencia);
652
+ evidenciasPorTipo.set(payload.evidenceType, atuais);
653
+ }
654
+ let evidenciaDeterministicaReprovada = false;
655
+ let evidenciaDeterministicaCompleta = true;
656
+ for (const tipo of requiredEvidenceEfetiva) {
657
+ const atestados = evidenciasPorTipo.get(tipo) ?? [];
658
+ if (atestados.some((item) => item.payload.result === "REPROVADO"))
659
+ evidenciaDeterministicaReprovada = true;
660
+ const aprovacoesPorPrincipal = new Map();
661
+ for (const item of atestados) {
662
+ if (item.payload.result === "APROVADO") {
663
+ aprovacoesPorPrincipal.set(item.principal.principalId, item.principal);
664
+ }
665
+ }
666
+ const dominiosAtestadores = new Set([...aprovacoesPorPrincipal.values()].map((principal) => principal.controlDomain));
667
+ if (aprovacoesPorPrincipal.size < entrada.gate.minAttestationsPerEvidence) {
668
+ evidenciaDeterministicaCompleta = false;
669
+ adicionarBloqueio(bloqueios, `quorum_atestadores_insuficiente:${tipo}`);
670
+ }
671
+ if (dominiosAtestadores.size < entrada.gate.minDistinctAttesterControlDomains) {
672
+ evidenciaDeterministicaCompleta = false;
673
+ adicionarBloqueio(bloqueios, `dominios_atestadores_insuficientes:${tipo}`);
674
+ }
675
+ }
676
+ const pareceresPorAvaliador = new Map();
677
+ for (const parecer of pareceresValidos) {
678
+ const atuais = pareceresPorAvaliador.get(parecer.principal.principalId) ?? [];
679
+ atuais.push(parecer);
680
+ pareceresPorAvaliador.set(parecer.principal.principalId, atuais);
681
+ }
682
+ const aprovacoes = new Map();
683
+ const capabilitiesCobertas = new Set();
684
+ let haRejeicaoIa = false;
685
+ let haConflitoIa = false;
686
+ for (const [principalId, pareceres] of pareceresPorAvaliador) {
687
+ const resultados = new Set(pareceres.map((item) => item.payload.result));
688
+ if (resultados.size > 1) {
689
+ haConflitoIa = true;
690
+ adicionarBloqueio(bloqueios, `avaliador:${principalId}:pareceres_conflitantes`);
691
+ continue;
692
+ }
693
+ const unico = pareceres[0];
694
+ if (unico.payload.result === "APROVADO") {
695
+ aprovacoes.set(principalId, unico.principal);
696
+ for (const parecer of pareceres)
697
+ capabilitiesCobertas.add(parecer.payload.capability);
698
+ }
699
+ if (unico.payload.result === "REPROVADO")
700
+ haRejeicaoIa = true;
701
+ }
702
+ const controlDomains = new Set([...aprovacoes.values()].map((principal) => principal.controlDomain));
703
+ const aprovacoesValidas = aprovacoes.size;
704
+ const controlDomainsDistintos = controlDomains.size;
705
+ const capabilitiesFaltantes = entrada.gate.evaluatorCapabilities.filter((capability) => !capabilitiesCobertas.has(capability));
706
+ const coberturaCapabilitiesIa = capabilitiesFaltantes.length === 0;
707
+ const quorumIa = politicaValida &&
708
+ aprovacoesValidas >= entrada.gate.minApprovals &&
709
+ controlDomainsDistintos >= entrada.gate.minDistinctControlDomains &&
710
+ coberturaCapabilitiesIa;
711
+ const exigeDeterministica = entrada.gate.evaluationMode !== "IA_ESPECIALIZADA" || requiredEvidenceEfetiva.length > 0;
712
+ const exigeIa = entrada.gate.evaluationMode !== "DETERMINISTICA";
713
+ const possuiQualquerEntrada = evidenciasValidas.length > 0 || pareceresValidos.length > 0;
714
+ let veredito;
715
+ if (!politicaValida) {
716
+ veredito = possuiQualquerEntrada ? "INCONCLUSIVO" : "NAO_AVALIADO";
717
+ }
718
+ else if (exigeDeterministica && evidenciaDeterministicaReprovada) {
719
+ veredito = "REPROVADO";
720
+ }
721
+ else if (exigeIa && haRejeicaoIa && entrada.gate.rejectionIsBinding) {
722
+ veredito = "REPROVADO";
723
+ }
724
+ else if (!possuiQualquerEntrada) {
725
+ veredito = "NAO_AVALIADO";
726
+ }
727
+ else if (exigeDeterministica && !evidenciaDeterministicaCompleta) {
728
+ veredito = "INCONCLUSIVO";
729
+ }
730
+ else if (exigeIa && (haConflitoIa || haRejeicaoIa || !quorumIa)) {
731
+ for (const capability of capabilitiesFaltantes) {
732
+ adicionarBloqueio(bloqueios, `capability_ia_nao_coberta:${capability}`);
733
+ }
734
+ if (!quorumIa)
735
+ adicionarBloqueio(bloqueios, "quorum_ia_insuficiente");
736
+ veredito = "INCONCLUSIVO";
737
+ }
738
+ else {
739
+ veredito = "APROVADO";
740
+ }
741
+ return {
742
+ veredito,
743
+ aprovacoesValidas,
744
+ controlDomainsDistintos,
745
+ evidenceIds: [...evidenceIds],
746
+ assessmentIds: [...assessmentIds],
747
+ bloqueios,
748
+ };
749
+ }
750
+ //# sourceMappingURL=trust.js.map