Semântica de execução, restrições e segurança

Última atualização: 21 de julho de 2026

Esta página resume como um Script se comporta em tempo de execução (ordem, transações, erros, bloqueio), a quais restrições estáticas ele está sujeito no momento de salvar e o seu modelo de segurança. Para a sintaxe, consulte o catálogo de Statements e as expressões de valor; para combinações práticas, consulte o cookbook.

Ordem e modo de execução

  • Os statements são executados sequencialmente de cima para baixo. Ao alcançar um Return, a execução termina nesse ponto.
  • O Sync é executado no caminho que processa a requisição; o Async, em segundo plano. É apenas uma distinção de onde a execução acontece; em ambos os casos o resultado é o valor de Return (para o formato da resposta da chamada, consulte Requisição e resposta na visão geral do Script e modos de execução).
  • Da capacidade (capability) ao modo: se a árvore de statements contiver qualquer um entre ExternalIo (uma chamada externa Http), MediaIngest (ingestão de arquivo de Media; { source, encoding } em fields.file; comum a url e base64) ou LongRunning (um Loop volumoso, etc.), então o executionMode é forçado para Async. Essas três são capacidades distintas e diferem quanto ao limite em que são contabilizadas nas Restrições estáticas abaixo.

Semântica de execução

Guard (pré-condições)

Não existe um statement guard dedicado. Você o expressa com If e then:[Return]. Quando a condição é violada, retorna um resultado e não executa os statements seguintes (um Script sem guard também é perfeitamente possível).

{ "type": "If", "condition": { "<": [ "{ /wallet/fields/balance/en-US }", "{ /payload/fields/cost }" ] },
  "then": [ { "type": "Return", "value": { "ok": false, "reason": "insufficient credit" }, "statusCode": 402 } ] }

Sem transações e compensação best-effort

Um Script não é uma transação. Em caso de falha, o engine tenta compensar (compensation) o trabalho realizado até então e retorna a causa do erro, mas com as seguintes limitações (assumidas por decisão de projeto).

  • Desfazer uma exclusão cria um novo sys.id, então as referências que apontavam para ele quebram (reverter uma criação é fácil; uma atualização precisa de uma before-image).
  • Efeitos externos (Http) são irreversíveis (uma chamada que já foi feita, e a cobrança dela, não podem ser desfeitas).
  • Em caso de crash do processo, pode restar um estado não compensado (orphan).

Se você precisa de atomicidade real, escreva a compensação no Script por conta própria ou coloque as operações irreversíveis (como chamadas externas) por último. A ordenação mais perigosa é aquela que "encadeia até o fim, mas não consegue reverter, e ainda assim parece segura".

Bloqueio otimista

Você reduz a contenção de update/patch com o version em ResourceUpdate e ResourcePatch. Se fornecer version (uma expressão de valor, Int), a atualização acontece somente quando coincide com o sys.version atual do alvo; uma divergência aborta com um erro de conflito de versão (que você pode tratar localmente com Try/catch). Se omitir, vale last-write-wins, sem verificação. Normalmente você lê primeiro com ResourceRead ou ResourcePageRead e passa esse sys.version (consulte CAS de bloqueio otimista no cookbook).

Gravações vão para origin

As gravações sempre chegam ao origin (draft), e a exposição na delivery (CDA/ACDA) é controlada por publish (o publish em ResourceCreate/ResourceUpdate/ResourcePatch, ou ResourcePublish/ResourceUnpublish).

O que conta como falha

  • Uma falha real é um erro em tempo de execução de statement: um status final de Http de 400 ou superior (4xx·5xx; não é uma falha quando ignoreStatusCode: true) ou timeout, um corpo de resposta que excede 10MiB, ou uma operação de recurso malsucedida (alvo inexistente, conflito de versão, operação não suportada, etc.). Nessas falhas o engine aborta e compensa, e você pode tratá-las localmente com Try/catch/finally.
  • Um Return não é um erro, mas uma saída antecipada normal. Não é alvo de catch (não existe o conceito de throw pelo usuário).
  • Dentro de um catch, você referencia { message, statement } via /error.

Sem agregação no servidor

Não há operações de servidor dedicadas a count, sum ou group-by. Você calcula iterando com ResourcePageRead e usando SetVar/JsonLogic, portanto fica limitado pelo tamanho do fetch e por maxIterations (inadequado para agregar milhões de registros).

Sem espera ou atraso

Um Script não tem statement Delay. Um Script é executado uma vez e pronto, no caminho da requisição (Sync) ou em segundo plano (Async), e não espera nem faz polling internamente até um job externo terminar (o resultado do Async é à parte: o chamador faz polling com o requestId recebido no 202 para obter o valor de Return).

Restrições estáticas (validadas ao salvar)

Os itens a seguir são verificados no momento em que um Script é salvo (na criação/atualização). Se algum for violado, o salvamento é rejeitado (a falha ocorre no momento da autoria, não em tempo de execução).

RestriçãoPadrão
Se houver I/O externa, executionMode deve ser AsyncN/A
Dentro de um Loop body, chamadas externas Http e ingestão de arquivo de Media são proibidasN/A
Máximo de chamadas Http externas por definição3 (maxExternalIo)
Máximo de SetVar por definição (incluindo aninhados)5 (maxSetVar)
Máximo total de statements por definição (incluindo aninhados)15 (maxStatements)
Limite de Http.retry2 (maxHttpRetry)

Os limites podem ser ajustados por configurações de servidor (weegloo.core.script.*); os valores acima são os padrões.

A ingestão de arquivo de Media é a capacidade MediaIngest e, ao contrário de uma chamada externa Http (ExternalIo), não conta para o limite de maxExternalIo (3). No entanto, a exigência de Async e a proibição no Loop body aplicam-se a ela exatamente como a Http.

Orçamento de tempo (tempo de execução)

ModoOrçamento padrão
Sync10 segundos (syncTimeoutMs)
Async60 segundos (asyncTimeoutMs)

Limites de quantidade por plano

Script é um recurso Billable, e a quantidade por Organization é limitada por plano.

PlanQuantidade de Script
Free3
Basic10
Pro50
EnterpriseIlimitado

Quando o limite é atingido, a criação de um novo Script é rejeitada (o mesmo caminho de outros recursos Billable).

Modelo de segurança

Cabeçalhos secret

Um item em Http.headers com secret:true é exclusivo do CMA (administrador): não é exposto ao usuário final (ServiceUser) e é descriptografado apenas imediatamente antes do envio. Coloque aqui segredos como uma chave de API de LLM (mesmo quando empacotado em um App Bundle, o valor secret é mascarado e nunca sai do Space de origem).

Identidade de execução e autorização

  • Identidade de execução: durante a execução, toda operação de recurso é realizada sob a identidade do usuário que chamou /execute. O createdBy/updatedBy de qualquer recurso criado ou atualizado é o chamador, e um escopo createdBy: ":self" também é resolvido em relação ao chamador.
  • Há dois limites de autorização e, em tempo de execução, o engine não reverifica as permissões de recurso a cada statement.
    1. No momento da autoria (salvar): ao salvar um Script, verifica-se se o autor realmente possui as permissões de recurso e de ação que seus statements usam. Se faltar uma que seja, o salvamento é rejeitado (WGL403015). Ou seja, um Script que contém uma operação não autorizada nunca chega a ser salvo.
    2. No momento da chamada (/execute): verifica-se apenas a permissão Execute do chamador sobre o Script. Sem ela, o resultado é 403. Uma vez aprovado, as permissões de recurso por statement não são verificadas novamente em tempo de execução; a execução prossegue. Funciona como a permissão de execução de função na programação. Se você tem permissão para executar a função, a permissão de cada operação individual dentro dela não é perguntada de novo.
  • Escopo de propriedade: createdBy: ":self" em um filtro where significa "apenas o que o chamador atual criou" (por exemplo, consultar apenas a própria carteira).
  • Permissões delegadas (atenção ao autor): combinando os dois limites acima, executar um Script equivale a agir com as permissões do autor delegadas a ele. O chamador precisa apenas de Execute, e os statements dentro do Script são executados exatamente dentro do escopo para o qual o autor foi autorizado no momento de salvar. Como consequência, uma operação de recurso que o chamador não conseguiria realizar sozinho ainda pode acontecer por meio do Script. Como as permissões concedidas ao autor são o alcance efetivo desse Script, defina com cuidado quais ações você coloca em um Script.

Checklist de resumo

Antes de salvar, verifique o seguinte.

  • Se houver uma chamada externa (Http) ou ingestão de arquivo de Media, o executionMode é "Async".
  • Você não colocou uma chamada externa dentro de um Loop body.
  • Chamadas externas são 3 ou menos, SetVar 5 ou menos, e o total de statements 15 ou menos.
  • Os valores secret foram colocados apenas via secret:true em Http.headers.
  • As operações irreversíveis (chamadas externas) foram colocadas o mais tarde possível.
  • Se você se preocupa com a contenção de update/patch, use o version em ResourceUpdate ou ResourcePatch.
  • Para retornar um resultado, você especificou Return.value.