Pular para o conteúdo principal
Página não listada
Esta página não está listada. Mecanismos de busca não irão indexá-la, e somente usuários que possuam o link direto poderão acessá-la

Regras de Processo Válido

Este documento define o catálogo normativo de regras de validade estrutural e semântica para definições de processo Kikwiflow (documentos JSON compostos por um mapa de nós de fluxo, flowNodes, e um ponto de entrada, defaultStartPoint). Cada regra recebe um identificador estável no formato KIKWI-NNN, um título, uma descrição normativa e os metadados necessários para implementação automatizada.

Este catálogo é a fonte de verdade para:

  • Linters de modelagem (validação em tempo de edição, antes do deploy).
  • Validadores de deploy (validação em tempo de publicação da definição de processo).
  • Agentes e ferramentas de análise estática que precisem determinar, de forma determinística, se um JSON de processo é válido.

Cada regra é independente e pode ser implementada isoladamente. O escopo deste documento é limitado à validação de schema e de referências semânticas dentro da própria definição de processo — ele não descreve o comportamento do motor de execução, não lista exceções lançadas em runtime e não explica por que uma regra existe. Para o comportamento funcional de cada tipo de nó, consulte Modelo de Processo e Nós de Fluxo.

Convenções

Severidade

ValorSignificado
BloqueanteA definição de processo que viola esta regra não deve ser considerada válida. Um validador de deploy deve rejeitá-la; um linter deve exibi-la como erro.
AvisoA definição de processo que viola esta regra pode ser aceita, mas o comportamento resultante é potencialmente não intencional. Um linter deve exibi-la como aviso; um validador de deploy pode aceitar a publicação.

Status

ValorSignificado
ExistenteA violação desta regra já impede o deploy da definição de processo na implementação atual do validador de deploy do motor.
SugeridaA violação desta regra não é detectada em nenhuma camada de validação hoje. É uma proposta de regra a ser implementada por um linter e/ou incorporada ao validador de deploy.
RejeitadaA regra foi avaliada e descartada — ou a redação estava semanticamente errada (contradiz o comportamento real e correto do motor), ou implementá-la exigiria travessia de grafo com risco inaceitável de falso-positivo. Mantida no catálogo só como registro, não deve ser implementada como está.

Convenções de referência

  • flowNodes refere-se ao mapa de nós da definição de processo, indexado por identificador de nó.
  • outgoing refere-se à lista de sequence flows de saída de um nó, cada uma contendo, entre outros campos, targetNodeId, expectedAnswer, isDefault e handlesNull.
  • boundaryEventIds refere-se à lista de identificadores de eventos de borda (timers, tratadores de erro) anexados a um nó.
  • "Nó pai" refere-se ao nó de fluxo ao qual um evento de borda está funcionalmente anexado por meio de boundaryEventIds.

A. Regras estruturais gerais do grafo

Aplicam-se a qualquer definição de processo, independentemente dos tipos de nó presentes.

IDTítuloDescriçãoSeveridadeStatus
KIKWI-001Integridade referencial das sequence flowsTodo targetNodeId declarado em uma sequence flow de qualquer nó deve referenciar o identificador de um nó existente em flowNodes.BloqueanteExistente
KIKWI-002Consistência entre chave e identificador do nóA chave usada para indexar um nó em flowNodes deve ser idêntica ao valor do campo id declarado dentro desse nó.BloqueanteSugerida (corrigida na raiz — ver nota)
KIKWI-003Ponto de entrada declarado e existenteO campo defaultStartPoint da definição de processo deve estar preenchido e referenciar o identificador de um nó existente em flowNodes.BloqueanteExistente
KIKWI-004Tipo do ponto de entradaO nó referenciado por defaultStartPoint deve ser do tipo DEFAULT_START_EVENT.AvisoSugerida
KIKWI-005Alcançabilidade de todos os nósTodo nó declarado em flowNodes deve ser alcançável a partir de defaultStartPoint, por meio de uma sequence flow, de uma referência em boundaryEventIds de um nó alcançável, ou de um targetJoinId de um PARALLEL_GATEWAY alcançável.AvisoSugerida
KIKWI-006Terminalidade explícitaUm nó sem nenhuma sequence flow em outgoing só é válido se for do tipo DEFAULT_END_EVENT, JOIN_GATEWAY ou BOUNDARY_ERROR_HANDLER.AvisoSugerida
KIKWI-007Saída única fora de gateways de decisão e divisãoTodo nó que não seja do tipo EXCLUSIVE_GATEWAY ou PARALLEL_GATEWAY deve declarar no máximo uma sequence flow em outgoing.AvisoSugerida

