@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,539 @@
1
+ // SEMA-GOVERNED: sema.produto.sistemas_interativos.portabilidade
2
+ // Descricao: analise local de portabilidade com perdas declaradas e planejamento de workers distribuidos sem execucao.
3
+ import { digestJsonSistemaInterativo, digestSha256Valido } from "./canonical.js";
4
+ export const SCHEMA_PORTABILIDADE = "sema.interactive.portability/v1";
5
+ export const SCHEMA_WORKERS_DISTRIBUIDOS = "sema.interactive.distributed-jobs/v1";
6
+ const ID = /^[a-z0-9][a-z0-9._:/-]{0,127}$/;
7
+ const VERSAO = /^[0-9]+(?:\.[0-9]+){1,3}(?:[-+][a-z0-9.-]+)?$/i;
8
+ const CHAVE_SENSIVEL = /(?:password|passwd|senha|secret|token|api.?key|private.?key|credential|authorization|cookie)/i;
9
+ const VALORES_SENSIVEIS = [
10
+ /\bbearer\s+[a-z0-9._~+\/-]{8,}/i,
11
+ /^(?:sk[-_][a-z0-9_-]{8,}|ghp_[a-z0-9]{20,}|github_pat_[a-z0-9_]{20,})$/i,
12
+ /^eyJ[a-z0-9_-]{8,}\.eyJ[a-z0-9_-]{8,}\.[a-z0-9_-]{8,}$/i,
13
+ /\b(?:AKIA|ASIA)[A-Z0-9]{16}\b/,
14
+ /-----BEGIN [A-Z0-9 ]*(?:PRIVATE KEY|CERTIFICATE)-----/,
15
+ /(?:^|[?&])(?:access_?token|api_?key|aws_?secret_?access_?key|secret|password|passwd|signature|sig|token|credential|authorization)=[^&#\s]+/i,
16
+ /:\/\/[^/\s:@]+:[^/\s@]+@/,
17
+ ];
18
+ const STATUS = new Set(["EXACT", "APPROXIMATE", "UNSUPPORTED"]);
19
+ const EVIDENCIAS_PORTABILIDADE = [
20
+ "import.scene", "import.assets", "import.materials", "import.animation", "import.physics",
21
+ "import.audio", "import.timeline", "package.build", "runtime.smoke",
22
+ ];
23
+ const EVIDENCIAS_JOB = ["output.digest", "job.log", "job.checkpoint", "resources.metrics"];
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 listaUnica(valor, validar, permitirVazia = false) {
40
+ return Array.isArray(valor)
41
+ && (permitirVazia || valor.length > 0)
42
+ && valor.every(validar)
43
+ && new Set(valor).size === valor.length;
44
+ }
45
+ function idsUnicos(valores) {
46
+ return valores.every(id) && new Set(valores).size === valores.length;
47
+ }
48
+ function somenteChaves(valor, permitidas) {
49
+ const allowlist = new Set(permitidas);
50
+ return Object.keys(valor).every((chave) => allowlist.has(chave));
51
+ }
52
+ function valorSensivel(valor) {
53
+ if (digestSha256Valido(valor) || /^opaque:sha256:[a-f0-9]{64}$/.test(valor))
54
+ return false;
55
+ return VALORES_SENSIVEIS.some((padrao) => padrao.test(valor));
56
+ }
57
+ function contemSensivel(valor, visitados = new Set()) {
58
+ if (typeof valor === "string")
59
+ return valorSensivel(valor);
60
+ if (!objeto(valor) && !Array.isArray(valor))
61
+ return false;
62
+ if (visitados.has(valor))
63
+ return true;
64
+ visitados.add(valor);
65
+ try {
66
+ if (Array.isArray(valor))
67
+ return valor.some((item) => contemSensivel(item, visitados));
68
+ return Object.entries(valor).some(([chave, item]) => CHAVE_SENSIVEL.test(chave) || contemSensivel(item, visitados));
69
+ }
70
+ finally {
71
+ visitados.delete(valor);
72
+ }
73
+ }
74
+ function exigir(bloqueios, condicao, codigo) {
75
+ if (!condicao)
76
+ bloqueios.push(codigo);
77
+ }
78
+ function digestSeguro(valor, bloqueios, codigo) {
79
+ try {
80
+ return digestJsonSistemaInterativo(valor);
81
+ }
82
+ catch {
83
+ bloqueios.push(codigo);
84
+ return "sha256:invalid";
85
+ }
86
+ }
87
+ function versao(valor) {
88
+ return typeof valor === "string" && VERSAO.test(valor);
89
+ }
90
+ export function digestManifestoFontePortabilidade(manifesto) {
91
+ return digestJsonSistemaInterativo({
92
+ experienceIrDigest: manifesto.experienceIrDigest,
93
+ snapshotDigest: manifesto.snapshotDigest,
94
+ entries: [...manifesto.entries]
95
+ .map((entry) => ({
96
+ semanticId: entry.semanticId,
97
+ sourceKind: entry.sourceKind,
98
+ contentDigest: entry.contentDigest,
99
+ required: entry.required,
100
+ }))
101
+ .sort((a, b) => a.semanticId.localeCompare(b.semanticId)),
102
+ });
103
+ }
104
+ export function analisarPlanoPortabilidadeInterativa(entrada) {
105
+ const bloqueios = [];
106
+ const reports = [];
107
+ const perdas = [];
108
+ const gaps = [];
109
+ if (!objeto(entrada)) {
110
+ return {
111
+ valido: false, planDigest: "sha256:invalid", targetReports: [], declaredLosses: [], migrationGaps: [],
112
+ nextActions: ["corrigir_plano_portabilidade"], converted: false, authoritative: false, executed: false, bloqueios: ["plano_invalido"],
113
+ };
114
+ }
115
+ const entradaSensivel = contemSensivel(entrada);
116
+ if (entradaSensivel)
117
+ bloqueios.push("plano_contem_dado_sensivel");
118
+ exigir(bloqueios, somenteChaves(entrada, [
119
+ "schemaVersion", "planId", "systemId", "experienceIrDigest", "source", "sourceManifest", "targets", "migrations", "acceptance",
120
+ ]), "campos_top_level_desconhecidos");
121
+ exigir(bloqueios, entrada.schemaVersion === SCHEMA_PORTABILIDADE, "schema_version_nao_suportada");
122
+ exigir(bloqueios, id(entrada.planId), "plan_id_invalido");
123
+ exigir(bloqueios, id(entrada.systemId), "system_id_invalido");
124
+ exigir(bloqueios, digestSha256Valido(entrada.experienceIrDigest), "experience_ir_digest_invalido");
125
+ const source = entrada.source;
126
+ const sourceValida = objeto(source)
127
+ && texto(source.engine)
128
+ && versao(source.version)
129
+ && digestSha256Valido(source.snapshotDigest)
130
+ && texto(source.coordinateSystem);
131
+ exigir(bloqueios, sourceValida, "source_invalida");
132
+ const sourceManifest = entrada.sourceManifest;
133
+ const manifestEntries = objeto(sourceManifest) && Array.isArray(sourceManifest.entries) ? sourceManifest.entries : [];
134
+ const manifestEntryIdsValidos = idsUnicos(manifestEntries.map((item) => objeto(item) ? item.semanticId : undefined));
135
+ const manifestEntriesPorId = new Map();
136
+ let manifestEntriesValidas = manifestEntries.length > 0 && manifestEntryIdsValidos;
137
+ for (const entry of manifestEntries) {
138
+ const valida = objeto(entry)
139
+ && id(entry.semanticId)
140
+ && texto(entry.sourceKind)
141
+ && digestSha256Valido(entry.contentDigest)
142
+ && typeof entry.required === "boolean";
143
+ if (!valida)
144
+ manifestEntriesValidas = false;
145
+ else {
146
+ const tipada = entry;
147
+ manifestEntriesPorId.set(tipada.semanticId, tipada);
148
+ }
149
+ }
150
+ const manifestShapeValido = objeto(sourceManifest)
151
+ && digestSha256Valido(sourceManifest.experienceIrDigest)
152
+ && digestSha256Valido(sourceManifest.snapshotDigest)
153
+ && digestSha256Valido(sourceManifest.manifestDigest)
154
+ && manifestEntriesValidas
155
+ && [...manifestEntriesPorId.values()].some((entry) => entry.required);
156
+ exigir(bloqueios, manifestShapeValido, "source_manifest_invalido");
157
+ const manifestVinculado = manifestShapeValido
158
+ && sourceManifest.experienceIrDigest === entrada.experienceIrDigest
159
+ && sourceValida
160
+ && sourceManifest.snapshotDigest === source.snapshotDigest;
161
+ exigir(bloqueios, manifestVinculado, "source_manifest_desvinculado");
162
+ let manifestDigestValido = false;
163
+ if (manifestShapeValido) {
164
+ const manifestoTipado = sourceManifest;
165
+ manifestDigestValido = manifestoTipado.manifestDigest === digestManifestoFontePortabilidade({
166
+ experienceIrDigest: manifestoTipado.experienceIrDigest,
167
+ snapshotDigest: manifestoTipado.snapshotDigest,
168
+ entries: manifestoTipado.entries,
169
+ });
170
+ }
171
+ exigir(bloqueios, manifestDigestValido, "source_manifest_digest_divergente");
172
+ const sourceManifestValido = manifestShapeValido && manifestVinculado && manifestDigestValido;
173
+ const semanticIdsObrigatorios = [...manifestEntriesPorId.values()]
174
+ .filter((entry) => entry.required)
175
+ .map((entry) => entry.semanticId);
176
+ const acceptance = entrada.acceptance;
177
+ const acceptanceValida = objeto(acceptance)
178
+ && inteiroNaoNegativo(acceptance.maxUnsupportedPerTarget)
179
+ && typeof acceptance.allowApproximate === "boolean"
180
+ && listaUnica(acceptance.requiredEvidence, texto)
181
+ && EVIDENCIAS_PORTABILIDADE.every((item) => acceptance.requiredEvidence.includes(item));
182
+ exigir(bloqueios, acceptanceValida, "acceptance_invalida_ou_evidencias_incompletas");
183
+ const targets = Array.isArray(entrada.targets) ? entrada.targets : [];
184
+ exigir(bloqueios, targets.length > 0, "targets_ausentes");
185
+ const targetIdsValidos = idsUnicos(targets.map((item) => objeto(item) ? item.targetId : undefined));
186
+ exigir(bloqueios, targetIdsValidos, "target_ids_invalidos_ou_duplicados");
187
+ const targetBasicoPorId = new Map();
188
+ for (const target of targets) {
189
+ if (objeto(target) && id(target.targetId) && texto(target.engine) && versao(target.version)) {
190
+ targetBasicoPorId.set(target.targetId, { engine: target.engine, version: target.version });
191
+ }
192
+ }
193
+ const migrations = Array.isArray(entrada.migrations) ? entrada.migrations : [];
194
+ exigir(bloqueios, migrations.length > 0, "migrations_ausentes");
195
+ const migrationIdsValidos = idsUnicos(migrations.map((item) => objeto(item) ? item.migrationId : undefined));
196
+ exigir(bloqueios, migrationIdsValidos, "migration_ids_invalidos_ou_duplicados");
197
+ let migrationsValidasGlobais = migrations.length > 0 && migrationIdsValidos;
198
+ const targetIdsComMigration = new Set();
199
+ for (const migration of migrations) {
200
+ const baseValida = objeto(migration)
201
+ && id(migration.migrationId)
202
+ && id(migration.targetId)
203
+ && texto(migration.engine)
204
+ && versao(migration.fromVersion)
205
+ && versao(migration.toVersion)
206
+ && migration.fromVersion !== migration.toVersion
207
+ && digestSha256Valido(migration.backupDigest)
208
+ && digestSha256Valido(migration.compatibilityReportDigest)
209
+ && digestSha256Valido(migration.testPlanDigest)
210
+ && digestSha256Valido(migration.rollbackPlanDigest);
211
+ exigir(bloqueios, baseValida, "migration_invalida_sem_backup_teste_ou_rollback");
212
+ if (!baseValida) {
213
+ migrationsValidasGlobais = false;
214
+ continue;
215
+ }
216
+ const tipada = migration;
217
+ const target = targetBasicoPorId.get(tipada.targetId);
218
+ const ligadaNaOrigem = sourceValida && tipada.engine === source.engine && tipada.toVersion === source.version;
219
+ const ligadaNoTarget = Boolean(target && tipada.engine === target.engine && tipada.toVersion === target.version);
220
+ if (!target || (!ligadaNaOrigem && !ligadaNoTarget)) {
221
+ bloqueios.push("migration_desconectada_do_target_ou_source");
222
+ migrationsValidasGlobais = false;
223
+ continue;
224
+ }
225
+ targetIdsComMigration.add(tipada.targetId);
226
+ }
227
+ for (const target of targets) {
228
+ if (!objeto(target)
229
+ || !id(target.targetId)
230
+ || !texto(target.engine)
231
+ || !versao(target.version)
232
+ || !texto(target.outputFormat)
233
+ || !Array.isArray(target.mappings)
234
+ || target.mappings.length === 0) {
235
+ bloqueios.push("target_invalido");
236
+ if (objeto(target) && id(target.targetId))
237
+ gaps.push(target.targetId);
238
+ continue;
239
+ }
240
+ const targetDiferenteDaSource = !(sourceValida && source.engine === target.engine && source.version === target.version);
241
+ if (!targetDiferenteDaSource)
242
+ bloqueios.push("target_igual_a_source_sem_migracao");
243
+ const mappingIdsValidos = idsUnicos(target.mappings.map((item) => objeto(item) ? item.mappingId : undefined));
244
+ const semanticIdsValidos = idsUnicos(target.mappings.map((item) => objeto(item) ? item.semanticId : undefined));
245
+ exigir(bloqueios, mappingIdsValidos, "mapping_ids_invalidos_ou_duplicados");
246
+ exigir(bloqueios, semanticIdsValidos, "semantic_ids_invalidos_ou_duplicados");
247
+ let exact = 0;
248
+ let approximate = 0;
249
+ let unsupported = 0;
250
+ let mappingsValidos = mappingIdsValidos && semanticIdsValidos;
251
+ let mappingsBoundToSource = sourceManifestValido;
252
+ const semanticIdsMapeados = new Set();
253
+ for (const mapping of target.mappings) {
254
+ const baseValida = objeto(mapping)
255
+ && id(mapping.mappingId)
256
+ && id(mapping.semanticId)
257
+ && texto(mapping.sourceKind)
258
+ && texto(mapping.targetKind)
259
+ && STATUS.has(mapping.status)
260
+ && Array.isArray(mapping.losses)
261
+ && mapping.losses.every(texto)
262
+ && new Set(mapping.losses).size === mapping.losses.length
263
+ && listaUnica(mapping.acceptanceCriteria, texto);
264
+ exigir(bloqueios, baseValida, "mapping_invalido");
265
+ if (!baseValida) {
266
+ mappingsValidos = false;
267
+ continue;
268
+ }
269
+ const tipado = mapping;
270
+ const manifestEntry = manifestEntriesPorId.get(tipado.semanticId);
271
+ if (!sourceManifestValido || !manifestEntry || manifestEntry.sourceKind !== tipado.sourceKind) {
272
+ bloqueios.push("mapping_desconectado_do_source_manifest");
273
+ mappingsBoundToSource = false;
274
+ continue;
275
+ }
276
+ semanticIdsMapeados.add(tipado.semanticId);
277
+ if (tipado.status === "EXACT") {
278
+ exact += 1;
279
+ if (tipado.losses.length > 0) {
280
+ bloqueios.push("mapping_exact_nao_pode_declarar_loss");
281
+ mappingsValidos = false;
282
+ }
283
+ }
284
+ else {
285
+ if (tipado.status === "APPROXIMATE")
286
+ approximate += 1;
287
+ if (tipado.status === "UNSUPPORTED")
288
+ unsupported += 1;
289
+ const perdaValida = tipado.losses.length > 0 && texto(tipado.fallback);
290
+ exigir(bloqueios, perdaValida, "mapping_nao_exato_exige_loss_e_fallback");
291
+ if (!perdaValida)
292
+ mappingsValidos = false;
293
+ if (perdaValida)
294
+ perdas.push({
295
+ targetId: target.targetId,
296
+ mappingId: tipado.mappingId,
297
+ status: tipado.status,
298
+ lossCodes: [...tipado.losses].sort(),
299
+ fallback: tipado.fallback,
300
+ });
301
+ }
302
+ }
303
+ const sourceCoverageComplete = sourceManifestValido
304
+ && semanticIdsObrigatorios.every((semanticId) => semanticIdsMapeados.has(semanticId));
305
+ exigir(bloqueios, sourceCoverageComplete, "mapping_cobertura_origem_incompleta");
306
+ const migrationLinked = targetIdsComMigration.has(target.targetId);
307
+ exigir(bloqueios, migrationLinked, "target_sem_migration_ligada");
308
+ const limite = acceptanceValida ? acceptance.maxUnsupportedPerTarget : 0;
309
+ const aceitaApproximate = acceptanceValida && acceptance.allowApproximate === true;
310
+ const ready = acceptanceValida
311
+ && targetIdsValidos
312
+ && targetDiferenteDaSource
313
+ && migrationsValidasGlobais
314
+ && mappingsValidos
315
+ && mappingsBoundToSource
316
+ && sourceCoverageComplete
317
+ && migrationLinked
318
+ && unsupported <= limite
319
+ && (approximate === 0 || aceitaApproximate);
320
+ if (!ready)
321
+ gaps.push(target.targetId);
322
+ reports.push({
323
+ targetId: target.targetId,
324
+ exact,
325
+ approximate,
326
+ unsupported,
327
+ sourceCoverageComplete,
328
+ mappingsBoundToSource,
329
+ migrationLinked,
330
+ readyForExternalMigration: ready,
331
+ requiresExternalValidation: true,
332
+ converted: false,
333
+ });
334
+ }
335
+ const planDigest = digestSeguro(entrada, bloqueios, "plano_nao_canonicalizavel");
336
+ const gapsUnicos = entradaSensivel ? [] : [...new Set(gaps)].sort();
337
+ const bloqueiosUnicos = [...new Set(bloqueios)].sort();
338
+ const valido = bloqueiosUnicos.length === 0 && gapsUnicos.length === 0;
339
+ const reportsFinais = entradaSensivel ? [] : reports.sort((a, b) => a.targetId.localeCompare(b.targetId))
340
+ .map((report) => valido ? report : { ...report, readyForExternalMigration: false });
341
+ return {
342
+ valido,
343
+ planDigest,
344
+ targetReports: reportsFinais,
345
+ declaredLosses: entradaSensivel ? [] : perdas.sort((a, b) => `${a.targetId}:${a.mappingId}`.localeCompare(`${b.targetId}:${b.mappingId}`)),
346
+ migrationGaps: gapsUnicos,
347
+ nextActions: bloqueiosUnicos.length > 0
348
+ ? ["corrigir_plano_portabilidade"]
349
+ : gapsUnicos.length > 0
350
+ ? gapsUnicos.map((targetId) => `revisar_perdas_e_acceptance:${targetId}`)
351
+ : reportsFinais.map((item) => `entregar_plano_ao_adapter_externo:${item.targetId}`),
352
+ converted: false,
353
+ authoritative: false,
354
+ executed: false,
355
+ bloqueios: bloqueiosUnicos,
356
+ };
357
+ }
358
+ function ordemTopologica(jobs) {
359
+ const ids = new Set(jobs.map((job) => job.jobId));
360
+ const referenciasInvalidas = jobs.some((job) => job.dependsOn.some((dep) => !ids.has(dep) || dep === job.jobId));
361
+ const graus = new Map(jobs.map((job) => [job.jobId, job.dependsOn.length]));
362
+ const filhos = new Map();
363
+ for (const job of jobs)
364
+ for (const dep of job.dependsOn)
365
+ filhos.set(dep, [...(filhos.get(dep) ?? []), job.jobId]);
366
+ const fila = [...graus.entries()].filter(([, grau]) => grau === 0).map(([jobId]) => jobId).sort();
367
+ const ordem = [];
368
+ while (fila.length > 0) {
369
+ const atual = fila.shift();
370
+ ordem.push(atual);
371
+ for (const filho of (filhos.get(atual) ?? []).sort()) {
372
+ const grau = (graus.get(filho) ?? 0) - 1;
373
+ graus.set(filho, grau);
374
+ if (grau === 0) {
375
+ fila.push(filho);
376
+ fila.sort();
377
+ }
378
+ }
379
+ }
380
+ return { ordem, ciclo: ordem.length !== jobs.length, referenciasInvalidas };
381
+ }
382
+ function dependeDe(jobId, ancestorId, porId, visitados = new Set()) {
383
+ if (visitados.has(jobId))
384
+ return false;
385
+ visitados.add(jobId);
386
+ const job = porId.get(jobId);
387
+ if (!job)
388
+ return false;
389
+ if (job.dependsOn.includes(ancestorId))
390
+ return true;
391
+ return job.dependsOn.some((dep) => dependeDe(dep, ancestorId, porId, visitados));
392
+ }
393
+ export function validarPlanoWorkersDistribuidos(entrada) {
394
+ const bloqueios = [];
395
+ const gaps = [];
396
+ const conflicts = [];
397
+ const assignments = [];
398
+ if (!objeto(entrada)) {
399
+ return {
400
+ valido: false, planDigest: "sha256:invalid", topologicalOrder: [], assignments: [], capabilityGaps: [], lockConflicts: [],
401
+ nextActions: ["corrigir_plano_workers"], completed: false, authoritative: false, executed: false, bloqueios: ["plano_invalido"],
402
+ };
403
+ }
404
+ const entradaSensivel = contemSensivel(entrada);
405
+ if (entradaSensivel)
406
+ bloqueios.push("plano_contem_dado_sensivel");
407
+ exigir(bloqueios, somenteChaves(entrada, [
408
+ "schemaVersion", "planId", "systemId", "inputDigest", "workers", "jobs", "leases", "evidenceRequirements",
409
+ ]), "campos_top_level_desconhecidos");
410
+ exigir(bloqueios, entrada.schemaVersion === SCHEMA_WORKERS_DISTRIBUIDOS, "schema_version_nao_suportada");
411
+ exigir(bloqueios, id(entrada.planId), "plan_id_invalido");
412
+ exigir(bloqueios, id(entrada.systemId), "system_id_invalido");
413
+ exigir(bloqueios, digestSha256Valido(entrada.inputDigest), "input_digest_invalido");
414
+ const workersBrutos = Array.isArray(entrada.workers) ? entrada.workers : [];
415
+ exigir(bloqueios, idsUnicos(workersBrutos.map((item) => objeto(item) ? item.workerId : undefined)), "worker_ids_invalidos_ou_duplicados");
416
+ const workers = [];
417
+ for (const worker of workersBrutos) {
418
+ const valido = objeto(worker)
419
+ && id(worker.workerId)
420
+ && listaUnica(worker.capabilities, id)
421
+ && positivo(worker.ramMb)
422
+ && inteiroNaoNegativo(worker.vramMb)
423
+ && positivo(worker.diskMb)
424
+ && positivo(worker.maxConcurrency)
425
+ && ["CONTAINER", "VM", "PROCESS_SANDBOX"].includes(String(worker.isolation));
426
+ exigir(bloqueios, valido, "worker_invalido");
427
+ if (valido)
428
+ workers.push(worker);
429
+ }
430
+ const jobsBrutos = Array.isArray(entrada.jobs) ? entrada.jobs : [];
431
+ exigir(bloqueios, jobsBrutos.length > 0, "jobs_ausentes");
432
+ exigir(bloqueios, idsUnicos(jobsBrutos.map((item) => objeto(item) ? item.jobId : undefined)), "job_ids_invalidos_ou_duplicados");
433
+ const jobs = [];
434
+ for (const job of jobsBrutos) {
435
+ const budgets = objeto(job) ? job.budgets : undefined;
436
+ const retry = objeto(job) ? job.retry : undefined;
437
+ const valido = objeto(job)
438
+ && id(job.jobId)
439
+ && ["COOK", "SHADERS", "RENDER", "TEST"].includes(String(job.type))
440
+ && digestSha256Valido(job.inputDigest)
441
+ && listaUnica(job.dependsOn, id, true)
442
+ && listaUnica(job.requiredCapabilities, id)
443
+ && objeto(budgets)
444
+ && positivo(budgets.ramMb)
445
+ && inteiroNaoNegativo(budgets.vramMb)
446
+ && positivo(budgets.diskMb)
447
+ && positivo(budgets.runtimeSeconds)
448
+ && id(job.idempotencyKey)
449
+ && positivo(job.checkpointIntervalSeconds)
450
+ && objeto(retry)
451
+ && inteiroNaoNegativo(retry.maxAttempts)
452
+ && positivo(retry.backoffSeconds)
453
+ && listaUnica(job.resourceLockIds, id, true)
454
+ && listaUnica(job.requiredEvidence, texto)
455
+ && EVIDENCIAS_JOB.every((item) => job.requiredEvidence.includes(item));
456
+ exigir(bloqueios, valido, "job_invalido_sem_budget_checkpoint_idempotency_ou_evidencia");
457
+ if (valido)
458
+ jobs.push(job);
459
+ }
460
+ exigir(bloqueios, new Set(jobs.map((job) => job.idempotencyKey)).size === jobs.length, "job_idempotency_key_duplicada");
461
+ const dag = ordemTopologica(jobs);
462
+ exigir(bloqueios, !dag.referenciasInvalidas, "job_dependency_invalida");
463
+ exigir(bloqueios, !dag.ciclo, "job_dependency_cycle");
464
+ const porId = new Map(jobs.map((job) => [job.jobId, job]));
465
+ for (const job of jobs) {
466
+ const candidatos = workers.filter((worker) => (job.requiredCapabilities.every((capability) => worker.capabilities.includes(capability))
467
+ && worker.ramMb >= job.budgets.ramMb
468
+ && worker.vramMb >= job.budgets.vramMb
469
+ && worker.diskMb >= job.budgets.diskMb)).sort((a, b) => a.workerId.localeCompare(b.workerId));
470
+ if (candidatos.length === 0)
471
+ gaps.push(job.jobId);
472
+ else
473
+ assignments.push({ jobId: job.jobId, workerId: candidatos[0].workerId });
474
+ }
475
+ const leasesBrutos = Array.isArray(entrada.leases) ? entrada.leases : [];
476
+ exigir(bloqueios, idsUnicos(leasesBrutos.map((item) => objeto(item) ? item.lockId : undefined)), "lease_ids_invalidos_ou_duplicados");
477
+ const leases = [];
478
+ for (const lease of leasesBrutos) {
479
+ const valido = objeto(lease)
480
+ && id(lease.lockId)
481
+ && id(lease.resourceId)
482
+ && ["GPU", "EDITOR", "CACHE"].includes(String(lease.resourceType))
483
+ && id(lease.ownerJobId)
484
+ && porId.has(lease.ownerJobId)
485
+ && typeof lease.exclusive === "boolean"
486
+ && positivo(lease.ttlSeconds)
487
+ && positivo(lease.heartbeatSeconds)
488
+ && lease.heartbeatSeconds < lease.ttlSeconds
489
+ && digestSha256Valido(lease.checkpointDigest);
490
+ exigir(bloqueios, valido, "lease_invalido_sem_ttl_heartbeat_ou_checkpoint");
491
+ if (valido)
492
+ leases.push(lease);
493
+ }
494
+ const leasesPorId = new Map(leases.map((lease) => [lease.lockId, lease]));
495
+ for (const job of jobs) {
496
+ const leasesDoJob = job.resourceLockIds.map((lockId) => leasesPorId.get(lockId));
497
+ exigir(bloqueios, leasesDoJob.every((lease) => lease?.ownerJobId === job.jobId
498
+ && lease.checkpointDigest === job.inputDigest), "job_lock_ausente_owner_ou_checkpoint_divergente");
499
+ const exigeGpu = job.type === "RENDER" || job.type === "SHADERS" || job.budgets.vramMb > 0;
500
+ exigir(bloqueios, !exigeGpu || leasesDoJob.some((lease) => lease?.resourceType === "GPU"), "job_gpu_lease_ausente");
501
+ }
502
+ for (let i = 0; i < leases.length; i += 1)
503
+ for (let j = i + 1; j < leases.length; j += 1) {
504
+ const a = leases[i];
505
+ const b = leases[j];
506
+ if (a.resourceId !== b.resourceId || (!a.exclusive && !b.exclusive) || a.ownerJobId === b.ownerJobId)
507
+ continue;
508
+ const ordenados = dependeDe(a.ownerJobId, b.ownerJobId, porId) || dependeDe(b.ownerJobId, a.ownerJobId, porId);
509
+ if (!ordenados)
510
+ conflicts.push(`${a.ownerJobId}|${b.ownerJobId}|${a.resourceId}`);
511
+ }
512
+ exigir(bloqueios, listaUnica(entrada.evidenceRequirements, texto)
513
+ && EVIDENCIAS_JOB.every((item) => entrada.evidenceRequirements.includes(item)), "evidence_requirements_incompletos");
514
+ const planDigest = digestSeguro(entrada, bloqueios, "plano_nao_canonicalizavel");
515
+ const gapsUnicos = entradaSensivel ? [] : [...new Set(gaps)].sort();
516
+ const conflitosUnicos = entradaSensivel ? [] : [...new Set(conflicts)].sort();
517
+ const bloqueiosUnicos = [...new Set(bloqueios)].sort();
518
+ const valido = bloqueiosUnicos.length === 0 && gapsUnicos.length === 0 && conflitosUnicos.length === 0;
519
+ return {
520
+ valido,
521
+ planDigest,
522
+ topologicalOrder: valido ? dag.ordem : [],
523
+ assignments: valido ? assignments.sort((a, b) => a.jobId.localeCompare(b.jobId)) : [],
524
+ capabilityGaps: gapsUnicos,
525
+ lockConflicts: conflitosUnicos,
526
+ nextActions: bloqueiosUnicos.length > 0
527
+ ? ["corrigir_plano_workers"]
528
+ : gapsUnicos.length > 0
529
+ ? gapsUnicos.map((jobId) => `provisionar_worker_compativel:${jobId}`)
530
+ : conflitosUnicos.length > 0
531
+ ? conflitosUnicos.map((conflictId) => `serializar_jobs_com_lock_conflitante:${conflictId}`)
532
+ : ["entregar_DAG_ao_orquestrador_externo"],
533
+ completed: false,
534
+ authoritative: false,
535
+ executed: false,
536
+ bloqueios: bloqueiosUnicos,
537
+ };
538
+ }
539
+ //# sourceMappingURL=portability.js.map
@@ -0,0 +1,3 @@
1
+ type Registro = Readonly<Record<string, unknown>>;
2
+ export declare function renderizarResultadoSistemasInterativos(payload: Registro): string;
3
+ export {};