@praxisui/dynamic-form 10.0.0-rc.4 → 10.0.0-rc.40

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.
@@ -4,7 +4,7 @@ doc_type: "adr"
4
4
  component: "praxis-dynamic-form"
5
5
  status: "accepted"
6
6
  owner: "praxis-ui"
7
- last_updated: "2026-09-10"
7
+ last_updated: "2026-10-23"
8
8
  ---
9
9
 
10
10
  # Dynamic Form Authoring Document Semantics
@@ -23,6 +23,63 @@ Ao aplicar um documento canônico:
23
23
 
24
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
25
 
26
+ ## Rule conversion and recovery
27
+
28
+ `config.formRules` owns the canonical rule expression and both effect branches.
29
+ `formRulesState` is derived visual authoring state. Wizard inline JSON Logic must
30
+ survive Apply, Save and reopen unchanged. Conditions outside the visual graph
31
+ vocabulary remain intact inline and are diagnosed as `runtime-only`; a valid
32
+ root-data reference (`var: ''`) is not an invalid field reference.
33
+
34
+ A partial graph must never weaken an AND/OR expression by dropping children.
35
+ Missing rule roots, rules without a serializable target, and missing, cyclic or
36
+ unsupported explicit condition graph nodes block Apply/Save while
37
+ retaining the draft and last accepted configuration. Repairing through the
38
+ properties panel revalidates a supplied replacement. A nonserializable visual
39
+ draft is repaired in the wizard or JSON; the effects panel and accepted-rule diagnostics are withheld until
40
+ conversion succeeds, so it cannot present the last accepted rule as the current
41
+ draft. Deleting the last rule removes both
42
+ `formRules` and `formRulesState`, including after a validation failure.
43
+
44
+ Editor validation that gates Apply/Save uses the injected `PraxisJsonLogicService`
45
+ and the same host operator registry as runtime evaluation. A registered host
46
+ operator can remain runtime-only in the visual builder and must still save and
47
+ reopen. Unknown operators and invalid arity remain blocked.
48
+
49
+ ### Reviewing conditional presentation rules
50
+
51
+ The rule wizard and list describe the condition, target labels, and every effect
52
+ in both branches. Boolean condition choices use Yes/No (Sim/Não). Grouping and
53
+ order remain visible for AND/OR; expressions outside the readable vocabulary
54
+ retain an explicit advanced/JSON review path and their original expression.
55
+
56
+ Indicators have separate scopes: the Visual Builder checks structure; the
57
+ structured effects panel reports whether a property can be edited; form
58
+ analysis validates the condition against the injected runtime registry and
59
+ reports unavailable targets or unsupported properties. A successful sample-data
60
+ preview proves only the selected branch for those data. None of these labels
61
+ replaces target access policies or a governed business decision.
62
+
63
+ Replacing JSON rules, clearing the list, and Reset refresh the same visual draft
64
+ and effects panel. A valid stale `formRulesState` is rebuilt from canonical
65
+ `formRules`; malformed explicit graphs remain repairable and block Apply/Save.
66
+ Removing or emptying `formRules` in a JSON replacement clears residual visual
67
+ state. Input echoes do not freeze subsequent edits or reset builder history.
68
+ Each canonical form rule reopens as one `propertyRule` with its complete target
69
+ list, both effect branches and authoring metadata. The bridge does not recreate
70
+ legacy conditional-validator nodes or duplicate a rule per target.
71
+
72
+ Presentation (`formRules`) and conditional actions (`formCommandRules`) retain
73
+ separate channels and validation policies. Hidden or inaccessible targets are
74
+ reported as unavailable; authoring does not grant access to those fields.
75
+
76
+ Identified standalone forms with host-provided fields use the same persisted
77
+ configuration initializer as schema-backed forms. Local-first restores saved
78
+ rules and field customizations after reload; input-first, volatile configuration
79
+ and transient layout persistence retain their existing policies. Standalone initialization does not
80
+ request a server schema. New host inputs received while storage or hooks are
81
+ pending remain authoritative when the form is built.
82
+
26
83
  ## Filter Form projection
27
84
 
28
85
  `praxis-filter-form` compartilha o mesmo documento canônico, parser e serializer,
@@ -161,7 +218,8 @@ that the resource schema could not be loaded.
161
218
 
162
219
  The wrapper also exposes the existing `configPersistenceStrategy` as **Fonte da configuração**.
163
220
  **Definida nesta página** selects `input-first`; **Preferências salvas** selects `local-first`.
164
- The runtime default remains `local-first`. When the goal is a page-owned layout, select `input-first`
221
+ **Configuração temporária** selects `volatile`, which never reads, saves or clears independent child preferences.
222
+ The runtime default remains `local-first`. For ordinary page layouts, select `input-first`
165
223
  so an older saved form preference does not replace the correctly persisted page sections on reload.
166
224
  Changing only the source preserves the authored page config even if the currently displayed effective
167
225
  layout came from older local preferences. This is an existing runtime input, not a new persistence
@@ -213,3 +271,11 @@ Conflicting preference regression: the external config hydration suite passed al
213
271
  and placeholder (log `/private/tmp/praxis-form-preference-conflict-tests.log`). This
214
272
  is an isolated storage-service test and serialized widget round-trip; actual
215
273
  backend persistence and visual editor interaction are validated separately.
