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#
| Tipo | O que isola |
|---|---|
container | O 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. |
worktree | Um 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. |
fargate | Apenas a descrição de uma caixa de tarefas remota. Seu executor não está neste repositório; ele é fornecido por um complemento. |
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:
- A tag da imagem é resolvida para um digest.
- 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.
- O contrato da imagem: um shell POSIX em
/bin/sh, um processo que a mantenha viva,git, umHOMEgravável e um/workspacegravável. Uma imagem distroless ou scratch não pode ser usada. - A caixa inicia, o
setup:do projeto é executado e depois seus controlesvalidate:rodam sobre uma cópia intacta demain, dentro da caixa. - 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.
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.networkno 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 doctortesta 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
securitydeorg_defaults/floor.yaml: uma varredura dos arquivos versionados em busca de credenciais incluídas em commits. Ele é declarado comoadvisory: 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_SECRETquando definida; caso contrário, um arquivogate.keycriado 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#
beeverforge/adapters/sandbox/registry.pybeeverforge/adapters/sandbox/container.pybeeverforge/adapters/sandbox/worktree.pybeeverforge/box_prove.pybeeverforge/runtime/temporal/activities.pybeeverforge/policy/floor.pybeeverforge/policy/conformance.pybeeverforge/org_defaults/floor.yamlbeeverforge/contracts/manifest.pybeeverforge/adapters/reviewer/base.pybeeverforge/adapters/reviewer/harness.pybeeverforge/gate_seal.py- ADR-0001, ADR-0037