Belweave/belay

Alcance qualquer meta que um comando possa medir (corrigir todos os testes com falha, concluir uma auditoria, tornar algo mais rápido ou menor, portar uma ferramenta, polir uma interface ou um texto) escalando em pequenos passos verificados. Cada alteração é pontuada por uma verificação bloqueada, commitada se vencer e desfeita se perder, em um ou vários repositórios. Use quando o usuário disser "belay", "hill climb", "climb this" ou "keep going until it passes", quiser uma execução longa e sem supervisão em direção a um alvo mensurável, ou pedir para retomar ou relatar uma escalada.

O que é belay?

Belay é uma habilidade para agentes de IA que implementa uma estratégia de escalada de colina (hill climbing) para atingir metas mensuráveis através de pequenos passos iterativos, cada um verificado automaticamente. O agente faz uma alteração, executa um comando de verificação personalizado que imprime uma pontuação numérica (como tempo, contagem de falhas ou pontuação de um juiz) e, em seguida, o script `scripts/belay.py` decide se a alteração deve ser mantida (commit) ou desfeita (reset) com base na melhoria ou piora da pontuação. Isso permite que o agente opere de forma autônoma por longos períodos, refinando o código em direção a um alvo definido pelo usuário, como "tornar o build 2x mais rápido" ou "corrigir todas as falhas de auditoria". A habilidade suporta múltiplos repositórios, verificações paralelas, guardas (testes de integridade), conjuntos de retenção (holdout) para evitar overfitting e um sistema de cartão de escalada para iniciar, pausar e retomar sessões. É ideal para Claude Code, Cursor, Codex ou qualquer agente que precise executar tarefas complexas de engenharia de software de forma estruturada e verificável, sem supervisão humana constante.

Funciona com~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/Belweave/belay/tree/HEAD/skills/belay

Installed? Explore more Produtividade e Colaboração skills: steipete/gemini, steipete/gh-issues, steipete/skill-creator · View all 6 →

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

O que belay faz?

Você atinge uma meta em muitos pequenos passos. Uma verificação pontua cada passo sem intervenção humana. scripts/belay.py mantém a pontuação: você edita, ele executa a verificação, commita uma vitória ou desfaz uma perda e escreve o registro. Você nunca escreve uma pontuação por conta própria e nunca decide que um passo "basicamente" passou.

Cada meta se torna a mesma coisa: um comando que imprime um número. Mais rápido é um tempo ou uma contagem. Uma auditoria é o número de testes com falha, um por achado. Uma portabilidade é o número de saídas que correspondem. Uma IU é a pontuação de um juiz.

Como trabalhar:

  • O usuário inicia uma escalada e sai. Não pare para dar atualizações. Eles leem três coisas: o cartão, uma pergunta que só eles podem responder e o relatório. Pergunte usando a ferramenta de perguntas do harness, se houver.
  • O estado reside no disco, não no chat. O cartão, o registro, suas anotações e a última saída da verificação estão em .belay/<nome>/. Após uma compactação ou falha, status fornece tudo de volta em uma chamada.
  • Nunca espere com um loop de sono. Execute comandos longos em segundo plano e planeje o próximo passo enquanto eles executam.
  • BELAY abaixo é o caminho absoluto de scripts/belay.py ao lado deste arquivo. Escreva o caminho completo em cada comando. Execute-o de dentro do repositório alvo. Caminhos e comandos que você passa são relativos à raiz do repositório.
  • A escalada tem seu próprio branch, climb/<nome>. Um passo desfeito reseta a árvore e exclui arquivos não rastreados que o git não ignora. Se mais alguém estiver trabalhando neste checkout, escale em uma worktree separada. Passe --here quando você já estiver em um branch criado para este trabalho.

1. Retome antes de começar

Execute python3 "$BELAY" list. Se existir uma escalada para esta meta, mude para seu branch, execute status <nome> e continue no passo 4. "Continuar" após uma falha ou uma nova sessão significa isso. Não comece de novo.

2. Construa a verificação

A escalada é tão boa quanto sua verificação. Uma verificação que mede a coisa errada gasta toda a execução melhorando a coisa errada. Coloque uma verificação aproximada funcionando primeiro e a refine depois com relock.

Pergunte: o que eu executaria para ver se a meta foi atingida? Faça esse comando imprimir um número. Use a forma mais forte que se encaixar: uma correspondência exata ou contagem de teste, depois uma contagem do trabalho (consultas, viagens de ida e volta, bytes), depois um relógio e um juiz de modelo apenas quando nada além do gosto puder dizer.

