@semacode/cli 2.0.1 → 2.2.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 (134) hide show
  1. package/LICENSE +39 -39
  2. package/README.md +141 -121
  3. package/dist/agentEntryPoints.js +499 -499
  4. package/dist/comandos.js +2 -0
  5. package/dist/doctorCommand.js +28 -0
  6. package/dist/execucoesExternas.js +19 -5
  7. package/dist/geracaoCore.js +97 -1
  8. package/dist/iaPrompts.d.ts +1 -1
  9. package/dist/iaPrompts.js +307 -307
  10. package/dist/index.d.ts +1 -0
  11. package/dist/index.js +1 -0
  12. package/dist/index.part01.d.ts +1 -1
  13. package/dist/index.part01.js +14 -4
  14. package/dist/index.part02.js +21 -21
  15. package/dist/index.part04.js +96 -96
  16. package/dist/index.part06.js +1 -1
  17. package/dist/index.part07.js +35 -24
  18. package/dist/init/templates.part01.js +393 -393
  19. package/dist/init/templates.part02.js +189 -189
  20. package/dist/initTemplatesBackend.js +73 -73
  21. package/dist/initTemplatesBase.js +81 -81
  22. package/dist/initTemplatesFlutter.js +137 -137
  23. package/dist/initTemplatesRuntime.js +350 -350
  24. package/dist/initTemplatesWeb.js +309 -309
  25. package/dist/nativeToolchains.d.ts +15 -0
  26. package/dist/nativeToolchains.js +132 -0
  27. package/dist/pipelineConteudo/adapters.d.ts +84 -0
  28. package/dist/pipelineConteudo/adapters.js +449 -0
  29. package/dist/pipelineConteudo/canonical.d.ts +18 -0
  30. package/dist/pipelineConteudo/canonical.js +107 -0
  31. package/dist/pipelineConteudo/command.d.ts +3 -0
  32. package/dist/pipelineConteudo/command.js +572 -0
  33. package/dist/pipelineConteudo/index.d.ts +9 -0
  34. package/dist/pipelineConteudo/index.js +12 -0
  35. package/dist/pipelineConteudo/ledger.d.ts +68 -0
  36. package/dist/pipelineConteudo/ledger.js +732 -0
  37. package/dist/pipelineConteudo/planner.d.ts +12 -0
  38. package/dist/pipelineConteudo/planner.js +366 -0
  39. package/dist/pipelineConteudo/projection.d.ts +16 -0
  40. package/dist/pipelineConteudo/projection.js +57 -0
  41. package/dist/pipelineConteudo/state.d.ts +23 -0
  42. package/dist/pipelineConteudo/state.js +615 -0
  43. package/dist/pipelineConteudo/trust.d.ts +17 -0
  44. package/dist/pipelineConteudo/trust.js +750 -0
  45. package/dist/pipelineConteudo/types.d.ts +331 -0
  46. package/dist/pipelineConteudo/types.js +4 -0
  47. package/dist/projetoConfig.js +7 -1
  48. package/dist/projetoResolucao.js +21 -6
  49. package/dist/sync/index.js +35 -35
  50. package/docs/README.md +28 -25
  51. package/docs/ai-onboarding.md +62 -62
  52. package/docs/ai-workflow.md +1 -1
  53. package/docs/auth.md +26 -26
  54. package/docs/cli.md +79 -72
  55. package/docs/commands.md +1 -1
  56. package/docs/database.md +15 -15
  57. package/docs/deploy.md +41 -36
  58. package/docs/documentation.md +39 -39
  59. package/docs/env.md +16 -16
  60. package/docs/frontend.md +41 -41
  61. package/docs/getting-started.md +57 -57
  62. package/docs/i18n.md +15 -15
  63. package/docs/pipeline-conteudo.md +246 -0
  64. package/docs/profiles.md +45 -43
  65. package/docs/repositories.md +43 -43
  66. package/docs/rollback.md +31 -31
  67. package/docs/security.md +32 -32
  68. package/docs/support.md +8 -8
  69. package/docs/syntax.md +1 -1
  70. package/docs/testing.md +35 -28
  71. package/docs/vocabulary.md +29 -29
  72. package/exemplos/agendamento.sema +1 -1
  73. package/exemplos/assinatura.sema +1 -1
  74. package/exemplos/auditoria.sema +1 -1
  75. package/exemplos/autenticacao.sema +1 -1
  76. package/exemplos/author_obra_comum.sema +1 -1
  77. package/exemplos/author_tema_sensivel.sema +1 -1
  78. package/exemplos/automacao.sema +1 -1
  79. package/exemplos/cadastro_usuario.sema +1 -1
  80. package/exemplos/calculadora.sema +1 -1
  81. package/exemplos/crud_simples.sema +1 -1
  82. package/exemplos/estoque.sema +1 -1
  83. package/exemplos/exportacao.sema +1 -1
  84. package/exemplos/fila.sema +1 -1
  85. package/exemplos/integracao_externa.sema +1 -1
  86. package/exemplos/multi_tenant.sema +1 -1
  87. package/exemplos/notificacao.sema +1 -1
  88. package/exemplos/operacao_estrategia.sema +132 -132
  89. package/exemplos/operacao_estrategia_discovery.sema +220 -220
  90. package/exemplos/operacao_estrategia_fluxo.sema +114 -114
  91. package/exemplos/operacao_estrategia_gates.sema +106 -106
  92. package/exemplos/operacao_estrategia_quarentena.sema +133 -133
  93. package/exemplos/operacao_estrategia_rollout.sema +124 -124
  94. package/exemplos/pagamento.sema +1 -1
  95. package/exemplos/pagamento_dominio.sema +1 -1
  96. package/exemplos/pedido.sema +1 -1
  97. package/exemplos/permissao.sema +1 -1
  98. package/exemplos/persistencia_vendor_first.sema +1 -1
  99. package/exemplos/pipeline-conteudo/README.md +44 -0
  100. package/exemplos/pipeline-conteudo/alvos.json +23 -0
  101. package/exemplos/pipeline-conteudo/definicao.json +136 -0
  102. package/exemplos/profile_conversas.sema +165 -165
  103. package/exemplos/profile_game.sema +1 -1
  104. package/exemplos/profile_legal.sema +1 -1
  105. package/exemplos/profile_ops.sema +1 -1
  106. package/exemplos/profile_research.sema +1 -1
  107. package/exemplos/profile_software.sema +1 -1
  108. package/exemplos/profile_workflow_n8n.sema +1 -1
  109. package/exemplos/relatorio.sema +1 -1
  110. package/exemplos/replica_analitica_erp.sema +1 -1
  111. package/exemplos/testes_embutidos.sema +1 -1
  112. package/exemplos/tratamento_erro.sema +1 -1
  113. package/exemplos/upload_arquivo.sema +1 -1
  114. package/exemplos/webhook.sema +1 -1
  115. package/node_modules/@sema/gerador-cpp/dist/index.d.ts +3 -0
  116. package/node_modules/@sema/gerador-cpp/dist/index.js +859 -0
  117. package/node_modules/@sema/gerador-cpp/dist/index.js.map +1 -0
  118. package/node_modules/@sema/gerador-cpp/package.json +7 -0
  119. package/node_modules/@sema/gerador-css/dist/index.part01.js +10 -10
  120. package/node_modules/@sema/gerador-css/dist/index.part02.js +460 -460
  121. package/node_modules/@sema/gerador-dotnet/dist/index.d.ts +3 -0
  122. package/node_modules/@sema/gerador-dotnet/dist/index.js +828 -0
  123. package/node_modules/@sema/gerador-dotnet/dist/index.js.map +1 -0
  124. package/node_modules/@sema/gerador-dotnet/package.json +7 -0
  125. package/node_modules/@sema/gerador-html/dist/index.js +17 -17
  126. package/node_modules/@sema/gerador-lua/dist/index.js +53 -8
  127. package/node_modules/@sema/gerador-lua/dist/index.js.map +1 -1
  128. package/node_modules/@sema/gerador-php/dist/index.js +121 -113
  129. package/node_modules/@sema/gerador-php/dist/index.js.map +1 -1
  130. package/node_modules/@sema/gerador-python/dist/index.part02.js +3 -3
  131. package/node_modules/@sema/gerador-typescript/dist/index.part02.js +11 -11
  132. package/node_modules/@sema/nucleo/dist/diagnosticos/melhorador.js +42 -42
  133. package/node_modules/@sema/padroes/dist/index.d.ts +1 -1
  134. package/package.json +12 -1
