---
name: support-bug-investigate
description: >
  Investigate a reported Pysae bug by reading the source code locally (cloned repos) until the
  exact root cause is found, then produce a concise, actionable root-cause report (30-40 lines max).
  Use when the user says /support-bug-investigate, 'enquête sur ce bug', 'analyse ce bug',
  'analyse ce ticket', 'trouve la cause racine', 'pourquoi ce bug', 'd où vient ce bug',
  'investigue ce problème client', 'investigate this bug', 'find the root cause', 'why does this happen',
  'debug this Pysae bug', shares a Pysae bug report from Intercom/Airtable, or when a client reports a
  problem with Plan de Transport, GTFS, driver UI, passenger display, or any Pysae product.
  Distinct from /support-mr-fix (which fixes the bug and opens a MR) and /support-ticket-create
  (which files the support ticket) — this skill only diagnoses the root cause, it changes nothing.
argument-hint: "[Intercom URL, Airtable record ID, GitLab issue URL, group_id, or a short description of the bug]"
allowed-tools:
  - Read
  - Glob
  - Grep
  - Bash
---

Enquête sur un bug Pysae en lisant le code source **en local** (pas via MCP API), jusqu'à identifier la cause racine exacte. Livre un rapport **concis et actionnable** (30-40 lignes max) que les devs peuvent directement exploiter.

## Required tools

- `glab`
- `mongo-tools`
- `atlas`

Run `pysae-ai-tools tools require <tools>` before starting; if it exits non-zero, abort and report the install command from stderr to the user.

## Principe directeur — cause racine, toujours

**Ne jamais s'arrêter à une analyse de surface.** L'enquête n'est pas terminée tant que tu n'as pas identifié :

- Le **fichier et la ligne exacts** où l'erreur survient
- Le **chemin d'exécution** complet (endpoint → service → repository → modèle → point de crash)
- Le **pourquoi** (changement de modèle, gap de migration, champ manquant, mauvaise query, etc.)
- Un **correctif concret** (commande MongoDB, patch de code, changement de config)

Lis autant de fichiers que nécessaire — pas de limite. Suis les imports, trace les appels de fonctions, lis les définitions de modèles. **Ne devine pas ; lis le code.**

## Workflow

### 1. Identifier le domaine et les repos à cloner

Depuis la description du bug, identifie :
- Le ou les repos probablement concernés — `/project-configuration all` (identité + description par repo)
- Le vocabulaire métier → technique — voir [../references/support-vocabulary.md](../references/support-vocabulary.md)

**Principaux repos de bugs client** :
- `pysae/api` — backend FastAPI + MongoDB (la majorité des bugs)
- `pysae/pysae-common` — lib partagée (types, mongo, auth)
- `pysae/gtfs-validator` — wrapper Docker autour de `etalab/transport-validator` (Rust)
- `pysae/op`, `pysae/driver`, `pysae/editor`, `pysae/info`, `pysae/screen` — frontends

### 2. Cloner (ou mettre à jour) les repos localement

Pour chaque repo à inspecter :

```bash
pysae-ai-tools code ensure-repo pysae/api
pysae-ai-tools code ensure-repo pysae/pysae-common
```

La commande clone sous `${PYSAE_AI_TOOLS_GIT_CLONE_DIR:-~/projects}/<path>` si absent, `git pull --ff-only` sinon. Elle imprime un JSON avec `local_path` — utilise-le pour tous les `Read`/`Grep`/`Glob` suivants.

**Toujours `git pull` avant lecture** — c'est le comportement par défaut de `ensure-repo` (ne pas passer `--no-pull`). Sinon tu analyses une copie périmée.

### 3. Chercher des changements récents liés

Avant de plonger dans le code, vérifie l'historique :

```bash
# commits récents qui matchent le symptôme
git -C <local_path> log --oneline --since="30 days ago" --grep="<motclé>"

# MRs récentes via glab
glab mr list --repo pysae/api --search "<motclé>" --all
```

### 4. Lire le code source — chemin d'exécution complet

Avec `Read`, `Grep`, `Glob` sur les copies locales :

1. **Point d'entrée** — router/endpoint qui reçoit la requête qui plante
2. **Service** — la couche métier appelée
3. **Repository** — l'accès MongoDB
4. **Modèle** — la définition Pydantic / type
5. **Point de crash** — la ligne exacte qui lève l'exception ou produit le mauvais résultat

