Communitygithub.com

agent-rig/rig

Kit de copie de compétences d'agent, d'agents et de modèles CI pilotés par configuration — natif pour Claude Code et adaptable à tout agent lisant AGENTS.md.

Qu'est-ce que rig ?

Cette compétence fournit un workflow de branche d'intégration (epic) pour décomposer des fonctionnalités complexes en enfants gérables, chacun étant développé sur des branches PR distinctes fusionnées dans une branche d'intégration partagée. Elle est conçue pour les agents de codage pilotés par configuration tels que Claude Code, Cursor ou Codex, et lit un fichier `.rig/config.json` pour la configuration. Le workflow gère l'ensemble du cycle de vie : planification, démarrage, exécution (avec révision des spécifications en amont), revue de code combinée, finalisation et nettoyage. La compétence garantit que les enfants sont terminés dans le bon ordre, en vérifiant les dépendances via un fichier d'état (`blockedBy`), et fusionne finalement l'ensemble de la branche d'intégration dans la branche principale sous forme d'une seule PR rebasée. Elle prend en charge le suivi des tickets via Linear, GitHub ou aucun tracker externe, et inclut des mécanismes de révision automatisée et de vérification de code mort.

Compatible avec✓Claude Code~Codex CLI~Cursor
npx skills add agent-rig/rig

Demander à votre IA préférée

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

Documentation

rig-epic — workflow de branche d'intégration

Pour les arcs multi-éléments où atterrir chaque élément directement sur le tronc casserait temporairement le contrat d'exécution, empilez les PR enfants sur une branche d'intégration partagée et rebasez cette branche sur le tronc en une seule PR à la fin. Chaque PR enfant est revue comme l'étape qu'elle est réellement ; la livraison vers le tronc est un seul rebasage compressé.

Configuration

Lit .rig/config.json (valeurs par défaut entre parenthèses) :

  • tracker.provider — linear | github | none (none). Comment les éléments parents/enfants sont stockés. none → les éléments vivent uniquement dans le fichier d'état de l'epic (ci-dessous) ; aucun appel de tracker.
  • tracker.team / tracker.project / tracker.ticketPrefix / tracker.githubIntegration.
  • vcs.baseRef (origin/main), vcs.defaultBranch (main), vcs.protectedBranchMergeQueue (false).
  • sourceScope[0] — où explorer pendant plan.
  • agents.architect / agents.reviewer (par défaut rig-<role>) — pour le panneau review en contexte frais.

Délègue à /rig-task (par enfant), /rig-worktree (clonages), /rig-review

  • /rig-review fix (la revue de diff combinée), /rig-tidy (optionnel).

Fichier d'état de l'epic (remplace toute mémoire externe)

Chaque epic actif est suivi dans un fichier JSON local au dépôt à .rig/epics/<branche-integration>.json :

{
  "parent": "ABC-42 ou un slug dans tracker=none",
  "parentTitle": "…",
  "integrationBranch": "abc-42-<slug>",
  "whyEpic": "quels enfants s'entrelacent et pourquoi",
  "children": [
    { "id": "ABC-43", "title": "…", "blockedBy": [], "branch": null, "status": "todo|merged" }
  ]
}

