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, MANQUANT ou NON 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 prune est 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 .env n’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_ENV est cohérent
  • APP_URL est 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:wipe ou é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 flushdb ou flushall utilisé par un worktree ne peut casser les autres
  • Les clés applicatives possèdent un préfixe unique

8. Cache Laravel

  • CACHE_PREFIX est unique
  • php artisan cache:clear ne 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/cache n’est pas partagé
  • storage/framework/cache n’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 stateful Sanctum 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:restart d’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 instances
  • onOneServer() 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/app n’est pas partagé involontairement
  • storage/logs est distinct
  • storage/framework est distinct
  • Les uploads locaux ne contaminent pas les autres worktrees
  • Les fichiers temporaires sont isolés
  • Les exports/imports sont isolés
  • Les storage:link pointent 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.lock correspond 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/build sont locaux au worktree
  • Un npm install dans 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_NAME est unique par worktree
  • Aucun container_name fixe 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 down d’un worktree ne détruit pas les containers d’un autre
  • docker compose down -v ne 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 :

  • Email
  • 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 -rf
  • DROP DATABASE
  • db:wipe
  • migrate:fresh
  • cache:clear
  • redis 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 :

  • create
  • setup
  • start
  • stop
  • restart
  • remove
  • cleanup

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à fait de erreur
  • 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 stop ne tue pas un processus appartenant à un autre worktree
  • Aucun pkill php / killall node gé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é
  • root pointe 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 et git status avant opérations importantes
  • Aucun agent ne fait git reset --hard sans contrôle
  • Aucun agent ne fait git clean -fd sans 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.json sont détectées
  • Les modifications concurrentes de package.json sont détectées
  • Les modifications concurrentes de .env.example sont 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 :

  • localhost
  • 127.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_URL
  • VITE_
  • 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 :

RessourceIsoléePartagée volontairementRisque
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.