@praxisui/dynamic-form 8.0.0-beta.19 → 8.0.0-beta.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -501,11 +501,20 @@ e mantém `fields[]` sincronizado como projeção; `fieldMetadata[]` não é
501
501
  alterado.
502
502
 
503
503
  **Adicionar bloco visual** oferece presets internos como texto, aviso,
504
- separador e card informativo. Esses presets são apenas atalhos de authoring que
504
+ separador, card informativo, `callout`, `keyValueList`, `recordSummary`,
505
+ `disclosure` e `emptyState`. Esses presets são apenas atalhos de authoring que
505
506
  geram documentos `praxis.rich-content` válidos para itens `kind: 'richContent'`;
506
507
  eles não criam novo `kind`, não criam `FieldMetadata` e não participam do
507
508
  payload de submit.
508
509
 
510
+ O runtime do formulário também passa `hostCapabilities` canônicos para
511
+ `@praxisui/rich-content`, permitindo:
512
+ - `actionButton` despachar ações via a mesma trilha de `customAction`/`globalAction`
513
+ já usada pelo formulário;
514
+ - `requiresCapabilities` resolver capacidades como `form.mode.edit`,
515
+ `form.mode.view`, `form.customization.enabled`, `form.resource.connected` e
516
+ `form.actions.submit`.
517
+
509
518
  Exemplo mínimo de uma coluna com campo, bloco visual e projeção `fields[]`:
510
519
 
511
520
  ```json
@@ -587,7 +596,7 @@ Os paths micro são normalizados para `fieldMetadata[].<prop>` para garantir que
587
596
  ## Regras de formulário (novo contrato)
588
597
 
589
598
  - Formato: cada regra tem `targetType` (`field | section | action | row | column | visualBlock`), `targets: string[]` (IDs canônicos do alvo), e `effect` com `condition` (`JsonLogicExpression | null`), `properties` e `propertiesWhenFalse`.
590
- - Regras de orientação visual geradas por LLM devem usar `type: "visualBlockGuidance"`, `targetType: "visualBlock"`, `context: "notification"` e `metadata.origin: "llm"` com `metadata.reviewStatus: "pending"`; o editor aceita a sugestão, marca como `accepted` e materializa `formRulesState`.
599
+ - Regra de negócio, política, elegibilidade, validação, compliance ou decisão compartilhada deve ser authorada no fluxo governado de `domain-rules`/`shared_rule_authoring`. `visualBlockGuidance` fica restrito a projeção visual opcional: quando uma decisão governada precisar explicar impacto na UI, a materialização `form_config` pode gerar `type: "visualBlockGuidance"`, `targetType: "visualBlock"` e `metadata.origin: "llm"` com `metadata.reviewStatus: "pending"`; o editor aceita a projeção, marca como `accepted` e materializa `formRulesState` internamente para round-trip visual.
591
600
  - Compatibilidade: regras antigas (`context/targetField`) são migradas para `properties/targets` automaticamente; prefixes legados `section:/action:/row:/column:` continuam sendo normalizados quando representarem alvos tradicionais. Para header actions de seção, o ID canônico é preservado como `section:<sectionId>:header-action:<actionLogicalId>`.
592
601
  - Semântica de limpeza: valores `null` em `properties/propertiesWhenFalse` removem o override e retornam ao valor base do layout; ausência mantém o valor base.
593
602
  - Whitelist por tipo (somente propriedades a seguir são aplicadas; demais são descartadas e logadas em dev):
@@ -849,7 +858,7 @@ Apache-2.0 – see the `LICENSE` packaged with this library or the repository ro
849
858
  targetArtifactKey: 'funcionarios-form-demo',
850
859
  targetLayer: 'form_config',
851
860
  targetArtifactType: 'praxis-dynamic-form',
852
- status: 'pending_review'
861
+ status: 'applied'
853
862
  }">
854
863
  </praxis-dynamic-form>
855
864
  ```
@@ -857,8 +866,10 @@ Apache-2.0 – see the `LICENSE` packaged with this library or the repository ro
857
866
  - `targetArtifactKey` usa `formId`/`componentInstanceId` quando omitido.
858
867
  - `targetLayer` default: `form_config`.
859
868
  - `targetArtifactType` default: `praxis-dynamic-form`.
