# Expiração escalonada Use `ladder()` em **Expira em**, na ação [Adicionar à lista](/pt/rules/actions/add_to_list/), para manter um valor na lista por mais tempo a cada reincidência. Por exemplo, um IP bloqueado pela primeira vez sai da lista em 1 hora, e um IP reincidente permanece 2 dias. ## Sintaxe ``` ladder(<índice>, , , ...) ``` - **Índice**: um campo (`$tentativas`) ou uma leitura publicada por uma ação anterior (`%bloqueios.cells.ip.value`), com valor numérico. Um número fixo, como `ladder(1, 1h, 4h)`, é recusado ao salvar a regra. - **Prazos**: de 1 a 10 prazos, cada um com um número inteiro seguido de `m`, `h` ou `d`. Cada prazo fica entre `5m` e 2 anos. O índice escolhe o prazo pela posição, contada a partir de 0: | Índice | Prazo escolhido | | :-------------------- | :--------------------------------------------- | | `0` | o primeiro | | `1`, `2`, ... | o prazo nessa posição | | além do último prazo | o último | | decimal | arredondado para baixo: `2,7` escolhe a posição 2 | | ausente ou negativo | o primeiro | Com `ladder(%bloqueios.cells.ip.value, 1h, 4h, 16h)`, o índice 0 escolhe 1 hora, o índice 1 escolhe 4 horas e o índice 2 ou maior escolhe 16 horas. ## Bloqueio por reincidência O índice costuma ser a contagem de bloqueios anteriores do mesmo valor. A análise `bloqueios` tem uma [célula sem gatilho](/pt/rules/analyses/#sem-gatilho) `ip`, que conta os eventos por `$ip` em 30 dias. A regra registra um evento nessa análise apenas quando o IP entra na lista de fato: ``` Condição 1: "ip_velocity" in %risco.triggered_cells Ações: Executar análise: bloqueios (resultado: bloqueios) Adicionar à lista → $ip em @ips_bloqueados, expira em ladder(%bloqueios.cells.ip.value, 1h, 4h, 16h, 2d) (resultado: ip_bloqueado) Condição 2: %ip_bloqueado.added == true Ações: Registrar análise: bloqueios ``` O campo **Resultado** da ação publica `%ip_bloqueado.added`. A leitura é `true` apenas quando a execução incluiu o IP na lista. Enquanto o IP está na lista, os eventos seguintes leem `false` e não contam como um novo bloqueio. Em uma rajada de eventos do mesmo IP, apenas uma execução lê `true`. A célula `ip` conta, assim, os bloqueios do IP, e não cada evento suspeito: | Bloqueio | Contagem na célula `ip` | Prazo na lista | | :-------- | :---------------------- | :------------- | | primeiro | 0 | 1 hora | | segundo | 1 | 4 horas | | terceiro | 2 | 16 horas | | quarto em diante | 3 ou mais | 2 dias | A janela da célula define por quanto tempo um bloqueio conta como reincidência. No exemplo, um IP sem bloqueios em 30 dias volta ao prazo de 1 hora. ## Pontos a considerar - **O prazo nunca encurta**: se o valor já estiver na lista, a execução mantém o prazo mais longo entre o atual e o escolhido, conforme [Adicionar à lista](/pt/rules/actions/add_to_list/). - **Observação e simulação não escrevem na lista**: em [observação](/pt/rules/versioning/#observação) e em [simulação](/pt/rules/simulation/), a ação não inclui o valor e não publica o resultado.