@@ -0,0 +1,615 @@
1
+ // SEMA-GOVERNED: sema.produto.pipeline_conteudo.estado
2
+ // Descricao: replay deterministico do ledger canonico, com veredito e condicao operacional independentes.
3
+ import { hashCanonicoConteudo } from "./canonical.js";
4
+ import { avaliarConstraintsDeterministicasConteudo, escopoAutorizacaoAlvo, escopoAutorizacaoGlobal, } from "./adapters.js";
5
+ import { validarLedgerConteudo } from "./ledger.js";
6
+ import { planejarPipelineConteudo, validarDefinicaoPipelineConteudo, } from "./planner.js";
7
+ import { avaliarGateConteudoInterno, validarConfiguracaoConfiancaConteudo, verificarEnvelopeAssinadoConteudo, } from "./trust.js";
8
+ const ALVO_GLOBAL = "\u0000global";
9
+ const EVIDENCIA_CONSTRAINTS_ADAPTER = "adapter.constraints.passed";
10
+ const IDADE_MAXIMA_POLICY_PADRAO_MS = 5 * 60 * 1000;
11
+ const DESVIO_FUTURO_POLICY_PADRAO_MS = 30 * 1000;
12
+ function chaveAlvo(targetId) {
13
+ return targetId ?? ALVO_GLOBAL;
14
+ }
15
+ function chaveGate(gateId, targetId) {
16
+ return `${gateId}\u0000${chaveAlvo(targetId)}`;
17
+ }
18
+ function chaveEtapa(stageId, targetId) {
19
+ return `${stageId}\u0000${chaveAlvo(targetId)}`;
20
+ }
21
+ function alvoExato(recebido, esperado) {
22
+ return recebido === esperado;
23
+ }
24
+ function gatePorAlvo(gate) {
25
+ return gate.scope === "POR_ALVO";
26
+ }
27
+ function unico(valores) {
28
+ return [...new Set(valores)];
29
+ }
30
+ function mesmosConjuntos(a, b) {
31
+ return a.length === b.size && a.every((item) => b.has(item));
32
+ }
33
+ function falhaEstado(runId, acoes) {
34
+ return { valido: false, runId, estadosGate: [], concluido: false, nextActions: unico(acoes), artifactsAceitos: [] };
35
+ }
36
+ function configuracaoConfianca(entrada) {
37
+ return entrada.configuracaoConfianca;
38
+ }
39
+ function eventosDoTipo(eventos, kind) {
40
+ const encontrados = [];
41
+ for (const evento of eventos) {
42
+ if (evento.envelope.payload.kind === kind) {
43
+ encontrados.push({
44
+ evento,
45
+ payload: evento.envelope.payload,
46
+ });
47
+ }
48
+ }
49
+ return encontrados;
50
+ }
51
+ function principalPorId(principals, principalId) {
52
+ const encontrados = principals.filter((principal) => principal.principalId === principalId);
53
+ return encontrados.length === 1 ? encontrados[0] : undefined;
54
+ }
55
+ function verificarAtestado(item, confianca, trustRootDigestEsperado, revocationDigestEsperado) {
56
+ const envelope = item.evento.envelope;
57
+ const verificacao = verificarEnvelopeAssinadoConteudo(envelope, confianca, {
58
+ trustRootDigestEsperado,
59
+ revocationDigestEsperado,
60
+ payloadTypeEsperado: "EVIDENCE_ATTESTED",
61
+ papeisPermitidos: ["EVIDENCE_ATTESTER", "ADAPTER"],
62
+ scopeRequerido: item.payload.authorizationScope,
63
+ agora: item.payload.observedAt,
64
+ });
65
+ if (!verificacao.valido || verificacao.principal?.principalId !== item.payload.attesterId)
66
+ return undefined;
67
+ return verificacao.envelopeVerificado;
68
+ }
69
+ function verificarParecer(item, confianca, trustRootDigestEsperado, revocationDigestEsperado) {
70
+ const envelope = item.evento.envelope;
71
+ const verificacao = verificarEnvelopeAssinadoConteudo(envelope, confianca, {
72
+ trustRootDigestEsperado,
73
+ revocationDigestEsperado,
74
+ payloadTypeEsperado: "AI_ASSESSMENT",
75
+ papeisPermitidos: ["EVALUATOR"],
76
+ scopeRequerido: item.payload.authorizationScope,
77
+ agora: item.payload.assessedAt,
78
+ });
79
+ if (!verificacao.valido || verificacao.principal?.principalId !== item.payload.evaluatorId)
80
+ return undefined;
81
+ return verificacao.envelopeVerificado;
82
+ }
83
+ function instanciaGateIds(definicao, inicio) {
84
+ const instancias = [];
85
+ for (const gate of definicao.gates) {
86
+ if (gatePorAlvo(gate)) {
87
+ for (const alvo of inicio.targets)
88
+ instancias.push({ gate, targetId: alvo.targetId });
89
+ }
90
+ else {
91
+ instancias.push({ gate });
92
+ }
93
+ }
94
+ return instancias;
95
+ }
96
+ function proximaAcao(estado) {
97
+ const id = chaveGate(estado.gateId, estado.targetId).replace("\u0000", ":");
98
+ if (estado.veredito === "APROVADO")
99
+ return undefined;
100
+ if (estado.artifactDigest.length === 0)
101
+ return `produzir_artefato:${id}`;
102
+ if (estado.veredito === "REPROVADO" ||
103
+ estado.blockers.some((item) => item === "artefato_desatualizado" || item.startsWith("constraint_nao_satisfeita:"))) {
104
+ return `corrigir_artefato:${id}`;
105
+ }
106
+ if (estado.condition === "FERRAMENTA_INDISPONIVEL" ||
107
+ estado.condition === "CAPACIDADE_AUSENTE" ||
108
+ estado.condition === "AUTORIZACAO_AUSENTE" ||
109
+ estado.condition === "FALHA_TRANSITORIA" ||
110
+ estado.condition === "FALHA_TERMINAL") {
111
+ return `resolver_condicao:${id}:${estado.condition}`;
112
+ }
113
+ return `coletar_evidencia:${id}`;
114
+ }
115
+ function escopoEsperadoArtefato(stage, inicio, targetId) {
116
+ if (stage.scope === "GLOBAL")
117
+ return targetId === undefined ? escopoAutorizacaoGlobal(inicio.runId) : undefined;
118
+ if (targetId === undefined)
119
+ return undefined;
120
+ const alvo = inicio.targets.find((item) => item.targetId === targetId);
121
+ return alvo === undefined ? undefined : escopoAutorizacaoAlvo(inicio.runId, alvo);
122
+ }
123
+ function chavesDependencias(stage, targetId, definicao, inicio) {
124
+ const stages = new Map(definicao.stages.map((item) => [item.stageId, item]));
125
+ const chaves = [];
126
+ for (const dependenciaId of stage.dependsOn) {
127
+ const dependencia = stages.get(dependenciaId);
128
+ if (dependencia === undefined)
129
+ continue;
130
+ if (dependencia.scope === "GLOBAL") {
131
+ chaves.push(chaveEtapa(dependenciaId, undefined));
132
+ }
133
+ else if (stage.scope === "POR_ALVO") {
134
+ chaves.push(chaveEtapa(dependenciaId, targetId));
135
+ }
136
+ else {
137
+ for (const alvo of inicio.targets)
138
+ chaves.push(chaveEtapa(dependenciaId, alvo.targetId));
139
+ }
140
+ }
141
+ return chaves;
142
+ }
143
+ function bloqueiosDependenciasAtuais(artifact, stage, definicao, inicio, artefatosPorEtapa) {
144
+ const bloqueios = [];
145
+ for (const chave of chavesDependencias(stage, artifact.targetId, definicao, inicio)) {
146
+ const dependencia = artefatosPorEtapa.get(chave);
147
+ if (dependencia === undefined)
148
+ bloqueios.push(`dependencia_ausente:${chave.replace("\u0000", ":")}`);
149
+ else if (!artifact.lineageDigests.includes(dependencia.digest))
150
+ bloqueios.push(`dependencia_desatualizada:${dependencia.digest}`);
151
+ }
152
+ return bloqueios;
153
+ }
154
+ function extrairObservacoes(data) {
155
+ if (data === undefined || data === null || typeof data !== "object" || Array.isArray(data))
156
+ return {};
157
+ const raiz = data;
158
+ const aninhada = raiz.observations;
159
+ const fonte = aninhada !== null && typeof aninhada === "object" && !Array.isArray(aninhada)
160
+ ? aninhada
161
+ : raiz;
162
+ const numero = (valor) => typeof valor === "number" && Number.isFinite(valor) && valor >= 0 ? valor : undefined;
163
+ return {
164
+ observedMediaType: typeof fonte.observedMediaType === "string" && fonte.observedMediaType.trim().length > 0
165
+ ? fonte.observedMediaType
166
+ : undefined,
167
+ artifactBytes: numero(fonte.artifactBytes),
168
+ mediaDuration: numero(fonte.mediaDuration),
169
+ textLength: numero(fonte.textLength),
170
+ };
171
+ }
172
+ function filtrarConstraintsDoAdapter(gate, artifact, alvo, adapter, evidencias) {
173
+ if (!gate.requiredEvidence.includes(EVIDENCIA_CONSTRAINTS_ADAPTER)) {
174
+ return { evidencias, bloqueios: [], reprovar: false };
175
+ }
176
+ if (alvo === undefined || adapter === undefined) {
177
+ return { evidencias: [], bloqueios: ["adapter_do_target_ausente"], reprovar: false };
178
+ }
179
+ if (!adapter.acceptedMediaTypes.includes(artifact.mediaType)) {
180
+ return { evidencias: [], bloqueios: [`media_type_nao_aceito:${artifact.mediaType}`], reprovar: true };
181
+ }
182
+ const aceitas = [];
183
+ const bloqueios = [];
184
+ let reprovar = false;
185
+ for (const evidencia of evidencias) {
186
+ const atestado = evidencia.payload;
187
+ if (atestado.evidenceType !== EVIDENCIA_CONSTRAINTS_ADAPTER) {
188
+ aceitas.push(evidencia);
189
+ continue;
190
+ }
191
+ const data = atestado.data;
192
+ if (data?.adapterId !== adapter.adapterId || data?.adapterVersion !== adapter.version) {
193
+ bloqueios.push(`constraint_adapter_binding_divergente:${atestado.evidenceId}`);
194
+ continue;
195
+ }
196
+ const observacoes = extrairObservacoes(atestado.data);
197
+ const resultado = avaliarConstraintsDeterministicasConteudo(artifact, adapter.deterministicConstraints, observacoes);
198
+ if (data?.constraintsDigest !== resultado.constraintsDigest) {
199
+ bloqueios.push(`constraint_digest_divergente:${atestado.evidenceId}`);
200
+ continue;
201
+ }
202
+ if (data?.resultsDigest !== resultado.resultsDigest) {
203
+ bloqueios.push(`constraint_result_digest_divergente:${atestado.evidenceId}`);
204
+ continue;
205
+ }
206
+ const haFalhaDeterministica = resultado.bloqueios.some((item) => item.startsWith("constraint_nao_satisfeita:"));
207
+ const mediaTypeAusente = observacoes.observedMediaType === undefined;
208
+ const mediaTypeReprovado = !mediaTypeAusente && (observacoes.observedMediaType !== artifact.mediaType ||
209
+ !adapter.acceptedMediaTypes.includes(observacoes.observedMediaType));
210
+ if (mediaTypeAusente)
211
+ bloqueios.push(`constraint_observed_media_type_ausente:${atestado.evidenceId}`);
212
+ if (mediaTypeReprovado)
213
+ bloqueios.push(`constraint_observed_media_type_divergente:${atestado.evidenceId}`);
214
+ const resultadoEsperado = resultado.valido && !mediaTypeAusente && !mediaTypeReprovado
215
+ ? "APROVADO"
216
+ : haFalhaDeterministica || mediaTypeReprovado
217
+ ? "REPROVADO"
218
+ : "INCONCLUSIVO";
219
+ if (atestado.result !== resultadoEsperado) {
220
+ bloqueios.push(`constraint_resultado_declarado_divergente:${atestado.evidenceId}`);
221
+ continue;
222
+ }
223
+ if (!resultado.valido)
224
+ bloqueios.push(...resultado.bloqueios.map((item) => `${item}:${atestado.evidenceId}`));
225
+ reprovar ||= resultadoEsperado === "REPROVADO";
226
+ aceitas.push(evidencia);
227
+ }
228
+ return { evidencias: aceitas, bloqueios: unico(bloqueios), reprovar };
229
+ }
230
+ function filtrarConfirmacoesDoAdapter(stage, adapter, evidencias) {
231
+ if (stage.adapterPolicy !== "CONFIRMATION") {
232
+ return { evidencias, bloqueios: [], reprovar: false };
233
+ }
234
+ if (adapter === undefined)
235
+ return { evidencias: [], bloqueios: ["adapter_do_target_ausente"], reprovar: false };
236
+ const predicates = new Set(adapter.confirmationPredicates);
237
+ const aceitas = [];
238
+ const bloqueios = [];
239
+ for (const evidencia of evidencias) {
240
+ const atestado = evidencia.payload;
241
+ if (!predicates.has(atestado.evidenceType)) {
242
+ aceitas.push(evidencia);
243
+ continue;
244
+ }
245
+ const data = atestado.data;
246
+ if (data?.adapterId !== adapter.adapterId || data?.adapterVersion !== adapter.version) {
247
+ bloqueios.push(`confirmacao_adapter_binding_divergente:${atestado.evidenceId}`);
248
+ continue;
249
+ }
250
+ if (typeof data?.observationDigest !== "string" || !/^sha256:[a-f0-9]{64}$/u.test(data.observationDigest)) {
251
+ bloqueios.push(`confirmacao_observation_digest_invalido:${atestado.evidenceId}`);
252
+ continue;
253
+ }
254
+ aceitas.push(evidencia);
255
+ }
256
+ return { evidencias: aceitas, bloqueios: unico(bloqueios), reprovar: false };
257
+ }
258
+ function capabilityAtestadorAdapter(adapter, evidenceType) {
259
+ return `content.adapter.attest:${encodeURIComponent(adapter.adapterId)}@${encodeURIComponent(adapter.version)}:${evidenceType}`;
260
+ }
261
+ function capabilitiesAtestadorDoAdapter(stage, adapter) {
262
+ if (adapter === undefined || stage.adapterPolicy === "NONE")
263
+ return {};
264
+ const tipos = stage.adapterPolicy === "CONSTRAINTS"
265
+ ? [EVIDENCIA_CONSTRAINTS_ADAPTER]
266
+ : adapter.confirmationPredicates;
267
+ return Object.fromEntries(tipos.map((tipo) => [tipo, capabilityAtestadorAdapter(adapter, tipo)]));
268
+ }
269
+ function gateEfetivoDoAdapter(gate, stage, adapter) {
270
+ if (stage.adapterPolicy === "NONE" || adapter === undefined)
271
+ return gate;
272
+ const adicionais = stage.adapterPolicy === "CONSTRAINTS"
273
+ ? [EVIDENCIA_CONSTRAINTS_ADAPTER]
274
+ : adapter.confirmationPredicates;
275
+ return { ...gate, requiredEvidence: unico([...gate.requiredEvidence, ...adicionais]) };
276
+ }
277
+ /**
278
+ * O estado nasce exclusivamente do replay. Campos como `concluido` presentes
279
+ * em JSON externo ou manifestos nao participam desta funcao.
280
+ */
281
+ export function derivarEstadoPipelineConteudo(entrada) {
282
+ const confianca = configuracaoConfianca(entrada);
283
+ const problemasConfiguracao = [];
284
+ const raizConfianca = validarConfiguracaoConfiancaConteudo(confianca, entrada.trustRootDigestEsperado, entrada.revocationDigestEsperado);
285
+ if (!raizConfianca.valida) {
286
+ problemasConfiguracao.push(...raizConfianca.bloqueios.map((item) => `raiz_confianca_invalida:${item}`));
287
+ }
288
+ const verificacaoPolitica = verificarEnvelopeAssinadoConteudo(entrada.envelopePolitica, confianca, {
289
+ trustRootDigestEsperado: entrada.trustRootDigestEsperado,
290
+ revocationDigestEsperado: entrada.revocationDigestEsperado,
291
+ payloadTypeEsperado: "TRUST_POLICY",
292
+ papeisPermitidos: ["POLICY_AUTHORITY"],
293
+ agora: entrada.envelopePolitica.payload.issuedAt,
294
+ });
295
+ if (!verificacaoPolitica.valido) {
296
+ problemasConfiguracao.push(...verificacaoPolitica.bloqueios.map((item) => `politica_nao_confiavel:${item}`));
297
+ }
298
+ const politica = entrada.envelopePolitica.payload;
299
+ const validacaoDefinicao = validarDefinicaoPipelineConteudo(entrada.definicao);
300
+ const policyDigest = hashCanonicoConteudo(politica);
301
+ if (!validacaoDefinicao.valida) {
302
+ problemasConfiguracao.push(...validacaoDefinicao.bloqueios.map((item) => `definicao_invalida:${item}`));
303
+ }
304
+ if (validacaoDefinicao.definitionDigest !== politica.definitionDigest) {
305
+ problemasConfiguracao.push("definition_digest_divergente");
306
+ }
307
+ if (hashCanonicoConteudo(entrada.definicao.gates) !== hashCanonicoConteudo(politica.gates)) {
308
+ problemasConfiguracao.push("politica_gates_divergentes_da_definicao");
309
+ }
310
+ if (confianca.trustDomainId !== politica.trustDomainId) {
311
+ problemasConfiguracao.push("trust_domain_divergente");
312
+ }
313
+ if (politica.trustRootDigest !== entrada.trustRootDigestEsperado) {
314
+ problemasConfiguracao.push("policy_trust_root_digest_divergente");
315
+ }
316
+ if (entrada.envelopePolitica.issuedAt !== politica.issuedAt) {
317
+ problemasConfiguracao.push("policy_issued_at_divergente");
318
+ }
319
+ const policyIssuedAt = Date.parse(politica.issuedAt);
320
+ const policyExpiresAt = Date.parse(politica.expiresAt);
321
+ if (!Number.isFinite(policyIssuedAt) || !Number.isFinite(policyExpiresAt) || policyExpiresAt <= policyIssuedAt) {
322
+ problemasConfiguracao.push("policy_janela_temporal_invalida");
323
+ }
324
+ if (typeof politica.runId !== "string" || politica.runId.trim().length === 0) {
325
+ problemasConfiguracao.push("policy_run_id_invalido");
326
+ }
327
+ if (problemasConfiguracao.length > 0) {
328
+ return falhaEstado("", problemasConfiguracao.map((item) => `corrigir_configuracao:${item}`));
329
+ }
330
+ const validacaoLedger = validarLedgerConteudo({
331
+ eventos: entrada.eventos,
332
+ envelopePolitica: entrada.envelopePolitica,
333
+ ledgerId: politica.ledgerId,
334
+ expectedHead: entrada.expectedHead,
335
+ principals: confianca.principals,
336
+ trustRootDigestEsperado: entrada.trustRootDigestEsperado,
337
+ revocationDigestEsperado: entrada.revocationDigestEsperado,
338
+ configuracaoConfianca: entrada.configuracaoConfianca,
339
+ contextoEsperado: {
340
+ runId: politica.runId,
341
+ trustDomainId: politica.trustDomainId,
342
+ trustRootDigest: entrada.trustRootDigestEsperado,
343
+ ledgerId: politica.ledgerId,
344
+ policyDigest,
345
+ definitionDigest: politica.definitionDigest,
346
+ },
347
+ });
348
+ if (!validacaoLedger.valido) {
349
+ return falhaEstado("", validacaoLedger.bloqueios.map((item) => `corrigir_ledger:${item}`));
350
+ }
351
+ const inicios = eventosDoTipo(entrada.eventos, "RUN_STARTED");
352
+ if (inicios.length !== 1) {
353
+ return falhaEstado(inicios[0]?.payload.runId ?? "", [inicios.length === 0 ? "iniciar_execucao" : "corrigir_ledger:multiplos_run_started"]);
354
+ }
355
+ const inicio = inicios[0].payload;
356
+ const ativacaoPolicy = Date.parse(inicios[0].evento.recordedAt);
357
+ const idadeMaximaPolicy = confianca.maxEnvelopeAgeMs ?? IDADE_MAXIMA_POLICY_PADRAO_MS;
358
+ const desvioFuturoPolicy = confianca.maxFutureSkewMs ?? DESVIO_FUTURO_POLICY_PADRAO_MS;
359
+ if (!Number.isFinite(ativacaoPolicy) ||
360
+ policyIssuedAt > ativacaoPolicy + desvioFuturoPolicy ||
361
+ ativacaoPolicy - policyIssuedAt > idadeMaximaPolicy ||
362
+ ativacaoPolicy > policyExpiresAt) {
363
+ return falhaEstado(inicio.runId, ["corrigir_execucao:policy_fora_da_janela_de_ativacao"]);
364
+ }
365
+ const eventoForaDaJanela = entrada.eventos.find((evento) => {
366
+ const registradoEm = Date.parse(evento.recordedAt);
367
+ return !Number.isFinite(registradoEm) || registradoEm < policyIssuedAt || registradoEm > policyExpiresAt;
368
+ });
369
+ if (eventoForaDaJanela !== undefined) {
370
+ return falhaEstado(inicio.runId, [
371
+ `corrigir_ledger:evento_fora_da_janela_da_politica:${eventoForaDaJanela.eventId}`,
372
+ ]);
373
+ }
374
+ if (inicio.definitionDigest !== validacaoDefinicao.definitionDigest ||
375
+ inicio.runId !== politica.runId ||
376
+ inicio.policyDigest !== policyDigest ||
377
+ politica.targetSetDigest !== hashCanonicoConteudo(inicio.targets) ||
378
+ inicio.trustDomainId !== politica.trustDomainId ||
379
+ inicio.trustRootDigest !== entrada.trustRootDigestEsperado ||
380
+ inicio.ledgerId !== politica.ledgerId) {
381
+ return falhaEstado(inicio.runId, ["corrigir_execucao:contexto_ou_target_set_divergente"]);
382
+ }
383
+ const planejamento = planejarPipelineConteudo(entrada.definicao, inicio.targets);
384
+ if (planejamento.bloqueios.length > 0) {
385
+ return falhaEstado(inicio.runId, planejamento.bloqueios.map((item) => `corrigir_configuracao_alvos:${item}`));
386
+ }
387
+ const revogadas = new Set(confianca.revokedKeyIds);
388
+ const stagesPorId = new Map(entrada.definicao.stages.map((stage) => [stage.stageId, stage]));
389
+ const adaptersPorId = new Map(entrada.definicao.adapters.map((adapter) => [adapter.adapterId, adapter]));
390
+ const artefatosPorEtapa = new Map();
391
+ const artefatosPorDigest = new Map();
392
+ const linhagemPorDigest = new Map();
393
+ const artifactIds = new Set();
394
+ const problemasReplay = [];
395
+ for (const item of eventosDoTipo(entrada.eventos, "ARTIFACT_REGISTERED")) {
396
+ const artifact = item.payload;
397
+ const bloqueios = [];
398
+ const stage = stagesPorId.get(artifact.stageId);
399
+ const principal = principalPorId(confianca.principals, artifact.producerId);
400
+ if (stage === undefined)
401
+ bloqueios.push("stage_nao_declarada");
402
+ if (artifactIds.has(artifact.artifactId))
403
+ bloqueios.push("artifact_id_repetido");
404
+ if (artifact.runId !== inicio.runId)
405
+ bloqueios.push("run_divergente");
406
+ if (principal === undefined || artifact.producerId !== item.evento.envelope.principalId) {
407
+ bloqueios.push("produtor_nao_confiavel");
408
+ }
409
+ else {
410
+ if (!principal.papeis.includes("PRODUCER"))
411
+ bloqueios.push("papel_produtor_ausente");
412
+ if (revogadas.has(principal.keyId))
413
+ bloqueios.push("chave_produtor_revogada");
414
+ if (stage !== undefined && !principal.capabilities.includes(stage.capability)) {
415
+ bloqueios.push(`capability_produtor_ausente:${stage.capability}`);
416
+ }
417
+ }
418
+ if (stage !== undefined) {
419
+ const escopo = escopoEsperadoArtefato(stage, inicio, artifact.targetId);
420
+ if (escopo === undefined)
421
+ bloqueios.push("target_incompativel_com_escopo_da_stage");
422
+ else {
423
+ if (artifact.authorizationScope !== escopo)
424
+ bloqueios.push("authorization_scope_divergente");
425
+ if (principal !== undefined && !principal.scopes.includes(escopo))
426
+ bloqueios.push("scope_produtor_ausente");
427
+ }
428
+ if (!stage.produces.includes(artifact.artifactType))
429
+ bloqueios.push("artifact_type_nao_declarado");
430
+ }
431
+ const linhagemDerivada = new Set([artifact.producerId]);
432
+ for (const digestAncestral of artifact.lineageDigests) {
433
+ const ancestral = artefatosPorDigest.get(digestAncestral);
434
+ const linhagemAncestral = linhagemPorDigest.get(digestAncestral);
435
+ if (ancestral === undefined || linhagemAncestral === undefined) {
436
+ bloqueios.push(`ancestral_nao_confiavel:${digestAncestral}`);
437
+ continue;
438
+ }
439
+ for (const principalId of linhagemAncestral)
440
+ linhagemDerivada.add(principalId);
441
+ }
442
+ if (!mesmosConjuntos(artifact.producerLineageIds, linhagemDerivada)) {
443
+ bloqueios.push("producer_lineage_divergente_da_linhagem_derivada");
444
+ }
445
+ if (stage !== undefined) {
446
+ bloqueios.push(...bloqueiosDependenciasAtuais(artifact, stage, entrada.definicao, inicio, artefatosPorEtapa));
447
+ }
448
+ artifactIds.add(artifact.artifactId);
449
+ if (bloqueios.length > 0) {
450
+ problemasReplay.push(...bloqueios.map((item) => `ignorar_artefato:${artifact.artifactId}:${item}`));
451
+ continue;
452
+ }
453
+ artefatosPorEtapa.set(chaveEtapa(artifact.stageId, artifact.targetId), artifact);
454
+ artefatosPorDigest.set(artifact.digest, artifact);
455
+ linhagemPorDigest.set(artifact.digest, linhagemDerivada);
456
+ }
457
+ const alegacoesPorId = new Map();
458
+ for (const item of eventosDoTipo(entrada.eventos, "EVIDENCE_CLAIMED")) {
459
+ const artifact = artefatosPorDigest.get(item.payload.artifactDigest);
460
+ if (item.payload.runId !== inicio.runId ||
461
+ item.payload.producerId !== item.evento.envelope.principalId ||
462
+ artifact === undefined ||
463
+ artifact.producerId !== item.payload.producerId) {
464
+ problemasReplay.push(`ignorar_alegacao_nao_ligada_a_artefato_valido:${item.payload.claimId}`);
465
+ continue;
466
+ }
467
+ alegacoesPorId.set(item.payload.claimId, item);
468
+ }
469
+ const condicoes = new Map();
470
+ const gatesPorId = new Map(entrada.definicao.gates.map((gate) => [gate.gateId, gate]));
471
+ for (const item of eventosDoTipo(entrada.eventos, "OPERATIONAL_CONDITION")) {
472
+ const gate = gatesPorId.get(item.payload.gateId);
473
+ const principal = principalPorId(confianca.principals, item.evento.envelope.principalId);
474
+ if (gate === undefined || principal === undefined || revogadas.has(principal.keyId)) {
475
+ problemasReplay.push(`ignorar_condicao_nao_autorizada:${item.evento.eventId}`);
476
+ continue;
477
+ }
478
+ const targetCorreto = gatePorAlvo(gate)
479
+ ? inicio.targets.some((alvo) => alvo.targetId === item.payload.targetId)
480
+ : item.payload.targetId === undefined;
481
+ if (!targetCorreto) {
482
+ problemasReplay.push(`ignorar_condicao_target_divergente:${item.evento.eventId}`);
483
+ continue;
484
+ }
485
+ condicoes.set(chaveGate(item.payload.gateId, item.payload.targetId), item.payload.condition);
486
+ }
487
+ const atestados = eventosDoTipo(entrada.eventos, "EVIDENCE_ATTESTED");
488
+ const pareceres = eventosDoTipo(entrada.eventos, "AI_ASSESSMENT");
489
+ const estadosGate = [];
490
+ for (const { gate, targetId } of instanciaGateIds(entrada.definicao, inicio)) {
491
+ const stage = stagesPorId.get(gate.stageId);
492
+ const artifact = artefatosPorEtapa.get(chaveEtapa(gate.stageId, targetId));
493
+ const condicaoExplicita = condicoes.get(chaveGate(gate.gateId, targetId));
494
+ if (artifact === undefined) {
495
+ estadosGate.push({
496
+ gateId: gate.gateId,
497
+ targetId,
498
+ artifactDigest: "",
499
+ veredito: "NAO_AVALIADO",
500
+ condition: condicaoExplicita ?? "PENDENTE",
501
+ evidenceIds: [],
502
+ assessmentIds: [],
503
+ blockers: ["artefato_ausente"],
504
+ });
505
+ continue;
506
+ }
507
+ const dependenciasDesatualizadas = bloqueiosDependenciasAtuais(artifact, stage, entrada.definicao, inicio, artefatosPorEtapa);
508
+ if (dependenciasDesatualizadas.length > 0) {
509
+ estadosGate.push({
510
+ gateId: gate.gateId,
511
+ targetId,
512
+ artifactDigest: artifact.digest,
513
+ veredito: "INCONCLUSIVO",
514
+ condition: condicaoExplicita ?? "AGUARDANDO_EVIDENCIA",
515
+ evidenceIds: [],
516
+ assessmentIds: [],
517
+ blockers: ["artefato_desatualizado", ...dependenciasDesatualizadas],
518
+ });
519
+ continue;
520
+ }
521
+ const evidenciasAceitas = [];
522
+ for (const item of atestados) {
523
+ const atestado = item.payload;
524
+ if (atestado.runId !== inicio.runId ||
525
+ atestado.gateId !== gate.gateId ||
526
+ atestado.stageId !== gate.stageId ||
527
+ !alvoExato(atestado.targetId, targetId) ||
528
+ atestado.artifactDigest !== artifact.digest ||
529
+ atestado.producerId !== artifact.producerId)
530
+ continue;
531
+ if (atestado.claimId !== undefined) {
532
+ const alegacao = alegacoesPorId.get(atestado.claimId)?.payload;
533
+ if (alegacao === undefined ||
534
+ alegacao.runId !== atestado.runId ||
535
+ alegacao.stageId !== atestado.stageId ||
536
+ !alvoExato(alegacao.targetId, atestado.targetId) ||
537
+ alegacao.artifactDigest !== atestado.artifactDigest ||
538
+ alegacao.evidenceType !== atestado.evidenceType ||
539
+ alegacao.producerId !== atestado.producerId)
540
+ continue;
541
+ }
542
+ const verificado = verificarAtestado(item, confianca, entrada.trustRootDigestEsperado, entrada.revocationDigestEsperado);
543
+ if (verificado !== undefined)
544
+ evidenciasAceitas.push(verificado);
545
+ }
546
+ const pareceresIa = [];
547
+ for (const item of pareceres) {
548
+ const parecer = item.payload;
549
+ if (parecer.runId !== inicio.runId ||
550
+ parecer.gateId !== gate.gateId ||
551
+ !alvoExato(parecer.targetId, targetId) ||
552
+ parecer.artifactDigest !== artifact.digest ||
553
+ parecer.rubricDigest !== gate.rubricDigest)
554
+ continue;
555
+ const verificado = verificarParecer(item, confianca, entrada.trustRootDigestEsperado, entrada.revocationDigestEsperado);
556
+ if (verificado !== undefined)
557
+ pareceresIa.push(verificado);
558
+ }
559
+ const alvo = targetId === undefined ? undefined : inicio.targets.find((item) => item.targetId === targetId);
560
+ const adapter = alvo === undefined ? undefined : adaptersPorId.get(alvo.adapterId);
561
+ const gateEfetivo = gateEfetivoDoAdapter(gate, stage, adapter);
562
+ const constraints = filtrarConstraintsDoAdapter(gateEfetivo, artifact, alvo, adapter, evidenciasAceitas);
563
+ const confirmacoes = filtrarConfirmacoesDoAdapter(stage, adapter, constraints.evidencias);
564
+ const avaliacao = avaliarGateConteudoInterno({
565
+ envelopePolitica: entrada.envelopePolitica,
566
+ gate,
567
+ requiredEvidenceAdicional: gateEfetivo.requiredEvidence.filter((tipo) => !gate.requiredEvidence.includes(tipo)),
568
+ attesterCapabilitiesAdicionais: capabilitiesAtestadorDoAdapter(stage, adapter),
569
+ artifactDigest: artifact.digest,
570
+ targetId,
571
+ runId: inicio.runId,
572
+ trustDomainId: inicio.trustDomainId,
573
+ trustRootDigest: inicio.trustRootDigest,
574
+ revocationDigestEsperado: entrada.revocationDigestEsperado,
575
+ ledgerId: inicio.ledgerId,
576
+ policyDigest: inicio.policyDigest,
577
+ definitionDigest: inicio.definitionDigest,
578
+ authorizationScope: artifact.authorizationScope,
579
+ producerId: artifact.producerId,
580
+ producerLineageIds: [...(linhagemPorDigest.get(artifact.digest) ?? [])],
581
+ evidenciasAceitas: confirmacoes.evidencias,
582
+ pareceresIa,
583
+ configuracaoConfianca: confianca,
584
+ });
585
+ const veredito = constraints.reprovar
586
+ ? "REPROVADO"
587
+ : avaliacao.veredito;
588
+ estadosGate.push({
589
+ gateId: gate.gateId,
590
+ targetId,
591
+ artifactDigest: artifact.digest,
592
+ veredito,
593
+ condition: condicaoExplicita ?? (veredito === "APROVADO" || veredito === "REPROVADO" ? "PRONTA" : "AGUARDANDO_EVIDENCIA"),
594
+ evidenceIds: avaliacao.evidenceIds,
595
+ assessmentIds: avaliacao.assessmentIds,
596
+ blockers: unico([...avaliacao.bloqueios, ...constraints.bloqueios, ...confirmacoes.bloqueios]),
597
+ });
598
+ }
599
+ const nextActions = estadosGate.map(proximaAcao).filter((acao) => acao !== undefined);
600
+ nextActions.push(...problemasReplay);
601
+ const gatesDeConclusao = new Set(entrada.definicao.requiredCompletionGates);
602
+ const estadosObrigatorios = estadosGate.filter((estado) => gatesDeConclusao.has(estado.gateId));
603
+ const concluido = problemasReplay.length === 0 &&
604
+ estadosObrigatorios.length > 0 &&
605
+ estadosObrigatorios.every((estado) => estado.veredito === "APROVADO");
606
+ return {
607
+ valido: true,
608
+ runId: inicio.runId,
609
+ estadosGate,
610
+ concluido,
611
+ nextActions: unico(nextActions),
612
+ artifactsAceitos: [...artefatosPorEtapa.values()],
613
+ };
614
+ }
615
+ //# sourceMappingURL=state.js.map
@@ -0,0 +1,17 @@
1
+ import type { ConfiguracaoConfiancaConteudo, EntradaAvaliacaoGateConteudo, EnvelopeAssinadoConteudo, OpcoesVerificacaoEnvelopeConteudo, ResultadoAvaliacaoGateConteudo, ResultadoValidacaoConfiguracaoConfiancaConteudo, ResultadoVerificacaoEnvelopeConteudo } from "./types.js";
2
+ export declare function digestConfiguracaoConfiancaConteudo(confianca: ConfiguracaoConfiancaConteudo): string;
3
+ export declare function digestRevogacoesConfiancaConteudo(confianca: ConfiguracaoConfiancaConteudo): string;
4
+ export declare function validarConfiguracaoConfiancaConteudo(confianca: ConfiguracaoConfiancaConteudo, trustRootDigestEsperado: string, revocationDigestEsperado: string): ResultadoValidacaoConfiguracaoConfiancaConteudo;
5
+ /** Verificacao publica: a autoridade so existe quando os dois pins externos conferem. */
6
+ export declare function verificarEnvelopeAssinadoConteudo<TPayload>(envelope: EnvelopeAssinadoConteudo<TPayload>, confianca: ConfiguracaoConfiancaConteudo, opcoes: OpcoesVerificacaoEnvelopeConteudo): ResultadoVerificacaoEnvelopeConteudo<TPayload>;
7
+ /**
8
+ * Replay historico interno: valida os pins contra o overlay atual antes de
9
+ * ignorar revogacoes somente para provar assinaturas historicas. Nao exportar
10
+ * este simbolo pela superficie publica do pacote.
11
+ */
12
+ export declare function verificarEnvelopeAssinadoConteudoHistoricoInterno<TPayload>(envelope: EnvelopeAssinadoConteudo<TPayload>, confiancaAtual: ConfiguracaoConfiancaConteudo, opcoes: OpcoesVerificacaoEnvelopeConteudo): ResultadoVerificacaoEnvelopeConteudo<TPayload>;
13
+ /**
14
+ * @internal O chamador deve fornecer contexto derivado pelo replay canonico.
15
+ * A unica superficie publica autoritativa para gates e derivarEstadoPipelineConteudo.
16
+ */
17
+ export declare function avaliarGateConteudoInterno(entrada: EntradaAvaliacaoGateConteudo): ResultadoAvaliacaoGateConteudo;