Checklist d’audit — Git Worktrees multi-instance
Objectif : auditer le setup actuel et vérifier qu’un nombre arbitraire de worktrees peut tourner simultanément sans collision, contamination croisée ou effet de bord.
Pour chaque point :
- Vérifier l’implémentation réelle dans le projet
- Indiquer
OK,RISQUE,MANQUANTouNON APPLICABLE - Citer les fichiers/configurations concernés
- Ne modifier aucun fichier pendant l’audit
- À la fin, produire une liste priorisée des problèmes trouvés
1. Git / Worktrees
- Chaque worktree utilise une branche Git distincte
- Le script empêche de réutiliser accidentellement une branche déjà montée dans un autre worktree
- Le worktree principal est correctement distingué des worktrees secondaires
- La suppression d’un worktree ne supprime pas une branche ou des données non fusionnées sans avertissement
git worktree pruneest géré ou documenté- Les worktrees supprimés ne laissent pas d’entrées Git orphelines
- Les fichiers non trackés importants ne sont pas supposés être partagés entre worktrees
- Aucun script ne suppose implicitement que le dépôt courant est le worktree principal
- Les chemins reposent sur la racine réelle du worktree et non sur un chemin absolu codé en dur
- Les hooks Git éventuellement utilisés fonctionnent depuis tous les worktrees
- Les scripts savent correctement retrouver le common Git dir et le worktree courant
2. Identité unique du worktree
- Chaque worktree possède un identifiant unique et stable
- Cet identifiant est dérivé de manière déterministe ou enregistré explicitement
- Les noms contenant
/,_, espaces ou caractères spéciaux sont normalisés - Deux branches dont les noms se ressemblent ne peuvent pas générer le même identifiant
- Il existe une stratégie pour éviter les collisions après troncature des noms
- L’identifiant est utilisé partout où une ressource doit être isolée
3. Variables d’environnement
- Chaque worktree possède son propre
.env - Le
.envn’est jamais partagé par symlink sauf intention explicite - Le script initialise correctement un nouveau
.env - Les secrets communs éventuels sont séparés des valeurs propres au worktree
APP_ENVest cohérentAPP_URLest propre au worktree- Les variables générées automatiquement sont idempotentes
- Une relance du script ne détruit pas des modifications manuelles du
.env - Les variables obligatoires manquantes sont détectées avant le démarrage
4. Hostnames / URLs
- Chaque worktree possède un hostname distinct
- Aucun hostname ne peut entrer en collision
- La génération du hostname supporte correctement les noms de branches complexes
/etc/hosts, DNS local ou wildcard DNS est correctement géré- Les entrées obsolètes peuvent être nettoyées
- Le reverse proxy route vers le bon worktree
- HTTP et HTTPS sont gérés de manière cohérente
- Les certificats locaux éventuels supportent les hostnames générés
- Les redirects Laravel ne renvoient pas vers le hostname d’un autre worktree
- Les URLs générées par les jobs/CLI utilisent le bon
APP_URL
5. Ports
- Tous les services nécessitant un port peuvent fonctionner simultanément
- Le port HTTP est unique
- Le port Vite est unique
- Le port WebSocket/Reverb est unique
- Les ports de debug éventuels sont uniques
- Les ports des outils annexes sont uniques
- L’allocation des ports résiste au lancement concurrent de deux créations de worktree
- Un port déjà occupé est détecté avant démarrage
- Les ports libérés peuvent être réutilisés sans collision
- Aucun port fixe caché n’est présent dans les scripts/configurations
6. Base de données
- Chaque worktree utilise une base isolée
- Le nom de base est unique
- Les migrations d’un worktree ne peuvent pas modifier la DB d’un autre
migrate:fresh,db:wipeou équivalent ne peut pas toucher une autre instance- Les seeds sont exécutés sur la bonne DB
- Les tests utilisent une DB propre au worktree
- Les connexions secondaires éventuelles sont également isolées
- Les DB de tests sont distinctes des DB de développement
- La suppression du worktree gère explicitement le devenir de sa DB
- Une protection existe contre la suppression accidentelle de la DB principale
7. Redis
- Cache Redis isolé par worktree
- Sessions Redis isolées
- Queues Redis isolées
- Locks Redis isolés
- Rate limiting isolé si nécessaire
- Broadcast/pub-sub isolé
- Horizon utilise le bon namespace
- Aucun
flushdbouflushallutilisé par un worktree ne peut casser les autres - Les clés applicatives possèdent un préfixe unique
8. Cache Laravel
CACHE_PREFIXest uniquephp artisan cache:clearne vide pas les données des autres worktrees- Le config cache est local au worktree
- Le route cache est local au worktree
- Le view cache est local au worktree
bootstrap/cachen’est pas partagéstorage/framework/cachen’est pas partagé
9. Sessions / Cookies
- Nom du cookie de session unique
- Domaine du cookie cohérent avec le hostname
- Les sessions d’un worktree ne sont pas réutilisées dans un autre
- Les cookies CSRF/XSRF ne provoquent pas de collisions
- Les cookies d’authentification persistante sont isolés
- Sanctum fonctionne correctement avec les domaines générés
- Les domaines
statefulSanctum sont correctement définis
10. Queues
- Chaque worktree possède sa queue ou son namespace
- Un worker d’un worktree ne peut pas consommer les jobs d’un autre
- Les failed jobs restent identifiables par worktree
- Horizon sépare correctement les environnements
- Les workers sont arrêtés lors de la suppression/arrêt d’un worktree
queue:restartd’un worktree ne perturbe pas les autres- Les jobs sérialisés ne dépendent pas d’un chemin absolu d’un autre worktree
11. Scheduler / Cron
- Le scheduler ne s’exécute pas involontairement dans tous les worktrees
- Une stratégie explicite détermine quels worktrees peuvent lancer le scheduler
withoutOverlapping()ne partage pas accidentellement ses locks entre instancesonOneServer()a le comportement attendu- Les tâches ayant des effets externes ne sont pas dupliquées
- Les cron système éventuels ne pointent pas vers un ancien worktree
12. Storage / fichiers locaux
- Chaque worktree possède son propre
storage/ storage/appn’est pas partagé involontairementstorage/logsest distinctstorage/frameworkest distinct- Les uploads locaux ne contaminent pas les autres worktrees
- Les fichiers temporaires sont isolés
- Les exports/imports sont isolés
- Les
storage:linkpointent vers le bon worktree - Les symlinks sont vérifiés après création
- Aucun chemin absolu vers un ancien worktree n’est stocké
13. Logs
- Les logs permettent d’identifier le worktree d’origine
- Deux worktrees n’écrivent pas dans le même fichier de log sauf intention explicite
- Les logs des workers sont distinguables
- Les logs du scheduler sont distinguables
- Les logs du reverse proxy permettent d’identifier l’instance
- Le nom du worktree est injecté dans le contexte de logging si utile
14. Composer / PHP
- Chaque worktree possède son propre
vendor/ composer.lockcorrespond bien à chaque branche- Aucun vendor partagé ne peut être écrasé par un autre worktree
- La version PHP utilisée est cohérente
- Les extensions PHP requises sont disponibles
- Les scripts Composer post-install ne touchent pas des ressources globales dangereuses
- Les caches Composer éventuellement partagés sont uniquement des caches de téléchargement
15. Node / npm / Vite
- Chaque worktree possède son propre
node_modules - Le lockfile propre à la branche est respecté
- Le serveur Vite possède un port unique
- HMR fonctionne avec le hostname du worktree
- Les URLs HMR/WebSocket sont correctes
- Les fichiers générés dans
public/buildsont locaux au worktree - Un
npm installdans un worktree ne modifie pas les dépendances d’un autre - Les caches npm/pnpm/yarn partagés ne contiennent que des artefacts sûrs à partager
16. Docker si utilisé
COMPOSE_PROJECT_NAMEest unique par worktree- Aucun
container_namefixe ne crée de collision - Les networks sont correctement namespacés
- Les volumes sont correctement namespacés
- Les bind mounts pointent vers le worktree courant
- Les ports exposés sont uniques
docker compose downd’un worktree ne détruit pas les containers d’un autredocker compose down -vne supprime pas des volumes partagés importants- Les services volontairement partagés sont clairement identifiés
- La destruction d’un worktree ne détruit jamais l’infrastructure commune
17. Services externes
Vérifier particulièrement :
- SMS
- Stripe/paiements
- Webhooks
- OpenAI / LLM
- Telegram
- Slack
- APIs métier
- S3 / object storage
- Search engines
- OAuth providers
Pour chacun :
- L’environnement de développement utilise sandbox/test quand disponible
- Un worktree secondaire ne peut pas déclencher involontairement une action production
- Les callbacks utilisent le hostname du bon worktree
- Les webhook URLs peuvent distinguer les worktrees
- Les idempotency keys ne créent pas de collisions
- Les emails/SMS de test sont interceptés si nécessaire
18. OAuth / authentification externe
- Les redirect URIs supportent les différents hostnames
- Google/GitHub/etc. acceptent les URLs générées
- Les secrets ne sont pas recopiés inutilement
- L’état OAuth/state/PKCE reste associé au bon worktree
- Un login initié sur WT-A ne termine pas sur WT-B
19. Services partagés
Pour chaque service partagé, documenter explicitement :
- MySQL
- Redis
- Mailpit/Mailhog
- Elasticsearch/Meilisearch
- MinIO
- RabbitMQ
- reverse proxy
- autres
Puis vérifier :
- Ce qui est partagé
- Ce qui est namespacé
- Ce qui est totalement isolé
- Ce qui se passe lors d’un reset
- Ce qui se passe lors de la suppression d’un worktree
20. Tests automatisés
- Deux suites de tests peuvent tourner simultanément
- Elles n’utilisent pas la même DB
- Elles ne partagent pas les mêmes fichiers temporaires
- Elles ne partagent pas les mêmes ports
- Elles ne détruisent pas les données de l’autre
- Les tests browser/E2E ciblent le bon hostname
- Dusk/Playwright/Cypress peuvent tourner en parallèle
- Les screenshots et artefacts de tests sont séparés
- Les mails/jobs/fakes sont correctement isolés
21. Commandes destructives
Chercher toutes les commandes du type :
rm -rfDROP DATABASEdb:wipemigrate:freshcache:clearredis flush*docker compose down -v- suppression de volumes
- suppression de répertoires
- suppression de hosts/vhosts
Pour chacune :
- La cible est explicitement limitée au worktree courant
- Le script refuse les valeurs vides
- Le script refuse
/ - Le script refuse le repository principal si ce n’est pas explicitement demandé
- Une variable vide ne peut jamais élargir une commande destructive
- Une protection existe contre les erreurs de quoting shell
22. Concurrence du script de création
Simuler deux commandes lancées exactement en même temps.
Vérifier :
- Allocation atomique des ports
- Allocation atomique des DB
- Allocation atomique des hostnames
- Écriture concurrente dans
/etc/hosts - Écriture concurrente dans nginx
- Création concurrente de fichiers registry
- Absence de race condition
- Utilisation de lock/flock si nécessaire
23. Idempotence
Pour toutes les commandes principales :
createsetupstartstoprestartremovecleanup
Vérifier :
- Une deuxième exécution ne casse rien
- Une exécution interrompue peut être reprise
- Un état partiellement créé est détecté
- L’outil sait distinguer
déjà faitdeerreur - Un rollback ou cleanup est possible après erreur
24. Processus orphelins
Après arrêt/suppression d’un worktree :
- Aucun serveur PHP orphelin
- Aucun
php artisan serve - Aucun worker queue
- Aucun Horizon
- Aucun scheduler
- Aucun Vite
- Aucun WebSocket server
- Aucun processus Node
- Aucun container Docker
- Aucun tmux/screen/process manager associé inutilement
25. Process management
- Le PID de chaque service est traçable
- Un
stopne tue pas un processus appartenant à un autre worktree - Aucun
pkill php/killall nodegénérique dangereux - Les processus sont identifiés par PID, working directory ou identifiant spécifique
- Le redémarrage cible uniquement le worktree courant
26. Nginx / reverse proxy
- Un fichier vhost distinct existe par worktree
- Les noms de fichiers sont uniques
- La configuration est validée avant reload (
nginx -t) - Une erreur dans un worktree ne casse pas les autres vhosts
- Le nettoyage retire uniquement le vhost concerné
rootpointe vers le bon/public- PHP-FPM reçoit le bon
SCRIPT_FILENAME - Les hostnames wildcard et regex ne routent pas vers la mauvaise instance
27. WSL
- Les chemins Windows/WSL ne sont pas mélangés de façon fragile
- Aucun chemin
/mnt/c/...codé en dur si non nécessaire - Les permissions Linux sont conservées
- Les symlinks fonctionnent correctement
- Les scripts fonctionnent après redémarrage WSL
- Les IP dynamiques WSL ne sont pas supposées fixes
- Les processus lancés sont bien visibles/arrêtables depuis WSL
- Le navigateur Windows peut résoudre les hostnames utilisés
28. Multitenancy Laravel
Puisque l’application est multi-tenant :
- L’identification du tenant ne dépend pas accidentellement du hostname de worktree
- Le hostname de développement et le hostname métier du tenant sont correctement distingués
- Les domaines tenant sont isolés entre worktrees
- Les tenants créés dans WT-A ne sont pas visibles dans WT-B sauf intention explicite
- Les DB tenant sont correctement isolées
- Les queues tenant-aware ne traversent pas les worktrees
- Les caches tenant-aware incluent aussi l’identité du worktree si nécessaire
- Les cookies multi-tenant ne fuient pas entre instances
- Les URLs générées pour les tenants utilisent le domaine attendu
- Les commandes artisan tenant-aware utilisent la DB du worktree courant
29. Agents IA travaillant simultanément
Si plusieurs Claude Code / Codex / agents travaillent en parallèle :
- Un agent = un worktree
- Un agent = une branche
- Les responsabilités sont suffisamment séparées
- Deux agents ne modifient pas volontairement le même fichier sauf nécessité
- Les agents n’exécutent pas de commandes Git sur le mauvais worktree
- Les agents vérifient
pwd, branche etgit statusavant opérations importantes - Aucun agent ne fait
git reset --hardsans contrôle - Aucun agent ne fait
git clean -fdsans contrôle - Aucun agent ne force-push une branche partagée
- Les commits sont fréquents et atomiques
- Chaque agent laisse le worktree dans un état récupérable
- Les conflits sont résolus lors de l’intégration, pas masqués
30. Intégration entre branches
- Une stratégie d’intégration est définie : merge, rebase ou cherry-pick
- Les branches sont régulièrement resynchronisées avec la branche de référence si nécessaire
- Les modifications de migrations concurrentes sont détectées
- Les modifications concurrentes de
composer.jsonsont détectées - Les modifications concurrentes de
package.jsonsont détectées - Les modifications concurrentes de
.env.examplesont détectées - Les modifications concurrentes des configs centrales sont détectées
- Une suite de tests complète est lancée après intégration
31. Observabilité
Idéalement, pouvoir exécuter une commande donnant :
Worktree Branch Host DB HTTP Vite Status main main huynh-yvon.team-of.test app_main 80 5173 UP auth feat/auth auth.team-of.test app_auth ... ... UP billing feat/billing billing.team-of.test app_billing ... ... DOWN
Vérifier :
- Branche
- chemin
- hostname
- DB
- ports
- PID/processus
- containers
- état nginx
- état queue
- état Vite
32. Nettoyage complet
Lors de la suppression d’un worktree, vérifier explicitement le traitement de :
- worktree Git
- branche Git
- DB
- DB de tests
.env- hostname
/etc/hosts- vhost nginx
- certificat local
- Redis keys
- queues
- workers
- scheduler
- Docker containers
- Docker networks
- Docker volumes
- logs
- fichiers temporaires
- PID files
- storage
- node_modules
- vendor
Pour chaque ressource, préciser si elle est :
- supprimée automatiquement ;
- conservée volontairement ;
- supprimée uniquement avec
--purge.
33. Protection du worktree principal
- Le worktree principal est explicitement identifiable
- Les commandes destructives ont des protections supplémentaires sur celui-ci
- Impossible de supprimer le worktree principal par erreur
- Impossible de supprimer sa DB par erreur
- Impossible de supprimer son vhost par erreur
- Impossible de le traiter comme une instance temporaire sans confirmation explicite
34. Scénarios à réellement tester
Ne pas se limiter à lire le code. Si possible, tester :
- Créer WT-A
- Créer WT-B
- Créer WT-C
- Démarrer les trois simultanément
- Ouvrir les trois applications simultanément
- Authentification différente dans chaque instance
- Écrire des données différentes dans chaque DB
- Lancer des migrations différentes
- Lancer des queues simultanément
- Lancer Vite simultanément
- Exécuter les tests simultanément
- Redémarrer WT-B sans toucher A/C
- Supprimer WT-B sans toucher A/C
- Recréer WT-B
- Lancer simultanément deux créations de worktree
- Tuer brutalement un setup en cours puis le relancer
- Redémarrer WSL puis relancer les worktrees
- Vérifier qu’aucun processus/port/configuration fantôme ne subsiste
35. Recherche de dépendances cachées
Effectuer une recherche globale dans le repository pour détecter :
localhost127.0.0.1- ports codés en dur
- noms de DB codés en dur
- noms Redis codés en dur
- domaines codés en dur
- chemins absolus
- chemins vers
/home/... - chemins vers
/mnt/c/... APP_URLVITE_REDIS_DB_QUEUE_SESSION_CACHE_BROADCAST_REVERB_SANCTUM_- noms de containers
- noms de volumes Docker
Identifier tout élément qui devrait dépendre de l’identité du worktree mais ne le fait pas.
Rapport final attendu
À la fin de l’audit, produire exactement ces sections :
1. Verdict global
Donner une note sur 10 pour la robustesse du système multi-worktree.
2. Problèmes critiques
Uniquement les problèmes susceptibles de :
- corrompre des données ;
- toucher un autre worktree ;
- toucher la production ;
- supprimer des ressources ;
- provoquer des comportements non déterministes.
3. Risques moyens
Problèmes pouvant provoquer des collisions, bugs ou difficultés d’exploitation sans risque majeur de perte de données.
4. Améliorations mineures
Ergonomie, observabilité, nettoyage, simplification.
5. Éléments correctement implémentés
Lister ce qui a réellement été vérifié dans le code et qui est robuste.
6. Tests manquants
Lister les scénarios qui ne sont pas couverts actuellement.
7. Ressources non isolées
Créer un tableau :
| Ressource | Isolée | Partagée volontairement | Risque |
|---|---|---|---|
| DB | |||
| Redis | |||
| Cache | |||
| Sessions | |||
| Queues | |||
| Storage | |||
| Logs | |||
| HTTP | |||
| Vite | |||
| WebSockets | |||
| Scheduler | |||
| Services externes |
8. Top 10 des actions recommandées
Classer par priorité réelle.
Règle importante pour cet audit
Ne suppose pas qu’un mécanisme fonctionne parce qu’un fichier ou une variable existe.
Trace réellement le flux :
création du worktree → génération config → démarrage → runtime → arrêt → suppression
et cherche particulièrement :
- les ressources globales cachées ;
- les variables partagées ;
- les chemins absolus ;
- les ports fixes ;
- les commandes destructives ;
- les race conditions ;
- les processus orphelins ;
- les effets de bord externes.
Le but n’est pas de confirmer que le système semble correct.
Le but est d’essayer activement de trouver une façon de le casser.
