Communitygithub.com

hmisaki/voicebox

Use esta habilidade para triar a fila de PRs abertos antes de um lançamento. Classifica cada PR aberto em deve-mesclar, candidato, substituído ou adiado; escreve um documento de triagem funcional; e executa o loop de mesclagem de ponta a ponta. Projetado para a passagem de 'PR speedrun' pré-lançamento, onde um mantenedor solo deseja limpar o backlog de entrada em uma única sessão.

O que é voicebox?

Esta habilidade, `hmisaki/voicebox`, automatiza o processo de triagem e mesclagem de Pull Requests (PRs) para mantenedores de projetos que precisam limpar um backlog de PRs abertos antes de um lançamento. Ela foi projetada para uma abordagem de 'speedrun', onde um desenvolvedor solo deseja revisar, classificar e mesclar o maior número possível de PRs críticos em uma única sessão focada, minimizando o risco e a perda de contexto. A habilidade oferece um fluxo de trabalho completo: ela primeiro coleta metadados de todos os PRs abertos (como tamanho, estado de mesclagem e arquivos alterados), depois os classifica em camadas (deve-mesclar, candidato, substituído, adiado) e, em seguida, gera um documento de triagem (`<VERSÃO>_PR_TRIAGE.md`) que serve como um placar e plano de ação. O fluxo de trabalho inclui etapas para criar uma árvore de trabalho isolada para revisão, fazer rebase de branches desatualizadas para evitar reversões indesejadas durante squash merges, mesclar PRs em lote ou individualmente, e gerenciar follow-ups pós-mesclagem. A habilidade também lida com casos complexos, como substituição de PRs com crédito adequado ao autor e aplicação parcial de alterações de um PR. É especialmente útil para projetos com mais de 10 PRs abertos, onde o mantenedor quer desbloquear a mesclagem sem perder o controle do que está sendo integrado. A saída final é um documento de triagem completo que rastreia o status de cada PR, permitindo que a sessão seja pausada e retomada.

Funciona com~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/hmisaki/voicebox/tree/HEAD/.agents/skills/triage-prs

Perguntar na sua IA favorita

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

Documentação

Triar PRs

Objetivo

Transformar um backlog de PRs abertos em um conjunto de mesclagens enviadas em uma única sessão focada. Produzir um plano rastreável e retomável (<VERSÃO>_PR_TRIAGE.md) e, em seguida, executá-lo — fazendo rebase quando necessário, mesclando em lotes seguros e isolados, aplicando follow-ups pós-mesclagem e fechando PRs substituídos ou parcialmente aplicáveis com crédito aos seus autores.

Esta habilidade se complementa com draft-release-notes e release-bump: trie primeiro, depois escreva as notas de lançamento contra o novo main, e então faça o corte do lançamento.

Quando usar

  • Antes de um lançamento menor ou maior, quando 10+ PRs abertos se acumularam.
  • Quando você quer desbloquear a mesclagem sem perder a narrativa do que está sendo integrado.
  • Quando você sabe que não pode revisar profundamente todos os PRs, mas precisa integrar o subconjunto crítico rapidamente.

Pré-requisitos

  • CLI gh autenticada no repositório.
  • Uma árvore de trabalho dedicada para revisão de PR (evitar contaminar o main com checkouts de branches de contribuidores).
  • Clareza sobre a versão alvo — o documento de triagem é nomeado a partir dela (ex.: 0.4.0_PR_TRIAGE.md).

Fluxo de trabalho

1. Configurar uma árvore de trabalho isolada para revisão de PR

git worktree list  # verifique se há alguma antiga primeiro
git worktree prune
git worktree add ../voicebox-pr-review -b pr-review-<VERSÃO> main

Mantenha a árvore de trabalho principal para trabalho de preparação de lançamento (rascunhos de changelog, follow-ups diretos no main). Mantenha a árvore de trabalho de revisão para gh pr checkout — cada checkout move o HEAD para um branch de contribuidor, o que você não quer fazer na árvore de trabalho principal.

2. Coletar metadados de cada PR aberto

