Skip to content

crew: delegar fatias de codigo a agy, opencode e Copilot sob guard rails e gate (0.4.0) - #21

Merged
4nrry merged 7 commits into
mainfrom
crew
Oct 13, 2026
Merged

4nrry merged 7 commits into
mainfrom
crew

Conversation

@4nrry

@4nrry 4nrry commented Oct 13, 2026

Copy link
Copy Markdown
Owner

Plugin novo crew: o Claude delega uma fatia de código bem delimitada e checável por máquina a CLIs de outras empresas rodando headless como workers baratos ou grátis, e revisa o diff depois.

  • Três backends, uma política só. agy (Gemini pelo Antigravity CLI), opencode (modelos grátis da Zen) e GitHub Copilot CLI (sem shell). As regras de escopo, caminho, comando e segredo moram em scripts/crew.py; os hooks e o plugin JS de cada CLI só repassam a chamada para ele, e tudo que não for um "allow" explícito é negado.
  • Gate que o worker não pula. Escopo, atalhos proibidos, formatter e os checks do projeto. No agy e no Copilot pelo Stop/agentStop hook, que força o worker a continuar; no opencode por um laço externo que retoma a sessão. O veredito JSON nunca lê exit 0 como sucesso.
  • Guard rails instalados só durante o run e removidos no fim, inclusive em SIGTERM/SIGHUP: sem caminho fora do repo, sem escrita fora do escopo, sem commit/push/install/deploy, .env/chaves/certificados bloqueados por padrão (secret_globs).
  • Uma skill por CLI (crew:agy, crew:opencode, crew:copilot) mais shared/delegate.md, e um hook UserPromptSubmit que injeta a skill quando a mensagem cita a CLI — hook e não description pelo mesmo motivo medido no agent-fleet (2 de 30). A taxa de acerto deste hook não foi medida.
  • Vigia de segundo plano. O run_command do agy manda comandos longos para segundo plano em ~4 s, qualquer que seja o WaitMsBeforeAsync, e depois espera até 30 min por eles; o driver encerra os processos marcados pelo run 15 s depois do gate verde, sem tocar no agy nem nos servidores MCP.

Uso real (n=1 por fatia): 10 fatias do porte Nest → TanStack Start do LOTVS pelo agy/Gemini 3.8 Flash, cada uma com o gate verde e o diff revisado contra apps/api (asserções das specs idênticas). O vigia encerrou o typecheck órfão nos dois últimos runs e o agy saiu sozinho. Smoke tests do opencode (3) e do Copilot (2, 0,94 crédito) num repo descartável; o detalhe está no README.

O que não foi medido está no README: qualidade, tempo ou custo contra o Claude fazendo a mesma tarefa; falsos positivos dos guards; runs em paralelo. Os guards são quebra-molas para um modelo cooperativo, não sandbox: caminho montado em tempo de execução (python3 -c) passa.

just check: 98 verificações sem falha; self-test do script com 311 asserções.

🤖 Generated with Claude Code

4nrry and others added 7 commits October 13, 2026 09:47
…ate (0.1.0)

O Claude escreve a task, define escopo e gate e revisa o diff; o agy executa
uma fatia por vez com hooks do proprio agy (.agents/hooks.json) instalados so
durante o run: PreToolUse nega caminho fora do repo, escrita fora do escopo e
comandos de commit/install/deploy; o gate configuravel por projeto (forbid,
format com {files}, checks) roda no `finish` do --json-schema e no Stop, e
nega o "terminei" enquanto falhar. O veredito nao confia no exit code: no agy
1.3.4 timeout, acao negada e schema nao satisfeito saem 0 (lab, n=1 por caso).
Modo review somente leitura com --mode plan.

Smoke tests (n=1 cada, gemini-3.8-flash-low): o Stop chega com
TERMINAL_STEP_TYPE quando ha --json-schema, entao um gate so em NO_TOOL_CALL
nao teria rodado; um cache de gate que guardava falha prendeu o worker, que
foi procurar o gate (env, git config, /proc; os tres negados) — agora so gate
verde e cacheado. Sem workflow script: os runs se serializam por construcao e
a revisao fica com a sessao. Sem alegacao de melhoria: nao ha run records.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Ferramentas por allowlist (arquivo + run_command + finish); rede,
  run_workflow, MCP e ferramenta desconhecida sao negados.
- Caminhos de argumento resolvidos com realpath (relativo, symlink, Cwd);
  cd para fora, //etc, /*, <, > e .git/.agents pelo shell negados.
- git so com subcomandos de leitura, com opcoes globais e aspas
  (g''it) tratadas; rm -f -r, find -delete, ln, chmod, nohup, & e
  redirecionamento para arquivo negados.
