@semacode/cli 2.2.0 → 2.3.1

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 (252) hide show
  1. package/LICENSE +39 -39
  2. package/README.md +251 -141
  3. package/dist/agentContext.d.ts +1 -1
  4. package/dist/agentContextPack.js +6 -1
  5. package/dist/agentContextTipos.d.ts +4 -2
  6. package/dist/agentContextTipos.js +7 -0
  7. package/dist/agentEntryPoints.js +551 -499
  8. package/dist/angular-consumer-standalone.d.ts +3 -1
  9. package/dist/angular-consumer-standalone.js +12 -8
  10. package/dist/comandos.js +4 -0
  11. package/dist/discovery/catalog.d.ts +11 -0
  12. package/dist/discovery/catalog.js +521 -0
  13. package/dist/discovery/command.d.ts +11 -0
  14. package/dist/discovery/command.js +226 -0
  15. package/dist/discovery/index.d.ts +5 -0
  16. package/dist/discovery/index.js +8 -0
  17. package/dist/discovery/ranker.d.ts +3 -0
  18. package/dist/discovery/ranker.js +310 -0
  19. package/dist/discovery/redaction.d.ts +2 -0
  20. package/dist/discovery/redaction.js +21 -0
  21. package/dist/discovery/render.d.ts +2 -0
  22. package/dist/discovery/render.js +100 -0
  23. package/dist/discovery/types.d.ts +119 -0
  24. package/dist/discovery/types.js +13 -0
  25. package/dist/drift.part01.d.ts +32 -2
  26. package/dist/drift.part01.js +2 -0
  27. package/dist/drift.part04.d.ts +3 -2
  28. package/dist/drift.part04.js +6 -3
  29. package/dist/drift.part05.d.ts +2 -1
  30. package/dist/drift.part05.js +4 -3
  31. package/dist/drift.part06.d.ts +2 -1
  32. package/dist/drift.part06.js +9 -5
  33. package/dist/drift.part07.d.ts +11 -10
  34. package/dist/drift.part07.js +40 -30
  35. package/dist/drift.part08.d.ts +2 -1
  36. package/dist/drift.part08.js +4 -3
  37. package/dist/drift.part11.js +71 -6
  38. package/dist/drift.part12.js +14 -1
  39. package/dist/drift.part13.d.ts +42 -7
  40. package/dist/drift.part13.js +660 -36
  41. package/dist/driftCache.d.ts +49 -0
  42. package/dist/driftCache.js +311 -0
  43. package/dist/driftCacheIncremental.d.ts +98 -0
  44. package/dist/driftCacheIncremental.js +596 -0
  45. package/dist/driftCatalogo.d.ts +91 -0
  46. package/dist/driftCatalogo.js +657 -0
  47. package/dist/driftCatalogoPersistente.d.ts +8 -0
  48. package/dist/driftCatalogoPersistente.js +77 -0
  49. package/dist/driftEscopo.d.ts +23 -0
  50. package/dist/driftEscopo.js +563 -0
  51. package/dist/driftEscopoReferencias.d.ts +4 -0
  52. package/dist/driftEscopoReferencias.js +265 -0
  53. package/dist/driftOrcamento.d.ts +12 -0
  54. package/dist/driftOrcamento.js +19 -3
  55. package/dist/execucoesExternas.js +5 -19
  56. package/dist/exemplosOficiais.js +29 -8
  57. package/dist/iaPrompts.d.ts +1 -1
  58. package/dist/iaPrompts.js +310 -307
  59. package/dist/index.d.ts +2 -0
  60. package/dist/index.js +23 -5
  61. package/dist/index.part01.d.ts +17 -2
  62. package/dist/index.part01.js +119 -8
  63. package/dist/index.part02.js +21 -21
  64. package/dist/index.part03.d.ts +2 -2
  65. package/dist/index.part03.js +14 -3
  66. package/dist/index.part04.d.ts +2 -2
  67. package/dist/index.part04.js +113 -101
  68. package/dist/index.part05.d.ts +1 -1
  69. package/dist/index.part05.js +99 -22
  70. package/dist/index.part06.js +6 -2
  71. package/dist/index.part07.js +24 -24
  72. package/dist/index.part08.js +1 -1
  73. package/dist/init/templates.part01.js +393 -393
  74. package/dist/init/templates.part02.js +189 -189
  75. package/dist/initTemplatesBackend.js +73 -73
  76. package/dist/initTemplatesBase.js +81 -80
  77. package/dist/initTemplatesFlutter.js +137 -137
  78. package/dist/initTemplatesRuntime.js +350 -350
  79. package/dist/initTemplatesWeb.js +309 -309
  80. package/dist/pipelineConteudo/command.js +1 -36
  81. package/dist/profileArtefatoValidadores.d.ts +3 -2
  82. package/dist/profileArtefatoValidadores.js +81 -0
  83. package/dist/profileAuthorTipos.d.ts +4 -3
  84. package/dist/profileCatalogo.d.ts +5 -5
  85. package/dist/profileCatalogo.js +30 -0
  86. package/dist/profileCommand.d.ts +8 -2
  87. package/dist/profileCommand.js +15 -5
  88. package/dist/profileRegras.d.ts +5 -5
  89. package/dist/profileRegras.js +13 -1
  90. package/dist/profileRulePacks.js +68 -0
  91. package/dist/projeto.d.ts +1 -1
  92. package/dist/projetoCarregar.d.ts +2 -2
  93. package/dist/projetoCarregar.js +47 -24
  94. package/dist/projetoCatalogo.d.ts +7 -0
  95. package/dist/projetoCatalogo.js +125 -0
  96. package/dist/projetoTipos.d.ts +14 -5
  97. package/dist/sistemasInterativos/adapterProtocol.d.ts +3 -0
  98. package/dist/sistemasInterativos/adapterProtocol.js +240 -0
  99. package/dist/sistemasInterativos/advancedCatalog.d.ts +5 -0
  100. package/dist/sistemasInterativos/advancedCatalog.js +442 -0
  101. package/dist/sistemasInterativos/autonomy.d.ts +230 -0
  102. package/dist/sistemasInterativos/autonomy.js +753 -0
  103. package/dist/sistemasInterativos/canonical.d.ts +3 -0
  104. package/dist/sistemasInterativos/canonical.js +43 -0
  105. package/dist/sistemasInterativos/catalog.d.ts +116 -0
  106. package/dist/sistemasInterativos/catalog.js +543 -0
  107. package/dist/sistemasInterativos/command.d.ts +7 -0
  108. package/dist/sistemasInterativos/command.js +311 -0
  109. package/dist/sistemasInterativos/controlRun.d.ts +56 -0
  110. package/dist/sistemasInterativos/controlRun.js +391 -0
  111. package/dist/sistemasInterativos/evidence.d.ts +5 -0
  112. package/dist/sistemasInterativos/evidence.js +306 -0
  113. package/dist/sistemasInterativos/experienceIr.d.ts +12 -0
  114. package/dist/sistemasInterativos/experienceIr.js +895 -0
  115. package/dist/sistemasInterativos/experienceIrSemantics.d.ts +30 -0
  116. package/dist/sistemasInterativos/experienceIrSemantics.js +368 -0
  117. package/dist/sistemasInterativos/experienceIrTypes.d.ts +370 -0
  118. package/dist/sistemasInterativos/experienceIrTypes.js +5 -0
  119. package/dist/sistemasInterativos/extensionCommand.d.ts +391 -0
  120. package/dist/sistemasInterativos/extensionCommand.js +383 -0
  121. package/dist/sistemasInterativos/index.d.ts +19 -0
  122. package/dist/sistemasInterativos/index.js +22 -0
  123. package/dist/sistemasInterativos/operations.d.ts +40 -0
  124. package/dist/sistemasInterativos/operations.js +1167 -0
  125. package/dist/sistemasInterativos/operationsTypes.d.ts +297 -0
  126. package/dist/sistemasInterativos/operationsTypes.js +11 -0
  127. package/dist/sistemasInterativos/planner.d.ts +2 -0
  128. package/dist/sistemasInterativos/planner.js +159 -0
  129. package/dist/sistemasInterativos/portability.d.ts +164 -0
  130. package/dist/sistemasInterativos/portability.js +539 -0
  131. package/dist/sistemasInterativos/render.d.ts +3 -0
  132. package/dist/sistemasInterativos/render.js +179 -0
  133. package/dist/sistemasInterativos/temporal.d.ts +183 -0
  134. package/dist/sistemasInterativos/temporal.js +543 -0
  135. package/dist/sistemasInterativos/types.d.ts +215 -0
  136. package/dist/sistemasInterativos/types.js +4 -0
  137. package/dist/sistemasInterativos/validator.d.ts +2 -0
  138. package/dist/sistemasInterativos/validator.js +305 -0
  139. package/dist/sync/index.js +35 -35
  140. package/docs/README.md +34 -28
  141. package/docs/ai-onboarding.md +62 -62
  142. package/docs/ai-workflow.md +9 -4
  143. package/docs/auth.md +26 -26
  144. package/docs/cli.md +79 -79
  145. package/docs/commands.md +47 -2
  146. package/docs/database.md +15 -15
  147. package/docs/deploy.md +41 -41
  148. package/docs/descoberta-capacidades.md +106 -0
  149. package/docs/documentation.md +39 -39
  150. package/docs/env.md +16 -16
  151. package/docs/frontend.md +41 -41
  152. package/docs/getting-started.md +57 -57
  153. package/docs/i18n.md +15 -15
  154. package/docs/pipeline-conteudo.md +246 -246
  155. package/docs/profiles.md +54 -45
  156. package/docs/repositories.md +43 -43
  157. package/docs/rollback.md +31 -31
  158. package/docs/security.md +32 -32
  159. package/docs/sistemas-interativos.md +376 -0
  160. package/docs/support.md +8 -8
  161. package/docs/testing.md +51 -35
  162. package/docs/vocabulary.md +29 -29
  163. package/exemplos/agendamento.sema +1 -1
  164. package/exemplos/assinatura.sema +1 -1
  165. package/exemplos/auditoria.sema +1 -1
  166. package/exemplos/autenticacao.sema +1 -1
  167. package/exemplos/author_obra_comum.sema +1 -1
  168. package/exemplos/author_tema_sensivel.sema +1 -1
  169. package/exemplos/automacao.sema +1 -1
  170. package/exemplos/cadastro_usuario.sema +1 -1
  171. package/exemplos/calculadora.sema +1 -1
  172. package/exemplos/crud_simples.sema +1 -1
  173. package/exemplos/estoque.sema +1 -1
  174. package/exemplos/exportacao.sema +1 -1
  175. package/exemplos/fila.sema +1 -1
  176. package/exemplos/integracao_externa.sema +1 -1
  177. package/exemplos/multi_tenant.sema +1 -1
  178. package/exemplos/notificacao.sema +1 -1
  179. package/exemplos/operacao_estrategia.sema +132 -132
  180. package/exemplos/operacao_estrategia_discovery.sema +220 -220
  181. package/exemplos/operacao_estrategia_fluxo.sema +114 -114
  182. package/exemplos/operacao_estrategia_gates.sema +106 -106
  183. package/exemplos/operacao_estrategia_quarentena.sema +133 -133
  184. package/exemplos/operacao_estrategia_rollout.sema +124 -124
  185. package/exemplos/pagamento.sema +1 -1
  186. package/exemplos/pagamento_dominio.sema +1 -1
  187. package/exemplos/pedido.sema +1 -1
  188. package/exemplos/permissao.sema +1 -1
  189. package/exemplos/persistencia_vendor_first.sema +1 -1
  190. package/exemplos/pipeline-conteudo/README.md +44 -44
  191. package/exemplos/pipeline-conteudo/alvos.json +23 -23
  192. package/exemplos/pipeline-conteudo/definicao.json +136 -136
  193. package/exemplos/profile_conversas.sema +165 -165
  194. package/exemplos/profile_game.sema +1 -1
  195. package/exemplos/profile_legal.sema +1 -1
  196. package/exemplos/profile_ops.sema +1 -1
  197. package/exemplos/profile_research.sema +1 -1
  198. package/exemplos/profile_simulation.sema +211 -0
  199. package/exemplos/profile_software.sema +1 -1
  200. package/exemplos/profile_workflow_n8n.sema +1 -1
  201. package/exemplos/relatorio.sema +1 -1
  202. package/exemplos/replica_analitica_erp.sema +1 -1
  203. package/exemplos/sistemas-interativos/README.md +100 -0
  204. package/exemplos/sistemas-interativos/advanced/acceptance-context-evaluate-valid.json +5 -0
  205. package/exemplos/sistemas-interativos/advanced/acceptance-lock-valid.json +16 -0
  206. package/exemplos/sistemas-interativos/advanced/asset-provenance-valid.json +32 -0
  207. package/exemplos/sistemas-interativos/advanced/autonomy-repair-valid.json +93 -0
  208. package/exemplos/sistemas-interativos/advanced/control-run-definition-valid.json +78 -0
  209. package/exemplos/sistemas-interativos/advanced/control-run-valid.json +27 -0
  210. package/exemplos/sistemas-interativos/advanced/distributed-workers-valid.json +79 -0
  211. package/exemplos/sistemas-interativos/advanced/editor-state-valid.json +42 -0
  212. package/exemplos/sistemas-interativos/advanced/engine-snapshot-after-valid.json +32 -0
  213. package/exemplos/sistemas-interativos/advanced/engine-snapshot-before-valid.json +23 -0
  214. package/exemplos/sistemas-interativos/advanced/job-orchestration-valid.json +39 -0
  215. package/exemplos/sistemas-interativos/advanced/multimodal-evidence-valid.json +46 -0
  216. package/exemplos/sistemas-interativos/advanced/multiplayer-authority-valid.json +39 -0
  217. package/exemplos/sistemas-interativos/advanced/playtest-fuzz-valid.json +37 -0
  218. package/exemplos/sistemas-interativos/advanced/portability-valid.json +104 -0
  219. package/exemplos/sistemas-interativos/advanced/temporal-evidence-valid.json +27 -0
  220. package/exemplos/sistemas-interativos/advanced/temporal-valid.json +118 -0
  221. package/exemplos/sistemas-interativos/experience-ir-valid.json +459 -0
  222. package/exemplos/sistemas-interativos/game-2d.json +83 -0
  223. package/exemplos/sistemas-interativos/game-3d-human.json +81 -0
  224. package/exemplos/sistemas-interativos/game-pixel-16-bit.json +97 -0
  225. package/exemplos/sistemas-interativos/game-pixel-8-bit.json +94 -0
  226. package/exemplos/sistemas-interativos/game-xr-human.json +80 -0
  227. package/exemplos/sistemas-interativos/hybrid-2-5d.json +108 -0
  228. package/exemplos/sistemas-interativos/protocol-mutating-rollback-valid.json +75 -0
  229. package/exemplos/sistemas-interativos/protocol-read-only-valid.json +58 -0
  230. package/exemplos/sistemas-interativos/simulation-2d-controlled.json +97 -0
  231. package/exemplos/sistemas-interativos/simulation-3d-calibrated-autonomous.json +141 -0
  232. package/exemplos/sistemas-interativos/simulation-headless-autonomous-batch.json +112 -0
  233. package/exemplos/sistemas-interativos/simulation-pixel-16-bit.json +103 -0
  234. package/exemplos/sistemas-interativos/simulation-text-controlled.json +95 -0
  235. package/exemplos/testes_embutidos.sema +1 -1
  236. package/exemplos/tratamento_erro.sema +1 -1
  237. package/exemplos/upload_arquivo.sema +1 -1
  238. package/exemplos/webhook.sema +1 -1
  239. package/node_modules/@sema/gerador-cpp/dist/index.js +176 -176
  240. package/node_modules/@sema/gerador-cpp/package.json +1 -1
  241. package/node_modules/@sema/gerador-css/dist/index.part01.js +10 -10
  242. package/node_modules/@sema/gerador-css/dist/index.part02.js +460 -460
  243. package/node_modules/@sema/gerador-dotnet/dist/index.js +169 -169
  244. package/node_modules/@sema/gerador-dotnet/package.json +1 -1
  245. package/node_modules/@sema/gerador-html/dist/index.js +17 -17
  246. package/node_modules/@sema/gerador-lua/dist/index.js +76 -47
  247. package/node_modules/@sema/gerador-lua/dist/index.js.map +1 -1
  248. package/node_modules/@sema/gerador-php/dist/index.js +113 -113
  249. package/node_modules/@sema/gerador-python/dist/index.part02.js +3 -3
  250. package/node_modules/@sema/gerador-typescript/dist/index.part02.js +11 -11
  251. package/node_modules/@sema/nucleo/dist/diagnosticos/melhorador.js +42 -42
  252. package/package.json +3 -3
