GBR: ADR-0004 REPL Assíncrono e HITL via Event Sourcing (Disk Log) | Wiki
GBR: ADR-0004 REPL Assíncrono e HITL via Event Sourcing (Disk Log)
- *Status:* Aceito/Feito(2026-05-17)
- *Data:* 13 de Maio, 2026
*Contexto:*
A CLI gleambr_ai requer uma interface de terminal (REPL) capaz de suportar três fluxos I/O concorrentes: (1) O bloqueio natural da leitura do teclado do usuário; (2) O fluxo intenso de streaming de texto (SSE) vindo das respostas do LLM via rede; (3) As interrupções de segurança (Human-in-the-Loop - HITL) geradas de forma assíncrona pelas ferramentas MCP locais. Uma abordagem síncrona convencional (Read-Eval-Print) causaria engarrafamento de mensagens (deadlocks de UI) ou inanição do processo de comunicação de rede. Adicionalmente, acumular estados transacionais de aprovação na memória volátil (RAM) expõe a ferramenta a perdas críticas de estado em caso de falha.
*Decisão:*
A interface do usuário será modelada como um *Ator REPL Assíncrono* guiado por eventos, adotando o padrão Event Sourcing para o fluxo de aprovação.
- *Delegação de Stdin:* O Ator REPL nunca invocará operações bloqueantes de terminal de forma direta. A leitura de teclado será delegada a processos efêmeros (Tasks) que enviarão o input resultante via mensagens OTP.
-
*Buffer de Disco (Saga Pattern):* Toda requisição de aprovação de segurança (HITL) gerada pelo Servidor MCP será persistida como um evento pendente no
gbr_disk_log. -
*Polling de Fundo:* O Ator REPL implementará um laço temporal (Tick) que inspecionará continuamente o
gbr_disk_log. Ao detectar eventos pendentes, o REPL suspenderá a renderização de novos chunks do LLM e sobreporá um aviso visual solicitando o input explícito do operador, gravando a resolução de volta no disco para que a ferramenta suspensa possa prosseguir.
*Consequências:*
- *Positivas:* A responsividade do terminal (UX) será imaculada, mesmo sob alta carga do Agente; o estado de segurança é 100% tolerante a falhas (um crash na CLI não perde pedidos pendentes); desacoplamento perfeito entre a lógica do Agente (MCP) e a interface de apresentação (REPL).
- *Negativas:* Exigência de gerenciamento cuidadoso dos cursores do terminal (ANSI Escape Codes) para não sobrescrever a linha de digitação do usuário enquanto o streaming da IA é impresso em background.
Análise da negativa
A Guerra dos Cursores (ANSI vs UX)
*O Problema Físico:*
O terminal (seja Windows Terminal, Alacritty ou iTerm2) tem apenas *um cursor físico*. Se você está digitando Você: crie um test_ e a IA manda um chunk de texto assíncrono via rede, o terminal imprime o chunk exatamente onde o cursor está. O resultado é: Você: crie um testAqui está o código_. Isso destrói a sanidade do desenvolvedor.
Estratégia A: O Padrão "Cursor Flutuante" (ANSI Hardcore)
Para permitir que você digite enquanto a IA responde, precisaríamos interceptar cada tecla do seu teclado (raw mode), e toda vez que um chunk chegasse da rede, o Ator REPL teria que disparar os seguintes Códigos de Escape ANSI:
-
\x1b[s(Salva a posição do seu cursor). -
\x1b[2K\r(Apaga a linha atual onde você estava digitando). -
\x1b[1A(Sobe o cursor para a área de chat). - Imprime o texto da IA.
-
\x1b[u(Restaura a posição do seu cursor lá embaixo). - Reimprime o que você estava digitando.
- *Risco:* No Windows 11, o buffer de scroll do terminal pode causar artefatos visuais se o usuário rolar a tela do mouse durante esse processo.
Estratégia B: O "Input Lock" Sequencial (A Recomendação do Mestre)
Como estamos fazendo um MVP de altíssima confiabilidade e já implementamos o gbr_disk_log para segurar requisições, *nós não precisamos de digitação simultânea.*
-
Você digita a sua intenção e aperta
<Enter>. -
O REPL muda de estado para
Streaminge *desabilita* a leitura de teclado do nossoTaskefêmero. - A IA despeja o código tranquilamente no terminal (como o ChatGPT faz).
-
Se o Servidor MCP pedir aprovação (HITL), a IA para, o REPL lê o disco, imprime o aviso e *habilita* o teclado momentaneamente para ler
[Y/N]. -
Quando a IA termina (
Done), o REPL imprime uma linha verdeVocê:e reabilita o teclado.
-
*A Mitigação:* Se você digitar algo enquanto a IA estiver falando, o próprio Sistema Operacional vai guardar as teclas no buffer e só vai cuspir na tela quando o REPL pedir o
io.get_linenovamente. Custo de engenharia: Zero. Confiabilidade: 100%.
*Veredito:* Adotaremos a *Estratégia B (Input Lock)* para o MVP. Eliminamos o risco de UX sem adicionar complexidade ANSI desnecessária.