- Gate isento so sem quebra de linha, $, substituicao ou redirect.
- Falsos positivos removidos: grep '/api/v1', git log --grep=publish.
- git do script com core.fsmonitor=false e hooksPath=/dev/null; config,
  hooks, flags de indice do git e ctx.json conferidos antes e depois.
- Arquivo ignorado novo ou alterado vira aviso; README e SKILL deixam de
  dizer que o git status pega escrita em arquivo ignorado.
- SIGHUP limpa os hooks; sobra de run morto e reconhecida; timeout do
  gate mata o grupo; envelope JSON nao-objeto reprova; aviso de versao.
- Docs: exit 0 nunca e sucesso (exit != 0 e falha), causa de hooks sem
  SessionStart desconhecida, consentimento antes do 1o run, nao editar a
  arvore durante o run, comandos sem $ARGUMENTS cru, "Nao ha run records".

Self-test 155 checks; smoke delegate e review reais (n=1) ok.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Os modelos Claude do agy dividem uma quota semanal e o Opus a esgota em
poucas fatias; o Sonnet medium e a escalada quando o Flash nao der conta.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`"backend": "opencode"` na task (ou --backend) roda o opencode 1.19.0 com os
modelos gratis do Zen, para quando a quota do agy acaba. O guard e um plugin
do opencode gerado no run dir e carregado so pelo OPENCODE_CONFIG_CONTENT do
run; ele manda cada chamada para `hook oc-pre`, que traduz a ferramenta e
pergunta ao mesmo decide_pre. O gate vira um loop externo (run, gate,
`run -s` com a saida do gate), o relatorio e o ultimo JSON da mensagem final,
e os bytes do opencode.json sao restaurados depois de cada processo do
opencode. Smoke tests n=1 no README; self-test de 155 para 209 checks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…sos do run encerrados

- secret_globs (padrao .env*, .dev.vars, *.pem, *.key, id_rsa*...; .env.example
  passa; [] desliga): negado nas ferramentas de arquivo e nas palavras do
  comando, nos dois backends. O motivo e o destino do que o worker le, nao
  desconfianca do modelo.
- O hook reescreve WaitMsBeforeAsync do run_command do agy: o modelo manda
  5000 e o agy esperou 16 min por um nx typecheck que foi para segundo plano.
- Worker e gate rodam com NX_DAEMON=false e com AGY_WORKER_RUN=<run>; no fim,
  os processos que carregam a marca sao encerrados (o daemon do Nx reparenta
  para o init e perde a ancestralidade, mas herda o ambiente).

Self-test: 223 checks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`"backend": "copilot"`: hooks do repo gerados por run em
.github/hooks/agy-worker-<run>.json, carregados so pelo COPILOT_ALLOW_ALL=true
do processo, traduzem cada ferramenta do Copilot para a mesma decide_pre
(hook cp-pre) e rodam o gate no agentStop (hook cp-stop), com o mesmo cache
e limite de tentativas. bash e task sempre excluidos do modelo; shell ou
subagente no stream reprova o run. Modelo fixo em auto (plano Free), com
override nao testado para plano pago. O veredito le os eventos JSONL, nunca
o exit code, e traz creditos gastos e modelo servido do usage file. Review
somente leitura: escopo vazio no hook e apply_patch excluido.

Self-test 209 -> 298 assercoes. Smoke n=1: delegate ok com gate forcado a
falhar uma vez (0,529 AI credits), review ok (0,411).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…vigia de segundo plano (0.4.0)

- plugins/agy-worker -> plugins/crew; scripts/agy_worker.py -> scripts/crew.py;
  estado no git dir em crew/ (era agy-worker/); CREW_RUN e CREW_GATE
  (AGY_WORKER_GATE ainda exportado); sobras de run morto da 0.3.0 reconhecidas.
- skills/agy, skills/opencode, skills/copilot (crew:agy, crew:opencode,
  crew:copilot) so com o que e de cada CLI; a parte comum em
  shared/delegate.md, com a task de exemplo em shared/.
- hooks/inject.sh (UserPromptSubmit): injeta a skill do backend nomeado como
  palavra inteira no prompt; so aconselha, sai sempre 0.
- Removida a reescrita de WaitMsBeforeAsync: o agy 1.3.4 aplica e manda o
  comando para segundo plano mesmo assim. BackgroundWatcher encerra, 15 s
  depois de o worker terminar com gate verde, so os descendentes do agy com a
  marca do run, fora dos hooks, da linha de base e de MCP servers; nunca o
  agy. Provado no lab (2 runs, n=1 cada). Stop com gate verde e sem finish
  pede o relatorio, no maximo 2 vezes.
- Aviso de processos que sobraram pela marca do run, nao pelo cwd (falso
  positivo com o laco de espera da sessao do Claude).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@4nrry
4nrry merged commit 9616b7c into main Oct 13, 2026
2 checks passed
@4nrry
4nrry deleted the crew branch October 13, 2026 15:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant