Communitygithub.com

hmisaki/voicebox

Utilisez cette compétence pour trier la file d'attente des PR ouvertes avant une release. Classe chaque PR ouverte en « doit fusionner », « candidat », « remplacé » ou « reporté » ; rédige un document de tri opérationnel ; et exécute la boucle de fusion de bout en bout. Conçue pour la passe de « vitesse PR » pré-release où un mainteneur solo souhaite vider le backlog entrant en une seule session.

Qu'est-ce que voicebox ?

Cette compétence permet à un développeur solo de trier et fusionner rapidement un grand nombre de Pull Requests (PR) avant une release, en automatisant la classification, la documentation et la fusion. Elle est conçue pour les mainteneurs de projets open source qui doivent gérer un backlog de PR avant une release mineure ou majeure, en minimisant les risques tout en maximisant la vitesse de livraison. La compétence s'appuie sur l'interface en ligne de commande `gh` et `git`, et fonctionne sur n'importe quel dépôt GitHub. Le processus suit un workflow structuré en 11 étapes : il commence par créer un espace de travail isolé, collecte les métadonnées de chaque PR, les classe en quatre catégories (fusion immédiate, candidat à réviser, remplacé, reporté), rédige un document de suivi (ex: `0.4.0_PR_TRIAGE.md`), puis exécute la boucle de fusion avec rebase, gestion des conflits partiels et suivi des statuts. La documentation insiste sur les pièges courants, comme l'utilisation erronée de `main..HEAD` pour évaluer une PR, et l'importance de rebaser avant une fusion squash. Enfin, elle prévoit des étapes post-fusion pour les correctifs mineurs et les suivis. Cette compétence est le premier maillon d'une chaîne idéale incluant les compétences `draft-release-notes` et `release-bump`.

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

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Trier les PRs

Objectif

Transformer un backlog de PRs ouvertes en un ensemble de fusions livrées en une seule session ciblée. Produire un plan tracé et reprenable (<VERSION>_PR_TRIAGE.md), puis l'exécuter – rebaser si nécessaire, fusionner par lots isolés, appliquer les suivis post-fusion, et fermer les PRs remplacées ou partiellement applicables en créditant leurs auteurs.

Cette compétence s'utilise avec draft-release-notes et release-bump : trier d'abord, puis rédiger les notes de version sur la nouvelle branche principale, puis publier la release.

Quand l'utiliser

  • Avant une release mineure ou majeure lorsque 10 PRs ou plus se sont accumulées
  • Lorsque vous voulez débloquer les fusions sans perdre le fil de ce qui est livré
  • Lorsque vous ne pouvez pas réviser chaque PR en profondeur personnellement, mais devez livrer rapidement le sous-ensemble critique

Prérequis

  • CLI gh authentifiée sur le dépôt
  • Un worktree dédié à la révision des PR (éviter de contaminer main avec des extractions de branches de contributeurs)
  • Clarté sur la version cible – le document de tri est nommé d'après elle (ex. 0.4.0_PR_TRIAGE.md)

Workflow

1. Créer un worktree isolé pour la révision des PRs

git worktree list  # vérifier d'abord les worktrees obsolètes
git worktree prune
git worktree add ../voicebox-pr-review -b pr-review-<VERSION> main

Gardez le worktree principal pour le travail de préparation de release (brouillons de changelog, suivis directs sur main). Gardez le worktree de révision pour les gh pr checkout – chaque extraction déplace HEAD vers une branche de contributeur, ce que vous ne voulez pas faire dans le worktree principal.

2. Rassembler les métadonnées pour chaque PR ouverte

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]}'