MetaPontuação
Bug ou funcionalidadeTestes com falha escritos a partir da especificação, não da sua correção
Auditoria, estabilizar, "fazer X funcionar"Testes com falha, um por achado
Velocidade ou tamanhoUma contagem do trabalho por trás do tempo, ou o tempo
Portabilidade ou cloneSaídas que correspondem à ferramenta real
Várias metas ao mesmo tempoProgresso em direção ao pior indicador
Aparência, sensação, escritajudge.py com uma rubrica e bons exemplos

Receitas para cada uma estão em references/checks.md. Leia a parte que corresponde à sua meta antes de escrever a verificação.

Use o que o repositório tem. --score '<regex>' lê a pontuação da saída de qualquer executor de teste, como --score '(\d+) failed'. Ele pega a última linha correspondente e soma os números que captura. Uma execução bem-sucedida sem correspondência pontua 0. Sem --score, a última linha da saída padrão da verificação deve ser o número puro. Repita --check para executar vários comandos de uma vez; suas pontuações somam. Adicione --repo <caminho> para cada outro checkout que a escalada edita. Um passo é então mantido ou desfeito em todos eles juntos.

Prove a verificação antes de confiar nela:

  • Ela pode falhar. Quebre o código de propósito e veja a pontuação piorar. Restaure com git checkout -- <arquivo>.
  • Ela pode ver uma vitória. Uma pequena melhoria real deve mover a pontuação.
  • Ela é estável. Execute-a 3 vezes. Se a pontuação variar sem alteração de código, substitua o relógio por uma contagem, ou use --runs 3, um --min-gain acima da variação (uma porcentagem como 3% quando a pontuação vai encolher muito) e --paired.
  • Ela não pode ser enganada. Varie a entrada a cada execução e compare com uma referência. Tente uma trapaça manualmente, como codificar a resposta, e confirme que a verificação ou um guarda a pega.
  • Ela é rápida. Você paga o tempo da verificação em cada passo. Mantenha um passo abaixo de 2 minutos: pontue uma amostra ou uma contagem por passo e mantenha a suíte completa ou a execução cronometrada como um guarda ou o conjunto de retenção.
  • A barra é alcançável. Descubra o melhor que o design atual pode fazer. Se a barra estiver além disso, diga isso no cartão e proponha uma barra que você possa alcançar.

Proteja tudo o que a pontuação não mede:

  • Guardas (--guard, passam saindo com 0). Liste o que o código que você vai alterar toca: chamadores, outras plataformas, dados salvos, APIs públicas. Cada um precisa de um guarda: os testes que passam hoje, typecheck, lint, o build. Quando a pontuação é uma contagem de falhas, mantenha esses testes que passam em seus próprios arquivos como um guarda, para que uma falha não possa passar como "menos falhas".
  • Bloqueio (--lock) da verificação, dos testes, das fixtures e do conjunto de retenção. try se recusa a pontuar enquanto um arquivo bloqueado diferir. Novos arquivos sob um caminho --lock se tornam o primeiro commit no branch da escalada. Qualquer outra alteração não commitada interrompe init.
  • Conjunto de retenção (--holdout), quando a verificação usa amostras, um benchmark ou um juiz: casos em que a escalada nunca treina, mantidos sob .belay/<nome>/holdout/. Não os abra novamente. Se a pontuação subir e o conjunto de retenção não, a escalada está overfitting. Pare e diga isso.

Auditorias e metas abertas. Liste o que a meta cobre como uma lista de verificação em .belay/<nome>/notes.md. Caçe bugs área por área. Escreva um teste com falha por achado real, a partir da especificação ou do relatório de bug. Quando um passo posterior encontrar um novo bug, adicione seu teste e execute relock --why "encontrado <bug>". A pontuação sobe por uma razão honesta e o registro mostra o porquê. Um achado que precisa da decisão do usuário vai nas anotações e no relatório, não na pontuação.

3. O cartão, depois init

Envie uma mensagem com o cartão e nada mais para decidir:

Cartão de escalada: build-speed

Meta: cold build 2x mais rápido, mesma saída

PontuaçãoMediana de segundos de build, menor é melhor: 47.0 agora, barra 23.5
Verificação./scripts/bench-build.sh, 3 execuções, pareado, ganho mínimo 3%
Guardasnpm test, npm run typecheck
Conjunto de retenção3 dos 12 aplicativos de amostra
Bloqueadosscripts/bench-build.sh, test/, samples/
Limitenenhum (cerca de 2 min por passo)