Nota sobre KIKWI-002: em vez de implementar esta regra como validação, a causa raiz foi corrigida — o motor (kikwi-core) passa a usar exclusivamente a chave do mapa flowNodes para todo bookkeeping de execução (gravação de taskDefinitionId, resolução de boundary events, etc.), nunca mais o campo id interno do nó. A dualidade que esta regra policiava deixou de existir como risco funcional — divergir id/chave ainda é uma inconsistência de legibilidade a evitar, mas não quebra mais a execução.

B. DEFAULT_START_EVENT

IDTítuloDescriçãoSeveridadeStatus
KIKWI-008Presença obrigatória do evento de inícioToda definição de processo deve conter ao menos um nó do tipo DEFAULT_START_EVENT.BloqueanteSugerida
KIKWI-009Saída obrigatória do evento de inícioTodo nó DEFAULT_START_EVENT deve declarar exatamente uma sequence flow em outgoing.BloqueanteExistente

C. DEFAULT_END_EVENT

IDTítuloDescriçãoSeveridadeStatus
KIKWI-010Ausência de saída no evento de fimUm nó DEFAULT_END_EVENT não deve declarar nenhuma sequence flow em outgoing.AvisoSugerida

D. EXECUTABLE_TASK

IDTítuloDescriçãoSeveridadeStatus
KIKWI-011Executor obrigatórioTodo nó EXECUTABLE_TASK deve declarar o campo executor com um valor não nulo e não vazio.BloqueanteExistente
KIKWI-012Executor resolvívelO valor declarado em executor deve corresponder a um componente registrado do tipo executor de tarefa, disponível no ambiente de execução do processo.BloqueanteExistente

E. EXTERNAL_TASK

IDTítuloDescriçãoSeveridadeStatus
KIKWI-013Ausência do campo executorUm nó EXTERNAL_TASK não deve declarar o campo executor — esse tipo de nó não é associado a um executor de tarefa.AvisoSugerida

F. EXCLUSIVE_GATEWAY

IDTítuloDescriçãoSeveridadeStatus
KIKWI-014Tipo de provedor de resposta obrigatórioTodo EXCLUSIVE_GATEWAY deve declarar providerType com um dos valores reconhecidos: BEAN ou VARIABLE.BloqueanteExistente
KIKWI-015Bean do provedor de resposta preenchidoSe providerType for BEAN, o campo providerBean deve estar preenchido.BloqueanteExistente
KIKWI-016Bean do provedor de resposta resolvívelSe providerType for BEAN, o valor de providerBean deve corresponder a um componente registrado do tipo provedor de resposta, disponível no ambiente de execução.BloqueanteExistente
KIKWI-017Variável do provedor de resposta preenchidaSe providerType for VARIABLE, o campo providerVariable deve estar preenchido.BloqueanteExistente
KIKWI-018Unicidade da sequence flow padrãoUm EXCLUSIVE_GATEWAY deve declarar no máximo uma sequence flow de saída com isDefault: true.BloqueanteExistente
KIKWI-019Unicidade da sequence flow de valor nuloUm EXCLUSIVE_GATEWAY deve declarar no máximo uma sequence flow de saída com handlesNull: true.BloqueanteExistente
KIKWI-020Unicidade de resposta esperadaAs sequence flows de saída de um mesmo EXCLUSIVE_GATEWAY não devem repetir o mesmo valor de expectedAnswer entre si.BloqueanteExistente
KIKWI-021Saída obrigatória do gateway de decisãoTodo EXCLUSIVE_GATEWAY deve declarar ao menos uma sequence flow em outgoing.BloqueanteExistente
KIKWI-022Cobertura de resposta por sequence flow padrãoRecomenda-se que todo EXCLUSIVE_GATEWAY declare uma sequence flow com isDefault: true, cobrindo respostas não previstas explicitamente pelas demais sequence flows.AvisoSugerida
KIKWI-023Tratamento de resposta nulaRecomenda-se que todo EXCLUSIVE_GATEWAY cujo provedor de resposta possa legitimamente retornar um valor nulo declare uma sequence flow com handlesNull: true.AvisoSugerida

G. PARALLEL_GATEWAY e JOIN_GATEWAY

IDTítuloDescriçãoSeveridadeStatus
KIKWI-024Join de destino obrigatórioTodo PARALLEL_GATEWAY deve declarar o campo targetJoinId.BloqueanteExistente
KIKWI-025Join de destino existenteO valor de targetJoinId deve referenciar o identificador de um nó existente em flowNodes.BloqueanteExistente
KIKWI-026Tipo do join de destinoO nó referenciado por targetJoinId deve ser do tipo JOIN_GATEWAY.BloqueanteExistente
KIKWI-027Pluralidade de ramosTodo PARALLEL_GATEWAY deve declarar ao menos duas sequence flows em outgoing.AvisoSugerida
KIKWI-028Alcance exclusivo do join por divisão paralelaRejeitada nesta revisão — a redação original está errada. Dizia que nenhuma sequence flow de um nó que não seja PARALLEL_GATEWAY deveria declarar um JOIN_GATEWAY como targetNodeId. Na prática, esse é o mecanismo normal e correto de um ramo sinalizar sua própria conclusão: uma EXECUTABLE_TASK/EXTERNAL_TASK dentro de um ramo aberto por PARALLEL_GATEWAY aponta sua própria outgoing direto para o JOIN_GATEWAY de destino o tempo todo (ver parallel-gateway-fan-out-join.json em kikwi-core-tests, testado desde antes desta revisão) — ContinuationService.generateNextTasksWithContext trata isso no branch genérico (registerBranchConclusion), não é um caso degenerado. Tentar implementar esta regra literalmente rejeita esse padrão real (confirmado rodando a suíte de testes: quebrou 3 fixtures válidos). O que de fato distingue "join alcançado corretamente" de "join alcançado por engano" não é o tipo do nó de origem — é se a execução está dentro de um contexto de ramo ativo (branchId/joinTaskId não-nulos), uma propriedade de caminho de execução, não estrutural, e que exigiria a mesma travessia de grafo arriscada que KIKWI-029 (com o mesmo risco de falso-positivo) para verificar em deploy-time. Não reintroduzir sem resolver esse problema primeiro.Rejeitada
KIKWI-029Convergência dos ramos para o join declaradoTodo ramo aberto por um PARALLEL_GATEWAY deve convergir para o JOIN_GATEWAY declarado em targetJoinId, seja atingindo-o diretamente, seja terminando em um DEFAULT_END_EVENT dentro do próprio ramo.AvisoSugerida

H. Timers de borda (BOUNDARY_INTERRUPTIVE_TIMER, BOUNDARY_NON_INTERRUPTIVE_TIMER)

IDTítuloDescriçãoSeveridadeStatus
KIKWI-030Vínculo funcional obrigatórioTodo timer de borda deve estar referenciado em boundaryEventIds de um nó do tipo EXECUTABLE_TASK ou EXTERNAL_TASK.BloqueanteSugerida (mesma categoria de "nó órfão" de KIKWI-005 — deliberadamente fora desta rodada)
KIKWI-031Referência de evento de borda existenteTodo identificador declarado em boundaryEventIds de um nó deve corresponder a um nó existente em flowNodes.BloqueanteExistente (agora em todo host — EXTERNAL_TASK foi o último a ganhar allowlist)
KIKWI-032Tipo de evento de borda reconhecidoTodo identificador declarado em boundaryEventIds deve corresponder a um nó de um dos tipos de evento de borda reconhecidos (BOUNDARY_INTERRUPTIVE_TIMER, BOUNDARY_NON_INTERRUPTIVE_TIMER, BOUNDARY_ERROR_HANDLER).BloqueanteExistente (idem)
KIKWI-033Tipo de provedor do timer interruptivoTodo BOUNDARY_INTERRUPTIVE_TIMER deve declarar providerType com um dos valores reconhecidos: STATIC, VARIABLE ou BEAN.BloqueanteExistente
KIKWI-034Valor estático do timer preenchidoSe providerType for STATIC, o campo staticValue deve estar preenchido.BloqueanteExistente
KIKWI-035Variável do timer preenchidaSe providerType for VARIABLE, o campo providerVariable deve estar preenchido.BloqueanteExistente
KIKWI-036Bean do timer preenchidoSe providerType for BEAN, o campo providerBean deve estar preenchido.BloqueanteExistente
KIKWI-037Política de agendamento obrigatóriaTodo BOUNDARY_NON_INTERRUPTIVE_TIMER deve declarar o campo schedulePolicy.BloqueanteExistente
KIKWI-038Tipo de política de agendamento reconhecidoschedulePolicy.type deve ser RATE_DURATION ou FIXED_DATES.BloqueanteExistente — mas não mais como checagem: ScheduleType só tem esses dois valores agora (CRON foi removido do enum), então isso é uma invariante de compilação, não algo que DeployValidator precisa verificar. DeployValidator ainda rejeita schedulePolicy.type nulo.
KIKWI-039Expressão de taxa preenchidaSe schedulePolicy.type for RATE_DURATION, o campo expression deve estar preenchido.BloqueanteExistente
KIKWI-040Datas fixas preenchidasSe schedulePolicy.type for FIXED_DATES, o campo fixedDates deve conter ao menos uma data.BloqueanteExistente
KIKWI-053Contagem de ocorrências positivaSe schedulePolicy.maxOccurrences estiver preenchido, deve ser um inteiro >= 10 ou negativo nunca agenda nenhum ciclo, o que provavelmente é um erro de modelagem e não a intenção do autor.AvisoSugerida
KIKWI-048Nó pai restrito a EXTERNAL_TASK para timer interruptivoUm BOUNDARY_INTERRUPTIVE_TIMER só deve estar referenciado em boundaryEventIds de um nó do tipo EXTERNAL_TASK — nunca EXECUTABLE_TASK. Não se aplica a BOUNDARY_NON_INTERRUPTIVE_TIMER, que não cancela o nó pai.BloqueanteExistente

