Arquitetura do núcleo do BeeverForge

A caixa e o piso de qualidade

Um job roda em uma caixa: um ambiente que o worker cria para esse job e descarta depois. A caixa executa a imagem do próprio cliente com as ferramentas da plataforma montadas dentro dela, e é provada contra os controles do próprio projeto antes de qualquer ticket ser recolhido.

Tipos de caixa#

TipoO que isola
containerO padrão. Um contêiner Docker descartável criado a partir da imagem do projeto. Limita CPU e memória, carrega segredos só durante o job e só vê o clone montado, a caixa de ferramentas, as diretrizes e um cache. Não isola a rede.
worktreeUm git worktree na própria máquina do worker. Isola apenas o estado do código: não isola CPU, memória, rede nem segredos. O código o descreve como nunca adequado para trabalho não confiável.
fargateApenas a descrição de uma caixa de tarefas remota. Seu executor não está neste repositório; ele é fornecido por um complemento.
Dentro de uma caixa de contêinerO worker inicia a caixa a partir da imagem do projeto pelo socket do Docker, com limites de CPU e memória, e passa os segredos do job como variáveis de ambiente. A caixa monta o clone do job, a caixa de ferramentas e as diretrizes como somente leitura, e um cache. Sua rede é a bridge do Docker por padrão.docker run com limites de CPUe memória,depois docker exec, pelo socketdo Dockersegredos como variáveis deambientebridge por padrãoCaixa: um contêiner da imagem do projeto/workspaceo clone do job/opt/beeverforge-toolboxbinários do harness, somente leitura/opt/beeverforge-guidelinesdiretrizes, somente leitura/cachecache de dependênciasWorker: o executor de jobsRede acessível a partir da caixa
Uma caixa container como o worker a inicia. Os segredos são passados durante o job; a rede não é isolada.

Um job durável é recusado em uma caixa que não limita nada, a menos que o projeto declare que o trabalho é do próprio operador. Mais tipos podem ser adicionados como pontos de entrada box.<kind>.

Provar a caixa#

beeverforge box prove transforma a configuração da caixa em um fato registrado (ADR-0037). Executa uma sequência fixa e para na primeira falha de que as verificações seguintes dependem, de modo que cada causa é informada uma única vez, com sua solução:

  1. A tag da imagem é resolvida para um digest.
  2. A caixa de ferramentas é verificada contra a imagem: uma imagem cuja biblioteca C difere da compilação da caixa de ferramentas, como uma imagem musl para uma caixa de ferramentas glibc, não consegue executar os binários do harness e é recusada nomeando a causa.
  3. O contrato da imagem: um shell POSIX em /bin/sh, um processo que a mantenha viva, git, um HOME gravável e um /workspace gravável. Uma imagem distroless ou scratch não pode ser usada.
  4. A caixa inicia, o setup: do projeto é executado e depois seus controles validate: rodam sobre uma cópia intacta de main, dentro da caixa.
  5. O harness é verificado: sua versão, suas credenciais como vistas dentro da caixa, o repositório de certificados confiáveis e se o endpoint do harness é acessível pela rede da caixa.
O que beeverforge box prove verificaA prova executa cinco verificações em uma ordem fixa e para na primeira falha de que as verificações seguintes dependem. Quando todas passam, a prova é registrada, e a varredura do quadro recolhe trabalho enquanto os fatos registrados se mantiverem.falhabeeverforge box prove1. A tag da imagem é resolvida para um digest2. A caixa de ferramentas corresponde à biblioteca C da imagem3. O contrato da imagem: /bin/sh,keep-alive, git, HOME e /workspacegraváveis4. A caixa inicia, setup: rodae depois validate: em umcheckout intacto de main5. O harness: versão, credenciais,repositório de confiança, endpoint acessívelUma falha de que dependemas verificações seguintesinterrompe a execução: uma causa,informada uma vez, com sua soluçãoProva registradaA varredura do quadro recolhe trabalhoenquanto os fatos registrados se mantiverem
As verificações de beeverforge box prove, na ordem em que rodam.

Em uma caixa que executa a imagem do cliente, a prova não pede nada a nenhum agente e não gasta tokens do harness. Em uma caixa sem imagem, onde o login do harness é uma sessão na máquina do operador, ela pede ao harness uma única palavra para confirmar que o login funciona.

Uma prova é válida enquanto o digest da imagem, a caixa de ferramentas e o hash dos comandos setup: e validate: do projeto não mudarem. Em uma caixa com imagem, a caixa de ferramentas é identificada por seu sistema operacional, sua arquitetura e sua biblioteca C; em uma caixa sem imagem, uma nova versão do harness torna a prova obsoleta. As provas não expiram por tempo. A varredura do quadro se recusa a recolher trabalho de um projeto cuja caixa tem algo a provar e não tem prova válida, e informa qual desses fatos mudou. Uma caixa worktree não tem imagem; só passa por esse controle em uma implantação que declara BEEVERFORGE_OWN_WORK, o ambiente em que o worker é a própria máquina do operador.

Um controle não bloqueante que falha durante a prova não impede o recolhimento, a menos que seu comando nem tenha conseguido ser executado.