Precisa da sua resposta: nenhuma

Responda go, ou altere uma linha.

Preencha cada linha com sua melhor escolha. Se o usuário deu uma meta sem barra, proponha uma que seja ambiciosa e verificável, como "2x mais rápido" ou "cada amostra corresponde". Aguarde "go", que aprova o cartão, o branch e seus commits. Pule a espera e coloque o cartão no topo do relatório quando o usuário já disse para executar sem perguntar, ou quando a meta é pequena e a barra não está em dúvida. Depois disso, não pergunte nada que você possa descobrir ou decidir sozinho.

python3 "$BELAY" init build-speed --goal "cold build 2x faster" \
  --check ./scripts/bench-build.sh --direction min --target 2x \
  --runs 3 --paired --min-gain 3% --guard "npm test" --guard "npm run typecheck" \
  --holdout ./scripts/bench-holdout.sh --lock scripts --lock test \
  --lock .belay/build-speed/holdout

Uma auditoria em um backend e um frontend:

python3 "$BELAY" init billing-audit --goal "every billing finding fixed" \
  --check "pytest tests/billing -q" --check "cd ../web && npx vitest run billing" \
  --score '(\d+) failed' --direction min --target 0 --repo ../web \
  --guard "pytest tests/legacy -q" --guard "cd ../web && npx tsc --noEmit" \
  --lock tests/billing --lock ../web/src/billing/__tests__

init cria o branch, mede a linha de base e se recusa a iniciar se um guarda já falhar. Corrija o que ele alerta antes do primeiro passo. Defina --max-hours ou --max-steps apenas quando o usuário nomear um limite. Sem um, a escalada é executada até que a barra seja atingida ou fique travada.

4. Escale

Cada passo é uma ideia, uma alteração, um try:

  1. Escolha a ideia. Não tente novamente uma que o registro já desfez, a menos que você possa dizer o que é diferente agora. Se juízes estiverem em uso, leia .belay/judge-notes.md.
  2. Faça uma alteração por uma razão e adivinhe seu efeito. Coloque o palpite na ideia: "cache o analisador (esperado -10%)". Quando um palpite está muito longe, seu modelo do código está errado. Crie um perfil antes do próximo passo.
  3. python3 "$BELAY" try "<ideia>". Ele commita uma vitória ou reseta a árvore. De qualquer forma, siga em frente. A saída completa da verificação do passo está em .belay/<nome>/last.txt, e a do melhor passo em best.txt. Leia-os em vez de executar a verificação novamente.
  4. Enquanto uma verificação é executada, não edite a árvore. Apenas um comando belay.py que altera a escalada é executado por vez. Se ele disser que outro ainda está em execução, aguarde.
  5. A cada 5 passos, atualize .belay/<nome>/notes.md em algumas linhas: o que funciona, o que não funciona, o que tentar a seguir. A próxima sessão retoma a partir dele.

Se você acredita em uma ideia que a verificação desfez duas vezes, a verificação não consegue vê-la. Torne a verificação mais refinada e execute relock. Nunca edite um arquivo bloqueado para fazer um passo passar.

Nunca trapaceie a verificação

Cada um destes aumenta a pontuação e piora o trabalho. Cada um é uma escalada fracassada mesmo que try a mantenha:

  • Criar casos especiais para as entradas que a verificação usa, ou codificar ou armazenar em cache saídas esperadas.
  • Pular, enfraquecer ou excluir testes, ou capturar e esconder erros.
  • Fazer o benchmark fazer menos trabalho em vez de tornar o código mais rápido.
  • Usar relock para descartar ou afrouxar um caso difícil para que a barra seja atingida. Relock só torna a verificação mais correta. Se a barra não puder ser alcançada, relate o piso que você mediu.
  • Ler o conjunto de retenção.

Uma vitória real torna o mesmo código melhor em entradas que a verificação nunca viu. Se o único caminho a seguir for um destes, a verificação está errada. Diga isso.

Continue reavaliando

A pontuação apenas representa o que o usuário quer. Verifique se ela ainda faz isso:

  • A cada 10 passos mantidos, e na barra: veja a coisa real você mesmo. Abra o aplicativo, leia a saída, veja a captura de tela. Execute a suíte de teste completa e o holdout. Se a pontuação e a coisa real divergiram, corrija a verificação e execute relock --why "...".
  • Algo quebrou que nenhum guarda pegou: encontre o passo com git bisect run <comando com falha>, depois repare-o com try --fix "<o que quebrou>", que mantém uma alteração que segura a pontuação. Se a única reparação abrir mão do ganho daquele passo, git revert o passo e relock --why "passo N revertido: quebrou X". Adicione o guarda que estava faltando.
  • Antes do relatório: revise git diff <início>..HEAD como uma única alteração, com novos olhos. Procure por testes removidos, erros engolidos, um recurso desativado, um padrão alterado e alterações de dados ou API. Repare com try --fix, depois execute a verificação e holdout --why final mais uma vez para que o relatório cite números medidos.