Exemple d'investigation sur l'API :

```bash
# Trouver l'endpoint
grep -rn "path_suffix_qui_plante" "$API/pysae/api/" --include="*.py"

# Suivre la route → service → repo → model
# (Read + Grep par nom de fonction/classe)
```

### 4b. Si le bug sent le timeout / la lenteur Mongo

Quand le rapport mentionne timeout, requête qui n'aboutit pas, page qui rame côté DB, ou erreur intermittente sous charge, vérifie côté Atlas avant de plonger plus loin :

```bash
# Slow ops récents (utilise le host du primary, cf. `atlas -P pysae-prod processes list`)
atlas -P pysae-prod performanceAdvisor slowQueryLogs list --processName <host:port> --output json

# Index manquants détectés par Atlas Performance Advisor
atlas -P pysae-prod performanceAdvisor suggestedIndexes list --output json
```

Si le slow op matche la collection/forme de requête du bug, la cause racine est probablement un index manquant ou une query mal indexée — confirme avec `mcp__mongodb-prod__explain` sur la même requête avant de conclure.

### 5. Formuler la cause racine

**Une seule** cause racine proven, pas une liste d'hypothèses. Appuie chaque affirmation sur une ligne de code précise (fichier + numéro de ligne).

### 6. Fournir un correctif concret

Au minimum un des éléments :
- **Commande MongoDB** pour réparer l'état en base
- **Patch de code** (diff ou snippet) à appliquer
- **Changement de config** (env var, feature flag)
- **MR de correction** si un fix simple (1-5 fichiers) est évident → proposer l'enchaînement avec `support-mr-fix`

## Format de sortie (obligatoire)

Toujours ce format, **30-40 lignes utiles max** :

```markdown
### Résumé du bug
[1-3 lignes : qu'est-ce qui est cassé, pour qui, depuis quand]

### Cause racine
[3-5 lignes : cause racine exacte avec fichier, ligne et explication technique]

### Chemin d'exécution
1. `<endpoint>` — `path/to/router.py:42`
2. `<service>` — `path/to/service.py:120`
3. `<repo>` — `path/to/repository.py:85`
4. Point de crash — `path/to/model.py:67`

### Quoi faire
- [Action concrète 1 — commande MongoDB ou patch de code]
- [Action concrète 2 — validation ou changement de config]
- [Option MR directe si petit fix : `/support-mr-fix`]
```

**Si tu dépasses 40 lignes, tu violes le format. Coupe sans pitié.** Pas de sections A-G, pas d'explications verbeuses, pas de liste d'hypothèses.

## Priorité — règle non négociable

Les niveaux de priorité sur GitLab doivent **toujours correspondre à la criticité Airtable**. Ne jamais s'auto-assigner une priorité sur GitLab. Le ticket Airtable est la source de vérité pour la criticité (voir [../references/support-vocabulary.md](../references/support-vocabulary.md#criticité-airtable--label-priority-gitlab)).

## Erreurs fréquentes

- **S'arrêter en surface** — « l'API retourne 500 » n'est **pas** une cause racine. Lis le code jusqu'à la ligne exacte.
- **Trop verbeux** — les devs ignorent les rapports > 40 lignes. Coupe.
- **Oublier `git pull`** — tu analyses une copie périmée. `ensure-repo` le fait par défaut, ne passe jamais `--no-pull`.
- **Confusion métier/technique** — toujours traduire via `support-vocabulary.md`.
- **Rater la chaîne de validation GTFS** — beaucoup de bugs PAN tracent vers etalab. Voir la section « Chaîne de validation GTFS » dans `support-vocabulary.md`.
- **S'auto-attribuer une priorité** — la priorité vient d'Airtable, toujours.

## Enchaînement avec les autres skills

Après l'enquête, les étapes suivantes habituelles :

1. `/support-ticket-create` — créer le ticket Airtable (injecte cette analyse dans Notes)
2. `/glab-issue-create --from-airtable <recID>` — créer l'issue GitLab depuis le ticket Airtable (pratiques du projet : templates GitLab, labels `priority::*`, `type::*`, board column, `/label ~augmented`)
3. `/support-mr-fix` — **uniquement** si la cause racine est simple, précise, 1-5 fichiers, pas de migration DB, pas de changement d'API publique — et si Patrick le valide explicitement

$ARGUMENTS