Ceci est la source unique de vérité que next/run/review/finish/prune lisent. Ajoutez .rig/epics/ à .gitignore (c'est un état de coordination transitoire). Inférence du parent (quand <PARENT> est omis) : si exactement un .rig/epics/*.json existe, utilisez-le ; si zéro ou plusieurs, demandez.

Bannière d'intention : chaque invocation DOIT imprimer une ligne en premier — mode, quelle branche les PR ciblent, ce qu'elle ne fera pas :

rig-epic: <sous-commande> — <action>. Les PR ciblent <branche>. Ne fera pas <chose>.

status (par défaut, lecture seule)

Lit le(s) fichier(s) d'état de l'epic. Rapport : branche d'intégration + commits en avance sur vcs.baseRef ; PR enfants ouvertes (gh pr list --base <branche-integration>) et leur état ; statut du tracker de chaque enfant (si un tracker est configuré) ; worktrees fusionnés/supprimés restants (suggérez /rig-epic prune) ; et une recommandation en une ligne (ouvrir la PR enfant X, prêt pour /rig-epic next, ou prêt pour /rig-epic finish). Ne modifie rien ; ne lance rien.

plan <FONCTIONNALITÉ>

Décompose une fonctionnalité en un parent + 3 à 8 enfants, écrit le fichier d'état, puis enchaîne vers start.

Utilisez ceci uniquement lorsque le travail a vraiment une forme d'epic (les enfants s'entrelacent — au moins un contrat d'exécution d'un enfant dépend d'un autre partiellement terminé). Si les éléments sont indépendants et que chacun peut atterrir seul sur le tronc, arrêtez-vous et dites à l'utilisateur d'exécuter /rig-sprint plan à la place — même décomposition, pas de branche d'intégration.

Procédure

  1. Lire le contexte. Documents produit/spec si le projet en a (demandez si incertain) ; explorez le codebase (sourceScope[0]) pour voir ce qui existe. Si un tracker est configuré, recherchez d'abord les éléments quasi dupliqués.
  2. Vérifier que c'est un epic (selon le test d'entrelacement ci-dessus). Si non → envoyer vers /rig-sprint plan.
  3. Créer le parent.
    • tracker: linear/github → créez l'élément parent (équipe/projet depuis la config) ; la description couvre l'Aperçu, pourquoi-c'est-un-epic et les enfants prévus.
    • tracker: none → le parent est un slug + titre enregistré uniquement dans le fichier d'état.
  4. Créer chaque enfant avec ses arêtes de dépendance.
    • Assez petit pour une session d'agent (1 à 3 fichiers) ; critères d'acceptation concrets et testables ; travail fondamental d'abord.
    • Enregistrez blockedBy pour chaque dépendance réelle — c'est ce que next lit pour choisir le prochain enfant non bloqué. Sans cela, le choix retombe sur l'ordre de déclaration et obtient des epics entrelacés incorrects.
    • Mode tracker : définissez les relations parent/bloqué-par natives du tracker et reflétez-les dans le fichier d'état. none : fichier d'état uniquement.
  5. Afficher un tableau récapitulatif (ID · Titre · Dépend de).
  6. Enchaîner vers start <PARENT> — plan est planifier-et-démarrer ; ne vous arrêtez pas pour demander.
  7. Arrêter après start. Rapportez la branche d'intégration, les enfants et la prochaine étape (/rig-epic next pour un seul, /rig-epic run pour la boucle). Ne démarrez jamais run automatiquement — l'exécution est un opt-in explicite.

start <PARENT>

Pré-vol : git fetch origin ; confirmez que le parent et au moins un enfant existent (dans le tracker, ou comme arguments pour none).

  1. Nom de la branche d'intégration : <slug-parent>-<slug-titre> (kebab, ex. abc-42-agent-comme-definition).
  2. Couper la branche d'intégration depuis vcs.baseRef sans checkout local :
    git fetch origin
    git push origin <vcs.baseRef>:refs/heads/<branche-integration>
    
    Non destructif. Si la branche existe déjà, laissez-la (ne jamais écraser — pourrait détruire un travail en cours).
  3. Écrire .rig/epics/<branche-integration>.json (schéma ci-dessus) avec le parent, pourquoi-cet-epic et chaque enfant + blockedBy. C'est ce qui fait que chaque /rig-task <enfant> cible la branche d'intégration au lieu du tronc.
  4. Si un tracker est configuré, ajoutez une note "Branche d'intégration : cible <branche-integration>, pas le tronc" à chaque enfant pour que le prochain agent ne relise pas cette compétence, et assurez-vous que le parent est En Cours (adaptatif : déplacez-le seulement s'il n'a pas déjà commencé ; différer si une intégration en direct l'a fait). Les enfants obtiennent leur propre En Cours depuis leur /rig-task Étape 1.
  5. Nommer la session "EPIC: <titre parent> (<parent>)" via scripts/set-session-name.sh (Claude-Code uniquement ; sans effet ailleurs) pour que la liste des tâches d'arrière-plan lise l'epic. Les enfants définissent leurs propres noms FEAT:/CHORE: avec --skip-if-prefix "EPIC:", donc cette étiquette d'epic reste en haut.
  6. Rapporter la branche, les enfants et la prochaine étape.

next (enfant unique)

  1. Résoudre la branche d'intégration active (une attendue ; demandez si plusieurs). Si la session n'est pas déjà nommée EPIC: (c'est-à-dire next invoqué directement, pas via start), nommez-la "EPIC: <titre parent> (<parent>)" (Claude-Code uniquement).
  2. Choisir le prochain enfant non bloqué : le premier enfant non terminé dont tous les blockedBy sont fusionnés dans la branche d'intégration. Énoncez le choix + le raisonnement dans la bannière.
  3. S'assurer que l'enfant précédent a atterri. Avec --auto-merge (Étape 4) chaque PR enfant est fusionnée dans la branche d'intégration automatiquement une fois les CI passées, donc la pointe d'intégration avance automatiquement — faites simplement git fetch origin et confirmez. (Fallback pour un enfant exécuté sans --auto-merge : avance rapide de la branche sur sa pointe — git push origin origin/<branche-enfant-precedent>:refs/heads/<branche-integration>, ce qui ferme automatiquement cette PR comme MERGED. Sûr à réexécuter.)
  4. Exécuter /rig-task <ENFANT> --base <branche-integration> --auto-merge (ajoutez --spec-cleared lorsque la révision des spécifications préchargée de run a déjà effacé les specs) — --base fait que la worktree de l'enfant provient de, et sa PR cible, la branche d'intégration ; --auto-merge fait que l'enfant active gh pr merge --squash --auto sur sa propre PR une fois sa revue propre, donc la CI la fait atterrir dans la branche d'intégration (toujours squash — ne pas faire de merge rebasé ; de nombreux dépôts l'interdisent. Si la branche d'intégration n'a pas de vérifications obligatoires, l'enfant fusionne directement). Exécutez en un seul coup (début→fin) ; il retourne une seule chaîne de résultat pour la porte de fusion.
  5. Porte de fusion — seul clean est vert pour fusion :
    • clean → l'enfant a activé l'auto-merge, donc sa PR atterrit quand CI passe. Attendez : interrogez gh pr view <N> --json state (~60s, jusqu'à ~30min) jusqu'à MERGED, puis git fetch origin et confirmez que la pointe a avancé. Enregistrez l'enfant merged + sa branche dans le fichier d'état, et assurez-vous que le ticket de l'enfant est Terminé (adaptatif — déplacez uniquement s'il n'est pas déjà Terminé ; différer si une intégration en direct l'a fermé). Si CI échoue / ne fusionne jamais → traiter comme non-clean.
    • autre chose (actionable/timeout, ou un état mis en pause par le tracker) → l'enfant n'a pas activé l'auto-merge ; arrêtez. Affichez le résultat, l'URL de la PR et tout résumé du relecteur. Attendez l'utilisateur ; ne réessayez pas une revue en pause.

next fait exactement un enfant. Utilisez run pour la boucle.

run [--advisor]

Révision des spécifications préchargée — une fois, avant la boucle. Examinez tous les specs des enfants ensemble, en amont, au lieu de découvrir les bloqueurs un enfant à la fois en cours d'exécution. Un enfant qui marque une pause sur une question de spec bloque tout l'epic (et sous exécution parallèle ou durable, un enfant en pause peut faire échouer tout le lot), donc résolvez les specs avant qu'un enfant ne commence à coder :

  1. Distribuez agents.architect + agents.qa sur les specs de chaque enfant, lus par rapport à la branche d'intégration ; chacun retourne ses bloqueurs.
  2. Consolidez en une liste de bloqueurs et résolvez-la une fois — clarifiez dans le tracker, ou décidez avec l'utilisateur. C'est le point de décision unique des specs de l'epic.
  3. Ensuite, exécutez chaque enfant avec sa porte de spec pré-effacée : /rig-task <ENFANT> --base <branche-integration> --auto-merge --spec-cleared, afin qu'aucun enfant ne fasse une nouvelle pause sur une question déjà répondue.

Ce passage de spec pré-codage ; la review de diff combinée (ci-dessous) est le passage de code post-fusion — des portes différentes.

--advisor (sans surveillance). Décidez de cette porte préchargée avec un passage conseiller au lieu d'un humain : un agents.architect délégué lit les specs de l'architecte + QA et soit procède avec une direction synthétisée par enfant (transmise textuellement au codeur de chaque enfant), soit s'arrête avec un rapport bloqué nommant ce qu'un humain doit décider. Aucun humain n'attend, donc l'epic fonctionne sans intervention jusqu'aux PR enfants ; un véritable bloqueur l'arrête quand même plutôt que de se disperser sur une mauvaise spec. (Le workflow durable Smithers associé implémente cela avec un modèle bon marché — le "conseiller Fable" — donc les epics lancés ne restent jamais bloqués à la porte.)

Ensuite, bouclez next jusqu'à ce qu'il ne reste aucun enfant non bloqué :

tant qu'un enfant non bloqué existe :
  exécutez /rig-epic next            # les enfants s'exécutent avec --spec-cleared (spec préchargée)
  s'il s'est arrêté sans fusionner (résultat ≠ clean) → arrêtez, rendez la main
  sinon → réévaluez les enfants non bloqués

Quand la file est vide, rapportez "epic prêt pour /rig-epic finish."

review [<PARENT>]

Exécutez après la fusion du dernier enfant dans la branche d'intégration, avant finish. La revue par PR (/rig-review dans chaque /rig-task) voit chaque enfant isolément ; celle-ci voit la forme combinée et la simplification visible seulement une fois que tout est en place. Les sous-agents en contexte frais (entrée = le diff compressé + titres des PR enfants) ne peuvent pas hériter des rationalisations mémorisées de l'implémenteur.

Exécutez avant prune — les sous-agents de revue ont besoin d'un checkout fonctionnel ; réutilisez une worktree d'enfant si elle existe encore (évite une nouvelle installation + resymlink d'env).

  1. Résolvez la branche d'intégration ; git fetch origin.
  2. Assurez une worktree de branche d'intégration ($WT). Réutilisez une worktree d'enfant fusionné avancée rapidement à la pointe d'intégration, sinon créez-en une avec /rig-worktree (--base <branche-integration> --reuse).
  3. Distribuez trois sous-agents en parallèle (un message, trois appels Agent), chacun cd dans $WT avec la pointe d'intégration extraite :
    • Lentille 1 — Simplification (agents.architect): diff git diff <vcs.baseRef>...HEAD ; liste des PR enfants via gh pr list --base <BR> --state merged. Mandat : trouver les abstractions à réduire, les helpers ajoutés par une PR que la forme finale d'une autre PR a rendus redondants, les boutons de configuration que personne ne définit, les chemins de code que le diff combiné a rendus morts, les types à un seul appelant. Suppressions/fusions concrètes, fichier:ligne, impact le plus élevé d'abord. Ignorez la correction.
    • Lentille 2 — Correction cross-PR (agents.reviewer): parcourez le catalogue de motifs de revue du projet (review.patternsFile) par rapport au diff combiné. La revue par PR a déjà été exécutée ; attrapez les interactions visibles seulement à la forme fusionnée (helper de PR-A vs appelant obsolète de PR-D ; PR-B a supprimé un bouton que PR-F lit encore). P0/P1/P2 avec fichier:ligne + catégorie.
    • Lentille 3 — Code mort et références obsolètes (agents.reviewer): pour chaque symbole que le diff a ajouté, est-il appelé ailleurs ? Pour chaque symbole supprimé, grep l'arborescence (workflows, manifests, IaC, scripts, docs) pour des références résiduelles. Rapportez avec fichier:ligne.
  4. Consolidez — dédupliquez, produisez une liste P0/P1/P2 groupée par lentille, imprimez les comptes.
  5. Triage :
    • 0 éléments → clean — prêt pour /rig-epic finish, arrêtez.
    • des constats → demandez via AskUserQuestion : appliquer maintenant / ignorer et terminer quand même (rétrograder en suivi) / pause. Sur appliquer maintenant, exécutez /rig-review fix --source local dans $WT (lance agents.coder, re-revoit jusqu'à propre), commitez + git push origin <branche-integration>, réexécutez review une fois pour confirmer la convergence.
  6. Chaîne de résultat (pour finish) : clean — … / appliqué — … / en pause — ….

finish [<PARENT>] [--merge]

Compresse toute la branche d'intégration en une seule PR vers le tronc. Défaut : ouvrez la PR et arrêtez — c'est la PR à examiner.

review est une porte dure. finish exécute toujours review en premier ; la PR compressée s'ouvre uniquement sur clean ou appliqué. Sur en pause, arrêtez et attendez.

  1. Exécutez review (porte) en ligne ; branchez sur son résultat (clean/appliqué → procédez ; en pause → arrêtez et imprimez les constats en attente).
  2. Rafraîchissez et rebasez si nécessaire. git fetch origin ; listez git log <vcs.baseRef>..origin/<branche-integration> --oneline. Si le tronc a bougé, rebasez d'abord la branche d'intégration dessus (git rebase <vcs.baseRef> sur une copie locale, puis git push --force-with-lease origin <local>:<branche-integration>).
  3. Ouvrez la PR finale vers vcs.defaultBranch avec un titre référençant le parent et un corps résumant tous les enfants. Dans un tracker avec un verbe de fermeture (Fixes <PARENT> / Closes #<n>), incluez-le pour que le parent se ferme automatiquement

Skills associés