Nota: KIKWI-033036 valem hoje só para BOUNDARY_INTERRUPTIVE_TIMER (o timer de borda) — os mesmos campos em TIMER_TASK (o timer de fluxo principal) continuam sem validação de deploy (tier B), deliberado nesta rodada por não estar no escopo original revisado com o time.

I. BOUNDARY_ERROR_HANDLER

IDTítuloDescriçãoSeveridadeStatus
KIKWI-041Tipo de nó pai restrito a EXECUTABLE_TASKUm BOUNDARY_ERROR_HANDLER só deve estar referenciado em boundaryEventIds de um nó do tipo EXECUTABLE_TASK.BloqueanteExistente (agora também em EXTERNAL_TASK, que antes não tinha nenhuma validação de boundaryEventIds)
KIKWI-042Unicidade de código de erro por nó paiHandlers de erro anexados ao mesmo nó pai não devem repetir o mesmo valor de errorCode, e no máximo um handler sem errorCode (curinga) é permitido por nó pai.BloqueanteExistente

J. RetryPolicy (aplicável a EXECUTABLE_TASK)

IDTítuloDescriçãoSeveridadeStatus
KIKWI-043Tentativas máximas explícitasSe retryPolicy estiver presente, o campo maxRetries deve estar explicitamente presente e ser maior ou igual a 1.BloqueanteExistente
KIKWI-044Estratégia de retry reconhecidaSe retryPolicy estiver presente, o campo strategy deve ser LINEAR ou EXPONENTIAL_BACKOFF.BloqueanteExistente
KIKWI-045Intervalo inicial do backoff exponencialSe retryPolicy.strategy for EXPONENTIAL_BACKOFF, o campo initialInterval deve estar preenchido.BloqueanteExistente
KIKWI-046Intervalos da estratégia linearRecomenda-se que, se retryPolicy.strategy for LINEAR, o campo intervals seja declarado com ao menos um elemento.AvisoSugerida

K. CALL_ACTIVITY_COORDINATOR

IDTítuloDescriçãoSeveridadeStatus
KIKWI-047calledElement obrigatóriocalledElement não pode ser nulo/vazio.BloqueanteExistente
KIKWI-052elementVariable requer collectionVariableelementVariable só é válido quando collectionVariable também está presente.BloqueanteExistente

collectionVariable resolver para uma List em runtime não é validado em deploy-time — o motor não tem mecanismo de declaração de tipo de variável de processo. Ver CALL_ACTIVITY_COORDINATOR — Subprocessos.

L. BOUNDARY_INTERRUPTIVE_CATCH_EVENT