274
+
275
+ ## Governed page child adapter
276
+
277
+ For published page authorship, use [the native page adapter](governed-page-widget-adapter.md), not the
278
+ common wrapper output directly. It preserves exact presence and only explicit editor deltas, locks
279
+ bindings/context to the admitted seed, and derives volatile execution inputs from page/widget identity.
280
+ Native `presentation` and `dossier` modes survive open/save/reopen; new visual flows still prefer
281
+ `view` with a separate display preference. Filter Form keeps its three-mode runtime subset.
@@ -0,0 +1,46 @@
1
+ ---
2
+ title: "PR 645 — final review and regression evidence"
3
+ doc_type: "guide"
4
+ component: "praxis-dynamic-form"
5
+ status: "validated"
6
+ owner: "praxis-ui"
7
+ last_updated: "2026-10-23"
8
+ ---
9
+
10
+ # Final review of PR 645
11
+
12
+ Review started at PR head `9ad3c8221b1de2bdba6b62adec778c185553bcd5`, against main `51075de81704596606bb578ab681124df5ae8493`. The follow-up source is identified by the refreshed 32-file `source-hashes.json`; earlier screenshots and logs remain historical evidence at the original head, not new executions against the follow-up. The original shared checkout and its server were preserved.
13
+
14
+ ## Findings resolved before integration
15
+
16
+ 1. **Shared graph ownership.** A and B could reference G/L, but clearing A retained `parentId=A`; clearing/removing B then left invalid orphan conditions. The existing graph owner now transfers retained parent references when the old edge is removed. Removal follows both child and condition references, including nested property rules, while preserving external sharing, immutable history and undo/redo. Incoming draft references are remapped together with IDs. The original red lane had two failures; the final service/component lane passed 74 tests.
17
+ 2. **Angular input assignment and cold storage.** Angular assigns `config` before `ngOnChanges`, so comparing against that property missed already-normalized replacements. The previous host document now determines whether the input changed. Genuine standalone replacements, including empty documents, rebuild without resuming an obsolete persisted initializer. A cold adapter that returns the old saved value on every subscription reproduced the failure; the final test asserts one config read and the latest field metadata.
18
+ 3. **Equivalent host echoes.** A local-first form can have a saved effective document different from its opening host document. An equivalent echo must retain the effective document and both rule branches, dirty controls and pending initialization. The public input retains the same type; an accessor observes only the transient pre-assignment references around the existing single effective document. Internal writes use that backing document directly. Only a config echo is excluded from the ownership epoch; other owner/mode/resource fences remain. Tests cover settled and pending-hook echoes, manual lifecycle calls without assignment, and two host assignments before one change-detection pass, ending either in an echo or a genuine update. Echo and batched-echo red lanes each reproduced one failure before correction.
19
+
20
+ Inventory classification: `suportado-parcialmente`, corrected at the existing Visual Builder graph and Dynamic Form runtime owners. No additional model, persistence adapter, endpoint, feature flag, exported type or parallel authoring document was introduced by the review fixes.
21
+
22
+ ## Final applicable gates
23
+
24
+ | Gate | Final result |
25
+ | --- | --- |
26
+ | Visual Builder service, Rule Editor, Rule Definition and Field Condition Editor | 74 passed |
27
+ | Form field metadata, first-config and external-config hydration | 74 passed |
28
+ | Official `build-libs.js --prod --only praxis-dynamic-form` dependency closure, including VB, Form and Page Builder | Passed |
29
+ | Library purity | Passed, 2320 files |
30
+ | Published documentation assets | Passed, 5 packages |
31
+ | Material select content model | Passed, zero debt |
32
+ | Catalog | Passed, zero errors/warnings |
33
+ | Authoring contract acceptance | Passed, 20/20 |
34
+ | Final component-doc extraction versus tracked source, excluding generation timestamp | Equal |
35
+
36
+ These are focal lane counts, not a combined unique-test total. The unchanged editor/converter/diagnostic and visual presentation evidence is recorded in `validation.md`. Tests use Chrome Headless and real Angular `componentRef.setInput`; mocked storage/hooks and schema reconciliation do not constitute live HTTP proof. The final review did not rerun the desktop/narrow live authoring journey or a database lane. It does not certify settled form/component identity switching, full-suite behavior, screen readers, concurrency or release publication.
37
+
38
+ The catalog initially lacked an ignored generated ingestion artifact. Official workspace generation resolved that environmental failure without editing tracked registry data. Authoring acceptance initially lacked the backend sibling path in the isolated worktree; the final gate used only an immutable source snapshot of canonical config-starter main `deebc69187f2aebcb23ebe259a6913947fc10b27`, not the unrelated dirty backend checkout. No backend runtime or database was started for this source-contract check.
39
+
40
+ The graph fix author was different from the runtime fix author. Root independently reviewed both final diffs; the graph author also independently reviewed the final runtime accessor, internal writes, batching and ownership fences. No blocking finding remained in the reviewed final source. Test/configuration strictness was not weakened.
41
+
42
+ ## Derived artifacts and skills
43
+
44
+ The existing documentation already describes graph ownership, host authority and persistence; the review enforces those invariants. No new public semantics require a README, HTTP corpus, AI manifest or landing delta. Final metadata extraction confirms no derived catalog change. Landing PR 268 from the original implementation remains outside this merge.
45
+
46
+ Visual Builder graph skill: `existente-adequada`, because its canonical graph-runtime guidance already requires shared ownership, graph integrity and undo proofs. Form schema/runtime skill: `atualizar-existente`, adding real Angular/cold adapter and effective-echo proofs in canonical skills PRs 838 and 839. Both were independently reviewed and integrated; final canonical merge is `3ca2d184ba803dac1e560697142475e5ee8336fa`. Validation used the repository's focal validator, Python preflight and both family audits. The optional quick validator lacked `yaml`; the official fallback passed. Official selective synchronization of this one skill passed: canonical, manifest and installed hashes match, and all 796 files outside the target remained unchanged. Five unrelated existing Praxis drifts were preserved. The raw selective receipt is `review-skill-sync-receipt.json`.
@@ -0,0 +1,50 @@
1
+ # Revisão independente — Form Authoring #635
2
+
3
+ Revisor: `rules_audit`; atualizado em 2026-10-23T21:18:03+00:00.
4
+ Checkout: `/Users/rodrigo/Dev/pessoal/praxis-plataform/.worktrees/form-p1-631-633`; branch `fix/form-authoring-635`; HEAD `51075de81704596606bb578ab681124df5ae8493` **mais alterações locais**. Os hashes abaixo identificam os bytes revisados, não um futuro commit.
5
+
6
+ ## Resultado e limites
7
+
8
+ Sem bloqueantes nos recortes revisados abaixo. Esta nota é revisão de código e evidência; não declara browser final, validação integral, contagem de testes únicos nem autorização de merge.
9
+
10
+ - **Autoria VB:** este agente implementou o trabalho em `praxis-visual-builder/src` e seus testes. A revisão independente desses trechos foi feita pelo coordenador `root`; a presente nota não substitui essa revisão por autorrevisão. A última rodada própria foi `88 SUCCESS` em sete includes (`/tmp/praxis-635-vb-final88.log`); as contagens intermediárias são execuções sobrepostas, não suítes somáveis.
11
+ - **Revisão independente feita por este agente:** ConfigEditor, painel de propriedades, textos/i18n, documentação e o follow-up runtime de `initialValue`. Não escrevi esses trechos. Não reexecutei suas suítes nem os builds finais nesta revisão. A ponte Form/propertyRule e sua preservação de metadados também têm revisão própria de `audit_environment`; aqui apenas confrontei seu contrato com o consumidor VB.
12
+
13
+ ## Escopos confrontados
14
+
15
+ - **ConfigEditor:** hidratação centralizada; `formRules` prevalece sobre projeção válida obsoleta; drafts inválidos continuam disponíveis e bloqueiam Apply/Save; JSON vazio e Reset não ressuscitam estado residual. O eco descartado é somente uma assinatura obsoleta conhecida; seleção de nó não substitui o documento. O teste de assinatura distingue `selected` de uma mudança real no valor da condição.
16
+ - **Painel e pureza:** o painel de efeitos obsoleto fica oculto durante falha de conversão; a mensagem esclarece qual configuração foi preservada. O painel usa o `PraxisJsonLogicService` injetado para validar/simular; prévia de ramo, edição de propriedade e validade runtime têm escopos explícitos. A guarda não oculta nem une o canal separado de comandos. Sem autorização extra de acesso ou decisão de negócio pela UX.
17
+ - **i18n/docs:** mensagem do draft presente uma vez em pt/en; documentação coerente com os canais separados, limitações da prévia, alvos indisponíveis e edição de JSON avançado. README descreve a assinatura aditiva `updateNode(..., conditionState?)`, atomicidade, histórico e preservação de draft. Nenhum novo manifest/modelo foi exigido para esse ajuste visual.
18
+ - **Runtime, revisão adicional:** a atualização local autoritativa de `initialValue` agora atualiza o cache mesmo antes dos controles. O build posterior usa o snapshot mais recente; se os controles já existem, o mesmo ramo faz reset/patch sem emitir mudanças de valor e restaura pristine/untouched. A condição existente `usesInitialValueAsAuthoritativeSnapshot()` continua excluindo edit/view com `readUrl` ou `resourcePath`; não encontrei ampliação da autoridade local sobre dados remotos. Confrontei os quatro casos storage/afterInit × atualização/limpeza e suas asserções sem HTTP. A revisão principal do guard de `loadEntity` pertence a `audit_environment`/root.
19
+
20
+ A atestação runtime existente registra `67/67` por seu executor (`standalone-runtime-final-attestation.json`); correspondência dos três hashes de fonte/testes com esta árvore: **True**. Isso não transforma essa execução em uma prova nova executada por este revisor.
21
+
22
+ Follow-up VB após a rodada de 86: a assinatura de eco normaliza somente dados de transporte (`selected`, `parentId`, `children` omitido/`[]` e ordem de chaves), preservando conteúdo e ordem semântica. Os dois novos casos cobrem o passo Condição montado no MatStepper ao ativar Visual, o eco atômico equivalente e a hidratação de mudança externa real. O coordenador revisou esse delta; a prova browser final permanece sob sua responsabilidade. `git diff --check` passou.
23
+
24
+ Follow-up independente final do escopo dos diagnósticos: aprovados os guards em HTML que também ocultam o diagnóstico aceito e seu placeholder vazio enquanto `ruleConversionFailed` estiver ativo. O alerta de conversão, o editor visual e o canal separado de comandos continuam disponíveis; estado aceito, persistência e gates não mudam. As três novas asserções do teste montado cobrem ambos os estados ausentes no draft inválido e o retorno do diagnóstico após reparo. A frase atualizada em `dynamic-form-authoring-document-semantics.md` corresponde ao comportamento. O executor root registrou `69 SUCCESS` em `/tmp/praxis-635-editor-diagnostic-scope-final.log` e build Form de produção verde; conferi o resultado bruto do log, sem executar outra suíte. Sem novos bloqueantes nesta revisão.
25
+
26
+ ## Identidade das fontes
27
+
28
+ SHA-256 agregado dos 12 arquivos revistos: `93fbacf7a416827699ef172877caeb82e1207c42dd8db8c180398a26158d0adb`.
29
+ Snapshot agregado de 17 arquivos VB de código/testes modificados ou novos: `fe60920e81205607fe87096add54791f0ca9492d35862cdf2f8df15ea1f739e5`. Esse segundo conjunto é de autoria, cuja aprovação independente pertence ao root.
30
+ Algoritmo: ordenar os paths relativos; concatenar para cada arquivo `path UTF-8`, NUL, bytes do arquivo, NUL; calcular SHA-256.
31
+
32
+ <details>
33
+ <summary>SHA-256 por fonte revista</summary>
34
+
35
+ | Fonte relativa ao checkout acima | SHA-256 |
36
+ | --- | --- |
37
+ | `projects/praxis-dynamic-form/src/lib/config-editor/praxis-dynamic-form-config-editor.ts` | `472441a47e45788961bdb1debe5618dd3f035fa9f588d16395a6e2debf713eaa` |
38
+ | `projects/praxis-dynamic-form/src/lib/config-editor/praxis-dynamic-form-config-editor.html` | `89ca1a449d24bacaa2ac051fa152623524f70d843bab2e834375014874dddd94` |
39
+ | `projects/praxis-dynamic-form/src/lib/config-editor/praxis-dynamic-form-config-editor.spec.ts` | `e1f6418631923aed67479168f534e2a7193dffce3efe682e3adf5371d0b7888e` |
40
+ | `projects/praxis-dynamic-form/src/lib/config-editor/rule-properties-panel.component.ts` | `42a0e7ed41ab822ed82e6dcb455671be0fc3546a4676bc09e4f2daffde71f241` |
41
+ | `projects/praxis-dynamic-form/src/lib/config-editor/rule-properties-panel.component.spec.ts` | `7428843281cfdd408064677bc531437843cea23f0e19ab32d1c376b749b46987` |
42
+ | `projects/praxis-dynamic-form/src/lib/praxis-dynamic-form.i18n.ts` | `2aadec19c29908e76faf3cb3a6620bc905f7088322f7cc3b92bed3069d82e011` |
43
+ | `projects/praxis-dynamic-form/src/lib/praxis-dynamic-form.ts` | `76d419643fc77da32c30b8fba1c7d65e955552adb84f0576f7f8b4eb9c2a7c1e` |
44
+ | `projects/praxis-dynamic-form/src/lib/praxis-dynamic-form.field-metadata-roundtrip.spec.ts` | `e8e967d0dccec403d2dff1c7691a5f609bf6d1c8bfd4f48a57139a3f9f78a403` |
45
+ | `projects/praxis-dynamic-form/src/lib/praxis-dynamic-form.first-config-hydration.spec.ts` | `da5d24f06e2fb5c72acc74a65dde090a2d5a0c9e14621236e9c6d1eb1c4df706` |
46
+ | `projects/praxis-dynamic-form/docs/dynamic-form-authoring-document-semantics.md` | `98235e6fae395e2f51a32ace72d9369d7b7f0e2097f689bf15b4f419bcb39d40` |
47
+ | `projects/praxis-dynamic-form/src/lib/config-editor/praxis-dynamic-form-config-editor.json-api.md` | `3a2e2c2e78c6286dbd34396ee21e468244321fda7c2c4bc6112252990d81bc58` |
48
+ | `projects/praxis-visual-builder/README.md` | `6250604032792b0f23f4b33d5a1596e51325b27911aba7f0268b801a571dbe6d` |
49
+
50
+ </details>
@@ -0,0 +1,76 @@
1
+ ---
2
+ title: "Conditional form authoring — issue 635 validation"
3
+ doc_type: "guide"
4
+ component: "praxis-dynamic-form"
5
+ status: "validated"
6
+ owner: "praxis-ui"
7
+ last_updated: "2026-10-23"
8
+ ---
9
+
10
+ # Conditional form authoring — issue 635
11
+
12
+ The subsequent [final PR review](final-review.md) records additional ownership and Angular input regressions found and corrected before integration, final source hashes and fresh focal/build gates. Browser screenshots below belong to the original PR head; they were not rerun during that final review.
13
+
14
+ The change was implemented in an isolated checkout on main `51075de81704596606bb578ab681124df5ae8493`. Unrelated changes in the original checkout were preserved. Classification: cross-library public behavior, with an additive optional `conditionState` argument on the existing `RuleBuilderService.updateNode` API. No new rule model, endpoint, AI contract, workspace configuration, dependency or public-api export was introduced.
15
+
16
+ ## Canonical inventory and impact
17
+
18
+ Existing canonical property effects, graph drafts, host operator registry, diagnostics and persistence already cover the requested behavior. Summaries/status scopes are `ja-suportado-so-ux`; replacement, graph transfer and standalone hydration were `suportado-parcialmente`. An atomic node plus complete owned condition-graph update was missing from the existing service operation: the optional existing RuleBuilderState argument supplies that operation without a parallel contract. Complete conditions derive from fresh graph fields; incomplete descendants must not become an unconditional or partial condition.
19
+
20
+ Owners: Visual Builder for authoring/history and Dynamic Form for the canonical document, diagnostics and persistence. Direct consumers are the Form config editor, authoring diagnostics and the All Fields showcase. Form→builder now produces one propertyRule per rule, retaining every target, both branches, identity and authoring/semantic metadata. Existing legacy ingestion remains; new authoring does not generate legacy conditional-validator nodes.
21
+
22
+ Presentation formRules and formCommandRules retain separate channels. Core access policy remains authoritative; formHidden/access filters were preserved. Source builds include a direct consumer and the official dependency closure. No backend schema, business rule or HTTP corpus changed.
23
+
24
+ ## Automated gates
25
+
26
+ | Gate | Result |
27
+ | --- | --- |
28
+ | Visual Builder: field condition, wizard, rule editor/list, target selector, service and summary | 88 passed |
29
+ | Form config editor, converters and diagnostics | 121 passed |
30
+ | Final mounted ConfigEditor diagnostic-scope guard | 69 passed (overlaps the preceding lane) |
31
+ | Standalone field metadata roundtrip, first/external config hydration | 67 passed |
32
+ | Official production dependency closure through Dynamic Form and Page Builder consumer | Passed |
33
+ | Final Visual Builder and Dynamic Form production builds | Passed |
34
+ | Purity and changed-document frontmatter | Passed |
35
+
36
+ These are focal unit/component lanes, not unique-test totals or a full release certification. The mounted Material stepper tests cover backward/forward navigation and linear blocking; real FieldConditionEditor debounce and canonical own echoes are exercised. Atomic graph tests cover incomplete descendants, cycles, shared nodes, removal, selection and undo. Host initialValue updates/clears during storage/hooks preserve the latest local authority without schema/entity HTTP. Existing remote-authority guards remain intact.
37
+
38
+ Logs in this folder contain the raw focal outcomes with terminal control sequences and trailing display padding removed. Historical failures were diagnosed before rerun; no test configuration or TypeScript strictness was weakened. The full test suite and screen-reader/assistive-technology certification were not run.
39
+
40
+ ## Browser validation
41
+
42
+ Chrome via visible UI on official UI4003/API8088, frozen task checkout. No DOM state injection, fetch, mocks or JSON were used to author the simple rule. The real library All Fields example was used: Toggle and URL were renamed to Ativo and Foto (URL) through the visible Metadata Editor. This is a local form example using real remote config persistence; it is not certification of the Quickstart Foto upload or its backend field-access policy.
43
+
44
+ The analyst task used target selection, Visual condition Ativo = Sim, visible/required true and false branches, readable review and Save. The review and list describe all four effects. The runtime false branch hides Foto; the true branch exposes a required input with aria-required=true. Sample-data preview evaluates the two branches separately and explicitly states its limits.
45
+
46
+ Verified scenarios include incomplete draft/disabled saving with stale accepted effects and diagnostics withheld, repaired draft, keyboard target/Boolean choices and Next/Anterior, JSON replacement and advanced runtime-only if condition, exact advanced Save/reload with both branches, and subsequent restoration of the simple rule. Merely selecting a rule and navigating leaves Sem alterações. Closing returns focus to Configurar formulário.
47
+
48
+ Reset was confirmed through its visible dialog: it restores the opened document in the editor and this host also clears persisted keys. A read-only GET returned404 afterward. Reload consequently returned to the host example, as intended; the rule was then authored and saved again. Final persisted receipt returned200/version5 with one rule, toggle===true and both visible/required branches intact. This does not certify ETag conflict handling or concurrent saves.
49
+
50
+ At390×844 the section selector, footer actions and effect controls fit; review content is readable by vertical scrolling. This is an agent simulation, not a human usability study: no human task-time or comprehension score is claimed. Multiple internal scroll areas remain a usability limit for small screens.
51
+
52
+ ## Independent review and derived guidance
53
+
54
+ Each implementation area was reviewed by a different agent. Root reviewed Visual Builder, runtime and converter changes; the VB author independently reviewed root ConfigEditor, panel, docs/i18n and the latest initialValue fix; the runtime author independently reviewed VB metadata preservation and root selection signature. Review covered canonical authority, replacement, both branches, ownership/history, consumers, source/test evidence and docs.
55
+
56
+ Owner documentation was updated. The Visual Builder README is synchronized by the official vendor helper in praxis-ui-landing-page PR268; vendor75/docs25/guides145/sitemap gates passed, with the existing Cron Mermaid warning. No AI manifest/catalog, exported model or HTTP semantic surface changed, so registry/corpus generation was unnecessary.
57
+
58
+ Skills: atualizar-existente for five existing skills in canonical praxis-codex-skills PR836, including document roundtrip, Form authoring settings and Visual Builder rules/graph/JSON Logic. No new skill was introduced. Standalone runtime guidance was already adequate in the canonical schema/runtime skill. Canonical skills PR836 was integrated at e13f4b4d1a0ed1bc127f15105cefc5f2eeb9524f. Official selective sync validated5/5 affected skills and preserved all783 files outside scope and unrelated local drifts. Landing PR268 remains open for review, without deployment.
59
+
60
+ ## Final visual receipts
61
+
62
+ The last PT retest confirmed Condition stayed selected after fresh Visual activation, saving was disabled, and both accepted diagnostics (including the empty placeholder) and stale effects were absent. Repair restored current diagnostics and effects. Immediate Boolean edit→Next and Anterior both worked. JSON formRules=[] with residual formRulesState produced zero rows and the empty diagnostic; replacing it with the complete document restored one editable rule. The test draft was discarded and focus returned to Configure form. No additional configuration was saved during this last retest.
63
+
64
+ English was exercised using the official providePraxisI18nConfig provider on the same UI origin. New summaries/status/preview copy and Yes were localized. The temporary host file was restored exactly: app.config.ts SHA256 bdf1dbc425b4d9babfa76b78a2f913ce36095d3e500d74d344ea5dd8bb251718. Host business labels and some existing metadata/control labels remain Portuguese; a whole-platform translation audit is not claimed. The final display-only diagnostic guard was then retested in PT and the mounted component lane.
65
+
66
+ ![Complete review](desktop-review-accepted.png)
67
+
68
+ ![Incomplete condition blocks saving without stale diagnostics](desktop-incomplete-accepted.png)
69
+
70
+ ![Narrow effect editor](narrow-effects-final-main.png)
71
+
72
+ ![Narrow review, lower effects after scrolling](narrow-review-effects-final-main.png)
73
+
74
+ ![English summary](english-summary-final.png)
75
+
76
+ ![Advanced expression preserved](advanced-reopen-final-main.png)
@@ -0,0 +1,134 @@
1
+ # P1 form authoring — issues #631, #632 and #633
2
+
3
+ Classification: public behavior change with cross-library consumers. Canonical owners are Dynamic Form (rules bridge, form client/context and hydration) and Metadata Editor (cascade authoring). No exported type, endpoint, workspace configuration or dependency change.
4
+
5
+ ## Scope and compatibility
6
+
7
+ - Preserve wizard JSON Logic and both property branches through Apply/Save/reopen. Invalid graphs remain available for repair and cannot silently become unconditional rules.
8
+ - Preserve non-identity cascade filter maps and extraction paths. Table rows own the current edit draft; suggestions fill missing mappings.
9
+ - Give each mounted form its own mutable CRUD client and editor context. This is a breaking beta DI correction; ancestor GenericCrudService replacements must migrate to supported component inputs or component-level test overrides. Shared HTTP infrastructure remains inherited.
10
+ - Make the Quickstart dependency demo a local relationship explorer. Selectors query real resources individually; fields are omitted from domain payloads. Its new document identities avoid inheriting old schema-backed connections.
11
+ - Open field customization from the current canonical materialization, rather than stale selection/render snapshots.
12
+
13
+ Existing contracts cover these behaviors: already supported but incorrectly materialized. No parallel contract or new authoring vocabulary was introduced.
14
+
15
+ ## Review and gate resolution
16
+
17
+ The implementation was isolated on main 8da9401a8; unrelated dirty checkout changes and unrelated documentation hunks were excluded. Reviewers different from the authors inspected conversion/diagnostics, cascade editing, DI ownership, demo and both remaining gates.
18
+
19
+ The old label test conflated a selected snapshot with the current materialization. Regression tests now preserve the Cargo expectation while giving the canonical document/presentation that label, and making selection/cache explicitly obsolete.
20
+
21
+ The earlier host-test compilation failure involved a nullable assertion in an unrelated dirty test. That test is absent from this main baseline; the demo target is compiled and executed without importing the unrelated changes or altering TypeScript configuration.
22
+
23
+ Additional review covered deleting the last invalid rule, repairing through the properties panel, diagnostics for conditions outside the graph subset and loading rules without formRulesState. Valid runtime-only conditions must remain intact; invalid conditions must remain blocked. JSON Logic var:'' is a valid root-data reference, not an invalid field path.
24
+
25
+ ## Validation
26
+
27
+ All selected gates passed on the isolated source tree:
28
+
29
+ | Gate | Result |
30
+ | --- | --- |
31
+ | Rule converters, configuration editor, diagnostics and isolation | 114 passed |
32
+ | Dynamic Form main/config/editorial/presentation/manifest/hydration/protocol | 334 passed |
33
+ | Cascade service and tab | 17 passed |
34
+ | CRUD dialog host consumer | 50 passed |
35
+ | Additional DI consumers: entity selection, schema recovery, layout tabs, presentation preset and widget editor | 77 passed |
36
+ | Dependency demo host target | 1 passed |
37
+ | Official build helper: Metadata Editor, Dynamic Form, CRUD + dependency closure | Passed |
38
+ | Final Dynamic Form and CRUD builds after gate repairs | Passed |
39
+ | Published documentation assets | Passed, 5 packages |
40
+ | MatSelect content model and diff whitespace | Passed |
41
+
42
+ The isolated dependency tree was installed using npm ci. No broad full-test-suite
43
+ or release certification is claimed. Counts represent separate lanes, not a
44
+ claim about unique test coverage.
45
+
46
+ Exact focal spec includes and commands are reproducible from the changed spec
47
+ paths; the main lane also includes first/external hydration, authoring protocol
48
+ and the authoring manifest. Builds use development configuration. Artifact logs
49
+ are retained in the workspace under artifacts/form-p1-fixes-20261022/clean-*.log.
50
+
51
+ ## Final local browser smoke
52
+
53
+ The isolated checkout was served frozen on official UI4003, with its proxy
54
+ explicitly directed to unavailable local API8088. This smoke exercised the local
55
+ editor only and did not attempt option loading or domain submission.
56
+
57
+ Through the visible JSON tab of dependency-fields-demo, a malformed condition
58
+ (`{"===": []}`) produced an invalid-condition diagnostic and disabled Apply and
59
+ Save. Correcting the document by removing rule/state through the same JSON tab
60
+ re-enabled both buttons. Drafts were cancelled and tabs closed; nothing was
61
+ saved to the host or remote configuration.
62
+
63
+ ![Invalid condition blocks Apply and Save](final-invalid-blocked.png)
64
+
65
+ ![Corrected document re-enables Apply and Save](final-recovered-enabled.png)
66
+
67
+ The native confirmation for the visual Remove button could not be accepted by
68
+ the browser-control adapter because its focus command timed out. That attempt
69
+ was abandoned and its tab closed. Visual deletion via that button is not claimed
70
+ as passed; the component regression covers deletion and reopen. The rule list
71
+ also retained a stale row after JSON replacement while canonical diagnostics
72
+ were empty: the remaining UI coherence work belongs to #635. The screenshots
73
+ record this limit rather than hiding it.
74
+
75
+ Tests are unit/component tests using ChromeHeadless, without a database. Dependency builds use the official build-libs helper and its dependency closure. No release workflow, deployment or domain mutation is performed.
76
+
77
+ ## Earlier visual audit evidence
78
+
79
+ The analyst journeys were repeated in Chrome on the previous shared source snapshot, using official UI4003/API8088 and assigned remote Neon branches with runtime identities/TLS. Those screenshots are historical visual evidence, not proof of this isolated revision. Current revision validation is listed separately above.
80
+
81
+ - #631: wizard Ativo=true/false controlled Foto visibility and required state; persisted expression and both effects survived reload.
82
+ - #632: Cargo/Departamento non-identity mapping survived explicit Edit, Save, Apply and reload.
83
+ - #633: RH, Base/Equipe/Membro and Ameaça/Missão/Incidente/Indenização chains completed with real filtered option requests; parent replacement/clear emptied descendants; no-result search and sibling-tab independence were checked.
84
+ - CRUD native Add dialog loaded its command schema and was closed without submission.
85
+
86
+ Limits retained: Foto originally arrived formHidden and required temporary exposure in the visible JSON editor. After reload the target catalog again omitted it, a remaining #635 issue. Structural dotted mapping proof does not certify backend acceptance of that filter. No narrow-screen, screen-reader, adverse-latency, remote ETag/concurrency or latest-release certification is claimed.
87
+
88
+ Detailed original audit artifacts are retained in the workspace artifacts/form-p1-fixes-20261022 directory and linked from the issue discussions. No credentials/network headers are published.
89
+
90
+ ## Derived artifacts and skills
91
+
92
+ README/JSON API owner documentation explains DI migration and the explorer; Metadata Editor README explains lossless cascade editing. No public-api, AI operation/path, manifest shape, HTTP corpus or landing-page contract changed, so no parallel derived contract was created. Authoring manifest tests and published documentation asset checks cover the existing surfaces.
93
+
94
+ Canonical cascade and runtime DI skill updates were previously integrated through praxis-codex-skills#826 and #827 and selectively synchronized. Existing form roundtrip guidance remains adequate: formRulesState is derived, canonical rules are preserved, and runtime discovery does not own persisted semantics. The additional gate repairs enforce that existing guidance.
95
+
96
+ ## Final review before integration — 2026-10-23
97
+
98
+ A new independent review of cad84dd00 found and corrected three cases before
99
+ integration:
100
+
101
+ - A missing or targetless rule root was silently dropped, so the new empty-rule
102
+ branch could delete the last accepted rules. Projection now rejects every
103
+ referenced invalid root, including a mixed valid/invalid graph. The editor
104
+ keeps the accepted document and invalid draft and blocks saving; an explicit
105
+ rootNodes=[] still supports intentional deletion.
106
+ - Blocking diagnostics used a built-in-only JSON Logic instance and rejected a
107
+ valid host operator. Editor diagnostics and command validation now share the
108
+ injected runtime service. A real registered operator is tested through runtime
109
+ evaluation and editor Save/reopen; unknown operators and invalid arity fail.
110
+ - Removing a cascade dependency retained its extraction override record. The
111
+ save path now removes both mapping and extraction override for removed
112
+ dependencies; save/reopen/re-add and last-dependency/default cases are covered.
113
+
114
+ An additional consumer inventory found four test fixtures still providing the
115
+ CRUD mock in the ancestor injector. They now use the documented component-level
116
+ replacement. The entity-selection fixture also supplies the current HttpResponse
117
+ read API while preserving request, error and cancellation assertions. The widget
118
+ editor fixture does not mount Dynamic Form and was intentionally left unchanged.
119
+
120
+ Before/after evidence: missing-root regressions failed before the fix; the host
121
+ operator regression failed before registry propagation; the extra DI lane had
122
+ 19 failures before fixture updates and finished 77/77. Final focused rules lane
123
+ 114/114 and cascades 17/17 passed. The 334-test form lane, 50-test CRUD lane and demo lane were also rerun after
124
+ the production repairs and passed. All three owner/consumer builds were rerun after production repairs.
125
+ No database or remote release workflow was required for these review repairs.
126
+
127
+ The earlier native-dialog/browser and #635 limitations remain unchanged. They
128
+ are not presented as newly validated by these unit/component regressions.
129
+
130
+ The two narrowly scoped guidance additions were independently reviewed and
131
+ integrated through praxis-codex-skills#829 (merge fb0fb5c). Both affected skills
132
+ were selectively synchronized and audited; the other 787 installed skill files
133
+ remained byte-identical and seven unrelated drifts were preserved. No new skill
134
+ or public contract was introduced.
@@ -0,0 +1,58 @@
1
+ # Dynamic Form em páginas governadas
2
+
3
+ O adapter do owner mantém `definition.inputs.config` como a única fonte de configuração do filho.
4
+ A página guarda autoria; o documento nativo é reconstruído a partir desses inputs. A projeção de
5
+ execução é transitória e nunca deve ser gravada de volta no documento da página.
6
+
7
+ O perfil inicial vem do contrato P0 `page-publication-p0` de `praxis-config-starter` (PR #506).
8
+ Core valida estrutura, referências, limites e exige validators dos owners. Este adapter valida o
9
+ perfil nativo local; não autoriza uma fonte, registra uma seed ou substitui a admissão no servidor.
10
+
11
+ `decodeDynamicFormPageInputs` reconstrói `praxis.dynamic-form.editor` v1:
12
+ config, bindings presentes (`mode`, `emptyState`, `presentationModeGlobal`) e contexto presente
13
+ (`backConfig`, `presentation`, `schemaPrefs`). Schema prefs só existe se algum dos três inputs
14
+ `notifyIfOutdated`, `snoozeMs`, `autoOpenSettingsOnOutdated` estiver presente. Ausência, `false`,
15
+ zero, objeto vazio admitido e `null` são preservados. Null em objetos mesclados de config é negado;
16
+ null dentro de arrays atômicos permanece autoria. `layoutScope` não cabe neste perfil.
17
+
18
+ Os cinco modos nativos são `create`, `edit`, `view`, `presentation` e `dossier`. O editor visual
19
+ continua preferindo os três modos de operação com `presentationModeGlobal` separado. Abrir um
20
+ documento nativo dos demais modos não deve convertê-lo. Filter Form mantém somente seus três modos.
21
+
22
+ `encodeDynamicFormPageInputs` é a projeção inversa sem defaults. Campos fora do perfil,
23
+ blocos vazios sem representação nos inputs, identidade/storage e dados de execução recebem
24
+ diagnóstico. O adapter não filtra silenciosamente autoria incompatível.
25
+
26
+ `projectDynamicFormPageEditorChanges(authoredInputs, editorBaseline, editorValue)` aplica apenas
27
+ deltas explícitos sobre a autoria original usando o reconciliador nativo do owner. Capture o
28
+ baseline após a normalização/montagem do editor e preserve-o durante aquela sessão. Alterar
29
+ bindings ou contexto do mesmo widget retorna `seed.replacement-required`; a página precisa
30
+ substituir o widget com nova key e nova fonte admitida. A API de projeção altera somente o draft
31
+ que o chamador recebe; ela não salva preferências nem persiste a página.
32
+
33
+ `materializeDynamicFormPageRuntimeInputs(inputs, pageId, widgetKey)` usa o helper canônico Core para
34
+ identidades `page:<pageId>:widget:<widgetKey>`, projeta `configPersistenceStrategy: 'volatile'`
35
+ e desabilita customização/copiloto independentes no filho. Submit e dados continuam nos contratos
36
+ de domínio existentes. Não existe input runtime `authoringDocument`.
37
+
38
+ A estratégia `volatile` impede leitura, gravação e limpeza de preferências próprias e conexão
39
+ persistida. O Form preserva identidade operacional para montar o formulário, mas as trilhas de
40
+ config/bindings/contexto/schema preferences ficam sem I/O de storage.
41
+ Defaults visuais/materializações transitórias permanecem internos ao runtime e ao editor.
42
+
43
+ Limites: JSON lossless, 256 KiB UTF-8 e profundidade 64 pelo helper Core compartilhado; o documento
44
+ integral da página também tem o mesmo orçamento. Não há host publicado, endpoint de publicação,
45
+ fonte admitida, banco ou release novos neste incremento. A integração Page Builder/host governado
46
+ é trabalho posterior; os wrappers comuns continuam atendendo os fluxos não governados existentes.
47
+
48
+ `volatile` também exclui overlays pessoais de configuração global nos defaults/estado de autoria
49
+ que o owner consome. A instância compartilhada `GlobalConfigService` pode ler sua chave global;
50
+ isso não é prova de zero leitura na aplicação. Tenant, cache, locale e CSP continuam infraestrutura
51
+ do host. O gate comprova ausência de I/O nas chaves do filho e ausência de influência da autoria
52
+ pessoal sobre a configuração publicada. Em Table, `TableDefaultsProvider.getDefaults(id,
53
+ { includeGlobal: false })` preserva defaults nativos sem duplicá-los; mudanças globais e reset
54
+ seguem a mesma política, inclusive o fallback de timezone usado em regras JSON Logic.
55
+
56
+ Respostas e filas de preferências capturam a geração, a identidade e a estratégia do filho. Trocar identidade, documento ou estratégia (inclusive A → volatile → A), ou destruir a instância, invalida a continuação antiga antes do próximo I/O ou da materialização. Uma requisição já enviada não é cancelada retroativamente. Respostas tardias de erro também passam pelo mesmo fence.
57
+
58
+ O fence segue a chave do recurso: conexão, inputs e schema preferences usam identidade do owner e geração do host; apresentação acrescenta a chave `form-pres:<id>:<mode>`. Hidratar mode/path das próprias preferências iniciais não troca o owner. Eventos de inputs do host invalidam a geração e iniciam uma resolução atual. Schema, config e escritas também capturam os bindings de runtime.
@@ -95,6 +95,22 @@ Regra operacional:
95
95
  - se o loader da coluna for localizado, apenas ele e atualizado;
96
96
  - se o loader nao puder ser localizado, o runtime usa fallback seguro de rebuild do form.
97
97
 
98
+ ## Saved configuration after request schema removal
99
+
100
+ When reconciling saved configuration with the current request schema, Core retains
101
+ removed schema-backed fields for authored layout continuity, but marks them hidden,
102
+ disabled and `submitPolicy: "omit"`. A required orphan with a null value therefore
103
+ does not invalidate the group, and a value still returned by the read projection
104
+ cannot reenter the request payload through `getRawValue()`.
105
+
106
+ A field whose `source` is absent is schema-backed for this reconciliation. Explicit
107
+ `source: "local"` fields preserve existing local/transient policies and may opt into
108
+ submission with `submitPolicy: "include"`. Hidden fields still present in the request
109
+ schema remain submit-eligible; do not turn all hidden controls into omitted fields.
110
+ If the server publishes a retained field again, current server validation, visibility,
111
+ enabled state and submit semantics replace the orphan state. No host payload strip,
112
+ new flag or layout deletion is needed.
113
+
98
114
  ## Melhorias no DynamicFieldLoader
99
115
 
100
116
  O guard de rerender do loader passou a incluir no snapshot: