> ## Documentation Index
> Fetch the complete documentation index at: https://docs.evolutionfoundation.com.br/llms.txt
> Use this file to discover all available pages before exploring further.

# Heartbeats

> Agentes proativos que acordam em uma agenda e decidem se devem agir

# Heartbeats

<img src="https://mintcdn.com/evoai-683d737d/KKvOt8ip-TVpeDVn/evo-nexus/imgs/doc-heartbeats.webp?fit=max&auto=format&n=KKvOt8ip-TVpeDVn&q=85&s=a66bd74da4acb53dfae3a3214f23d808" alt="Heartbeats — agentes proativos com agenda, status e custo" width="1920" height="975" data-path="evo-nexus/imgs/doc-heartbeats.webp" />

**Heartbeats são agentes proativos.** Um heartbeat é uma configuração que acorda um agente em uma agenda para que ele faça triagem de trabalho sem ser pedido. Em vez de você lembrar de perguntar ao Atlas "tem PR parado?" toda manhã, o Atlas acorda a cada 4 horas, verifica e age só se houver algo a fazer.

## O Modelo Mental

Uma rotina é **sistemática** — o mesmo script roda todo dia às 7h. Um heartbeat é **proativo** — o agente acorda, observa e decide se deve agir. Cada execução de heartbeat responde a uma única pergunta:

> Dado o estado atual do meu domínio, devo trabalhar agora ou pular?

O agente retorna um veredicto em JSON. Se `action: work`, o dispatcher deixa o agente executar seus turnos. Se `action: skip`, a execução termina imediatamente com custo próximo de zero.

## Anatomia de um Heartbeat

Heartbeats vivem em `config/heartbeats.yaml` (fonte da verdade) e são espelhados no banco do dashboard. Cada entrada tem:

| Campo | O que faz |
| - | - |
| `id` | Slug único, kebab-case (ex. `atlas-4h`) |
| `agent` | Qual agente acordar (`atlas-project`, `zara-cs`, …) |
| `interval_seconds` | A cada quantos segundos o trigger por intervalo dispara. Mínimo 60 |
| `max_turns` | Limite duro de turnos do Claude por execução (padrão 10) |
| `timeout_seconds` | Timeout duro para matar o subprocesso (padrão 300) |
| `lock_timeout_seconds` | Limite para limpeza de locks parados (padrão 1800) |
| `wake_triggers` | Subconjunto de `[interval, new_task, mention, manual, approval_decision]` |
| `decision_prompt` | A pergunta que o agente responde — precisa forçar um veredicto JSON |
| `goal_id` | Slug opcional de goal para injeção de contexto |
| `required_secrets` | Chaves do `.env` que o agente precisa |
| `enabled` | Chave-mestra. Sempre começa em `false` |

## Início Rápido

### 1. Crie um heartbeat

No Claude Code, use a skill `create-heartbeat`:

> "Crie um heartbeat de 4 horas para atlas-project que triagem PRs e issues parados."

A skill conduz pelos campos, deixa `enabled: false` por padrão e chama `POST /api/heartbeats`. A entrada aparece na página **Heartbeats** do dashboard como desabilitada.

Alternativamente, edite `config/heartbeats.yaml` diretamente e chame `POST /api/heartbeats/reindex` para espelhar no banco.

### 2. Dry-run antes de habilitar

No dashboard, clique em **Run now** no card (ou chame `POST /api/heartbeats/{id}/run`). Isso dispara uma execução manual única, independente do relógio do interval. Inspecione o resultado:

* O agente retornou JSON válido?
* A decisão foi razoável?
* Ficou dentro de `max_turns` e `timeout_seconds`?

Se sim, ative o toggle. O dispatcher pega no próximo tick do interval.

### 3. Monitore as execuções

Cada execução registra `started_at`, `finished_at`, `status`, `tokens_input`, `tokens_output`, `cost_usd` e o `decision_json` parseado. A página **Heartbeats** no dashboard mostra as últimas 10 execuções por card e o custo agregado de 7 dias.

## Wake Triggers

Um heartbeat acorda em qualquer um dos triggers listados em `wake_triggers`:

* **interval** — o scheduler dispara a cada `interval_seconds`. Quase sempre incluído.
* **manual** — alguém clica em "Run now" ou chama a API. Permite a operadores debugar.
* **mention** — um `@agent-slug` num comentário de ticket dispara um mention trigger (se o agente tiver um heartbeat habilitado com `mention` nos wake\_triggers). Máximo 3 mentions por comentário.
* **new\_task** — uma task de goal criada com este agente como `assignee_agent` acorda o heartbeat.
* **approval\_decision** — uma solicitação de aprovação foi decidida (feature futura).

Mais triggers = mais responsividade. Menos triggers = custo mais previsível.

## Controle de Custo

Como heartbeats queimam tokens em cada execução, coloque guardrails:

1. **Comece com `enabled: false`**. Sempre. Revise a primeira execução manual antes de habilitar.
2. **Use um `decision_prompt` afiado**. Se o agente escreve um parágrafo quando devia escrever JSON, você desperdiça tokens.
3. **Tenda ao `skip`**. Treine o prompt para pular a menos que haja urgência genuína. Um heartbeat de 4 horas que pula 4 das 6 execuções diárias está fazendo seu trabalho.
4. **Mantenha `max_turns` baixo** para heartbeats puramente de triagem (5–10). Só aumente para agentes que podem precisar agir em múltiplos itens.
5. **Acompanhe `cost_7d`** no card do dashboard. Se um heartbeat sobe consistentemente, o prompt provavelmente está muito leniente — aperte os critérios de skip.

## Debugando

### Um heartbeat não está disparando

1. Cheque o `enabled` do heartbeat — está individualmente ligado?
2. Cheque o log do dispatcher (`journalctl -u evo-nexus -f` ou os logs do serviço do dashboard) para registro do interval.
3. Chame `POST /api/heartbeats/{id}/run` — uma execução manual funciona? Se sim, é problema de scheduler; se não, é problema do agente ou prompt.

### Uma execução falhou

Olhe o `stderr_tail` e `stdout_tail` da execução. Causas comuns:

* `required_secrets` faltando no `.env`
* `decision_prompt` não forçou JSON — o parser não conseguiu extrair o veredicto
* O agente bateu em `max_turns` antes de retornar (aumente o limite ou aperte o prompt)
* O agente bateu em `timeout_seconds` (chamada de integração foi lenta — aumente o timeout ou adicione um retry dentro do agente)

### Drift entre YAML e banco

Se você editou `config/heartbeats.yaml` à mão e o dashboard ainda mostra o estado antigo:

```bash theme={null}
curl -X POST http://localhost:8080/api/heartbeats/reindex
```

Reconstrói as linhas do banco a partir do YAML. Seguro de rodar a qualquer momento.

## Skills do CLI

| Skill | O que faz |
| - | - |
| `create-heartbeat` | Wizard interativo para adicionar um novo heartbeat |
| `manage-heartbeats` | Listar, habilitar/desabilitar, disparar execuções manuais, inspecionar histórico |

## Relacionados

* `docs/goals.md` — ligar um heartbeat a um goal para injeção de contexto
* `docs/tickets.md` — `@mentions` em tickets acordam heartbeats
* Código: `dashboard/backend/heartbeat_dispatcher.py`, `dashboard/backend/routes/heartbeats.py`, `dashboard/backend/heartbeat_schema.py`


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.