@praxisui/page-builder 8.0.0-beta.2 → 8.0.0-beta.21

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
@@ -11,10 +11,10 @@ Ferramentas de edicao para paginas dinamicas canonicas baseadas em `praxis-dynam
11
11
  ## When to use
12
12
 
13
13
  - Montar paginas dinamicas com widgets e layout visual sobre o runtime canonico
14
- - Entregar experiencia de configuracao de pagina/widget sem depender de editor visual de conexoes
14
+ - Entregar experiencia de configuracao de pagina/widget com editor visual canonico de conexoes
15
15
  - Integrar page composition com IA, settings panel e contratos compartilhados do Praxis UI
16
16
 
17
- O pacote permanece focado no shell canonico de authoring em torno de `praxis-dynamic-page`: palette, page settings, widget shell e catalogos de IA. A composicao declarativa de conexoes deve ser feita exclusivamente via JSON/configuracao canonica no `@praxisui/core`; os editores visuais legados de conexoes sairam do escopo ativo desta fase.
17
+ O pacote permanece focado no shell canonico de authoring em torno de `praxis-dynamic-page`: palette, page settings, widget shell, catalogos de IA e edicao visual de `composition.links`. A fonte de verdade das conexoes continua sendo o contrato `WidgetPageDefinition` do `@praxisui/core`; o editor visual apenas materializa esse contrato canonico.
18
18
 
19
19
  ## Instalacao
20
20
 
@@ -36,12 +36,19 @@ Peer dependencies (Angular v20):
36
36
 
37
37
  Este pacote expoe o shell ativo do builder canonico de pagina dinamica:
38
38
  - `ComponentPaletteDialogComponent` para adicionar widgets a pagina.
39
- - `FloatingToolbarComponent` e `TileToolbarComponent` para acoes rapidas de add/save/preview/configuracao.
40
- - visualizador inicial de conexoes somente leitura para inspecao de `composition.links`.
39
+ - `FloatingToolbarComponent` para ações de página/canvas e ações contextuais do widget selecionado no runtime `praxis-dynamic-page`. Quando o widget possui `WidgetShell` com cabeçalho visível, as ações editoriais transitórias entram no próprio header do shell; quando não há header, o runtime usa uma toolbar contextual de fallback. Em ambos os casos o widget ativo fica identificado e pode abrir assistente com contexto, configuração e remoção governada sem persistir controles editoriais no `shell.actions`.
40
+ - `ConnectionEditorComponent` para inspecionar, criar e remover conexoes canonicas em `composition.links`.
41
41
  - `WidgetShellEditorComponent` e `DynamicPageConfigEditorComponent` para authoring de shell/canvas sem redefinir a semantica canonica de composicao.
42
42
 
43
- Conexoes continuam pertencendo ao contrato `WidgetPageDefinition`, mas a criacao/manutencao delas nesta fase deve acontecer por JSON/configuracao canonica e nao por builder/graph/editor visual legado.
44
- O viewer ativo nesta fase existe apenas para inspecao contextual do contrato canonico e nao para editar links inline.
43
+ Conexoes continuam pertencendo ao contrato `WidgetPageDefinition`. O editor visual do Page Builder cria, remove e edita links inline preservando o envelope canonico `page.composition.links`, incluindo `condition` em Json Logic, `policy` operacional e `transform` canônico, sem introduzir modelo paralelo de grafo. O historico de desfazer/refazer do editor e transitorio: ele reemite snapshots canonicos por `pageChange`, mas nao persiste estado de historico dentro da pagina.
44
+
45
+ Cada link persistido usa `CompositionLink.id` como identidade estavel. Superficies de authoring tambem devem usar `id` ao criar ou remover links; aliases como `linkId` nao fazem parte do contrato canonico.
46
+
47
+ O roadmap tecnico para evoluir o editor radial esta registrado em [`connection-editor-reference-study.md`](./connection-editor-reference-study.md).
48
+
49
+ Nested component ports devem ser modeladas no mesmo contrato `composition.links`, usando `component-port + nestedPath`.
50
+ O editor representa o endpoint nested como sub-identidade do owner top-level, sem criar um no de canvas separado para o widget filho.
51
+ Planos de IA (`UiCompositionPlan`) tambem devem usar `nestedPath` para widgets internos; nao gere `widgetEvent`, wrappers host-specific ou `bindingPath` profundo como caminho principal para nested ports.
45
52
 
46
53
  ## AI Capabilities Registration
47
54
 
@@ -94,21 +101,53 @@ Registro via token:
94
101
 
95
102
  Para gerar uma página a partir de um prompt usando o backend canônico do `praxis-config-starter`, configure `PageBuilderAgenticAuthoringService` com o endpoint interno opt-in `/api/praxis/config/ai/authoring`.
96
103
 
97
- O chrome conversacional do assistente usa `PraxisAiAssistantShellComponent` de `@praxisui/ai`. O Page Builder continua dono da semântica agentic de página: resolução de intenção, preview, apply, save, reopen e compilação do plano validado para `WidgetPageDefinition`.
104
+ O chrome conversacional do assistente usa `PraxisAiAssistantShellComponent` de `@praxisui/ai`, mas a presença minimizada deve ser renderizada pelo shell da aplicação com `PraxisAiAssistantSessionHostComponent`, lendo o `PraxisAssistantSessionRegistryService`. O Page Builder apenas registra sua sessão com identidade estável e contexto `Page Builder`; a identidade pública continua sendo o copiloto semântico Praxis. O Page Builder continua dono da semântica agentic de página: resolução de intenção, preview, apply, save, reopen e compilação do plano validado para `WidgetPageDefinition`.
105
+
106
+ O composer do Page Builder IA segue o padrão atual de chats LLM: a ação de envio é icon-only, com `aria-label` semântico para gerar preview. O texto não deve aparecer como label visual do botão.
107
+
108
+ Ao minimizar uma sessão com contexto preservado, o assistente recolhe para o próprio botão `auto_awesome` do Page Builder. O botão troca seu nome acessível para reabrir o copiloto e exibe estado visual minimizado, sem criar um dock local paralelo ao host global de sessões.
109
+
110
+ A barra de título do assistente deve ser derivada do contexto de abertura. O Page Builder fornece título, subtítulo e badge de modo diferentes para autoria de página, autoria focada em widget, revisão de preview e continuação governada, em vez de exibir uma descrição estática do produto.
111
+
112
+ ### Agentic Authoring Manifest
113
+
114
+ `PRAXIS_PAGE_BUILDER_AUTHORING_MANIFEST` declara o contrato executável de authoring do pacote e é exportado pelo `public-api` de `@praxisui/page-builder`.
115
+
116
+ O manifesto cobre as famílias de operação `page.configure`, `canvas.configure`, `widget.add`, `widget.remove`, `widget.moveResize`, `widget.shell.configure`, `composition.link.add`, `composition.link.remove`, `composition.plan.compile`, `state.set`, `page.preview.apply`, `page.persist.save` e `childOperation.delegate`.
117
+
118
+ As fronteiras canônicas são:
119
+ - o documento persistido continua sendo `WidgetPageDefinition`;
120
+ - `UiCompositionPlan` é apenas o plano intermediário de IA e deve compilar antes do preview/apply local;
121
+ - wiring persistido usa `page.composition.links`, incluindo `nestedPath` para component ports internas;
122
+ - o Page Builder não redefine inputs de widgets filhos. Edições de `definition.inputs` devem delegar para `ComponentDocMeta.authoringManifestRef` ou `ComponentDocMeta.configEditor` publicado pela lib dona do componente;
123
+ - `pageIdentity` e ETag pertencem ao fluxo de persistência do `praxis-config-starter` e não entram no documento runtime da página.
98
124
 
99
125
  ```ts