Pour chaque PR, vous voulez :

  • La taille (+additions/-deletions)
  • L'état de fusionnabilité (CLEAN, UNSTABLE, DIRTY = conflits, UNKNOWN = GitHub calcule encore)
  • Si les modifications par le mainteneur sont autorisées sur la branche (nécessaire plus tard si vous rebasez pour l'auteur)
  • Les chemins de fichiers modifiés (aide à repérer les chevauchements entre PRs)

UNKNOWN est fréquent juste après un push sur main – essayez simplement la fusion et voyez.

3. Classer en catégories

Triez chaque PR dans exactement une catégorie :

Catégorie 1 — Fusionner : petite, fusionnable, corrige un vrai bug, CI propre, faible coût de révision. Correctifs d'une ligne, assouplissements de dépendances, durcissement de sécurité ciblé. Ce sont les victoires faciles.

Catégorie 2 — Candidat, à réviser : taille moyenne (50-200 lignes), touche plus de surface, semble valable mais nécessite une lecture plus attentive. Nouvelles fonctionnalités utilisateur qui correspondent à la direction du produit.

Remplacé : le correctif ou la fonctionnalité est déjà couverte par quelque chose de fusionné. Fermez avec un commentaire pointant vers la PR remplaçante. Vérifiez attentivement – un « titre similaire » n'est pas une preuve ; comparez les diffs réels.

Reporter à la prochaine release : grandes fonctionnalités, conflits sales, PRs en brouillon, tout ce qui touche au pipeline de release d'une manière qui introduirait un risque. Ne fusionnez pas cela dans une session de vitesse – ils nécessitent une attention dédiée.

4. Rédiger le document de tri

Créez <VERSION>_PR_TRIAGE.md à la racine du worktree de révision des PRs. Structure :

# <Dépôt> <VERSION> — Tri des PRs

Document de travail pour suivre quelles PRs ouvertes sont livrées dans <VERSION>. Supprimer après la release.

Dernière mise à jour : <DATE>

## Progression

**Catégorie 1 : 0 / N fusionnées**
**Catégorie 2 : 0 / M traitées**
**Tri des remplacées : en attente**

---

## Fusionner pour <VERSION> — corrections de bugs critiques

| PR | Statut | Taille | Ce qu'elle corrige | Pourquoi indispensable |
|---|---|---|---|---|
| [#123](url) | [ ] | +5/-0 | ... | ... |

## Candidat sérieux — nécessite une révision rapide

| PR | Statut | Taille | Résumé |
|---|---|---|---|

## Fermer comme remplacée

| PR | Statut | Raison |
|---|---|---|

## Reporter à <VERSION_SUIVANTE>

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

---

## Ordre d'attaque

1. Fermer les PRs remplacées (commentaires d'une ligne)
2. Fusionner la catégorie 1 par lots sans dépendances – vérifiez que les chemins de fichiers ne se chevauchent pas
3. Réviser les candidats de catégorie 2 individuellement
4. Relancer `draft-release-notes` pour récupérer tout
5. Lancer `release-bump`

L'en-tête Progression est la partie la plus importante – c'est votre tableau de bord et vous permet de reprendre proprement si la session est interrompue.

5. Exécuter la boucle — par PR

Pour chaque PR dans la liste des catégories 1 / 2 :

a. Extraire dans le worktree de révision :

cd ../voicebox-pr-review
git checkout pr-review-<VERSION>  # réinitialiser à la base neutre
gh pr checkout <N>

b. Lire le vrai commit, pas main..HEAD :

git show HEAD                    # les modifications réelles de la PR
git show --stat HEAD             # fichiers modifiés + nombre de lignes

Ne PAS réviser via git diff main..HEAD si la branche de la PR est plus ancienne que main. Ce diff inclut tous les commits qui ont atterri sur main après que la PR a été créée sous forme de lignes - (suppression). Une PR de 3 lignes peut ressembler à une annulation de 700 lignes. C'est la manière la plus simple de mal évaluer une PR.

c. Évaluer les préoccupations : exactitude, périmètre, interaction avec le travail déjà fusionné, compatibilité de version (par exemple, impossible d'utiliser une API qui nécessite une version de dépendance que nous ne pins pas encore).

d. Rebaser si la branche est en retard sur main :

git fetch origin main
git rebase origin/main

C'est essentiel avant une fusion squash. Le squash de GitHub calcule diff(tête-PR, base-de-fusion) – sur une branche obsolète, ce diff inclut l'annulation de tous les commits intermédiaires. Rebaser avance la base de fusion pour que le squash soit propre.

e. Si les modifications par le mainteneur sont autorisées, pousser le rebase vers le fork du contributeur :

git remote add <auteur> https://github.com/<auteur>/<dépôt>.git
git fetch <auteur> <branche>              # obtenir d'abord sa référence
git push <auteur> HEAD:<branche> --force-with-lease

Cela maintient l'interface utilisateur GitHub PR synchronisée avec l'état rebasé et rend la fusion propre du côté GitHub.

f. Fusionner :

gh pr merge <N> --squash

g. Mettre à jour le document de tri – cocher la case à ✅ fusionné <sha> (utiliser le SHA court de gh pr view <N> --json mergeCommit --jq '.mergeCommit.oid[0:7]'). Mettre à jour l'en-tête Progression.

6. Traiter les petits correctifs par lots

Les PRs avec ≤5 lignes de changement, CI propre, chemins de fichiers ne se chevauchant pas, et intention évidemment correcte (par exemple assouplissement de dépendance d'une ligne, ajout de variable d'environnement, correction de chemin d'import) peuvent être fusionnées en une seule boucle sans la cérémonie de révision par PR :

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

Vérifiez ensuite que chacune a atterri proprement :

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. Suivis post-fusion

Parfois, une PR mérite d'être fusionnée malgré un problème mineur connu (par exemple, dictionnaire de types incomplet, nettoyage de sentinelle obsolète). Ne bloquez pas la fusion ; appliquez le suivi comme une branche normale + PR juste après :

cd <worktree-principal>
git pull --ff-only origin main
git checkout -b fix/<nom-court>
# éditer...
git commit -m "fix(<zone>): <résumé>"
git push -u origin fix/<nom-court>
gh pr create --title "..." --body "Suivi de #<N>. ..."

Enregistrez les deux SHA dans le document de tri (✅ fusionné <sha-PR> + suivi <PR>).

Exception directe vers main : uniquement sous une politique explicite et limitée (par exemple « session de vitesse release »). N'en faites pas la valeur par défaut.

8. Remplacée : fermer avec un commentaire créditant

gh pr close <N> --comment "Fermeture — remplacée par la fusion de #<M> qui a livré <brève description>. Merci !"

Vérifiez d'abord les diffs – un « titre similaire » ne suffit pas. Si la PR est partiellement remplacée (le diagnostic est correct mais seule la moitié des changements est encore nécessaire), appliquez partiellement à la place.

9. Motif d'application partielle

Lorsqu'une PR contient à la fois des changements précieux et douteux :

cd <worktree-principal>
git pull --ff-only origin main

# Cherry-picker des fichiers spécifiques depuis la branche de la PR
git checkout <sha-commit-PR> -- <fichier1> <fichier2>

# Réviser les modifications staging, ajuster si nécessaire
git diff --cached

# Appliquer des modifications chirurgicales aux fichiers que vous ne voulez pas remplacer en bloc
# (par exemple, le fichier de la PR est antérieur à un commit récent sur main que vous devez préserver)

# Commiter avec un crédit de l'auteur original
git commit -m "$(cat <<'EOF'
<objet>

<corps expliquant ce qui a été conservé vs abandonné>

Co-Authored-By: <auteur> <[email protected]>
EOF
)"
git push ...  # branche + PR, sauf exception directe vers main

Puis fermez la PR avec un commentaire expliquant ce qui a été appliqué et ce qui a été abandonné, en référençant le SHA du commit.

10. Garder le document à jour

Chaque fusion, chaque fermeture, chaque suivi → mettez à jour <VERSION>_PR_TRIAGE.md. Le document est votre journal de session. Si vous êtes interrompu et reprenez demain, le document est la seule source de vérité pour « où en suis-je ? ».

11. Lorsque le tri est terminé

  • Chaque PR dans le document a un statut terminal (✅ fusionné / ✅ fermé / reporté)
  • L'en-tête Progression montre N/N pour chaque catégorie
  • La prochaine compétence à exécuter est draft-release-notes (pour régénérer [Unreleased] contre le nouveau main), puis release-bump

Vous pouvez supprimer le document de tri après la mise en ligne de la release, ou le conserver dans l'historique de version comme archive.

Pièges

  • main..HEAD sur une branche obsolète ment. Il montre tout ce que main a gagné depuis la division de la branche comme des suppressions. Révissez toujours via git show HEAD pour le commit réel de la PR.
  • Fusion squash d'une branche non rebasée annule le travail intermédiaire. Le squash calcule diff(tête-PR, base-de-fusion). Rebaser avance la base de fusion.
  • mergeable=UNKNOWN est temporaire – GitHub recalcule après un push. Essayez simplement la fusion.
  • L'ordre des routes est important (FastAPI et similaires) : DELETE /history/failed doit être enregistré avant DELETE /history/{id}, sinon le chemin paramétré consommera "failed" comme ID.
  • Le -weak_framework d'Apple écrase -framework pour le même framework, quel que soit l'ordre – utilisez-le via cargo:rustc-link-arg=-Wl,-weak_framework,Name lorsqu'une dépendance lie en dur quelque chose d'optionnel.
  • Les planchers de version de dépendance limitent ce que vous pouvez appliquer. Avant d'accepter un renommage d'argument comme torch_dtype= → dtype=, vérifiez que le pin de version minimale le supporte. Parfois, la bonne décision est de cherry-picker la moitié de la PR.
  • Les types audio !Send comme cpal::Stream ne peuvent pas traverser les points await ou spawn_blocking. Parfois, une attente synchrone « pas idéale mais correcte » est la meilleure solution disponible ; signalez mais ne bloquez pas.
  • Les nightly builds de PyTorch ne sont pas publiables pour les releases – non déterministes, peuvent régresser entre les exécutions. Si une PR suggère de passer à nightly pour corriger un problème GPU, préférez TORCH_CUDA_ARCH_LIST=...+PTX ou attendez un support stable.

Référence des commandes canoniques

# Métadonnées des PRs en masse
gh pr list --state open --limit 50 --json number,title,author,mergeable,mergeStateStatus,additions,deletions,maintainerCanModify,files

# Vue détaillée d'une seule PR
gh pr view <N> --json body,author,headRefName,baseRefName,mergeable,maintainerCanModify,files,statusCheckRollup

# Le commit réel, pas le diff branche-vs-main
git show HEAD
git show --stat HEAD
gh pr diff <N>

# Rebaser la branche du contributeur sur le main actuel
git fetch origin main && git rebase origin/main

# Pousser le rebase vers le fork du contributeur (nécessite maintainerCanModify=true)
git remote add <auteur> https://github.com/<auteur>/<dépôt>.git
git fetch <auteur> <branche>
git push <auteur> HEAD:<branche> --force-with-lease

# Fusionner
gh pr merge <N> --squash

# Confirmer le SHA de fusion pour le document de tri
gh pr view <N> --json state,mergeCommit --jq '{state, sha: .mergeCommit.oid[0:7]}'

# Fermer une remplacée
gh pr close <N> --comment "Fermeture — remplacée par la fusion de #<M>. Merci !"

Notes

  • Ne révisez jamais une branche obsolète via main..HEAD. C'est la ligne la plus importante de cette compétence.
  • Le document de tri est l'état de la session. Perdez le document, perdez la session. Mettez-le à jour après chaque action.
  • Créditez les contributeurs même sur les applications partielles. Utilisez les crédits Co-Authored-By: et des commentaires de fermeture qui pointent vers le commit appliqué.
  • Ne laissez pas la perfection être l'ennemi de la livraison. Un correctif qui passe de « cassé » à « fonctionne avec un problème mineur connu » est une amélioration nette. Signalez le problème, créez un suivi, fusionnez le correctif.

Individual skills in this repo

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

Skills associés