Phase 19 - Lesson 01

Capstone 01 — Terminal-Native Coding Agent

Em 2026, o formato de um agente de programação já está consolidado. Um harness TUI, um estado de planejamento persistente, uma superfície de ferramentas em sandbox e um loop que planeja, age, observa e recupera-se. Claude Code, Cursor 3 e OpenCode parecem todos idênticos quando observados de longe. Este projeto prático (capstone) desafia você a construir um agente de ponta a ponta — do CLI de entrada à pull request de saída — e avaliá-lo em relação ao mini-swe-agent e ao Live-SWE-agent no SWE-bench Pro. Você aprenderá por que a parte mais difícil não é a chamada do modelo, mas sim o loop de ferramentas, o sandbox e o teto de custo em uma execução de 50 turnos.

Type: Capstone Languages: TypeScript / Bun (harness), Python (eval scripts) Prerequisites: Phase 11 (LLM engineering), Phase 13 (tools and protocols), Phase 14 (agents), Phase 15 (autonomous systems), Phase 17 (infrastructure) Phases exercised: P0 · P5 · P7 · P10 · P11 · P13 · P14 · P15 · P17 · P18 Time: 35 hours

Problem

Os agentes de programação se tornaram a categoria dominante de aplicação de IA em 2026. Claude Code (Anthropic), Cursor 3 com Composer 2 e Agent Tabs (Cursor), Amp (Sourcegraph), OpenCode (112 mil estrelas), Factory Droids e Google Jules distribuem variações da mesma arquitetura: um harness de terminal, uma superfície de ferramentas autorizada, um sandbox e um loop de planejar-agir-observar construído em torno de um modelo de fronteira. A fronteira de sucesso é estreita — o Live-SWE-agent alcançou 79,2% no SWE-bench Verified com o Opus 4.5 —, mas a engenharia envolvida é ampla. A maioria dos modos de falha não decorre de erros do modelo, mas sim de instabilidade no loop de ferramentas, envenenamento de contexto, custo descontrolado de tokens e operações destrutivas no sistema de arquivos.

Não é possível compreender verdadeiramente esses agentes a partir de uma perspectiva externa. É preciso construir um, observar o loop falhar no turno 47 quando o ripgrep retorna 8MB de correspondências e reconstruir a camada de truncamento. Esse é o objetivo deste capstone.

Concept

O harness possui quatro superfícies principais. Plan mantém um objeto de estado no estilo TodoWrite que o modelo reescreve a cada turno. Act despacha chamadas de ferramentas (read, edit, run, search, git). Observe captura a saída padrão (stdout), a saída de erro (stderr) e códigos de saída, aplica truncamento e envia o resumo de volta ao modelo. Recover lida com erros de ferramentas sem estourar a janela de contexto ou entrar em loops infinitos. O formato de 2026 adiciona mais um elemento: hooks. PreToolUse, PostToolUse, SessionStart, SessionEnd, UserPromptSubmit, Notification, Stop e PreCompact — pontos de extensão configuráveis onde o operador injeta políticas, telemetria e proteções.

O sandbox é executado no E2B ou Daytona. Cada tarefa roda em um devcontainer novo com um git worktree montado com permissão de leitura e escrita. O harness nunca toca o sistema de arquivos do host. O worktree é destruído após o sucesso ou falha da tarefa. O controle de custos é aplicado em três camadas: um limite de tokens por turno, um orçamento financeiro por sessão e um limite rígido de turnos (geralmente 50). A camada de observabilidade utiliza spans OpenTelemetry com as convenções semânticas de GenAI, enviados para uma instância própria do Langfuse.

