Em uma tarefa longa de IA, o mais assustador nem sempre é a falha. É o silêncio.
Uma pessoa pode terminar tarefas de casa, fazer compras, comer e voltar; a IA ainda aparece como “trabalhando”. Nesse momento existem duas hipóteses muito diferentes:
- Ela está rodando uma suíte enorme de testes.
- Ela travou em algum ponto horas atrás.
Um spinner não separa bem essas situações. A ausência de commits também não: testes, investigação, comparação, geração e esperas externas podem ficar bastante tempo sem produzir um artefato visível.
Por isso, IA de longa duração precisa de algo além de inteligência: observabilidade.
1. Conclusão: se uma tarefa pode durar bastante, exponha o estado atual
Um agente de longa duração não deveria informar somente no final. O estado intermediário também precisa ser legível.
Não é necessário dizer “ainda estou vivo” a cada minuto. É necessário conseguir responder:
- O que está fazendo agora?
- O que já terminou?
- O que falta?
- Está testando?
- Está bloqueado?
- Quando a atividade foi confirmada pela última vez?
- Quando ocorreu a última mudança material?
Um exemplo de configuração prática é atualizar o Heartbeat depois de cerca de 10 minutos sem artefato visível e tratar um Heartbeat com mais de 20 minutos como STALE_UNKNOWN, não como “parado”.
Silêncio significa primeiro “não sabemos”, e não “falhou”.
2. Por que apenas o histórico de commits não basta
Commits do Git são ótimos para provar mudança material, mas fracos como única prova de atividade atual.
Uma suíte de regressão de uma hora pode estar saudável sem gerar commit algum. Por outro lado, criar um commit inútil de Heartbeat a cada dez minutos só polui o histórico.
Separe:
Heartbeat = estado atual
Material change = evidência de que código, contratos, artefatos ou verificações realmente mudaram
Com lastHeartbeatAt e lastMaterialChangeAt separados, fica fácil entender “30 minutos sem commit, mas TESTING confirmado há 5 minutos”.
O objetivo não é ter mais commits. É tornar o silêncio interpretável.
3. O que registrar no mínimo?
Um run longo se beneficia destes campos:
runIdstate: RUNNING / BLOCKED / COMPLETED / STALE_UNKNOWN etc.phase: READING / IMPLEMENTING / TESTING / VERIFYING etc.workingOnstartedAtlastHeartbeatAtlastMaterialChangeAtbranch / baseSha / headSha / PRcompletedMilestones / remainingMilestonesblockerstestsnextCheckpoint
Assim, um trabalho de seis horas deixa de ser “uma caixa-preta de seis horas” e pode ser lido como:
IMPLEMENTING → TESTING → INTEGRATING → VERIFYING
Uma caixa-preta pode ser brilhante, mas continua sendo uma caixa-preta. Depois de algumas horas, isso cansa a cabeça.
4. Durante testes, Heartbeats são ainda mais importantes
Um teste longo se parece muito com um agente congelado.
Antes de iniciar, registre:
phase = TESTING- nome da suíte
- escopo
- um número objetivo como
84 / 127, se houver total fixo - se alguma falha já apareceu
Evite porcentagens inventadas como “82% concluído” em design ou debugging. Ninguém sabe exatamente o que compõe os 18% restantes.
Percentuais fazem sentido quando o denominador é fixo:
- 84 / 127 tests
- 3 / 5 acceptance gates
“Implementação 82% pronta” é a versão IA de “estou chegando” dita por alguém que talvez ainda esteja em casa.
5. Leia “parou?” em etapas
Uma política prática pode classificar a idade do Heartbeat assim:
| Idade | Interpretação |
|---|---|
| 0–10 minutos | CURRENT |
| 10–20 minutos | HEARTBEAT_OVERDUE |
| Mais de 20 minutos | STALE_UNKNOWN |
STALE_UNKNOWN não é FAILED.
Depois, confira nesta ordem:
- registro atual de progresso
- Check / Status
- branch / PR
- último commit
- inferência apenas no final
Se o Heartbeat estiver velho, mas aparecer um PR ou commit novo depois, o agente provavelmente continuou trabalhando e só esqueceu de atualizar o status.
IA também pode ter o caso: trabalho feito, timesheet esquecido.
6. Erros a evitar
Não colocar commits de Heartbeat na main
Isso polui o histórico, cria conflitos e pode disparar CI ou deploy desnecessário. Prefira uma superfície mutável: comentário de Issue, Check, Status ou área ops não produtiva.
Não criar um comentário novo a cada Heartbeat
Um registro mutável por run é muito mais legível. Um comentário a cada dez minutos vira arqueologia operacional.
Não transformar silêncio em falha automaticamente
Se o Heartbeat apenas envelheceu, use STALE_UNKNOWN. Falha exige evidência afirmativa.
Não vazar segredos
Nada de API keys, tokens, senhas, URLs privadas, conversas privadas cruas, dados pessoais ou arquivos confidenciais.
Não parar trabalho seguro porque a observabilidade falhou
Se a API de progresso falhar, use outro sink e continue o que puder continuar com segurança.
7. Modelo prático
State: RUNNING
Phase: TESTING
Run ID: agent-20260916-long-task
Started: 10:00
Last heartbeat: 14:05
Last material change: 13:42
Branch: feat/long-task
Head SHA: abc1234
PR: #123
Working on:
- regression tests
Completed:
- runtime implementation
- contract update
Remaining:
- regression completion
- merge verification
- production readback
Blockers:
- none
Tests:
- 84 / 127 passed so far
- no failure observed
Next checkpoint:
- finish regression, then integration
Com isso, “será que parou?” vira “ah, está testando”.
A visibilidade de progresso não existe principalmente para pressionar a IA. Ela evita que humanos reiniciem, interrompam ou repitam instruções por falta de informação.
8. Resumo: projete inteligência e visibilidade separadamente
Em tarefas longas, diferencie:
- sem commit ≠ parado
- Heartbeat ≠ progresso material
- Heartbeat velho ≠ falha
- um blocker ≠ parada global
- silêncio em teste ≠ dormindo
Se uma IA consegue trabalhar por seis horas, uma pessoa não deveria ter que observá-la por seis horas.
O melhor desenho é: quando você voltar, consegue ver imediatamente onde ela está.
O agente ideal de longa duração não é o que fala o tempo todo.
Ele trabalha quieto, mas sua posição fica clara quando você olha.