5. Quando ele trava

try e status imprimem PLATEAU após 5 passos sem ganho. Pare de tentar ideias e encontre o bloqueador. Meça antes de adivinhar:

  • De onde o tempo ou a contagem de erros realmente vêm? Crie um perfil.
  • A verificação é instável, muito grosseira para ver pequenos ganhos ou cega para o problema?
  • Existe uma ideia maior que os pequenos passos não conseguem alcançar?
  • Qual ferramenta, acesso, dado ou computação mudaria os próximos dez passos?

Registre com python3 "$BELAY" review "<o que você encontrou>", que silencia PLATEAU por 5 passos. Corrija o que puder: uma verificação mais rápida, uma métrica mais refinada, uma abordagem diferente. Pergunte ao usuário apenas pelo que só eles podem dar, como acesso ou dinheiro, e apenas depois que todas as outras ideias estiverem esgotadas.

6. Pare e relate

Pare quando qualquer um destes for verdadeiro:

  • try imprime BARRA ATINGIDA. Ele executa o conjunto de retenção para você. Uma vitória visível com um conjunto de retenção plano não é uma vitória.
  • status imprime TRAVADO: duas revisões de bloqueador sem ganho entre elas.
  • try se recusa com "Orçamento usado".
  • O conjunto de retenção discorda da pontuação.
  • O próximo passo precisa de algo que só o usuário pode dar.

Então faça a revisão final acima, exclua .belay/<nome>/data/ e envie o relatório. Torne-o legível em dez segundos:

Escalada build-speed: barra atingida

47.1s → 18.7s, 2.5x mais rápido (barra 23.5s, atingida no passo 41)

Conjunto de retenção51.0s → 20.2s, moveu-se com a pontuação
Passos19 mantidos de 52
SegurançaGuardas passaram em todos os passos mantidos. Suíte completa e revisão final limpas
Branchclimb/build-speed, 19 commits

O que funcionou

  • Cache de tipo incremental: −12s

Tentado e desfeito

  • Troca swc: quebrou 3 guardas

Seu movimento

  • Revisar: git log --oneline 1a2b3c4..climb/build-speed

O título é um de: barra atingida, travado, orçamento gasto, conjunto de retenção discorda, precisa de você. Cite números que o script mediu, nunca estimativas. Se você alterou a verificação ou a barra ao longo do caminho, diga isso no título. Maiores vitórias primeiro. No máximo 3 marcadores por seção. Pule seções vazias.

Se o usuário então quiser mais, defina uma barra mais difícil para a mesma reivindicação com raise 2x --why "..." e continue escalando. Nunca mude para uma nova meta.

Subagentes

Se o harness puder iniciar subagentes, use-os para leitura paralela durante a configuração e para novos olhos na revisão do bloqueador e na revisão final. Peça conclusões, não despejos de arquivos. Apenas você escreve na árvore da escalada, porque try a reseta. Um auxiliar lê ou rascunha um patch em sua própria worktree para você aplicar e try. Sem subagentes, faça inline.

Comandos

ComandoFaz
init <nome> --goal "..." --check "..." --direction min|maxLinha de base, branch, bloqueio. Opções: --check (repetir), --score '<regex>', --target (número ou 2x), --guard (repetir), --lock (repetir), --holdout, --repo (repetir), --runs, --paired, --min-gain, --timeout, --max-hours, --max-steps, --here
try "<ideia>" [--fix]Pontua a edição, depois mantém ou desfaz. --fix mantém um reparo que segura a pontuação
status [nome]Pontuação, últimos passos, anotações, PLATEAU ou TRAVADO
relock --why "..."Aceita uma verificação alterada e mede novamente
holdout --why "..."Executa o conjunto de retenção agora
review "<encontrado>"Registra uma revisão de bloqueador
raise <barra> --why "..."Define uma barra mais difícil após atingir esta
budget [--hours N] [--steps N]Define ou mostra o orçamento restante
listLista todas as escaladas em qualquer estado
compact <nome>Exclui data/ e mantém o restante
destroy <nome>Exclui tudo que compact mantém

Habilidades Relacionadas