100
126
  import { PAGE_BUILDER_AGENTIC_AUTHORING_OPTIONS } from '@praxisui/page-builder';
127
+ import { DomainKnowledgeService, DomainRuleService } from '@praxisui/core';
101
128
 
102
129
  providers: [
103
130
  {
104
131
  provide: PAGE_BUILDER_AGENTIC_AUTHORING_OPTIONS,
105
- useValue: {
106
- baseUrl: '/api/praxis/config/ai/authoring',
107
- headersFactory: () => ({
108
- 'X-Tenant-ID': tenantId,
109
- 'X-User-ID': userId,
110
- 'X-Env': 'local',
111
- }),
132
+ useFactory: () => {
133
+ const domainKnowledge = inject(DomainKnowledgeService);
134
+ const domainRules = inject(DomainRuleService);
135
+ return {
136
+ baseUrl: '/api/praxis/config/ai/authoring',
137
+ // Domain Knowledge change-sets stay governed by praxis-config-starter.
138
+ createProjectKnowledgeChangeSet: (request, options) => domainKnowledge.createChangeSet(request, options),
139
+ getProjectKnowledgeChangeSet: (changeSetId, options) => domainKnowledge.getChangeSet(changeSetId, options),
140
+ validateProjectKnowledgeChangeSet: (changeSetId, options) => domainKnowledge.validateChangeSet(changeSetId, options),
141
+ transitionProjectKnowledgeChangeSetStatus: (changeSetId, request, options) =>
142
+ domainKnowledge.transitionChangeSetStatus(changeSetId, request, options),
143
+ applyProjectKnowledgeChangeSet: (changeSetId, options) => domainKnowledge.applyChangeSet(changeSetId, options),
144
+ sharedRuleIntake: (request, options) => domainRules.intake(request, options),
145
+ headersFactory: () => ({
146
+ 'X-Tenant-ID': tenantId,
147
+ 'X-User-ID': userId,
148
+ 'X-Env': 'local',
149
+ }),
150
+ };
112
151
  },
113
152
  },
114
153
  ]
@@ -116,12 +155,20 @@ providers: [
116
155
 
117
156
  Fluxo canônico:
118
157
 
119
- - `resolveIntent` envia prompt, pagina atual e widget selecionado para resolver operacao, recurso, schema, surface e elegibilidade.
158
+ - `resolveIntent` envia todo prompt de authoring, pagina atual e widget selecionado para resolver operacao, recurso, schema, surface e elegibilidade no backend canonico. O Page Builder nao deve inferir intencao, recurso ou operacao por heuristica local antes dessa chamada.
120
159
  - `previewPage` envia o prompt junto de `intentResolution` elegivel e recebe `MinimalFormPlan` + `CompiledFormPatch`.
160
+ - `DomainKnowledgeService` em `@praxisui/core` e o cliente canonico para continuar propostas de Project Knowledge como change-sets governados em `/api/praxis/config/domain-knowledge/change-sets`; o Page Builder pode acionar essa trilha como cockpit, mas nao deve materializar evidencias localmente nem tratar o frontend como fonte primaria da decisao.
161
+ - Hosts podem habilitar `[agenticAuthoringEnableStreaming]="true"` para usar `/api/praxis/config/ai/authoring/turn/stream/**`. O Page Builder consome eventos SSE de progresso e usa o `result` terminal como a mesma fonte de preview; se o endpoint de start ainda nao estiver disponivel, o fluxo pode voltar para `resolveIntent` + `previewPage`. Depois que a conexao SSE e iniciada, erros de transporte sao tolerados por uma janela curta de reconexao e, se persistirem, sao exibidos como falha do stream em vez de disparar uma segunda execucao sincrona silenciosa.
162
+ - Em streaming, a conversa deve refletir estados intermediarios do turno, como resolucao de intencao, selecao de recurso, planejamento e geracao de preview. Nao trate o SSE apenas como transporte do resultado final: cada `PraxisAssistantTurnViewState` emitido precisa atualizar status, mensagens, anexos, respostas rapidas, diagnosticos e preview disponivel.
163
+ - Para cenarios corporativos, mantenha streaming e diagnosticos como capacidades opt-in do host. Streaming melhora feedback percebido em prompts curtos ou ambiguos; diagnosticos exibem prompt/contexto/catalogos e devem ficar restritos a auditoria, suporte ou ambientes controlados.
121
164
  - `resolveIntent` e `previewPage` tambem aceitam `sessionId`, `clientTurnId`, `conversationMessages`, `pendingClarification` e `attachmentSummaries` para que respostas curtas e contexto anexado continuem o turno sem reescrever o prompt no frontend.
122
165
  - `attachmentSummaries` deve conter apenas metadados serializaveis (`id`, `name`, `kind`, `mimeType`, `sizeBytes`, `source`, `hasPreview`). O frontend nao envia `File`, bytes, base64 nem URLs locais `blob:`. Quando uma pergunta de clarificacao nasce de um turno com anexos, o backend pode ecoar esses resumos em `pendingClarification.diagnostics.attachmentSummaries`; o Page Builder reenvia esse estado no proximo turno.
123
- - `PageBuilderAiAdapter.applyCompiledFormPatch` aplica somente `compiledFormPatch.patch.page` no runtime do builder.
124
- - `applyPage` persiste o mesmo `patch.page` em `ui_user_config`, com `componentType`, `componentId`, `scope` e `If-Match` delegados ao backend canônico.
166
+ - Enquanto o contrato LLM do Page Builder for metadata-only para anexos, o shell agentic deve ocultar a acao de anexar e desabilitar anexos colados. Nao exponha seletor de arquivo ou paste de imagem como se a LLM fosse processar pixels, PDF ou conteudo binario.
167
+ - Quando `resolveIntent` retornar candidatos ambiguos, o Page Builder deve preservar `quickReplies` como chips clicaveis ricos. Campos como `description`, `icon`, `tone` e `contextHints` pertencem ao contrato do backend e nao devem ser recriados ou descartados no frontend.
168
+ - Hosts podem habilitar `[agenticAuthoringIncludeLlmDiagnostics]="true"` apenas em cenarios de auditoria/debug. O input adiciona `contextHints.includeLlmDiagnostics=true` nas chamadas `resolveIntent` e, quando o backend retorna `llmDiagnostics`, o Page Builder mostra esse JSON em um painel tecnico separado da conversa. O padrao permanece desligado para nao expor prompt/contexto operacional em fluxos comuns.
169
+ - Para criacao de dashboard apos escolha de recurso, `previewPage` pode retornar `uiCompositionPlan.layoutPreset=resource-dashboard`; o builder deve aplicar esse plano como preview de pagina, nao tratar o artefato como fluxo restrito a formulario.
170
+ - `PageBuilderAiAdapter.applyCompiledFormPatch` aplica somente `compiledFormPatch.patch.page` no runtime do builder, materializando uma cópia local antes de atualizar a página.
171
+ - `applyPage` persiste a página renderizável corrente após o preview local em `ui_user_config`, com `componentType`, `componentId`, `scope` e `If-Match` delegados ao backend canônico.
125
172
 
126
173
  O frontend não deve persistir o envelope completo do patch como payload de runtime. O envelope fica para preview, auditoria e diagnóstico; o documento salvo é a página renderizável.
127
174
 
@@ -162,6 +209,99 @@ Exemplo com `praxis-rich-content`: o editor canônico é
162
209
  edita `definition.inputs.document`, `layout` e `rootClassName` sem criar uma DSL
163
210
  local de page-builder para blocos ricos.
164
211
 
212
+ Exemplo com `praxis-chart`: o editor canônico publicado por
213
+ `@praxisui/charts` usa um adaptador de widget sobre `PraxisChartConfigEditor`.
214
+ O editor de domínio continua editando `PraxisXUiChartContract`; o adaptador
215
+ devolve `{ inputs: { ...chartInputs, chartDocument } }` para que o runtime
216
+ atualize `definition.inputs` sem lógica específica de chart no Page Builder.
217
+
218
+ Exemplo com `praxis-table`: o editor canônico publicado por `@praxisui/table`
219
+ usa um adaptador de widget sobre `PraxisTableConfigEditor`. O editor de domínio
220
+ continua editando `TableAuthoringDocument`; o adaptador devolve
221
+ `{ inputs: { ...tableInputs, config, resourcePath, horizontalScroll } }`,
222
+ preservando `tableId` e `componentInstanceId` enquanto publica apenas inputs
223
+ declarados pelo contrato público da tabela.
224
+
225
+ Exemplo com `praxis-dynamic-form`: o editor canônico publicado por
226
+ `@praxisui/dynamic-form` usa um adaptador de widget sobre
227
+ `PraxisDynamicFormConfigEditor`. O editor de domínio continua editando
228
+ `DynamicFormAuthoringDocument`; o adaptador devolve
229
+ `{ inputs: { ...formInputs, config, mode, formId, componentInstanceId } }` e
230
+ projeta preferências públicas como `backConfig`, `notifyIfOutdated`, `snoozeMs`
231
+ e `autoOpenSettingsOnOutdated`. O Page Builder não interpreta campos, regras ou
232
+ seções do formulário.
233
+
234
+ Exemplo com `praxis-filter-form`: o editor canônico publicado por
235
+ `@praxisui/dynamic-form` também usa `PraxisDynamicFormConfigEditor`, mas por um
236
+ adaptador próprio de widget. O filtro consome o mesmo contrato `FormConfig`,
237
+ enquanto o adaptador devolve somente os inputs públicos do filtro:
238
+ `{ inputs: { ...filterInputs, config, formId, resourcePath, mode } }`.
239
+
240
+ Exemplo com `praxis-files-upload`: o editor canônico publicado por
241
+ `@praxisui/files-upload` usa um adaptador de widget sobre
242
+ `PraxisFilesUploadConfigEditor`. O editor de domínio continua editando
243
+ `FilesUploadConfig`; o adaptador devolve
244
+ `{ inputs: { ...uploadInputs, config, filesUploadId, componentInstanceId } }`
245
+ e preserva bindings públicos como `baseUrl`, `displayMode`, `context` e
246
+ `enableCustomization`. O Page Builder não interpreta estratégia, limites,
247
+ opções de backend, quotas ou rate-limit.
248
+
249
+ Exemplo com `praxis-crud`: o editor canônico publicado por `@praxisui/crud`
250
+ usa um adaptador de widget sobre `CrudMetadataEditorComponent`. O editor de
251
+ domínio continua editando `CrudAuthoringDocument`/`CrudMetadata`; o adaptador
252
+ devolve `{ inputs: { ...crudInputs, metadata, crudId, componentInstanceId } }`
253
+ e preserva `context` e `enableCustomization`. O Page Builder não interpreta
254
+ resource binding, tabela interna, open modes, ações ou defaults de
255
+ modal/drawer.
256
+
257
+ Exemplo com `praxis-list`: o editor canônico publicado por `@praxisui/list`
258
+ usa um adaptador de widget sobre `PraxisListConfigEditor`. O editor de domínio
259
+ continua editando `PraxisListConfig`; o adaptador devolve
260
+ `{ inputs: { ...listInputs, config } }`, preservando `listId` e demais inputs
261
+ do widget.
262
+
263
+ Exemplo com `praxis-expansion`: o editor canônico publicado por
264
+ `@praxisui/expansion` usa um adaptador de widget sobre
265
+ `PraxisExpansionConfigEditor`. O editor de domínio continua editando
266
+ `ExpansionMetadata`; o adaptador devolve
267
+ `{ inputs: { ...expansionInputs, config } }`, preservando `expansionId` e demais
268
+ inputs do widget. Para widgets recém-inseridos sem `config` inicial, o adaptador
269
+ mantém um fallback estável para não sobrescrever edições durante change
270
+ detection.
271
+
272
+ Exemplo com `praxis-tabs`: o editor canônico publicado por `@praxisui/tabs`
273
+ usa um adaptador de widget sobre `PraxisTabsConfigEditor`. O editor de domínio
274
+ continua editando `TabsAuthoringDocument`; o adaptador devolve
275
+ `{ inputs: { ...tabsInputs, config, tabsId } }`, preservando bindings como
276
+ `tabsId` e `componentInstanceId` enquanto publica apenas os inputs consumidos
277
+ pelo runtime.
278
+
279
+ Exemplo com `praxis-stepper`: o editor canônico publicado por
280
+ `@praxisui/stepper` usa um adaptador de widget sobre
281
+ `PraxisStepperConfigEditor`. O editor de domínio continua editando
282
+ `StepperMetadata`; o adaptador devolve
283
+ `{ inputs: { ...stepperInputs, config, stepperId, selectedIndex } }`. Sub-editores
284
+ internos de form/list/upload continuam pertencendo ao editor do stepper. Eles
285
+ devem abrir em host aninhado próprio do `@praxisui/stepper`, mantendo o editor
286
+ pai montado; o Page Builder apenas hospeda o editor publicado pela metadata.
287
+ No fluxo de inclusão, `Apply` e `Save` do sub-editor devem atualizar o mesmo
288
+ widget filho pendente, evitando duplicação de lista/upload dentro do step.
289
+
290
+ ## Child AI Authoring Manifests
291
+
292
+ Componentes que suportam edições governadas por IA devem publicar
293
+ `ComponentDocMeta.authoringManifestRef` na própria lib dona. O Page Builder usa
294
+ esse sinal apenas para discovery, readiness e delegação; ele não recompila nem
295
+ redeclara operações internas do componente filho.
296
+
297
+ Exemplos já publicados pelo catálogo de componentes:
298
+ - `praxis-table` -> `PRAXIS_TABLE_AUTHORING_MANIFEST`
299
+ - `praxis-list` -> `PRAXIS_LIST_AUTHORING_MANIFEST`
300
+ - `praxis-dynamic-form` -> `PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST`
301
+ - `praxis-tabs` -> `PRAXIS_TABS_AUTHORING_MANIFEST`
302
+ - `praxis-stepper` -> `PRAXIS_STEPPER_AUTHORING_MANIFEST`
303
+ - `praxis-expansion` -> `PRAXIS_EXPANSION_AUTHORING_MANIFEST`
304
+
165
305
  Catalogos conhecidos (exports):
166
306
  - `TABLE_AI_CAPABILITIES` - `@praxisui/table` (`praxis-table`)
167
307
  - `CRUD_AI_CAPABILITIES` - `@praxisui/crud` (`praxis-crud`)
@@ -188,6 +328,15 @@ O builder canonico expoe authoring de shell/palette sobre `praxis-dynamic-page`.
188
328
 
189
329
  `page` e um `WidgetPageDefinition` (do `@praxisui/core`) contendo `widgets` e opcionalmente `composition.links`. O envelope `composition` e o caminho `composition.links` formam a superficie canonica persistida para wiring da pagina, com `condition` em Json Logic e `policy` para comportamento operacional.
190
330
 
331
+ Links para acoes globais tambem pertencem a `composition.links`: use
332
+ `composition.links[].to.kind = "global-action"` com `to.ref.actionId` e, quando necessario,
333
+ `to.ref.payload`, `to.ref.payloadExpr` ou `to.ref.meta`. O Page Builder nao cria executor universal
334
+ nem campos paralelos de comando; ele apenas materializa o `GlobalActionRef` governado que o runtime de composicao
335
+ entrega.
336
+
337
+ Para conectar portas de widgets internos em containers como `praxis-tabs` ou `praxis-expansion`, use `composition.links[].from/to.ref.nestedPath`.
338
+ `ref.widget` continua sendo o owner top-level no canvas, e o ultimo segmento de `nestedPath` deve ser `kind: "widget"` com `key` estavel.
339
+
191
340
  Para conteudo editorial rico dentro da pagina, use um widget `praxis-rich-content`
192
341
  com `definition.inputs.document: RichContentDocument`. Isso evita criar uma DSL
193
342
  local de page-builder para cards, imagens, timelines ou blocos de apresentacao,
@@ -229,7 +378,7 @@ this.settingsPanel.open({
229
378
 
230
379
  - Trate `composition.links` como parte do contrato canonico salvo no JSON da pagina.
231
380
  - Use `composition.links[].condition` para guardas semanticas em Json Logic e `composition.links[].policy` para debounce/distinct/missing-value.
232
- - Quando precisar revisar ligacoes, prefira inspecao textual/versionada do contrato e do runtime, nao um editor visual legado.
381
+ - Quando precisar revisar ligacoes, use o editor visual para interacao e mantenha a inspecao textual/versionada do contrato como fonte de auditoria.
233
382
 
234
383
  ## API (resumo)
235
384
 
@@ -238,10 +387,30 @@ Exports deste pacote:
238
387
  - `FloatingToolbarComponent`
239
388
  - `TileToolbarComponent`
240
389
  - `WidgetShellEditorComponent`
390
+ - `ConnectionEditorComponent`
241
391
  - `DynamicPageConfigEditorComponent`
242
392
  - `DynamicPageBuilderComponent`
243
393
  - `PageBuilderAgenticAuthoringService`
244
394
  - `PAGE_BUILDER_AGENTIC_AUTHORING_OPTIONS`
395
+ - `createProjectKnowledgeChangeSet`, `getProjectKnowledgeChangeSet`, `validateProjectKnowledgeChangeSet`, `transitionProjectKnowledgeChangeSetStatus` e `applyProjectKnowledgeChangeSet` permitem que o cockpit continue Project Knowledge citado como `Domain Knowledge` governado por change-set canonico, sempre com validacao, aprovacao, aplicacao e readback seguro no backend.
396
+ - `sharedRuleIntake` permite abrir a trilha governada de `domain-rules/intake` quando o backend devolver `recommendedAuthoringFlow=shared_rule_authoring`; o handoff exportado preserva `endpoint`, `intakeEndpoint`, `nextEndpoint`, `routeGateStatus`, `routeFailureCode`, `routeDecisionSource` e `previewDisposition` para que hosts mostrem a rota canonica completa sem reinterpretar localmente a decisao.
397
+
398
+ Campos de routing no handoff:
399
+ - `routeGateStatus` vem do gate de resolucao de intencao retornado pelo backend, como `route_required`.
400
+ - `routeFailureCode` preserva o motivo canonico, como `intent-resolution-shared-rule-route-required`.
401
+ - `routeDecisionSource` indica se a fonte foi `contextHints.domainCatalog.recommendedAuthoringFlow` ou o gate de resolucao.
402
+ - `previewDisposition` explicita que o preview visual foi bloqueado por rota governada, em vez de sugerir um `componentEditPlan`.
403
+
404
+ Checkpoint operacional de review/publicacao:
405
+ - O Page Builder emite o handoff canonico de `shared_rule_authoring` e oferece um cockpit governado para continuar a decisao sem assumir autoria primaria da regra de negocio.
406
+ - O cockpit chama, por cliente real, a sequencia `definition/intake -> simulation -> governed review -> status transition -> semantic publication confirmation -> publication/materializations -> enforcement validation`.
407
+ - Quando um preview traz `diagnostics.projectKnowledgeAudit`, o cockpit de Project Knowledge pode propor `add_evidence` via `/api/praxis/config/domain-knowledge/change-sets`, validar, aprovar, aplicar e reler a projecao segura sem expor o conteudo bruto da evidencia na UI.
408
+ - Quando o prompt de authoring trouxer um caminho explicito como `/api/helpdesk/chamados`, a validacao do cockpit deve confirmar que o backend preservou esse alvo canonico no handoff, sem re-grounding por vocabulario solto do prompt.
409
+ - Timeline e historico governado sao observabilidade derivada. O cockpit pode exibir indisponibilidade dessa projecao, mas nao deve tratar a timeline como fonte primaria ou bloquear create/simulate/approve/activate quando o backend antigo ainda nao expuser o endpoint.
410
+ - A revisao deve exibir readiness, approvals, warnings, diagnostics e predicted materializations vindos do backend; nao reconstrua heuristicas de publicacao no frontend.
411
+ - A publicacao deve ser uma acao deliberada e confirmada semanticamente antes de chamar `/domain-rules/publications`.
412
+ - Materializacoes resultantes devem ser apresentadas como projecoes derivadas irmas (`option_source`, `backend_validation`, `workflow_action`, `approval_policy` ou futuras camadas), nao como novas regras primarias.
413
+ - A validacao de enforcement no cockpit consulta materializacoes aplicadas e prepara a evidencia para o runtime consumidor; ela nao reimplementa localmente a politica publicada.
245
414
 
246
415
  Integracoes comuns:
247
416
  - `SettingsPanelService.open({ id, title, content: { component, inputs } })` para page settings e shell editors