A montagem da caixa de ferramentas#

Os binários do harness não são instalados na imagem do cliente. Eles ficam em uma caixa de ferramentas montada em cada caixa como somente leitura em /opt/beeverforge-toolbox; as diretrizes do operador também são montadas como somente leitura. O código declara o limite dessa opção: somente leitura protege contra acidentes, não contra um adversário, porque um processo rodando como root na caixa ainda pode copiar um binário para fora.

Tráfego de rede de saída#

A rede da caixa container é, por padrão, a bridge do Docker, que dá acesso total à internet de saída. Tudo o que a rede da caixa alcança pode ser alcançado pelo código que o agente escreveu.

  • box.network no registro seleciona outra rede do Docker, como uma rede restrita ou uma atrás de um proxy fornecido pela implantação. O núcleo não tem lista de permissões nem proxy embutidos.
  • Um job precisa, no mínimo, do endpoint do harness. Um projeto em uma plataforma Git remota também precisa da plataforma Git e do tracker, e de tudo o que setup: instalar a partir de registros de pacotes.
  • A prova verifica se o endpoint do harness é acessível. Quando um projeto declara uma identidade de máquina, beeverforge doctor testa se a caixa consegue alcançar o endereço de metadados de instância da nuvem.
  • Um ambiente isolado da rede não consegue executar um job, porque o agente de programação é um serviço remoto.

O piso de qualidade#

O piso está em policy/floor.py: os papéis de validação test e security são obrigatórios. Antes da passada de implementação, depois do dimensionamento, o executor verifica que os dois papéis estão presentes depois da cascata de padrões da implantação, presets do stack, do bloco de todo o repositório e dos blocos por componente. Um projeto em que falta um deles é recusado com o papel nomeado e uma solução; nada é executado.

  • Todo projeto herda um controle security de org_defaults/floor.yaml: uma varredura dos arquivos versionados em busca de credenciais incluídas em commits. Ele é declarado como advisory: true.
  • A herança só adiciona os papéis que o projeto não declara. Um projeto que declara um papel o mantém exatamente como escrito, então pode substituir o comando de um papel obrigatório, ou torná-lo não bloqueante, e ainda assim cumprir o piso. O piso verifica que os papéis existem, não o que eles executam.
  • Os caminhos protegidos são aditivos: um projeto pode ampliar a lista da implantação e não tem nenhum campo para remover itens. Uma mudança que toca um caminho protegido nunca recebe merge automático.

O que advisory: true faz. O controle é executado e informado, com uma marca de aviso no corpo do pull request. Ele nunca faz o job falhar, nunca bloqueia o merge e nunca dispara um reparo. Um perfil pode tornar bloqueante um controle não bloqueante, nunca o contrário.

Executor e revisor separados#

O revisor roda em um contexto próprio. Ele recebe o ticket, o diff, os resultados dos controles e as restrições, e nunca vê como a mudança foi feita nem o que o executor diz ter feito. O revisor do Claude Code é uma sessão nova, não retomada, em modo de planejamento; o revisor genérico do harness é informado de que não escreveu o código. O código observa que a independência diminui quando o revisor e o executor usam o mesmo harness.

O diff é a verdade#

O ADR-0001 formula assim: “O rótulo é um palpite; o diff é a verdade.” A revisão recebe git diff da base medida até HEAD, calculado dentro da caixa. O resumo do próprio executor vai para o pull request, marcado como uma afirmação: nenhum controle o verifica e ele não é mostrado ao revisor.

Respostas seladas aos controles humanos#

Uma pessoa aprova uma versão de produção, responde a um controle de merge ou diz “ainda não” no painel, que verifica quem está chamando antes de enviar qualquer coisa. Como qualquer coisa que alcance o motor poderia enviar o mesmo sinal, cada resposta é selada por gate_seal.py:

  • O selo é um HMAC-SHA256 sobre o tipo de controle, o id do workflow, uma expiração, um nonce e exatamente os campos sobre os quais o workflow vai agir, como a versão e quem aprova.
  • Um selo vale por 600 segundos e para um único workflow, e é consumido uma única vez.
  • O worker o verifica em uma atividade, com uma comparação de tempo constante, antes de liberar uma versão ou fazer um merge. Qualquer falha conta como não, é registrada onde o painel a mostra e deixa o controle pendente.
  • A chave é BEEVERFORGE_GATE_SECRET quando definida; caso contrário, um arquivo gate.key criado com modo 0600, ao lado do registro ou em ~/.beeverforge/.

Limites que o módulo documenta. O selo prova que um processo com a chave enviou a resposta, não que foi o painel. A chave é simétrica, então qualquer processo que consiga lê-la pode selar; o painel e o papel de produto do worker são signatários legítimos. O selo resiste à caixa container, que nunca vê a chave. Não resiste a uma caixa worktree, que roda como o usuário do operador e pode ler o arquivo da chave, nem aos papéis avaliadores, que na instalação com compose rodam como caixas worktree dentro do contêiner do worker. Resolver isso exige um selo assimétrico.

O que o selo muda: um acesso não previsto ao motor pode ler e cancelar workflows, mas não pode aprovar uma versão nem fazer o merge de um pull request.

Fontes#