Architecture

  user CLI  ->  harness (Bun + Ink TUI)
                  |
                  v
           plan / act / observe loop  <--->  Claude Sonnet 4.7 / GPT-5.4-Codex / Gemini 3 Pro
                  |                          (via OpenRouter, model-agnostic)
                  v
           tool dispatcher (MCP StreamableHTTP client)
                  |
     +------------+------------+----------+
     v            v            v          v
  read/edit    ripgrep     tree-sitter   git/run
     |            |            |          |
     +------------+------------+----------+
                  |
                  v
           E2B / Daytona sandbox  (worktree isolated)
                  |
                  v
           hooks: Pre/Post, Session, Prompt, Compact
                  |
                  v
           OpenTelemetry -> Langfuse (spans, tokens, $)
                  |
                  v
           PR via GitHub app

Stack

  • Runtime do harness: Bun 1.2 + Ink 5 (React-no-terminal)
  • Acesso ao modelo: API unificada do OpenRouter com Claude Sonnet 4.7, GPT-5.4-Codex, Gemini 3 Pro, Opus 4.5 (para tarefas mais complexas)
  • Transporte de ferramentas: Model Context Protocol StreamableHTTP (revisão de 2026 do MCP)
  • Sandbox: Sandboxes E2B (JS SDK) ou devcontainers Daytona
  • Busca de código: subprocesso ripgrep, analisadores tree-sitter pré-compilados para 17 linguagens
  • Isolamento: git worktree add por tarefa, com limpeza em caso de sucesso ou falha
  • Harness de avaliação: SWE-bench Pro (subconjunto verificado) + Terminal-Bench 2.0 + seu próprio conjunto de validação de 30 tarefas
  • Observabilidade: SDK do OpenTelemetry com semconv gen_ai.* → Langfuse hospedado localmente
  • Envio de PR: GitHub App com token de granularidade fina, com escopo limitado ao repositório alvo

Build It

  1. TUI e loop de comandos. Estruture um projeto Bun com Ink. Aceite agent run <repo> "<task>". Exiba uma visualização dividida: painel do plano (topo), fluxo de chamadas de ferramentas (meio), orçamento de tokens (rodapé). Adicione cancelamento no Ctrl-C que acione o hook SessionEnd antes de sair.

  2. Estado do plano. Defina um esquema TodoWrite tipado (itens pendentes / em andamento / concluídos com notas). O modelo deve reescrever o estado completo a cada turno por meio de uma chamada de ferramenta — não permita mutações incrementais. Persista o plano em .agent/state.json para que a execução possa ser retomada após falhas.

  3. Superfície de ferramentas. Defina seis ferramentas: read_file, edit_file (com visualização de diff), ripgrep, tree_sitter_symbols, run_shell (com limite de tempo) e git (status / diff / commit / push). Exponha-as via MCP StreamableHTTP para que o harness seja independente de transporte. Cada ferramenta deve retornar saídas truncadas (limite máximo de 4k tokens por chamada).

  4. Encapsulamento do sandbox. Cada tarefa inicia um sandbox E2B. Crie um branch limpo com git worktree add -b agent/$TASK_ID. Todas as chamadas de ferramentas devem ser executadas dentro do sandbox. O sistema de arquivos do host deve ser inacessível.

  5. Hooks. Implemente todos os oito tipos de hooks de 2026. Conecte pelo menos quatro hooks personalizados: (a) proteção de comandos destrutivos no PreToolUse que impeça rm -rf fora do worktree, (b) contabilidade de tokens no PostToolUse, (c) inicialização do orçamento no SessionStart e (d) gravação do pacote final de rastreamento no Stop.

  6. Loop de avaliação. Clone um subconjunto de 30 tarefas do SWE-bench Pro em Python. Execute seu harness em relação a cada uma delas. Compare com o mini-swe-agent (a linha de base mínima) em relação a pass@1, turnos por tarefa e custo financeiro por tarefa. Salve os resultados em eval/results.jsonl.

  7. Controle de custos. Limites rígidos: 50 turnos, 200k de contexto, $5 por tarefa. O hook PreCompact deve resumir turnos antigos em um bloco de estado anterior ao atingir a marca de 150k tokens, liberando espaço para novas observações sem perder o plano geral.

  8. Envio de PR. No sucesso, a etapa final consiste em executar git push + uma chamada à API do GitHub que abra um PR contendo o plano e o resumo do diff no corpo da mensagem.

