Hefesto
Assistente de IA pessoal e local-first que conhece de verdade os meus repositórios: cita arquivo, linha e commit em vez de inventar, e coordena agentes de escrita sob aprovação humana explícita
O endpoint mantém um log append-only por execução. Ao reconectar, o navegador envia o Last-Event-ID e a API reproduz só os eventos que faltaram, sem duplicar nada.
Visão Geral
Hefesto nasceu de dois problemas do meu dia a dia como desenvolvedor: assistentes de IA genéricas alucinam sobre um repositório quando o contexto é só um recorte ad hoc, e ferramentas que 'escrevem código sozinhas' costumam esconder o quanto de autonomia real estão exercendo. Em vez de um chatbot plugado num repositório, é uma assistente com memória estruturada do histórico do projeto (commits → documentos → decisões → perguntas em aberto → conversas) e uma camada separada de execução autônoma, com aprovação humana obrigatória e isolamento real de escrita.
O que a assistente faz
Respostas com fonte, sempre
Toda resposta sobre documentação ou código cita path, linha inicial/final e hash do commit de onde a informação saiu. Sem evidência no repositório, a resposta diz isso em vez de inventar.
Conversa por voz ponta a ponta
Grava, transcreve localmente com Whisper (CPU), responde e narra de volta usando a Web Speech API nativa do navegador, sem pipeline de áudio extra nem chave de API obrigatória.
Streaming resiliente a reconexão
O chat em stream mantém um log append-only por execução; reconectar reproduz só os eventos que faltaram via Last-Event-ID, sem duplicar nem perder nada.
Escrita isolada e aprovada
A tela de agentes leva ao orquestrador de escrita: cada tarefa roda numa branch e worktree isolados, com aprovação humana explícita antes de qualquer mudança em disco.
O Desafio
- Garantir que o chat em stream sobreviva a uma reconexão do navegador sem duplicar nem perder nenhum evento, mesmo com o EventSource tentando reconectar sozinho depois de uma resposta já ter terminado.
- Fazer com que toda resposta cite arquivo, linha e commit reais, não uma aproximação: inventar uma citação seria pior do que admitir que não encontrou evidência.
- Coordenar múltiplos agentes de IA sobre o mesmo repositório expôs um comportamento não determinístico: às vezes um provider respondia como se não tivesse acesso a um arquivo que estava, de fato, disponível no sandbox.
A Solução
- Cada execução mantém um log append-only de eventos por trás do endpoint de stream; a reconexão usa o Last-Event-ID do navegador para retomar exatamente do ponto onde parou, em vez de reiniciar a resposta.
- Escopo padrão é sempre 'só documentação'; código só entra com --scope code explícito, e cada resposta carrega path, linhas e hash do commit de onde a informação saiu, ou diz que não sabe.
- A lição virou prática de engenharia: tratar toda resposta de agente como potencialmente inconsistente, nunca como uma chamada de função garantida, e isolar qualquer escrita em branch e worktree próprios, revisáveis antes de qualquer merge.
Arquitetura do Sistema
Três serviços locais independentes, cada um seu próprio repositório, conversando por HTTP em loopback e nunca expostos fora da máquina. O front web é a porta de entrada visual tanto do chat de documentação quanto do orquestrador de agentes de escrita.
O orquestrador de agentes é um projeto próprio, com página dedicada: veja o Maestro.
Local-First por Padrão Real
Local-first aqui não é discurso de marketing, é a premissa de projeto:
- As três APIs escutam só em 127.0.0.1, sem autenticação, porque nunca deveriam sair da máquina; CORS restrito às origens locais conhecidas dos próprios dev servers.
- Nada é escrito sem aprovação explícita, seja uma edição pontual de arquivo no chat ou uma tarefa completa de agentes, e a escrita é sempre isolada em branch e worktree próprios.
- Redação de segredos em múltiplas camadas: variáveis de ambiente nunca entram na configuração persistida, e padrões de chave/token/senha são removidos de contexto, diffs, logs e respostas antes de serem gravados.
- Comandos destrutivos de Git/terminal (
git reset --hard,git push --force,rm -rfe equivalentes) são bloqueados por política, a menos que explicitamente confirmados.