gh pr list --state open --limit 50 --json \
  number,title,author,isDraft,mergeable,mergeStateStatus,files,additions,deletions,reviewDecision,statusCheckRollup,maintainerCanModify \
  --jq '.[] | {num: .number, title, author: .author.login, mergeable, state: .mergeStateStatus, canModify: .maintainerCanModify, changes: "+\(.additions)/-\(.deletions)", files: [.files[].path]}'

Você deseja, para cada PR:

  • Tamanho (+adições/-deleções)
  • Estado de mesclagem (CLEAN, UNSTABLE, DIRTY = conflitos, UNKNOWN = GitHub ainda computando)
  • Se edições de mantenedor são permitidas no branch (necessário depois se você fizer rebase para o autor)
  • Caminhos de arquivos tocados (ajuda a identificar sobreposições entre PRs)

UNKNOWN é comum logo após um push para o main — apenas tente a mesclagem e veja.

3. Classificar em camadas

Classifique cada PR exatamente em um balde:

Camada 1 — Mesclar: pequenos, mescláveis, corrigem um bug real, CI limpo, baixo custo de revisão. Correções de uma linha, relaxamentos de dependência, endurecimento de segurança direcionado. Esses são os ganhos fáceis.

Camada 2 — Candidato, revisar: tamanho médio (50-200 linhas), toca mais área de superfície, parece sólido, mas precisa de uma leitura mais atenta. Novas funcionalidades voltadas para o usuário que se encaixam na direção do produto.

Substituir: a correção ou funcionalidade já está coberta por algo mesclado. Feche com um comentário apontando para o PR substituto. Verifique cuidadosamente — "título semelhante" não é prova; compare os diffs reais.

Adiar para o próximo lançamento: grandes funcionalidades, conflitos sujos, PRs em rascunho, qualquer coisa que toque no pipeline de lançamento de forma que introduza risco. Não mescle isso em uma speedrun — eles precisam de foco dedicado.

4. Escrever o documento de triagem

Crie <VERSÃO>_PR_TRIAGE.md na raiz da árvore de trabalho de revisão de PR. Estrutura:

# <Repo> <VERSÃO> — Triagem de PR

Documento de trabalho para rastrear quais PRs abertos serão integrados em <VERSÃO>. Apagar após o corte do lançamento.

Última atualização: <DATA>

## Progresso

**Camada 1: 0 / N mesclados**
**Camada 2: 0 / M tratados**
**Triagem de substituição: pendente**

---

## Mesclar para <VERSÃO> — correções críticas de bugs