Use It

$ agent run ./my-repo "Fix the race condition in worker.rs"
[plan]  1 locate worker.rs and enumerate mutex uses
        2 identify shared state under contention
        3 propose fix, verify tests
[tool]  ripgrep mutex.*lock -t rust           (44 matches, truncated)
[tool]  read_file src/worker.rs 120..180
[tool]  edit_file src/worker.rs (+8 -3)
[tool]  run_shell cargo test worker::          (passed)
[plan]  1 done · 2 done · 3 done
[done]  PR opened: #482   turns=9   tokens=38k   cost=$0.41

Ship It

A habilidade entregável é detalhada em outputs/skill-terminal-coding-agent.md. Dado o caminho de um repositório e a descrição de uma tarefa, o sistema executa o loop completo de planejar-agir-observar em um sandbox e retorna a URL do PR juntamente com o pacote de rastreamento. Critérios de avaliação para este capstone:

Weight Criterion How it is measured
25 SWE-bench Pro pass@1 vs baseline Seu harness vs mini-swe-agent em 30 tarefas Python equivalentes
20 Clareza arquitetônica Separação de planejar/agir/observar, superfície de hooks e esquema de ferramentas — revisados em relação à estrutura do Live-SWE-agent
20 Segurança Testes de escape do sandbox, prompts de permissão e proteção contra comandos destrutivos aprovados em testes adversariais (red-team)
20 Observabilidade Rastreamento completo (100% das chamadas de ferramentas cobertas por spans) e contabilidade de tokens por turno
15 UX do desenvolvedor Inicialização a frio < 2s, recuperação de falhas retomando o plano e cancelamento limpo de ferramentas no Ctrl-C
100

Exercises

  1. Substitua o modelo de suporte do Claude Sonnet 4.7 pelo Qwen3-Coder-30B servido no vLLM. Compare o pass@1 e o custo financeiro por tarefa. Relate os pontos onde o modelo de código aberto apresenta desempenho inferior.

  2. Adicione um subagente reviewer que revise o diff antes de enviar o PR e que possa solicitar um loop de revisão adicional. Meça se revisões falso-positivas reduzem a taxa de sucesso do SWE-bench abaixo da linha de base de agente único (dica: geralmente sim).

  3. Teste os limites de segurança do sandbox: crie uma tarefa que tente executar um curl para uma URL externa e outra que tente gravar fora do worktree. Confirme que ambas as tentativas são bloqueadas pelo hook PreToolUse. Registre as tentativas em log.

  4. Implemente a compactação no PreCompact utilizando um modelo menor (Haiku 4.5). Meça a perda de fidelidade do plano após uma compactação de 3x.

  5. Substitua o transporte MCP StreamableHTTP por stdio. Faça um benchmark do tempo de inicialização a frio e da latência por chamada. Escolha o vencedor para uso estritamente local.

Key Terms

Term What people say What it actually means
Harness "O loop do agente" O código que envolve o modelo e gerencia as ferramentas, o estado do plano e o orçamento
Hook "Ouvinte de eventos do agente" Um script personalizado executado em um dos oito eventos do ciclo de vida do harness
Worktree "Sandbox do Git" Um checkout do Git vinculado a um caminho separado; descartável sem afetar o clone principal
TodoWrite "Estado do plano" Uma lista tipada de itens pendentes, em andamento ou concluídos que o modelo reescreve a cada turno
StreamableHTTP "Transporte MCP" Revisão de 2026 do MCP: conexão HTTP de longa duração com streaming bidirecional que substitui SSE
Token ceiling "Orçamento de contexto" Limite por turno ou por sessão para tokens de entrada e saída; aciona a compactação ou o encerramento
pass@1 "Taxa de sucesso na primeira tentativa" Fração de tarefas do SWE-bench resolvidas na primeira execução, sem tentativas adicionais ou visualização do conjunto de testes

Further Reading

0 lifetime access. Curriculum based on AI Engineering from Scratch by Rohit Ghumare (MIT, used under attribution).