@@ -0,0 +1,753 @@
1
+ // SEMA-GOVERNED: sema.produto.sistemas_interativos.autonomia + sema.produto.sistemas_interativos.testes_autonomos
2
+ // Descricao: validadores locais para reparo autonomo elegivel, playtest/fuzz bounded e autoridade multiplayer.
3
+ import { digestJsonSistemaInterativo, digestSha256Valido } from "./canonical.js";
4
+ import { validarAcceptanceLock } from "./operations.js";
5
+ export const SCHEMA_AUTONOMIA = "sema.interactive.autonomy/v1";
6
+ export const SCHEMA_PLAYTEST_FUZZ = "sema.interactive.playtest-fuzz/v1";
7
+ export const SCHEMA_AUTORIDADE_MULTIPLAYER = "sema.interactive.multiplayer-authority/v1";
8
+ const ID = /^[a-z0-9][a-z0-9._:/-]{0,127}$/;
9
+ const VERSAO = /^[0-9]+\.[0-9]+\.[0-9]+(?:[-+][a-z0-9.-]+)?$/i;
10
+ const TOKEN_RECOVERY = /^sha256:[a-f0-9]{64}$/;
11
+ const CHAVE_SENSIVEL = /(?:password|passwd|senha|secret|token|api.?key|private.?key|credential|authorization|cookie)/i;
12
+ const VALORES_SENSIVEIS = [
13
+ /\bbearer\s+[a-z0-9._~+\/-]{8,}/i,
14
+ /^(?:sk[-_][a-z0-9_-]{8,}|ghp_[a-z0-9]{20,}|github_pat_[a-z0-9_]{20,})$/i,
15
+ /^eyJ[a-z0-9_-]{8,}\.eyJ[a-z0-9_-]{8,}\.[a-z0-9_-]{8,}$/i,
16
+ /\b(?:AKIA|ASIA)[A-Z0-9]{16}\b/,
17
+ /-----BEGIN [A-Z0-9 ]*(?:PRIVATE KEY|CERTIFICATE)-----/,
18
+ /(?:^|[?&])(?:access_?token|api_?key|aws_?secret_?access_?key|secret|password|passwd|signature|sig|token|credential|authorization)=[^&#\s]+/i,
19
+ /:\/\/[^/\s:@]+:[^/\s@]+@/,
20
+ ];
21
+ const RISCOS = new Set(["OBSERVATION_ONLY", "SAFE_REVERSIBLE", "PRIVILEGED", "IRREVERSIBLE"]);
22
+ const MODOS = new Set(["OBSERVE_ONLY", "SUGGEST", "SAFE_APPLY_EXTERNAL"]);
23
+ const DECISOES = new Set(["PASS", "FAIL", "INCONCLUSIVE"]);
24
+ function objeto(valor) {
25
+ return typeof valor === "object" && valor !== null && !Array.isArray(valor);
26
+ }
27
+ function texto(valor) {
28
+ return typeof valor === "string" && valor.trim().length > 0;
29
+ }
30
+ function id(valor) {
31
+ return typeof valor === "string" && ID.test(valor);
32
+ }
33
+ function positivo(valor) {
34
+ return typeof valor === "number" && Number.isFinite(valor) && valor > 0;
35
+ }
36
+ function inteiroNaoNegativo(valor) {
37
+ return typeof valor === "number" && Number.isInteger(valor) && valor >= 0;
38
+ }
39
+ function inteiroPositivo(valor) {
40
+ return typeof valor === "number" && Number.isInteger(valor) && valor > 0;
41
+ }
42
+ function faixaTempoAcceptanceValida(valor) {
43
+ return objeto(valor)
44
+ && somenteChaves(valor, ["start", "end", "unit"])
45
+ && typeof valor.start === "number"
46
+ && Number.isFinite(valor.start)
47
+ && valor.start >= 0
48
+ && typeof valor.end === "number"
49
+ && Number.isFinite(valor.end)
50
+ && valor.end > valor.start
51
+ && ["FRAME", "TICK", "SECOND"].includes(String(valor.unit));
52
+ }
53
+ function listaUnica(valor, validar, permitirVazia = false) {
54
+ return Array.isArray(valor)
55
+ && (permitirVazia || valor.length > 0)
56
+ && valor.every(validar)
57
+ && new Set(valor).size === valor.length;
58
+ }
59
+ function idsUnicos(valores) {
60
+ return valores.every(id) && new Set(valores).size === valores.length;
61
+ }
62
+ function somenteChaves(valor, permitidas) {
63
+ const allowlist = new Set(permitidas);
64
+ return Object.keys(valor).every((chave) => allowlist.has(chave));
65
+ }
66
+ function valorSensivel(valor) {
67
+ if (digestSha256Valido(valor) || /^opaque:sha256:[a-f0-9]{64}$/.test(valor))
68
+ return false;
69
+ return VALORES_SENSIVEIS.some((padrao) => padrao.test(valor));
70
+ }
71
+ function contemSensivel(valor, visitados = new Set()) {
72
+ if (typeof valor === "string")
73
+ return valorSensivel(valor);
74
+ if (!objeto(valor) && !Array.isArray(valor))
75
+ return false;
76
+ if (visitados.has(valor))
77
+ return true;
78
+ visitados.add(valor);
79
+ try {
80
+ if (Array.isArray(valor))
81
+ return valor.some((item) => contemSensivel(item, visitados));
82
+ return Object.entries(valor).some(([chave, item]) => {
83
+ if (chave === "recoveryToken" && digestSha256Valido(item))
84
+ return false;
85
+ return CHAVE_SENSIVEL.test(chave) || contemSensivel(item, visitados);
86
+ });
87
+ }
88
+ finally {
89
+ visitados.delete(valor);
90
+ }
91
+ }
92
+ function exigir(bloqueios, condicao, codigo) {
93
+ if (!condicao)
94
+ bloqueios.push(codigo);
95
+ }
96
+ function digestSeguro(valor, bloqueios, codigo) {
97
+ try {
98
+ return digestJsonSistemaInterativo(valor);
99
+ }
100
+ catch {
101
+ bloqueios.push(codigo);
102
+ return "sha256:invalid";
103
+ }
104
+ }
105
+ function causaPorInvariante(invariante) {
106
+ if (invariante.includes("camera"))
107
+ return ["camera_target_or_shot_contract_diverged"];
108
+ if (invariante.includes("physics") || invariante.includes("collision"))
109
+ return ["physics_relation_diverged"];
110
+ if (invariante.includes("audio") || invariante.includes("speech"))
111
+ return ["timeline_audio_sync_diverged"];
112
+ if (invariante.includes("save"))
113
+ return ["state_persistence_diverged"];
114
+ return ["observed_state_diverged_from_contract"];
115
+ }
116
+ export function tokenRecuperacaoEsperado(ciclo) {
117
+ return digestJsonSistemaInterativo({
118
+ runId: ciclo.runId,
119
+ cycleIndex: ciclo.cycleIndex,
120
+ previousCycleDigest: ciclo.previousCycleDigest,
121
+ checkpoints: ciclo.proposals.filter((item) => item.mutates).map((item) => item.checkpointDigest).sort(),
122
+ });
123
+ }
124
+ export function digestAcceptanceLocksAutonomia(locks) {
125
+ return digestJsonSistemaInterativo([...locks].map((item) => ({
126
+ lock: {
127
+ ...item.lock,
128
+ timeRange: { ...item.lock.timeRange },
129
+ approver: { ...item.lock.approver },
130
+ ...(item.lock.invalidation === undefined ? {} : { invalidation: { ...item.lock.invalidation } }),
131
+ },
132
+ lockDigest: item.lockDigest,
133
+ ...(item.invalidationEvidenceDigest === undefined ? {} : { invalidationEvidenceDigest: item.invalidationEvidenceDigest }),
134
+ })).sort((a, b) => a.lock.lockId.localeCompare(b.lock.lockId)));
135
+ }
136
+ export function digestAcceptanceClaimAutonomia(claim) {
137
+ return digestJsonSistemaInterativo({ ...claim, timeRange: { ...claim.timeRange } });
138
+ }
139
+ export function validarCicloReparoAutonomo(entrada) {
140
+ const bloqueios = [];
141
+ const elegiveis = [];
142
+ const bloqueados = [];
143
+ const diagnosticosSaida = [];
144
+ if (!objeto(entrada)) {
145
+ return {
146
+ valido: false, cycleDigest: "sha256:invalid", eligibleSafePatches: [], blockedPatches: [], diagnostics: [],
147
+ nextActions: ["corrigir_ciclo_autonomia"], completed: false, authoritative: false, executed: false, bloqueios: ["ciclo_invalido"],
148
+ };
149
+ }
150
+ const entradaSensivel = contemSensivel(entrada);
151
+ if (entradaSensivel)
152
+ bloqueios.push("ciclo_contem_dado_sensivel");
153
+ exigir(bloqueios, somenteChaves(entrada, [
154
+ "schemaVersion", "runId", "cycleIndex", "previousCycleDigest", "triggeredStopCriteria", "systemId",
155
+ "definitionDigest", "policy", "diagnostics", "proposals", "simulations", "proofs", "resourceLocks",
156
+ "acceptanceLocks", "acceptanceLocksDigest", "acceptanceClaims", "recoveryToken",
157
+ ]), "campos_top_level_desconhecidos");
158
+ exigir(bloqueios, entrada.schemaVersion === SCHEMA_AUTONOMIA, "schema_version_nao_suportada");
159
+ exigir(bloqueios, id(entrada.runId), "run_id_invalido");
160
+ const cycleIndexValido = inteiroPositivo(entrada.cycleIndex);
161
+ const cycleIndex = cycleIndexValido ? entrada.cycleIndex : 0;
162
+ exigir(bloqueios, cycleIndexValido, "cycle_index_invalido");
163
+ const previousCycleDigestValido = cycleIndexValido && (cycleIndex === 1
164
+ ? entrada.previousCycleDigest === "GENESIS"
165
+ : digestSha256Valido(entrada.previousCycleDigest));
166
+ exigir(bloqueios, previousCycleDigestValido, "previous_cycle_digest_invalido");
167
+ exigir(bloqueios, id(entrada.systemId), "system_id_invalido");
168
+ exigir(bloqueios, digestSha256Valido(entrada.definitionDigest), "definition_digest_invalido");
169
+ const policy = entrada.policy;
170
+ const policyValida = objeto(policy)
171
+ && MODOS.has(policy.mode)
172
+ && Number.isInteger(policy.maxCycles)
173
+ && policy.maxCycles > 0
174
+ && listaUnica(policy.stopCriteria, texto)
175
+ && listaUnica(policy.allowedRiskClasses, (item) => RISCOS.has(item))
176
+ && listaUnica(policy.requireHumanApprovalFor, (item) => RISCOS.has(item), true)
177
+ && policy.requireHumanApprovalFor.includes("PRIVILEGED")
178
+ && policy.requireHumanApprovalFor.includes("IRREVERSIBLE");
179
+ exigir(bloqueios, policyValida, "policy_invalida");
180
+ const policyTipada = policyValida ? policy : undefined;
181
+ const cycleDentroDoLimite = Boolean(policyTipada && cycleIndexValido && cycleIndex <= policyTipada.maxCycles);
182
+ exigir(bloqueios, cycleDentroDoLimite, "cycle_index_excede_max_cycles");
183
+ const triggeredStopCriteriaValidos = listaUnica(entrada.triggeredStopCriteria, texto, true)
184
+ && policyTipada !== undefined
185
+ && entrada.triggeredStopCriteria.every((criterion) => policyTipada.stopCriteria.includes(criterion));
186
+ exigir(bloqueios, triggeredStopCriteriaValidos, "triggered_stop_criteria_invalidos");
187
+ const stopCriteriaAcionado = triggeredStopCriteriaValidos && entrada.triggeredStopCriteria.length > 0;
188
+ if (stopCriteriaAcionado)
189
+ bloqueios.push("stop_criteria_ja_acionado");
190
+ const cicloPodeProsseguir = cycleDentroDoLimite && previousCycleDigestValido && !stopCriteriaAcionado;
191
+ const diagnostics = Array.isArray(entrada.diagnostics) ? entrada.diagnostics : [];
192
+ exigir(bloqueios, diagnostics.length > 0, "diagnostics_ausentes");
193
+ exigir(bloqueios, idsUnicos(diagnostics.map((item) => objeto(item) ? item.diagnosticId : undefined)), "diagnostic_ids_invalidos_ou_duplicados");
194
+ const diagnosticIds = new Set();
195
+ const diagnosticTargets = new Map();
196
+ for (const item of diagnostics) {
197
+ const valido = objeto(item)
198
+ && id(item.diagnosticId)
199
+ && id(item.failedInvariant)
200
+ && id(item.phase)
201
+ && listaUnica(item.evidenceIds, id)
202
+ && id(item.semanticTargetId);
203
+ exigir(bloqueios, valido, "diagnostic_invalido");
204
+ if (valido) {
205
+ const tipado = item;
206
+ diagnosticIds.add(tipado.diagnosticId);
207
+ diagnosticTargets.set(tipado.diagnosticId, tipado.semanticTargetId);
208
+ diagnosticosSaida.push({
209
+ failedInvariant: tipado.failedInvariant,
210
+ phase: tipado.phase,
211
+ evidenceIds: tipado.evidenceIds,
212
+ likelyCauses: causaPorInvariante(tipado.failedInvariant),
213
+ nextActions: [`propor_patch_sem_apply:${tipado.diagnosticId}`],
214
+ });
215
+ }
216
+ }
217
+ const locks = Array.isArray(entrada.resourceLocks) ? entrada.resourceLocks : [];
218
+ exigir(bloqueios, idsUnicos(locks.map((item) => objeto(item) ? item.lockId : undefined)), "lock_ids_invalidos_ou_duplicados");
219
+ const locksPorId = new Map();
220
+ for (const lock of locks) {
221
+ const baseValido = objeto(lock)
222
+ && id(lock.lockId)
223
+ && ["GPU", "EDITOR", "CACHE"].includes(String(lock.resourceType))
224
+ && id(lock.ownerRunId)
225
+ && id(lock.ownerJobId)
226
+ && digestSha256Valido(lock.checkpointDigest);
227
+ exigir(bloqueios, baseValido, "resource_lock_invalido");
228
+ if (!baseValido)
229
+ continue;
230
+ const tipado = lock;
231
+ if (tipado.ownerRunId !== entrada.runId) {
232
+ bloqueios.push("resource_lock_owner_run_divergente");
233
+ continue;
234
+ }
235
+ locksPorId.set(tipado.lockId, tipado);
236
+ }
237
+ const proposals = Array.isArray(entrada.proposals) ? entrada.proposals : [];
238
+ exigir(bloqueios, proposals.length > 0, "proposals_ausentes");
239
+ exigir(bloqueios, idsUnicos(proposals.map((item) => objeto(item) ? item.patchId : undefined)), "patch_ids_invalidos_ou_duplicados");
240
+ const propostasValidas = new Map();
241
+ const patchesReversiveis = new Set();
242
+ const diagnosticsCobertos = new Set();
243
+ for (const proposal of proposals) {
244
+ const baseValida = objeto(proposal)
245
+ && id(proposal.patchId)
246
+ && id(proposal.diagnosticId)
247
+ && diagnosticIds.has(proposal.diagnosticId)
248
+ && id(proposal.semanticTargetId)
249
+ && id(proposal.ownerJobId)
250
+ && id(proposal.adapterId)
251
+ && typeof proposal.adapterVersion === "string"
252
+ && VERSAO.test(proposal.adapterVersion)
253
+ && texto(proposal.operation)
254
+ && RISCOS.has(proposal.riskClass)
255
+ && typeof proposal.mutates === "boolean"
256
+ && typeof proposal.humanApproved === "boolean"
257
+ && digestSha256Valido(proposal.inputDigest)
258
+ && objeto(proposal.mutationScope)
259
+ && somenteChaves(proposal.mutationScope, ["artifactDigest", "sceneId", "timeRange"])
260
+ && digestSha256Valido(proposal.mutationScope.artifactDigest)
261
+ && id(proposal.mutationScope.sceneId)
262
+ && faixaTempoAcceptanceValida(proposal.mutationScope.timeRange)
263
+ && Array.isArray(proposal.resourceLockIds)
264
+ && proposal.resourceLockIds.every(id)
265
+ && new Set(proposal.resourceLockIds).size === proposal.resourceLockIds.length;
266
+ exigir(bloqueios, baseValida, "proposal_invalida");
267
+ if (!baseValida)
268
+ continue;
269
+ const tipada = proposal;
270
+ if (diagnosticTargets.get(tipada.diagnosticId) !== tipada.semanticTargetId) {
271
+ bloqueios.push("proposal_target_diverge_diagnostico");
272
+ continue;
273
+ }
274
+ if (tipada.inputDigest !== entrada.definitionDigest) {
275
+ bloqueios.push("proposal_input_digest_diverge_definition");
276
+ continue;
277
+ }
278
+ diagnosticsCobertos.add(tipada.diagnosticId);
279
+ propostasValidas.set(tipada.patchId, tipada);
280
+ const locksCoerentes = tipada.resourceLockIds.length > 0
281
+ && tipada.resourceLockIds.every((lockId) => {
282
+ const lock = locksPorId.get(lockId);
283
+ if (!lock)
284
+ return false;
285
+ return lock.ownerRunId === entrada.runId
286
+ && lock.ownerJobId === tipada.ownerJobId
287
+ && lock.checkpointDigest === tipada.checkpointDigest
288
+ && lock.checkpointDigest === tipada.snapshotDigest;
289
+ });
290
+ if (tipada.mutates && !locksCoerentes)
291
+ bloqueios.push("resource_lock_owner_ou_checkpoint_divergente");
292
+ const reversivel = !tipada.mutates || (digestSha256Valido(tipada.snapshotDigest)
293
+ && digestSha256Valido(tipada.checkpointDigest)
294
+ && digestSha256Valido(tipada.rollbackPlanDigest)
295
+ && locksCoerentes);
296
+ exigir(bloqueios, reversivel, "patch_mutante_sem_snapshot_checkpoint_rollback_ou_lock");
297
+ if (reversivel)
298
+ patchesReversiveis.add(tipada.patchId);
299
+ if (tipada.riskClass === "OBSERVATION_ONLY" && tipada.mutates)
300
+ bloqueios.push("observation_only_nao_pode_mutar");
301
+ if (tipada.riskClass === "PRIVILEGED" || tipada.riskClass === "IRREVERSIBLE") {
302
+ if (!tipada.humanApproved)
303
+ bloqueios.push("patch_risco_alto_sem_aprovacao_humana");
304
+ bloqueados.push(tipada.patchId);
305
+ }
306
+ }
307
+ for (const diagnosticId of diagnosticTargets.keys()) {
308
+ if (!diagnosticsCobertos.has(diagnosticId))
309
+ bloqueios.push("diagnostic_sem_proposal_valida");
310
+ }
311
+ const acceptanceLocksBrutos = Array.isArray(entrada.acceptanceLocks) ? entrada.acceptanceLocks : [];
312
+ exigir(bloqueios, idsUnicos(acceptanceLocksBrutos.map((item) => objeto(item) && objeto(item.lock) ? item.lock.lockId : undefined)), "acceptance_lock_ids_invalidos_ou_duplicados");
313
+ const acceptanceLocks = [];
314
+ for (const item of acceptanceLocksBrutos) {
315
+ const lockResult = objeto(item) ? validarAcceptanceLock(item.lock) : undefined;
316
+ let valido = objeto(item)
317
+ && somenteChaves(item, ["lock", "lockDigest", "invalidationEvidenceDigest"])
318
+ && Boolean(lockResult?.valid && lockResult.value)
319
+ && digestSha256Valido(item.lockDigest)
320
+ && item.lockDigest === lockResult?.value?.lockDigest;
321
+ if (valido && lockResult?.value) {
322
+ const lock = lockResult.value.lock;
323
+ if (lock.status === "ACTIVE")
324
+ valido = item.invalidationEvidenceDigest === undefined;
325
+ else {
326
+ const { invalidation: _invalidation, ...base } = lock;
327
+ const previousResult = validarAcceptanceLock({ ...base, status: "ACTIVE" });
328
+ valido = digestSha256Valido(item.invalidationEvidenceDigest)
329
+ && Boolean(previousResult.value
330
+ && lock.invalidation?.previousLockDigest === previousResult.value.lockDigest
331
+ && Date.parse(lock.invalidation.invalidatedAt) >= Date.parse(lock.createdAt));
332
+ }
333
+ }
334
+ exigir(bloqueios, valido, "acceptance_lock_invalido");
335
+ if (valido && objeto(item) && lockResult?.value)
336
+ acceptanceLocks.push({
337
+ lock: lockResult.value.lock,
338
+ lockDigest: lockResult.value.lockDigest,
339
+ ...(item.invalidationEvidenceDigest === undefined ? {} : { invalidationEvidenceDigest: item.invalidationEvidenceDigest }),
340
+ });
341
+ }
342
+ const acceptanceLocksDigestValido = digestSha256Valido(entrada.acceptanceLocksDigest)
343
+ && entrada.acceptanceLocksDigest === digestAcceptanceLocksAutonomia(acceptanceLocks);
344
+ exigir(bloqueios, acceptanceLocksDigestValido, "acceptance_locks_digest_divergente");
345
+ const acceptanceClaimsBrutos = Array.isArray(entrada.acceptanceClaims) ? entrada.acceptanceClaims : [];
346
+ exigir(bloqueios, idsUnicos(acceptanceClaimsBrutos.map((item) => objeto(item) ? item.claimId : undefined)), "acceptance_claim_ids_invalidos_ou_duplicados");
347
+ const claimsPorPatch = new Map();
348
+ for (const claim of acceptanceClaimsBrutos) {
349
+ const baseValida = objeto(claim)
350
+ && somenteChaves(claim, ["claimId", "patchId", "artifactDigest", "sceneId", "timeRange", "acceptanceLocksDigest", "claimDigest"])
351
+ && id(claim.claimId)
352
+ && id(claim.patchId)
353
+ && propostasValidas.has(claim.patchId)
354
+ && digestSha256Valido(claim.artifactDigest)
355
+ && id(claim.sceneId)
356
+ && faixaTempoAcceptanceValida(claim.timeRange)
357
+ && digestSha256Valido(claim.acceptanceLocksDigest)
358
+ && claim.acceptanceLocksDigest === entrada.acceptanceLocksDigest
359
+ && digestSha256Valido(claim.claimDigest);
360
+ let valida = baseValida;
361
+ if (baseValida) {
362
+ const tipada = claim;
363
+ valida = tipada.claimDigest === digestAcceptanceClaimAutonomia({
364
+ claimId: tipada.claimId,
365
+ patchId: tipada.patchId,
366
+ artifactDigest: tipada.artifactDigest,
367
+ sceneId: tipada.sceneId,
368
+ timeRange: tipada.timeRange,
369
+ acceptanceLocksDigest: tipada.acceptanceLocksDigest,
370
+ }) && !claimsPorPatch.has(tipada.patchId)
371
+ && tipada.artifactDigest === propostasValidas.get(tipada.patchId)?.mutationScope.artifactDigest
372
+ && tipada.sceneId === propostasValidas.get(tipada.patchId)?.mutationScope.sceneId
373
+ && tipada.timeRange.start === propostasValidas.get(tipada.patchId)?.mutationScope.timeRange.start
374
+ && tipada.timeRange.end === propostasValidas.get(tipada.patchId)?.mutationScope.timeRange.end
375
+ && tipada.timeRange.unit === propostasValidas.get(tipada.patchId)?.mutationScope.timeRange.unit;
376
+ if (valida)
377
+ claimsPorPatch.set(tipada.patchId, tipada);
378
+ }
379
+ exigir(bloqueios, valida, "acceptance_claim_invalido_ou_duplicado_por_patch");
380
+ }
381
+ const patchesLiberadosPorAcceptance = new Set();
382
+ for (const proposal of propostasValidas.values()) {
383
+ const claim = claimsPorPatch.get(proposal.patchId);
384
+ if (!claim || !acceptanceLocksDigestValido) {
385
+ bloqueios.push("patch_sem_acceptance_claim_content_addressed");
386
+ continue;
387
+ }
388
+ const locksMesmoBinding = acceptanceLocks.map((item) => item.lock).filter((lock) => lock.status === "ACTIVE"
389
+ && lock.artifactDigest === claim.artifactDigest && lock.sceneId === claim.sceneId);
390
+ const unidadeAmbigua = locksMesmoBinding.some((lock) => lock.timeRange.unit !== claim.timeRange.unit);
391
+ const sobreposto = locksMesmoBinding.some((lock) => lock.timeRange.unit === claim.timeRange.unit
392
+ && claim.timeRange.start < lock.timeRange.end && lock.timeRange.start < claim.timeRange.end);
393
+ if (unidadeAmbigua || sobreposto) {
394
+ bloqueios.push(unidadeAmbigua ? "acceptance_lock_time_unit_ambigua" : "patch_toca_acceptance_lock_ativo");
395
+ bloqueados.push(proposal.patchId);
396
+ }
397
+ else
398
+ patchesLiberadosPorAcceptance.add(proposal.patchId);
399
+ }
400
+ const simulations = Array.isArray(entrada.simulations) ? entrada.simulations : [];
401
+ exigir(bloqueios, idsUnicos(simulations.map((item) => objeto(item) ? item.simulationId : undefined)), "simulation_ids_invalidos_ou_duplicados");
402
+ const simulacoes = new Map();
403
+ for (const simulation of simulations) {
404
+ const valido = objeto(simulation)
405
+ && id(simulation.simulationId)
406
+ && id(simulation.patchId)
407
+ && propostasValidas.has(simulation.patchId)
408
+ && digestSha256Valido(simulation.sandboxDigest)
409
+ && digestSha256Valido(simulation.resultDigest)
410
+ && typeof simulation.passed === "boolean"
411
+ && Array.isArray(simulation.evidenceDigests)
412
+ && simulation.evidenceDigests.length > 0
413
+ && simulation.evidenceDigests.every(digestSha256Valido);
414
+ exigir(bloqueios, valido, "simulation_invalida");
415
+ if (valido) {
416
+ const tipada = simulation;
417
+ simulacoes.set(tipada.simulationId, tipada);
418
+ }
419
+ }
420
+ const proofs = Array.isArray(entrada.proofs) ? entrada.proofs : [];
421
+ exigir(bloqueios, idsUnicos(proofs.map((item) => objeto(item) ? item.proofId : undefined)), "proof_ids_invalidos_ou_duplicados");
422
+ const provasPorPatch = new Map();
423
+ for (const proof of proofs) {
424
+ const simulacao = objeto(proof) && id(proof.simulationId) ? simulacoes.get(proof.simulationId) : undefined;
425
+ const proposta = objeto(proof) && id(proof.patchId) ? propostasValidas.get(proof.patchId) : undefined;
426
+ const valido = objeto(proof)
427
+ && id(proof.proofId)
428
+ && id(proof.patchId)
429
+ && propostasValidas.has(proof.patchId)
430
+ && Boolean(simulacao && simulacao.patchId === proof.patchId)
431
+ && id(proof.verifierId)
432
+ && Boolean(proposta && proof.verifierId !== proposta.adapterId)
433
+ && proof.independentOfProducer === true
434
+ && Array.isArray(proof.evidenceDigests)
435
+ && proof.evidenceDigests.length > 0
436
+ && proof.evidenceDigests.every(digestSha256Valido)
437
+ && DECISOES.has(proof.decision);
438
+ exigir(bloqueios, valido, "proof_invalida");
439
+ if (valido) {
440
+ const tipada = proof;
441
+ provasPorPatch.set(tipada.patchId, tipada);
442
+ }
443
+ }
444
+ for (const proposal of propostasValidas.values()) {
445
+ if (!proposal.mutates)
446
+ continue;
447
+ const simulacao = [...simulacoes.values()].find((item) => item.patchId === proposal.patchId);
448
+ if (!simulacao)
449
+ bloqueios.push("patch_mutante_sem_simulation");
450
+ if (!provasPorPatch.has(proposal.patchId))
451
+ bloqueios.push("patch_mutante_sem_proof_independente");
452
+ }
453
+ if (policyValida) {
454
+ for (const proposal of propostasValidas.values()) {
455
+ const simulacao = [...simulacoes.values()].find((item) => item.patchId === proposal.patchId);
456
+ const proof = provasPorPatch.get(proposal.patchId);
457
+ const seguro = proposal.riskClass === "SAFE_REVERSIBLE"
458
+ && proposal.mutates
459
+ && policy.mode === "SAFE_APPLY_EXTERNAL"
460
+ && cicloPodeProsseguir
461
+ && policy.allowedRiskClasses.includes("SAFE_REVERSIBLE")
462
+ && patchesReversiveis.has(proposal.patchId)
463
+ && patchesLiberadosPorAcceptance.has(proposal.patchId)
464
+ && Boolean(simulacao?.passed)
465
+ && proof?.decision === "PASS";
466
+ if (seguro)
467
+ elegiveis.push(proposal.patchId);
468
+ else if (proposal.riskClass !== "OBSERVATION_ONLY" && !bloqueados.includes(proposal.patchId))
469
+ bloqueados.push(proposal.patchId);
470
+ }
471
+ }
472
+ exigir(bloqueios, TOKEN_RECOVERY.test(String(entrada.recoveryToken)), "recovery_token_invalido");
473
+ if (id(entrada.runId) && proposals.every(objeto)) {
474
+ try {
475
+ exigir(bloqueios, entrada.recoveryToken === tokenRecuperacaoEsperado(entrada), "recovery_token_checkpoint_divergente");
476
+ }
477
+ catch {
478
+ bloqueios.push("recovery_token_nao_derivavel");
479
+ }
480
+ }
481
+ const cycleDigest = digestSeguro(entrada, bloqueios, "ciclo_nao_canonicalizavel");
482
+ const bloqueiosUnicos = [...new Set(bloqueios)].sort();
483
+ const valido = bloqueiosUnicos.length === 0;
484
+ const elegiveisFinais = valido ? [...new Set(elegiveis)].sort() : [];
485
+ const bloqueadosFinais = entradaSensivel ? [] : [...new Set(bloqueados)].sort();
486
+ const nextActions = valido
487
+ ? [...bloqueadosFinais.map((patchId) => `revisar_ou_rejeitar_patch:${patchId}`),
488
+ ...elegiveisFinais.map((patchId) => `entregar_patch_ao_runner_externo_autorizado:${patchId}`)]
489
+ : ["corrigir_ciclo_autonomia"];
490
+ if (nextActions.length === 0)
491
+ nextActions.push("corrigir_ciclo_autonomia");
492
+ return {
493
+ valido,
494
+ cycleDigest,
495
+ eligibleSafePatches: elegiveisFinais,
496
+ blockedPatches: bloqueadosFinais,
497
+ diagnostics: entradaSensivel ? [] : diagnosticosSaida,
498
+ nextActions,
499
+ completed: false,
500
+ authoritative: false,
501
+ executed: false,
502
+ bloqueios: bloqueiosUnicos,
503
+ };
504
+ }
505
+ const STOP_FUZZ = ["CRASH", "HANG", "RESOURCE_EXHAUSTION", "INVARIANT_FAILURE"];
506
+ const EVIDENCIAS_FUZZ = ["runtime.boot", "runtime.loop", "runtime.failure", "runtime.replay", "state.digest", "crash.trace"];
507
+ export function validarPlanoPlaytestFuzz(entrada) {
508
+ const bloqueios = [];
509
+ const scenarioIds = [];
510
+ if (!objeto(entrada)) {
511
+ return { valido: false, planDigest: "sha256:invalid", scenarioIds: [], nextActions: ["corrigir_plano_playtest_fuzz"], authoritative: false, executed: false, bloqueios: ["plano_invalido"] };
512
+ }
513
+ if (contemSensivel(entrada))
514
+ bloqueios.push("plano_contem_dado_sensivel");
515
+ exigir(bloqueios, somenteChaves(entrada, [
516
+ "schemaVersion", "planId", "systemId", "definitionDigest", "bots", "inputActions", "stateCheckpoints",
517
+ "saveLoadCases", "fuzzBounds", "stopCriteria", "evidenceRequirements",
518
+ ]), "campos_top_level_desconhecidos");
519
+ exigir(bloqueios, entrada.schemaVersion === SCHEMA_PLAYTEST_FUZZ, "schema_version_nao_suportada");
520
+ exigir(bloqueios, id(entrada.planId), "plan_id_invalido");
521
+ exigir(bloqueios, id(entrada.systemId), "system_id_invalido");
522
+ exigir(bloqueios, digestSha256Valido(entrada.definitionDigest), "definition_digest_invalido");
523
+ const actions = Array.isArray(entrada.inputActions) ? entrada.inputActions : [];
524
+ exigir(bloqueios, idsUnicos(actions.map((item) => objeto(item) ? item.actionId : undefined)), "action_ids_invalidos_ou_duplicados");
525
+ const actionIds = new Set();
526
+ for (const action of actions) {
527
+ const valido = objeto(action)
528
+ && id(action.actionId)
529
+ && ["BUTTON", "AXIS", "POINTER", "TEXT"].includes(String(action.type))
530
+ && typeof action.minimum === "number"
531
+ && Number.isFinite(action.minimum)
532
+ && typeof action.maximum === "number"
533
+ && Number.isFinite(action.maximum)
534
+ && action.minimum <= action.maximum;
535
+ exigir(bloqueios, valido, "input_action_invalida");
536
+ if (valido)
537
+ actionIds.add(action.actionId);
538
+ }
539
+ const bots = Array.isArray(entrada.bots) ? entrada.bots : [];
540
+ exigir(bloqueios, bots.length > 0, "bots_ausentes");
541
+ exigir(bloqueios, idsUnicos(bots.map((item) => objeto(item) ? item.botId : undefined)), "bot_ids_invalidos_ou_duplicados");
542
+ const botsValidos = [];
543
+ for (const bot of bots) {
544
+ const valido = objeto(bot)
545
+ && id(bot.botId)
546
+ && ["EXPLORER", "GOAL", "ADVERSARIAL", "REGRESSION"].includes(String(bot.strategy))
547
+ && inteiroNaoNegativo(bot.seed)
548
+ && inteiroPositivo(bot.maxSteps)
549
+ && listaUnica(bot.permissions, id)
550
+ && bot.permissions.every((permission) => actionIds.has(permission));
551
+ exigir(bloqueios, valido, "bot_invalido_ou_permissao_fora_da_allowlist");
552
+ if (valido)
553
+ botsValidos.push(bot);
554
+ }
555
+ const checkpoints = Array.isArray(entrada.stateCheckpoints) ? entrada.stateCheckpoints : [];
556
+ exigir(bloqueios, idsUnicos(checkpoints.map((item) => objeto(item) ? item.checkpointId : undefined)), "checkpoint_ids_invalidos_ou_duplicados");
557
+ const checkpointIds = new Set();
558
+ const checkpointPorId = new Map();
559
+ for (const checkpoint of checkpoints) {
560
+ const valido = objeto(checkpoint)
561
+ && id(checkpoint.checkpointId)
562
+ && ["BEFORE", "AFTER"].includes(String(checkpoint.phase))
563
+ && digestSha256Valido(checkpoint.stateDigest);
564
+ exigir(bloqueios, valido, "state_checkpoint_invalido");
565
+ if (valido) {
566
+ const tipado = checkpoint;
567
+ checkpointIds.add(tipado.checkpointId);
568
+ checkpointPorId.set(tipado.checkpointId, tipado);
569
+ }
570
+ }
571
+ const cases = Array.isArray(entrada.saveLoadCases) ? entrada.saveLoadCases : [];
572
+ exigir(bloqueios, idsUnicos(cases.map((item) => objeto(item) ? item.caseId : undefined)), "save_load_case_ids_invalidos_ou_duplicados");
573
+ const tiposCaso = new Set();
574
+ const casosValidos = [];
575
+ for (const caso of cases) {
576
+ const valido = objeto(caso)
577
+ && id(caso.caseId)
578
+ && ["NORMAL", "CORRUPT_RECOVERY", "VERSION_MIGRATION"].includes(String(caso.type))
579
+ && id(caso.sourceCheckpointId)
580
+ && checkpointIds.has(caso.sourceCheckpointId)
581
+ && id(caso.targetCheckpointId)
582
+ && checkpointIds.has(caso.targetCheckpointId)
583
+ && caso.sourceCheckpointId !== caso.targetCheckpointId
584
+ && checkpointPorId.get(caso.sourceCheckpointId)?.phase === "BEFORE"
585
+ && checkpointPorId.get(caso.targetCheckpointId)?.phase === "AFTER"
586
+ && caso.sandboxOnly === true
587
+ && caso.originalImmutable === true;
588
+ exigir(bloqueios, valido, "save_load_case_invalido_ou_nao_isolado");
589
+ if (valido) {
590
+ tiposCaso.add(String(caso.type));
591
+ casosValidos.push(caso);
592
+ }
593
+ }
594
+ for (const tipo of ["NORMAL", "CORRUPT_RECOVERY", "VERSION_MIGRATION"])
595
+ exigir(bloqueios, tiposCaso.has(tipo), `save_load_case_${tipo.toLowerCase()}_ausente`);
596
+ const bounds = entrada.fuzzBounds;
597
+ const boundsValidos = objeto(bounds)
598
+ && inteiroPositivo(bounds.maxSteps)
599
+ && positivo(bounds.maxRuntimeSeconds)
600
+ && positivo(bounds.maxMemoryMb)
601
+ && positivo(bounds.maxDiskMb)
602
+ && inteiroPositivo(bounds.maxCases);
603
+ exigir(bloqueios, boundsValidos, "fuzz_bounds_invalidos");
604
+ const boundsTipados = boundsValidos ? bounds : undefined;
605
+ if (boundsTipados) {
606
+ exigir(bloqueios, botsValidos.every((bot) => bot.maxSteps <= boundsTipados.maxSteps), "bot_max_steps_excede_fuzz_bounds");
607
+ exigir(bloqueios, botsValidos.length * casosValidos.length <= boundsTipados.maxCases, "scenario_count_excede_fuzz_bounds");
608
+ }
609
+ exigir(bloqueios, listaUnica(entrada.stopCriteria, (item) => STOP_FUZZ.includes(item))
610
+ && STOP_FUZZ.every((item) => entrada.stopCriteria.includes(item)), "stop_criteria_incompletos");
611
+ exigir(bloqueios, listaUnica(entrada.evidenceRequirements, texto)
612
+ && EVIDENCIAS_FUZZ.every((item) => entrada.evidenceRequirements.includes(item)), "evidence_requirements_incompletos");
613
+ for (const bot of botsValidos)
614
+ for (const caso of casosValidos) {
615
+ scenarioIds.push(`${entrada.planId}:${bot.botId}:${caso.caseId}`);
616
+ }
617
+ const planDigest = digestSeguro(entrada, bloqueios, "plano_nao_canonicalizavel");
618
+ const bloqueiosUnicos = [...new Set(bloqueios)].sort();
619
+ return {
620
+ valido: bloqueiosUnicos.length === 0,
621
+ planDigest,
622
+ scenarioIds: bloqueiosUnicos.length === 0 ? scenarioIds.sort() : [],
623
+ nextActions: bloqueiosUnicos.length === 0 ? ["entregar_cenarios_ao_runner_sandbox_externo"] : ["corrigir_plano_playtest_fuzz"],
624
+ authoritative: false,
625
+ executed: false,
626
+ bloqueios: bloqueiosUnicos,
627
+ };
628
+ }
629
+ const SEGURANCA_MULTIPLAYER = ["IDENTITY", "AUTHORIZATION", "ANTI_REPLAY", "RATE_LIMIT", "INTEGRITY"];
630
+ const EVIDENCIA_MULTIPLAYER = ["multiplayer.session", "multiplayer.sync", "multiplayer.conflict", "multiplayer.reconnect", "multiplayer.authority"];
631
+ export function validarModeloAutoridadeMultiplayer(entrada) {
632
+ const bloqueios = [];
633
+ const gaps = [];
634
+ if (!objeto(entrada)) {
635
+ return { valido: false, modelDigest: "sha256:invalid", authorityGaps: [], nextActions: ["corrigir_modelo_autoridade"], authoritative: false, executed: false, bloqueios: ["modelo_invalido"] };
636
+ }
637
+ const entradaSensivel = contemSensivel(entrada);
638
+ if (entradaSensivel)
639
+ bloqueios.push("modelo_contem_dado_sensivel");
640
+ exigir(bloqueios, somenteChaves(entrada, [
641
+ "schemaVersion", "modelId", "systemId", "topology", "authorities", "replicatedState", "conflicts",
642
+ "reconnect", "securityInvariants", "evidenceRequirements",
643
+ ]), "campos_top_level_desconhecidos");
644
+ exigir(bloqueios, entrada.schemaVersion === SCHEMA_AUTORIDADE_MULTIPLAYER, "schema_version_nao_suportada");
645
+ exigir(bloqueios, id(entrada.modelId), "model_id_invalido");
646
+ exigir(bloqueios, id(entrada.systemId), "system_id_invalido");
647
+ exigir(bloqueios, ["SERVER_AUTHORITATIVE", "CLIENT_AUTHORITATIVE", "PEER_TO_PEER", "HYBRID"].includes(String(entrada.topology)), "topology_invalida");
648
+ const authorities = Array.isArray(entrada.authorities) ? entrada.authorities : [];
649
+ exigir(bloqueios, authorities.length > 0, "authorities_ausentes");
650
+ exigir(bloqueios, idsUnicos(authorities.map((item) => objeto(item) ? item.authorityId : undefined)), "authority_ids_invalidos_ou_duplicados");
651
+ const autoridadePorId = new Map();
652
+ for (const authority of authorities) {
653
+ const valido = objeto(authority)
654
+ && id(authority.authorityId)
655
+ && ["SERVER", "CLIENT", "PEER"].includes(String(authority.role))
656
+ && id(authority.principalId);
657
+ exigir(bloqueios, valido, "authority_invalida");
658
+ if (valido) {
659
+ const tipada = authority;
660
+ autoridadePorId.set(tipada.authorityId, tipada);
661
+ }
662
+ }
663
+ const roles = [...autoridadePorId.values()].map((authority) => authority.role);
664
+ const topology = String(entrada.topology);
665
+ const topologyRolesCoerentes = topology === "SERVER_AUTHORITATIVE"
666
+ ? roles.includes("SERVER")
667
+ : topology === "CLIENT_AUTHORITATIVE"
668
+ ? roles.includes("CLIENT")
669
+ : topology === "PEER_TO_PEER"
670
+ ? roles.filter((role) => role === "PEER").length >= 2
671
+ : topology === "HYBRID"
672
+ ? roles.includes("SERVER") && (roles.includes("CLIENT") || roles.includes("PEER"))
673
+ : false;
674
+ exigir(bloqueios, topologyRolesCoerentes, "topology_sem_authority_role_compativel");
675
+ const states = Array.isArray(entrada.replicatedState) ? entrada.replicatedState : [];
676
+ exigir(bloqueios, states.length > 0, "replicated_state_ausente");
677
+ exigir(bloqueios, idsUnicos(states.map((item) => objeto(item) ? item.stateId : undefined)), "state_ids_invalidos_ou_duplicados");
678
+ const stateIds = new Set();
679
+ for (const state of states) {
680
+ const baseValida = objeto(state)
681
+ && id(state.stateId)
682
+ && id(state.semanticTargetId)
683
+ && typeof state.sensitive === "boolean"
684
+ && id(state.ownerAuthorityId)
685
+ && listaUnica(state.writerAuthorityIds, id)
686
+ && listaUnica(state.readerAuthorityIds, id)
687
+ && positivo(state.frequencyHz)
688
+ && ["SERVER_WINS", "SEQUENCE", "CRDT", "LOCKSTEP", "CONSENSUS"].includes(String(state.conflictPolicy))
689
+ && typeof state.clientInputValidated === "boolean";
690
+ exigir(bloqueios, baseValida, "replicated_state_invalido");
691
+ if (!baseValida)
692
+ continue;
693
+ const tipado = state;
694
+ stateIds.add(tipado.stateId);
695
+ const owner = autoridadePorId.get(tipado.ownerAuthorityId);
696
+ const expectedRole = topology === "SERVER_AUTHORITATIVE"
697
+ ? "SERVER"
698
+ : topology === "CLIENT_AUTHORITATIVE"
699
+ ? "CLIENT"
700
+ : topology === "PEER_TO_PEER"
701
+ ? "PEER"
702
+ : undefined;
703
+ if (!owner
704
+ || !tipado.writerAuthorityIds.every((item) => autoridadePorId.has(item))
705
+ || !tipado.readerAuthorityIds.every((item) => autoridadePorId.has(item)))
706
+ gaps.push(tipado.stateId);
707
+ if (expectedRole && (owner?.role !== expectedRole
708
+ || !tipado.writerAuthorityIds.every((item) => autoridadePorId.get(item)?.role === expectedRole)))
709
+ gaps.push(tipado.stateId);
710
+ if (tipado.sensitive && (owner?.role !== "SERVER" || tipado.clientInputValidated !== true))
711
+ gaps.push(tipado.stateId);
712
+ if (tipado.sensitive && !tipado.writerAuthorityIds.every((item) => autoridadePorId.get(item)?.role === "SERVER"))
713
+ gaps.push(tipado.stateId);
714
+ if (tipado.writerAuthorityIds.length > 1 && !["SEQUENCE", "CRDT", "LOCKSTEP", "CONSENSUS"].includes(tipado.conflictPolicy))
715
+ gaps.push(tipado.stateId);
716
+ }
717
+ const conflicts = Array.isArray(entrada.conflicts) ? entrada.conflicts : [];
718
+ exigir(bloqueios, idsUnicos(conflicts.map((item) => objeto(item) ? item.conflictId : undefined)), "conflict_ids_invalidos_ou_duplicados");
719
+ for (const conflict of conflicts)
720
+ exigir(bloqueios, objeto(conflict)
721
+ && id(conflict.conflictId)
722
+ && id(conflict.stateId)
723
+ && stateIds.has(conflict.stateId)
724
+ && texto(conflict.resolution), "conflict_invalido");
725
+ const reconnect = entrada.reconnect;
726
+ exigir(bloqueios, objeto(reconnect)
727
+ && reconnect.disconnectDetected === true
728
+ && reconnect.reconnectAllowed === true
729
+ && reconnect.resyncSnapshot === true
730
+ && reconnect.replaySinceSequence === true
731
+ && positivo(reconnect.timeoutMs), "reconnect_incompleto");
732
+ exigir(bloqueios, listaUnica(entrada.securityInvariants, texto)
733
+ && SEGURANCA_MULTIPLAYER.every((item) => entrada.securityInvariants.includes(item)), "security_invariants_incompletos");
734
+ exigir(bloqueios, listaUnica(entrada.evidenceRequirements, texto)
735
+ && EVIDENCIA_MULTIPLAYER.every((item) => entrada.evidenceRequirements.includes(item)), "evidence_requirements_incompletos");
736
+ const modelDigest = digestSeguro(entrada, bloqueios, "modelo_nao_canonicalizavel");
737
+ const gapsUnicos = entradaSensivel ? [] : [...new Set(gaps)].sort();
738
+ const bloqueiosUnicos = [...new Set(bloqueios)].sort();
739
+ return {
740
+ valido: bloqueiosUnicos.length === 0 && gapsUnicos.length === 0,
741
+ modelDigest,
742
+ authorityGaps: gapsUnicos,
743
+ nextActions: gapsUnicos.length > 0
744
+ ? gapsUnicos.map((stateId) => `definir_autoridade_e_validacao:${stateId}`)
745
+ : bloqueiosUnicos.length > 0
746
+ ? ["corrigir_modelo_autoridade"]
747
+ : ["capturar_traces_multiplayer_em_runner_externo"],
748
+ authoritative: false,
749
+ executed: false,
750
+ bloqueios: bloqueiosUnicos,
751
+ };
752
+ }
753
+ //# sourceMappingURL=autonomy.js.map