| PR | Status | Tamanho | O que corrige | Por que é essencial |
|---|---|---|---|---|
| [#123](url) | [ ] | +5/-0 | ... | ... |

## Candidato forte — precisa de uma revisão rápida

| PR | Status | Tamanho | Resumo |
|---|---|---|---|

## Fechar como substituído

| PR | Status | Motivo |
|---|---|---|

## Adiar para <PRÓXIMA_VERSÃO>

- [#xxx](url) ... — motivo

---

## Ordem de ataque

1. Fechar PRs substituídos (comentários de uma linha)
2. Mesclar camada 1 em lotes livres de dependências — verifique se os caminhos de arquivo não se sobrepõem
3. Revisar camada 2 individualmente
4. Reexecutar `draft-release-notes` para capturar tudo
5. Executar `release-bump`

O cabeçalho Progresso é a parte mais importante — é seu placar e permite que você retome de forma limpa se a sessão for interrompida.

5. Executar o loop — por PR

Para cada PR na lista da camada 1 / camada 2:

a. Fazer checkout na árvore de trabalho de revisão:

cd ../voicebox-pr-review
git checkout pr-review-<VERSÃO>  # resetar para base neutra
gh pr checkout <N>

b. Ler o commit real, não main..HEAD:

git show HEAD                    # as alterações reais do PR
git show --stat HEAD             # arquivos tocados + contagem de linhas

NÃO revise via git diff main..HEAD se o branch do PR for mais antigo que o main. Esse diff inclui todos os commits que foram para o main após o fork do PR como linhas - (deleção). Um PR de 3 linhas pode parecer uma reversão de 700 linhas. Esta é a maneira mais fácil de julgar mal um PR.

c. Avaliar preocupações: correção, escopo, interação com trabalho já mesclado, compatibilidade de versão (ex.: não se pode usar uma API que requer uma versão de dependência que ainda não fixamos).

d. Fazer rebase se o branch estiver atrás do main:

git fetch origin main
git rebase origin/main

Isso é essencial antes de fazer squash-merge. O squash do GitHub computa diff(cabeça-do-PR, base-de-mesclagem) — em um branch desatualizado, esse diff inclui reverter todos os commits intermediários. O rebase move a base-de-mesclagem para frente, para que o squash fique limpo.

e. Se edições de mantenedor forem permitidas, enviar o rebase de volta para o fork do contribuidor:

git remote add <autor> https://github.com/<autor>/<repo>.git
git fetch <autor> <branch>              # obter a ref primeiro
git push <autor> HEAD:<branch> --force-with-lease

Isso mantém a UI de PR do GitHub sincronizada com o estado rebasado e torna a mesclagem limpa do lado do GitHub.

f. Mesclar:

gh pr merge <N> --squash

g. Atualizar o documento de triagem — marque a caixa de seleção como ✅ merged <sha> (use o SHA curto de gh pr view <N> --json mergeCommit --jq '.mergeCommit.oid[0:7]'). Atualize o cabeçalho de Progresso.

6. Agrupar pequenas correções

PRs com ≤5 linhas de alteração, CI limpo, caminhos de arquivo não sobrepostos e intenção obviamente correta (ex.: relaxamento de dependência de uma linha, adição de variável de ambiente, correção de caminho de importação) podem ser mesclados em um único loop sem a cerimônia de revisão por PR:

for pr in 425 384 416 429; do
  echo "=== Mesclando PR $pr ==="
  gh pr merge $pr --squash
done

Verifique depois se cada um foi integrado corretamente:

for pr in 425 384 416 429; do
  gh pr view $pr --json state,mergeCommit --jq "{pr: $pr, state, sha: .mergeCommit.oid[0:7]}"
done

7. Follow-ups pós-mesclagem

Às vezes, vale a pena mesclar um PR apesar de um problema menor conhecido (ex.: mapa de tipos incompleto, limpeza de sentinela desatualizada). Não bloqueie a mesclagem; aplique o follow-up como um branch normal + PR logo em seguida:

cd <árvore-de-trabalho-principal>
git pull --ff-only origin main
git checkout -b fix/<nome-curto>
# editar...
git commit -m "fix(<área>): <linha única>"
git push -u origin fix/<nome-curto>
gh pr create --title "..." --body "Follow-up de #<N>. ..."

Registre ambos os SHAs no documento de triagem (✅ merged <sha-do-pr> + follow-up <pr>).

Exceção de direto-ao-main: apenas sob uma política explícita e com escopo definido (ex.: "speedrun de lançamento"). Não use como padrão.

8. Substituir: fechar com um comentário creditando

gh pr close <N> --comment "Fechando — substituído por #<M> mesclado, que integrou <breve descrição>. Obrigado!"

Verifique os diffs primeiro — "título semelhante" não é suficiente. Se o PR estiver parcialmente substituído (o diagnóstico está certo, mas apenas metade das alterações ainda são necessárias), faça uma aplicação parcial.

9. Padrão de aplicação parcial

Quando um PR tem alterações valiosas e questionáveis agrupadas:

cd <árvore-de-trabalho-principal>
git pull --ff-only origin main

# Cherry-pick de arquivos específicos do branch do PR
git checkout <sha-do-commit-do-pr> -- <arquivo1> <arquivo2>

# Revisar as alterações em stage, ajustar conforme necessário
git diff --cached

# Aplicar edições cirúrgicas em arquivos que você não quer substituir em massa
# (ex.: o arquivo do PR é anterior a um commit recente no main que você precisa preservar)

# Commitar com um trailer creditando o autor original
git commit -m "$(cat <<'EOF'
<assunto>

<corpo explicando o que foi mantido vs. descartado>

Co-Authored-By: <autor> <[email protected]>
EOF
)"
git push ...  # branch + PR, a menos que sob a exceção de direto-ao-main

Em seguida, feche o PR com um comentário explicando o que foi aplicado e o que foi descartado, referenciando o SHA do commit.

10. Manter o documento atualizado

Cada mesclagem, cada fechamento, cada follow-up → atualize <VERSÃO>_PR_TRIAGE.md. O documento é seu registro da sessão. Se você for interrompido e retomar amanhã, o documento é a única fonte da verdade para "onde estou."

11. Quando a triagem estiver concluída

  • Cada PR no documento tem um status final (✅ merged / ✅ closed / deferred)
  • Cabeçalho de Progresso mostra N/N para cada camada
  • A próxima habilidade a executar é draft-release-notes (para regenerar [Unreleased] contra o novo main), depois release-bump

Você pode deletar o documento de triagem após o lançamento ser enviado, ou mantê-lo no histórico de versões como um registro.

Armadilhas

  • main..HEAD em um branch desatualizado mente. Ele mostra tudo que o main ganhou desde a divisão do branch como deleções. Sempre revise via git show HEAD para o commit real do PR.
  • Fazer squash-merge em um branch sem rebase reverte trabalho intermediário. O squash computa diff(cabeça-do-PR, base-de-mesclagem). O rebase move a base-de-mesclagem para frente.
  • mergeable=UNKNOWN é transitório — o GitHub está recomputando após um push. Apenas tente a mesclagem.
  • A ordem das rotas importa (FastAPI e similares): DELETE /history/failed deve ser registrado antes de DELETE /history/{id}, ou o caminho parametrizado consumirá "failed" como um ID.
  • -weak_framework do Apple substitui -framework para o mesmo framework, independentemente da ordem — use via cargo:rustc-link-arg=-Wl,-weak_framework,Name quando uma dependência faz link rígido de algo opcional.
  • Pisos de versão de dependência restringem o que você pode aplicar. Antes de aceitar uma renomeação de argumento como torch_dtype= → dtype=, verifique se o pino de versão mínima suporta. Às vezes, a ação correta é cherry-pick da metade do PR.
  • Tipos de áudio !Send como cpal::Stream não podem cruzar pontos de await ou spawn_blocking. Às vezes, uma espera síncrona "não ideal, mas correta" é a melhor correção disponível; sinalize, mas não bloqueie.
  • Builds noturnas do PyTorch não são enviáveis para lançamentos — não determinísticas, podem regredir entre execuções. Se um PR sugerir mudar para a noturna para corrigir um problema de GPU, prefira TORCH_CUDA_ARCH_LIST=...+PTX ou aguarde suporte estável.

Referência de comandos canônicos

# Metadados em massa de PRs
gh pr list --state open --limit 50 --json number,title,author,mergeable,mergeStateStatus,additions,deletions,maintainerCanModify,files

# Visualização detalhada de um único PR
gh pr view <N> --json body,author,headRefName,baseRefName,mergeable,maintainerCanModify,files,statusCheckRollup

# O commit real, não o diff branch-vs-main
git show HEAD
git show --stat HEAD
gh pr diff <N>

# Rebase do branch do contribuidor no main atual
git fetch origin main && git rebase origin/main

# Enviar rebase de volta para o fork do contribuidor (maintainerCanModify=true necessário)
git remote add <autor> https://github.com/<autor>/<repo>.git
git fetch <autor> <branch>
git push <autor> HEAD:<branch> --force-with-lease

# Mesclar
gh pr merge <N> --squash

# Confirmar SHA da mesclagem para o documento de triagem
gh pr view <N> --json state,mergeCommit --jq '{state, sha: .mergeCommit.oid[0:7]}'

# Fechar substituído
gh pr close <N> --comment "Fechando — substituído por #<M> mesclado. Obrigado!"

Notas

  • Nunca revise um branch desatualizado via main..HEAD. Esta é a linha mais importante desta habilidade.
  • O documento de triagem é o estado da sessão. Perdeu o documento, perdeu a sessão. Atualize-o após cada ação.
  • Credite os contribuidores mesmo em aplicações parciais. Use trailers Co-Authored-By: e comentários de fechamento que linkem para o commit aplicado.
  • Não deixe o perfeito ser inimigo do entregue. Uma correção que vai de "quebrado" para "funciona com um pequeno problema conhecido" é uma melhoria estrita. Sinalize o problema, abra um follow-up, mescle a correção.

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

Habilidades Relacionadas