IDTítuloDescriçãoSeveridadeStatus
KIKWI-049Nó pai restrito a EXTERNAL_TASK ou TIMER_TASKUm BOUNDARY_INTERRUPTIVE_CATCH_EVENT só deve estar referenciado em boundaryEventIds de um nó do tipo EXTERNAL_TASK ou TIMER_TASK — nunca EXECUTABLE_TASK. Um EXECUTABLE_TASK executa seu handler de forma síncrona, sem fronteira transacional onde o motor possa interromper com segurança antes de um efeito colateral real já ter acontecido.BloqueanteExistente — correção de catálogo: o código sempre aceitou TIMER_TASK como host válido também, além de EXTERNAL_TASK; o título/descrição desta linha só citava EXTERNAL_TASK, sem relação com o trabalho desta rodada.
KIKWI-050Tipo de provedor obrigatórioTodo BOUNDARY_INTERRUPTIVE_CATCH_EVENT deve declarar providerType com um dos valores reconhecidos: STATIC, VARIABLE, BEAN ou TEMPLATE.BloqueanteExistente — correção de catálogo: já era validado via validateCorrelationKeySource (compartilhado com EVENT_CATCHER/EVENT_THROWER) antes desta rodada; o catálogo estava com status desatualizado e faltava TEMPLATE como 4º valor reconhecido.
KIKWI-051Ausência de catchType/matchPolicyUm BOUNDARY_INTERRUPTIVE_CATCH_EVENT não deve declarar catchType nem matchPolicy — ao contrário de EVENT_CATCHER, um evento de borda sempre resolve exatamente 1 chave.AvisoSugerida

M. EVENT_CATCHER

Seções inteiras (M, N, O) adicionadas nesta revisão — este tipo de nó já era validado em código desde antes, mas nunca ganhou entrada no catálogo (escrito antes de EVENT_CATCHER/EVENT_THROWER/TIMER_TASK existirem como tipos implantáveis). Nenhuma regra nova de validador foi implementada aqui — só o catálogo estava incompleto.

IDTítuloDescriçãoSeveridadeStatus
KIKWI-054Tipo de provedor obrigatórioTodo EVENT_CATCHER deve declarar providerType com um dos valores reconhecidos: STATIC, VARIABLE, BEAN ou TEMPLATE.BloqueanteExistente
KIKWI-055Campo do provedor preenchidoConforme providerType: staticKey (STATIC), providerVariable (VARIABLE), providerBean resolvível a um CorrelationKeysProvider (BEAN), ou correlationTemplates não-vazio (TEMPLATE).BloqueanteExistente
KIKWI-056GROUP incompatível com STATICcatchType: GROUP não pode combinar com providerType: STATICSTATIC sempre resolve exatamente 1 chave, incompatível com o scatter-gather de GROUP.BloqueanteExistente
KIKWI-057boundaryEventIds restrito a timersUm EVENT_CATCHER.boundaryEventIds só pode referenciar BOUNDARY_INTERRUPTIVE_TIMER ou BOUNDARY_NON_INTERRUPTIVE_TIMER — nem BOUNDARY_ERROR_HANDLER, nem BOUNDARY_INTERRUPTIVE_CATCH_EVENT (ainda não suportado como boundary de outro EVENT_CATCHER).BloqueanteExistente

N. EVENT_THROWER

IDTítuloDescriçãoSeveridadeStatus
KIKWI-058Tipo de provedor obrigatório + campo correspondenteMesma validação condicional de KIKWI-054/055, aplicada a EVENT_THROWER — sem catchType/matchPolicy (não existem nesse tipo de nó; sempre resolve exatamente 1 chave, política v1 é falhar se ninguém estiver esperando).BloqueanteExistente

O. TIMER_TASK

IDTítuloDescriçãoSeveridadeStatus
KIKWI-059boundaryEventIds restrito a timers e catch eventUm TIMER_TASK.boundaryEventIds só pode referenciar BOUNDARY_INTERRUPTIVE_TIMER, BOUNDARY_NON_INTERRUPTIVE_TIMER ou BOUNDARY_INTERRUPTIVE_CATCH_EVENT — nunca BOUNDARY_ERROR_HANDLER (não há handler síncrono nenhum pra um TIMER_TASK resolver via try/catch).BloqueanteExistente

TIMER_TASK.providerType/staticValue/providerVariable/providerBean (os mesmos campos de BOUNDARY_INTERRUPTIVE_TIMER, seção H) permanecem tier B — não validados em deploy, só falham quando o timer é efetivamente instanciado. Ver a nota ao final da seção H.

Ver também