860
- - `materializedPayload` pode ser um `FormLayoutRule` direto ou uma operação reconhecida, como `rule.visualBlockGuidance.add`.
869
+ - Para consumo runtime, prefira `status: 'applied'`; `pending_review` pertence a etapas de governança antes da aplicação.
870
+ - `materializedPayload` pode ser um `FormLayoutRule` direto ou uma operação reconhecida, como `rule.visualBlockGuidance.add`, desde que essa operação seja tratada como projeção visual derivada e não como fonte primária da regra de negócio.
861
871
  - A rastreabilidade da regra compartilhada fica em `metadata.domainRule`.
872
+ - Quando o backend enviar `decisionDiagnostics`, o runtime preserva esse envelope em `metadata.domainRule.decisionDiagnostics`, mantendo a explicação canônica da decisão semântica governada junto da regra derivada.
862
873
 
863
874
  E2E vivo com API real:
864
875
 
@@ -0,0 +1,80 @@
1
+ ---
2
+ title: "Dynamic Form Authoring Document Semantics"
3
+ doc_type: "adr"
4
+ component: "praxis-dynamic-form"
5
+ status: "accepted"
6
+ owner: "praxis-ui"
7
+ last_updated: "2026-04-15"
8
+ ---
9
+
10
+ # Dynamic Form Authoring Document Semantics
11
+
12
+ ## Decision
13
+
14
+ `DynamicFormAuthoringDocument` e o snapshot canônico completo de autoria de `praxis-dynamic-form`.
15
+
16
+ Ao aplicar um documento canônico:
17
+
18
+ - `config` substitui integralmente a configuração anterior.
19
+ - `bindings` substitui integralmente os bindings persistíveis anteriores.
20
+ - ausência de `bindings.mode` implica limpeza do binding persistido e retorno ao modo default efetivo do host.
21
+ - `contextSnapshot` substitui integralmente o contexto autoral persistido anterior.
22
+ - ausência de `backConfig`, `presentation` ou `schemaPrefs` dentro de `contextSnapshot` significa remoção explícita do bloco ausente.
23
+
24
+ Payloads legados ou parciais recebidos por APIs de compatibilidade, como `applyConfigFromAdapter(...)`, permanecem com semântica `merge-compat`: campos não informados devem ser preservados até migração completa para o contrato canônico.
25
+
26
+ Valores de runtime/discovery, como `schemaUrl`, `submitUrl` e `submitMethod`, não fazem parte do `DynamicFormAuthoringDocument`. O editor pode exibi-los apenas como diagnóstico read-only do host atual, mas nunca os persiste em `bindings` ou `contextSnapshot`.
27
+
28
+ ## Field Metadata Editor Patches
29
+
30
+ Patches vindos de `@praxisui/metadata-editor` para `fieldMetadata` seguem semantica de JSON Merge Patch no campo editado.
31
+
32
+ Para `entityLookup`, o bloco `fieldMetadata[].optionSource` e aninhado e deve ser mesclado em profundidade. O dynamic-form deve preservar campos existentes, como `key`, `resourcePath`, `valuePropertyPath` e `capabilities.byIds`, quando o editor alterar apenas partes do contrato, como `dependsOn`, `selectionPolicy`, `detail` ou `capabilities.auditSnapshot`.
33
+
34
+ Essa regra evita perda silenciosa do contrato canonico de Entity Lookup durante o fluxo: abrir editor -> aplicar/salvar -> reabrir editor -> runtime consumir.
35
+
36
+ ## Consequences
37
+
38
+ - `backConfig`, `presentation` e `schemaPrefs` permanecem fora de `FormConfig`, mas fazem parte oficialmente do documento autoral persistível em `contextSnapshot`.
39
+ - `Apply` e `Save` vindos do editor operam em modo `replace-all`.
40
+ - `reset` do editor limpa todos os modos persistidos do artefato.
41
+ - adapters legados continuam suportados sem limpeza destrutiva de contexto ausente.
42
+
43
+ ## Visual Blocks Inside Layout
44
+
45
+ Blocos visuais dentro de seção, linha ou coluna devem seguir a decisão
46
+ canônica registrada em:
47
+
48
+ - `../../../docs/2026-04-dynamic-form-visual-blocks-layout-items-plan.md`
49
+ - `../../../../docs/adr/ADR-0006-dynamic-form-layout-items-visual-blocks.md`
50
+ - `./layout-items-visual-blocks.md`
51
+ - `./dynamic-form-rules-authoring-plan.md`
52
+
53
+ A semântica alvo é `FormColumn.items`, com uma union discriminada entre campo e
54
+ rich content. `FormColumn.fields` pode ser aceito como entrada de migração para
55
+ configurações antigas, mas não deve seguir como segunda fonte de verdade.
56
+
57
+ O editor deve produzir e persistir o documento canônico, e o runtime deve
58
+ consumi-lo sem adaptador oculto. O round-trip esperado é:
59
+
60
+ `abrir editor -> adicionar bloco visual -> aplicar/salvar -> reabrir -> renderizar`
61
+
62
+ Guardrail permanente:
63
+
64
+ - bloco visual não entra em `fieldMetadata`;
65
+ - bloco visual não cria `FormControl`;
66
+ - bloco visual não entra no payload de submit;
67
+ - bloco visual não usa `source`, `transient` ou `submitPolicy`.
68
+ - operações AI para bloco visual devem escrever apenas em
69
+ `sections[].rows[].columns[].items[]`, usando itens `kind: 'richContent'`;
70
+ - `sections[].rows[].columns[].fields[]` é apenas projeção/migração de campos
71
+ e não pode ser usado para representar bloco visual.
72
+ - presets de bloco visual no editor são atalhos internos para criar
73
+ `RichContentDocument` com nodes já suportados por `@praxisui/rich-content`;
74
+ presets não introduzem novo `kind` nem contrato paralelo.
75
+ - "Adicionar campo da API" reinsere somente campos já existentes em
76
+ `fieldMetadata[]` e ausentes de `columns[].items[]`; a operação escreve o
77
+ item `kind: 'field'` em `items[]` e preserva `fieldMetadata[]`.
78
+
79
+ Em fase beta, não vamos deixar legado para trás sem migração, mas também não
80
+ vamos manter legado como contrato paralelo permanente.
@@ -0,0 +1,313 @@
1
+ ---
2
+ title: "Dynamic Form LLM Rule Authoring Guide"
3
+ slug: "dynamic-form-llm-rule-authoring-guide"
4
+ description: "Guia operacional para criar, explicar, revisar e aplicar regras de Dynamic Form com apoio de LLM."
5
+ doc_type: "guide"
6
+ document_kind: "host-guide"
7
+ category: "architecture"
8
+ audience:
9
+ - "business-analyst"
10
+ - "frontend"
11
+ - "host"
12
+ - "platform-team"
13
+ - "llm-agent"
14
+ level: "intermediate"
15
+ status: "active"
16
+ owner: "praxis-ui"
17
+ tags:
18
+ - "dynamic-form"
19
+ - "rules"
20
+ - "llm"
21
+ - "json-logic"
22
+ - "governance"
23
+ toc: true
24
+ sidebar: true
25
+ reading_time: "10 min"
26
+ last_updated: "2026-04-22"
27
+ source_of_truth:
28
+ - "projects/praxis-dynamic-form/docs/dynamic-form-rules-authoring-plan.md"
29
+ - "projects/praxis-dynamic-form/src/lib/ai/dynamic-form-rule-authoring-context.ts"
30
+ - "projects/praxis-dynamic-form/src/lib/ai/form-ai-capabilities.ts"
31
+ - "projects/praxis-dynamic-form/src/lib/utils/rule-authoring-diagnostics.ts"
32
+ - "projects/praxis-dynamic-form/src/lib/services/form-rules.service.ts"
33
+ - "projects/praxis-core/src/lib/models/form/rule-property.schema.ts"
34
+ ---
35
+
36
+ # Dynamic Form LLM Rule Authoring Guide
37
+
38
+ Este guia define como um analista, host corporativo ou agente LLM deve pedir,
39
+ gerar, explicar, revisar e aplicar regras em `praxis-dynamic-form`.
40
+
41
+ O objetivo e tirar a regra do improviso. A LLM nao deve "adivinhar codigo"; ela
42
+ deve operar sobre o vocabulario autoral publicado pelo componente:
43
+
44
+ - `formRules` e o contrato executavel.
45
+ - `formRulesState` e estado interno do builder visual.
46
+ - `fieldMetadata[].name` identifica campos de negocio.
47
+ - `sections[].rows[].columns[].items[]` identifica layout canonico.
48
+ - `RULE_PROPERTY_SCHEMA` define quais propriedades cada alvo aceita.
49
+ - `rule-authoring-diagnostics` e `ruleDiagnosticsChange` fecham o ciclo de
50
+ validacao e explicacao.
51
+
52
+ ## Contrato de responsabilidade
53
+
54
+ | Papel | Pode fazer | Nao deve fazer |
55
+ | --- | --- | --- |
56
+ | Analista | Descrever intencao, revisar impacto, aceitar ou rejeitar sugestao. | Editar `formRulesState` manualmente. |
57
+ | LLM | Gerar proposta em `formRules`, explicar impacto e corrigir diagnostics. | Escrever JS, handler, funcao ou regra fora de Json Logic. |
58
+ | Editor | Validar alvo, condicao, propriedades e round-trip visual. | Aplicar regra invalida silenciosamente. |
59
+ | Runtime | Aplicar somente propriedades saneadas e emitir diagnostics. | Criar campos, controles ou payload a partir de visual block. |
60
+
61
+ ## Contexto minimo que a LLM precisa receber
62
+
63
+ A LLM nao precisa analisar codigo em runtime. Ela precisa receber um pacote de
64
+ conhecimento serializado pelo host/editor:
65
+
66
+ ```json
67
+ {
68
+ "component": "praxis-dynamic-form",
69
+ "capabilityCatalogVersion": "v1.11",
70
+ "fields": [
71
+ { "name": "tipoContrato", "label": "Tipo de contrato", "type": "select" },
72
+ { "name": "dataFim", "label": "Data fim", "type": "date" }
73
+ ],
74
+ "targets": {
75
+ "field": ["tipoContrato", "dataFim"],
76
+ "section": ["dados-contratuais"],
77
+ "action": ["submit", "cancel"],
78
+ "visualBlock": ["aviso-lgpd"]
79
+ },
80
+ "allowedRuleProperties": {
81
+ "field": ["visible", "required", "disabled", "readonly", "label", "hint"],
82
+ "visualBlock": ["visible", "hidden", "text", "title", "message", "rootClassName"]
83
+ },
84
+ "visualBlockNodes": {
85
+ "aviso-lgpd": [
86
+ { "id": "title", "label": "Aviso LGPD", "kind": "card", "roles": ["title"] },
87
+ { "id": "message", "label": "Aviso", "kind": "text", "roles": ["text", "message"] }
88
+ ]
89
+ },
90
+ "existingRules": [],
91
+ "diagnostics": []
92
+ }
93
+ ```
94
+
95
+ Esse pacote deve ser derivado de `FormConfig`, do catalogo de capacidades e dos
96
+ diagnostics atuais. Ele e o "mapa semantico operacional" do formulario.
97
+
98
+ No runtime/editor, use `buildDynamicFormRuleAuthoringContext(config)` para
99
+ montar esse pacote de forma canonica. A funcao publica:
100
+
101
+ - remove campos `formHidden` dos alvos de regra;
102
+ - coleta campos, secoes, linhas, colunas, actions e visual blocks;
103
+ - publica `allowedRuleProperties` a partir de `RULE_PROPERTY_SCHEMA`;
104
+ - publica `visualBlockNodes` com os nos editaveis de cada rich content block
105
+ quando regras puderem alterar `text`, `title` ou `message`;
106
+ - inclui `existingRules` e `diagnostics`;
107
+ - carrega guardrails permanentes para a LLM, incluindo a regra de que
108
+ `formRulesState` e gerado apenas por internals Praxis apos revisao humana.
109
+
110
+ ## Prompt recomendado para criar regra
111
+
112
+ Use pedidos com intencao, alvo, condicao, efeito e criterio de aceite:
113
+
114
+ ```text
115
+ Crie uma regra para o formulario de funcionario.
116
+
117
+ Intencao: quando tipoContrato for "temporario", o campo dataFim deve ficar
118
+ obrigatorio e visivel. Quando nao for temporario, dataFim deve ficar opcional.
119
+
120
+ Use somente JSON Logic canonico.
121
+ Use somente alvos existentes no target catalog.
122
+ Nao altere formRulesState.
123
+ Marque metadata.origin como "llm" e metadata.reviewStatus como "pending".
124
+ Explique o impacto antes de aplicar.
125
+ ```
126
+
127
+ Resposta esperada da LLM:
128
+
129
+ ```json
130
+ {
131
+ "formRules": [
132
+ {
133
+ "id": "rule-data-fim-contrato-temporario",
134
+ "name": "Data fim obrigatoria para contrato temporario",
135
+ "description": "Exige data fim quando o contrato do funcionario for temporario.",
136
+ "metadata": {
137
+ "origin": "llm",
138
+ "reviewStatus": "pending"
139
+ },
140
+ "targetType": "field",
141
+ "targets": ["dataFim"],
142
+ "effect": {
143
+ "condition": {
144
+ "==": [{ "var": "tipoContrato" }, "temporario"]
145
+ },
146
+ "properties": {
147
+ "visible": true,
148
+ "required": true
149
+ },
150
+ "propertiesWhenFalse": {
151
+ "required": false
152
+ }
153
+ }
154
+ }
155
+ ]
156
+ }
157
+ ```
158
+
159
+ ## Prompt para regra LGPD
160
+
161
+ ```text
162
+ Crie uma regra LGPD para o formulario.
163
+
164
+ Quando o campo consentimentoLgpd for false, o botao submit deve ficar
165
+ desabilitado e o bloco visual aviso-lgpd deve mostrar a mensagem:
166
+ "Aceite o termo de privacidade para continuar."
167
+
168
+ Use targetType "action" para submit e "visualBlock" para aviso-lgpd.
169
+ Nao coloque aviso-lgpd em fieldMetadata.
170
+ Nao crie FormControl para aviso-lgpd.
171
+ Use JSON Logic canonico.
172
+ Deixe a sugestao pendente de revisao humana.
173
+ ```
174
+
175
+ Resposta esperada:
176
+
177
+ ```json
178
+ {
179
+ "formRules": [
180
+ {
181
+ "id": "rule-submit-bloqueado-sem-lgpd",
182
+ "name": "Bloquear envio sem consentimento LGPD",
183
+ "metadata": {
184
+ "origin": "llm",
185
+ "reviewStatus": "pending"
186
+ },
187
+ "targetType": "action",
188
+ "targets": ["submit"],
189
+ "effect": {
190
+ "condition": { "===": [{ "var": "consentimentoLgpd" }, false] },
191
+ "properties": { "disabled": true },
192
+ "propertiesWhenFalse": { "disabled": false }
193
+ }
194
+ },
195
+ {
196
+ "id": "rule-aviso-lgpd-sem-consentimento",
197
+ "name": "Aviso LGPD sem consentimento",
198
+ "metadata": {
199
+ "origin": "llm",
200
+ "reviewStatus": "pending"
201
+ },
202
+ "targetType": "visualBlock",
203
+ "targets": ["aviso-lgpd"],
204
+ "effect": {
205
+ "condition": { "===": [{ "var": "consentimentoLgpd" }, false] },
206
+ "properties": {
207
+ "visible": true,
208
+ "message": "Aceite o termo de privacidade para continuar."
209
+ },
210
+ "propertiesWhenFalse": {
211
+ "visible": false
212
+ }
213
+ }
214
+ }
215
+ ]
216
+ }
217
+ ```
218
+
219
+ ## Prompt para explicar regra existente
220
+
221
+ ```text
222
+ Explique esta regra para um analista de negocio.
223
+
224
+ Responda com:
225
+ 1. Quando ela dispara.
226
+ 2. O que ela altera.
227
+ 3. Se afeta payload ou apenas UI.
228
+ 4. Riscos de negocio.
229
+ 5. Diagnostics que precisam correcao.
230
+ ```
231
+
232
+ A explicacao deve traduzir Json Logic para linguagem de dominio e citar os
233
+ alvos por label quando o contexto tiver label disponivel.
234
+
235
+ ## Prompt para corrigir diagnostics
236
+
237
+ ```text
238
+ Corrija as regras abaixo usando os diagnostics do editor.
239
+
240
+ Nao mude a intencao de negocio.
241
+ Se um alvo nao existir, proponha o alvo existente mais proximo e explique.
242
+ Se uma propriedade for rejeitada pelo schema, substitua por uma propriedade
243
+ permitida ou remova com justificativa.
244
+ Mantenha metadata.reviewStatus como "pending".
245
+ ```
246
+
247
+ Mapeamento operacional:
248
+
249
+ | Diagnostic | Acao esperada da LLM |
250
+ | --- | --- |
251
+ | `missing-targets` | Pedir ou preencher `targets`. |
252
+ | `field-target-not-found` | Trocar por `fieldMetadata[].name` existente. |
253
+ | `target-not-found` | Trocar por alvo existente no mesmo `targetType`. |
254
+ | `invalid-condition` | Reescrever como Json Logic canonico. |
255
+ | `unsupported-property` | Usar propriedade permitida por `RULE_PROPERTY_SCHEMA`. |
256
+ | `unsupported-target-type` | Escolher um `targetType` permitido. |
257
+ | `missing-effect` | Criar `effect.condition` e `effect.properties`. |
258
+ | `rule-evaluation-error` | Simplificar condicao e remover operadores nao suportados. |
259
+
260
+ Quando o diagnostic envolver apenas propriedade rejeitada, valor invalido ou
261
+ valor parcialmente saneado, o editor tambem pode aplicar a acao deterministica
262
+ `Corrigir`. Essa acao usa o mesmo sanitizer central do runtime, remove ou
263
+ coage propriedades conforme `RULE_PROPERTY_SCHEMA` e regenera `formRulesState`.
264
+ Use LLM quando a correcao exigir decisao semantica de dominio, por exemplo
265
+ trocar uma propriedade inexistente por outra intencionalmente equivalente ou
266
+ explicar por que uma regra deve ser removida.
267
+
268
+ ## Fluxo de aplicacao seguro
269
+
270
+ 1. Host/editor monta o pacote de contexto.
271
+ 2. LLM gera uma proposta por operacao autoral ou em `formRules`.
272
+ Para regra de negocio, politica, elegibilidade, validacao, compliance ou
273
+ decisao compartilhada, use `domain-rules`/`shared_rule_authoring` antes de
274
+ materializar `form_config`. Para uma projecao visual derivada de decisao ja
275
+ governada, aceite `operationId: "rule.visualBlockGuidance.add"` com
276
+ `type: "visualBlockGuidance"`, `targetType: "visualBlock"`,
277
+ `context: "notification"` e metadata pendente.
278
+ 3. Compilador/adapter rejeita qualquer tentativa de gravar `formRulesState`.
279
+ 4. Editor valida alvos, condicao e propriedades.
280
+ 5. Editor mostra diff e impacto para o analista.
281
+ 6. Analista aceita, edita ou rejeita.
282
+ 7. Ao aceitar, editor marca `metadata.reviewStatus: "accepted"`.
283
+ 8. Editor tenta gerar `formRulesState` por conversor interno.
284
+ 9. Runtime aplica regra e emite `ruleDiagnosticsChange` se houver problema.
285
+
286
+ ## Guardrails permanentes
287
+
288
+ - Nunca persistir codigo executavel em regra.
289
+ - Nunca editar `formRulesState` diretamente por LLM.
290
+ - Nunca tentar contornar essa regra no patch final: `compileAiResponse` e
291
+ `applyPatch` tambem rejeitam escrita direta em `formRulesState`.
292
+ - Nunca materializar regra visual direto no estado do builder. O editor preserva
293
+ semantica de `formRules[].type` usando `config.ruleType` internamente no
294
+ round-trip.
295
+ - Nunca criar alvo que nao exista no mapa de targets.
296
+ - Nunca usar propriedade fora do schema permitido.
297
+ - Nunca tratar `visualBlock` como campo.
298
+ - Para `visualBlock` com varios nos editaveis, usar o node id correspondente em
299
+ `textNodeId`, `titleNodeId` ou `messageNodeId`.
300
+ - Nunca esconder erro de regra: todo descarte deve virar diagnostic ou status.
301
+ - Regras LLM entram como `pending`; aceite humano e uma decisao explicita.
302
+
303
+ ## Sinal de prontidao para runtime
304
+
305
+ Uma regra esta pronta para runtime quando:
306
+
307
+ - todos os targets existem;
308
+ - a condicao e Json Logic valida;
309
+ - as propriedades passam pelo whitelist;
310
+ - o impacto foi explicado;
311
+ - o preview true/false foi revisado;
312
+ - a origem/revisao esta coerente;
313
+ - o runtime nao emite diagnostic apos aplicar.