Relatórios e sinais
Como um card devolve resultado, como o orquestrador percebe que ele terminou, e o que "parked" quer dizer.
Um card reporta um resultado estruturado que sobrevive a ele: o relatório vive na tabela, não no scrollback. É assim que um orquestrador lê o que aconteceu sem parsear ANSI.
O relatório
Cada relatório traz:
- o payload, com
ok: truepara sucesso eok: falsepara falha declarada; - um
verdict(aprovado/reprovado/ nulo), quando é uma revisão; - o
roledo reporter no momento do relatório — é assim que se distingue um review de um implementer se autoaprovando; - o
channelpor onde entrou, carimbado pelo servidor.
Relatórios são numerados; ler com o último número visto devolve o próximo, sem reler o mesmo e sem perder rodadas antigas.
Saber que um card terminou
O app empurra um ponteiro de texto para quem deve saber: o card que spawnou, ou a última diretiva enviada, ou a marca de orquestrador do board. Não é notificação do sistema — nada pisca fora da janela, e isso foi pedido, não esquecido. São quatro avisos:
| Aviso | Quando dispara |
|---|---|
| relatório disponível | o card chamou report |
saiu sem chamar report |
o processo morreu devendo um relatório |
ocioso sem chamar report |
ficou quieto além do piso, com task viva |
| subiu e não produziu nenhum byte | 30s sem uma única saída — o processo está vivo e calado, e nada foi encerrado |
O terceiro tem três frases diferentes, e a diferença é o mecanismo, não estilo: sem agente lendo a linha, o card não podia reportar e a frase não acusa; com o turno declarado encerrado pelo próprio card, a acusação está sustentada por um fato que ele mesmo emitiu; sem fato de turno, é silêncio inferido — a frase diz há quanto tempo o card está quieto e pede conferência, em vez de afirmar abandono. Um alarme que erra ensina o orquestrador a ignorá-lo, e é assim que o sinal verdadeiro morre.
O último é o único que não é sobre silêncio depois de trabalhar, e sim sobre nunca ter falado: é o nome honesto de um PTY que não produziu um byte. Ele avisa, nunca mata — um processo que só demorou a pintar não pode ser destruído por um relógio.
O padrão continua sendo consultar o status e então ler o relatório. O
card_status responde:
| Estado | O que quer dizer |
|---|---|
running |
o turno declarado acabou e saída chegou depois — um turno novo começou |
idle |
turno encerrado, ou parado esperando você |
at-prompt |
shell livre no prompt (um shell não tem turno, então nunca é idle) |
waiting |
bloqueado numa decisão de consentimento |
exited |
o processo morreu |
no-output |
subiu e não emitiu nenhum byte; o primeiro byte apaga o estado sozinho |
unknown |
a saída não distingue trabalho de repintura |
unknown não é falha do app: um TUI parado repinta a tela para sempre, e um
TUI pode estar rodando dentro de um card bash. Leia como confira a tela
antes de decidir um despacho — nunca como livre.
Falar com um card vivo
Enviar texto a um card é enfileirar, e volta na hora. O texto pode terminar em alguns estados diferentes, e a diferença importa:
| Estado | O que aconteceu |
|---|---|
queued |
está na fila do card |
delivered |
confirmado na tela — o agente tem o texto |
parked |
a fila do provider segurou; o agente ainda não viu |
unconfirmed |
escreveu, sem evidência na tela |
failed |
visivelmente travado e limpo — reenviar |
cancelled |
o autor morreu antes de a entrega sair |
parked não é delivered. Essa distinção nasceu de um dano real: um
aviso de “pare agora” ficou na fila e chegou depois do dano. Um canal de
correção que só entrega no fim do turno não é canal de correção.
Linhagem
Quem criou quem é registrado com motivo, provider e profundidade, e sobrevive a restart. Todo spawn de agente declara um motivo — é o único campo que o app não consegue derivar. Há um teto de profundidade na cadeia de spawns.