Dar a um coding agent acesso para abrir pull requests parece uma extensão natural do autocomplete. Não é. O agente passa a explorar o repositório, editar vários arquivos, executar comandos e propor uma mudança que alguém talvez aprove com pressa porque o CI ficou verde.
O resultado esperado não é “confiar mais no modelo”. É montar um caminho em que uma tarefa pequena pode virar um draft PR, mas uma mudança inadequada não consegue chegar à branch protegida só porque foi escrita com muita convicção.
A divisão de responsabilidades é simples:
AGENTS.mdregistra contexto e limites para o agente;CODEOWNERS, reviews obrigatórias e CI fazem o bloqueio real;- uma auditoria curta mostra quando as falhas estão se repetindo;
- tarefas de alto impacto continuam com pessoas desde o início.
O contexto mínimo antes da autonomia
Um coding agent ainda trabalha com contexto limitado, pode escolher uma API inexistente e pode produzir código válido na aparência que não atende ao requisito. Um contexto enorme não elimina o primeiro problema: o estudo Lost in the Middle encontrou degradação quando a informação relevante ficava no meio de entradas longas. Por isso, mantenha as instruções curtas, específicas e próximas do código a que se aplicam, em vez de despejar o manual inteiro da empresa no prompt. O linter já conhece o style guide; ele não precisa de uma leitura dramática feita pelo agente.
Dependências inventadas também não são um caso folclórico. Spracklen et al., em We Have a Package for You!, analisaram 16 LLMs e 576.000 amostras. O resumo reporta média de pelo menos 5,2% de pacotes alucinados em modelos comerciais, 21,7% em modelos open source e 205.474 nomes únicos inventados. A correção prática é exigir confirmação no lockfile, no registry e na documentação oficial antes de adicionar uma dependência. A observação segura em produção é registrar no PR toda alteração de manifesto ou lockfile e fazê-la passar por review de owner e scanner de dependências.
Há ainda limites do produto escolhido. No GitHub, o Copilot cloud agent trabalha em um repositório e um branch por tarefa, abre um draft PR e tem timeout rígido de 59 minutos. O branch usa o prefixo copilot/. Workflows enviados pelo agente precisam de uma pessoa em Approve and run workflows; há uma aprovação adicional quando o PR não é atribuído a uma pessoa. Esses controles existem porque um workflow ainda não revisado pode alcançar permissões e secrets. O sinal observável é direto: draft PR incompleto, sessão encerrada no limite ou workflow aguardando aprovação não deve ser “resolvido” relaxando o ruleset; reduza o escopo da tarefa.
AGENTS.md: política versionada, não catraca
AGENTS.md é uma convenção aberta em Markdown, sem schema obrigatório. Ferramentas compatíveis leem o arquivo da raiz e podem aplicar instruções mais próximas do diretório editado. Isso permite regras específicas em um monorepo sem acoplar a política a um único fornecedor.
Mas vale dizer uma vez, sem rodeio: AGENTS.md é convenção, não enforcement. Ele orienta o agente; não impede um commit, não exige review e não substitui autorização no GitHub.
Um arquivo de raiz pode começar assim:
# AGENTS.md
## Escopo
- Trabalhe somente neste repositório, em um branch e um draft PR por tarefa.
- Não faça commit direto em `main`.
- Mantenha a mudança restrita aos arquivos e critérios de aceite da issue.
## Regras por tipo de arquivo
- Código em `src/`: toda mudança de comportamento exige teste novo ou atualizado.
- Arquivos em `tests/`: podem ser alterados sem o gate inverso.
- Não altere `migrations/`, arquivos de autenticação, `.env*`, secrets ou
`.github/workflows/`. Pare e solicite intervenção humana.
- Documentação pode mudar sem teste de código.
## Verificação
- Execute a suíte, o linter e o type checker definidos pelo repositório.
- Não adicione dependências sem confirmação humana.
- Confirme pacotes, APIs e flags no lockfile e na documentação oficial.
## Pull request
- Use o título `[agent] <área> — <objetivo>`.
- Informe os testes executados e o que ficou fora do escopo.
A remediação para instruções ignoradas é reduzir conflitos, criar um AGENTS.md aninhado quando a regra for local e transformar limites críticos em controles externos. Observe isso nos PRs: se o mesmo desvio aparece duas vezes, ajuste a instrução; se o desvio tem impacto de segurança, não espere a terceira tentativa para criar um gate.
CODEOWNERS e ruleset: onde a política ganha dentes
O arquivo abaixo solicita os revisores adequados para caminhos sensíveis:
# .github/CODEOWNERS
* @org/dev-leads
/src/ @org/dev-leads
**/migrations/** @org/db-owners
**/*auth* @org/security
**/.env* @org/security
.github/ @org/dev-leads
.github/CODEOWNERS @org/dev-leads
Troque @org/... pelos times reais, com permissão de escrita, e proteja o próprio CODEOWNERS. Depois, no ruleset da branch principal, habilite Require review from Code Owners, exija ao menos uma aprovação e torne os checks de CI obrigatórios. O GitHub documenta o comportamento e as regras de sintaxe do CODEOWNERS.
Se um agente tocar autenticação ou uma migration, a remediação é bloquear o merge até a análise do owner, não pedir ao próprio agente que “revise com mais cuidado”. A observação segura é o histórico de reviews por caminho: toda mudança sensível precisa deixar o nome de quem aprovou e os checks executados.
CI: produção mudou, teste também precisa mudar
A regra “mudou comportamento, mudou teste” precisa sair do Markdown e entrar no CI. O script abaixo falha quando encontra arquivo de produção no diff, mas nenhum arquivo de teste:
#!/usr/bin/env python3
"""Falha se o diff tocar produção sem tocar testes. Heurística, não cobertura."""
import os
import subprocess
import sys
base = os.environ.get("GITHUB_BASE_REF") or os.environ.get("BASE_SHA") or "origin/main"
try:
output = subprocess.check_output(
["git", "diff", "--name-only", f"{base}...HEAD"],
text=True,
)
except subprocess.CalledProcessError:
output = subprocess.check_output(
["git", "diff", "--name-only", "HEAD~1"],
text=True,
)
files = [line.strip() for line in output.splitlines() if line.strip()]
def is_test(path):
name = path.replace("\\", "/").lower()
return (
"/test/" in f"/{name}/"
or "/tests/" in f"/{name}/"
or name.endswith(
(
"_test.py", "_test.go", "_test.ts", "_test.tsx",
".test.js", ".test.ts", ".spec.ts", ".spec.js", "test.java",
)
)
or name.startswith("tests/")
)
def is_production(path):
name = path.replace("\\", "/").lower()
if is_test(name) or name.endswith((".md", ".txt", ".rst")):
return False
if name.startswith((".github/", "docs/", "automation/")):
return False
return name.endswith(
(".py", ".go", ".ts", ".tsx", ".js", ".jsx", ".java", ".kt",
".rs", ".rb", ".c", ".cc", ".cpp")
)
production = [path for path in files if is_production(path)]
tests = [path for path in files if is_test(path)]
if production and not tests:
print("Produção alterada sem arquivo de teste no mesmo diff:")
print("\n".join(production))
print("Isto é heurística de presença, não prova de cobertura.")
sys.exit(1)
print(f"ok: {len(production)} prod, {len(tests)} test files")
Salve-o como scripts/require_tests_with_prod.py. O workflow completo usa o actions/checkout@v7, release documentada em 2026-08-22, e busca o histórico necessário para comparar a branch:
name: agent-gates
on:
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
jobs:
require-tests-with-prod:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0
- name: Verificar mudança de produção sem teste
env:
GITHUB_BASE_REF: origin/${{ github.base_ref }}
run: python3 scripts/require_tests_with_prod.py
Marque agent-gates e a suíte real como required checks. Essa heurística verifica presença de arquivo de teste, não cobertura nem qualidade. Um teste pode existir e não exercitar nada — uma tradição antiga, agora automatizada. A remediação é combinar o gate com execução da suíte e review do comportamento. Observe em produção a taxa de PRs barrados pelo check e, após o merge, falhas associadas às áreas alteradas; recorrência pede teste mais específico ou redução do escopo aceito pelo agente.
Auditoria semanal sem inventar o usuário do bot
Uma vez por semana, liste os PRs recentes e filtre os que vieram do agente. Primeiro confirme o campo author em um PR real; o identificador pode variar e não deve ser hardcoded por palpite.
gh pr list \
--search "is:pr created:>=$(date -u -d '7 days ago' +%F)" \
--state all \
--limit 50 \
--json number,title,author,createdAt,mergeable,reviews,statusCheckRollup,files
Procure quatro padrões no mesmo ritual:
- pacote ou import que não existe no registry;
- código de produção sem teste significativo;
- tentativa de alterar auth, secrets, migrations ou workflows;
- PR incompleto, CI falhando ou sequência longa de pedidos de correção.
Para cada padrão, registre a ocorrência, a correção aplicada e o gate que evitará repetição. O método de observação é o próprio rastro do GitHub: autor, arquivos, checks, reviews e tempo até o PR sair de draft. Em organizações Enterprise, métricas de uso podem complementar essa leitura, mas não substituem abrir o diff. Dashboard nenhum percebe que o teste só chama o método feliz e vai embora satisfeito.
Ative também o secret scanning. Se houver alerta, revogue ou rotacione o segredo fora do agente, remova-o do histórico conforme o procedimento do time e revise como ele entrou no contexto.
Quando o agente deve ficar fora
O guia de boas práticas do GitHub recomenda evitar tarefas amplas, ambíguas, críticas para produção, ligadas a segurança, PII, autenticação ou resposta a incidentes. Na prática, deixe fora da autonomia:
- migrations, schema e operações de banco com escrita;
- autenticação, autorização, IAM e regras de acesso;
- secrets, credenciais,
.enve sua rotação; - workflows com permissões ou acesso a secrets;
- correções production-critical e resposta a incidentes.
A OWASP GenAI LLM Top 10 de 2026 coloca Sensitive Information Disclosure em segundo e Excessive Agency em terceiro. Improper Output Handling agora inclui código inseguro gerado por assistentes. A resposta não é escrever um prompt mais severo: reduza ferramentas e permissões, não entregue credenciais no contexto e exija autorização no sistema que executa a ação. Observe tentativas negadas, arquivos sensíveis tocados e alertas de secret scanning sem expor o conteúdo do segredo nos logs.
A DevDojo deixaria um agente abrir PRs quando a tarefa fosse pequena, reversível, com critérios de aceite objetivos, sem auth, secrets, migrations ou criticidade de produção; o PR seria draft, com CI obrigatório e CODEOWNERS. O time recuaria para sugestão assistida — sem autonomia de PR — diante de dependências inventadas, repetição do mesmo desvio, testes decorativos, mudanças fora do escopo, alertas de segredo ou review ping-pong persistente.
Próximo passo
Escolha hoje uma issue pequena de documentação ou teste, adicione AGENTS.md, CODEOWNERS e o check agent-gates, proteja a branch e rode um único draft PR piloto. Só amplie o escopo depois de revisar o diff, os checks e o rastro de aprovação desse PR.