Brahim Bousnguar

Notes · Article

Comment l’équipe Claude Code relit le code qu’écrit Claude

Par · · 14 min de lecture

Claude écrit environ 90 % de Claude Code, et l’équipe relit toujours chaque changement. Ce qui a changé, c’est qui fait la lecture. Claude vérifie son propre travail avant même qu’une pull request existe, un panel d’agents relit chaque PR, et l’approbation d’une personne n’est exigée que là où se trouve le risque. De juin à septembre, le nombre de pull requests mergées a plus que doublé, tandis que la part qu’il a fallu annuler baissait de plus de 40 %.

C’est tiré de How the Claude Code team does code review, publié sur le blog claude.dev le 15 octobre par Addy Osmani, Morgan Westlee Lunt et Qing Wang. Addy l’a republié sous forme d’article X le 26 octobre. Plus tôt ce mois-ci, j’ai résumé une autre réponse au même problème, celle d’Overmind : relisez le plan, pas la pull request. L’équipe Claude Code a gardé la revue après le code. Elle a simplement cessé d’en faire une seule barrière.

Lire chaque ligne a cessé d’être le critère

Quand des agents écrivent le code, le nombre de changements explose. Dans le monorepo d’Anthropic, les changements intégrés par jour sont passés d’environ 2 500 en mai à plus de 30 000 en septembre. Claude Code vit dans son propre dépôt, mais subit la même pression. Personne ne lit ça ligne par ligne.

Alors l’équipe est revenue à ce à quoi sert la revue. Elle remplit deux rôles : trouver et corriger les problèmes avant la mise en production, et répandre la compréhension du code dans l’équipe. L’essentiel de l’article porte sur le premier.

Leur phrase clé, c’est que « un humain a-t-il lu le code ? » est un indicateur imprécis. La vraie question, c’est ce qui pourrait mal tourner avec ce changement, et quel contrôle, automatique ou humain, est le bon pour l’attraper.

Ça a aussi déplacé la revue dans le temps. Avant, c’était une barrière en bout de chaîne : écrire le code, ouvrir une PR, attendre un collègue. Maintenant, ça fonctionne plutôt comme un correcteur orthographique pendant qu’on écrit. La plupart des changements ont été relus et corrigés par Claude au moins une fois avant qu’on demande à une personne d’y jeter un œil.

L’objectif est concret. La plupart des PR des dépôts Claude Code (la CLI, les applications desktop et web, les applications mobiles) doivent être mergées avec au plus une personne dans la boucle, et cette personne peut être l’auteur. L’équipe suit le nombre d’approbations humaines par PR, en médiane et au 95e centile, les commentaires humains, et le temps qu’une PR passe à attendre une personne. Les reverts et les incidents servent de garde-fou, parce que le temps humain a deux faces : le temps passé à relire, et le temps passé à réparer ce que le mauvais code casse. Si les reverts augmentent, on n’a pas gagné de temps, on l’a seulement déplacé.

Avant

Une barrière à la fin

  1. HumainÉcrit le code
  2. HumainOuvre une pull request
  3. HumainAttend un collègue
  4. HumainLit chaque ligne

La questionUn humain a-t-il lu le code ?

vs

Maintenant

Un correcteur pendant qu’on écrit

  1. ClaudeVérifie et corrige, au moins une fois
  2. AgentsRelisent la pull request
  3. HumainRegarde là où est le risque

La questionQu’est-ce qui peut mal tourner, et quel contrôle l’attrape ?

Suiviapprobations par PR, médiane et p95commentaires humainstemps d’attente d’une personne

Garde-foutaux de reverttaux d’incident

ObjectifLa plupart des pull requests mergées avec au plus une personne dans la boucle, qui peut être l’auteur.

Le même changement, relu à la fin ou tout du long. Les lignes surlignées sont celles où une personne relit. L’objectif et les chiffres qui le suivent sont ceux de l’équipe.

Six couches, puis le retour arrière

Un changement typique, parti d’un portable ou d’une session Claude dans Slack, traverse six couches de contrôles : la vérification avant la PR, la CI obligatoire, la revue par IA, une revue de sécurité, une approbation humaine proportionnée au risque, et une merge queue avec des feature flags. Sous toutes ces couches, il y a le retour arrière rapide.

Chaque couche attrape certains problèmes et en rate d’autres. Peu passent les six, et le retour arrière s’occupe du reste. La majeure partie du chemin est automatisée, et l’attention d’une personne va là où est le risque.

  • automatisé
  • une personne, selon le risque
  • rattrapage
  • un problème arrêté
L’image que donne l’article, ce sont des couches, pas une barrière unique. Quelle couche arrête quel problème relève du schéma : il ne donne aucun chiffre par couche.

Avant la PR, montrer le résultat

L’essentiel de la revue se fait désormais avant qu’une pull request existe. Claude reçoit quelque chose qu’il peut exécuter, comme des tests, un build ou une capture d’écran à comparer à la maquette, et doit montrer le résultat au lieu de dire que c’est fini. Ensuite, un sous-agent relit le diff avec un contexte neuf. Beaucoup de membres de l’équipe lancent aussi des skills internes avant d’ouvrir une PR : un qui chasse les bugs, un qui simplifie le diff, un qui vérifie le comportement de bout en bout.

Boris Cherny, le créateur de Claude Code, considère que donner à Claude un moyen de vérifier son travail est sans doute ce qui compte le plus pour obtenir de bons résultats. Selon lui, cela rend le résultat final deux à trois fois meilleur.

Quand le relecteur signale sans cesse la même chose, l’équipe corrige à la source : dans le skill, avec une règle de lint, ou dans deux fichiers d’instructions. CLAUDE.md dit ce qu’est le projet : la stack, les conventions, les objectifs et les non-objectifs. Chaque revue le charge, alors il reste court et renvoie vers d’autres docs. Le relecteur signale aussi le code qui enfreint une de ses conventions, et les changements qui rendent une de ses lignes obsolète.

REVIEW.md est écrit par les code owners, pour dire au relecteur ce qui compte dans leur partie du code, et l’équipe vérifie à part si le relecteur le suit. Les bons sont courts. Ils disent à quoi ressemble un échec dans ce dépôt (pour la doc, c’est « elle ment », pour la config, « elle route mal »), plafonnent les nits, listent les chemins à ignorer, et exigent un fichier et une ligne comme preuve au lieu d’une supposition tirée d’un nom. Ils demandent aussi un résumé qui commence par un décompte et dit clairement quand il n’y a rien à corriger.

  1. 1Exécuter

    Des tests, un build, ou une capture comparée à la maquette

  2. 2Montrer

    La sortie, pas « c’est fini »

  3. 3Un regard neuf

    Un sous-agent relit le diff avec un contexte vierge

Boris ChernySon estimation : un moyen de vérifier son travail rend le résultat deux à trois fois meilleur.

Chaque revue le charge

CLAUDE.md

  • La stack et les conventions
  • Les objectifs et les non-objectifs
  • Court, renvoie vers d’autres docs

Le relecteur signale le code qui enfreint une convention, et un changement qui rend une ligne obsolète

et

Les code owners l’écrivent

REVIEW.md

  • À quoi ressemble un échec ici : une doc qui ment, une config qui route mal
  • Un plafond de nits
  • Les chemins à ignorer
  • Un fichier et une ligne comme preuve, pas une supposition tirée d’un nom
  • Un résumé qui commence par un décompte, et dit clairement quand il n’y a rien à corriger

Vérifié à part : le relecteur le suit-il ?

La preuve avant la revue, puis les deux fichiers où atterrit une remarque répétée. Les lignes de REVIEW.md sont la description qu’en donne l’article.

Le relecteur vote avant de commenter

Chaque pull request reçoit une revue de Claude avant qu’une personne la regarde. Elle lit le diff au regard de tout le dépôt et de l’intention annoncée de la PR, et se demande si le changement résout son problème, s’intègre au système, ou casse autre chose. Sur un correctif de bug, elle cherche la cause racine.

Les remarques sont vérifiées avant que quiconque les voie. Plusieurs agents cherchent des bugs en même temps. Un groupe distinct vote sur chaque remarque, et elle n’est publiée que si assez d’entre eux s’accordent à dire qu’elle est réelle. Les remarques qui ne portent que sur le style, les diagnostics ou le nettoyage sont écartées ; l’équipe a d’abord testé ces filtres en A/B sur ses propres PR. Ce qui reste arrive en commentaires en ligne, triés par gravité, chacun étiqueté Important, Nit ou Pre-existing, pour qu’un vieux bug n’ait pas l’air d’être la faute de l’auteur.

Au lancement de la research preview, la part des PR internes recevant des commentaires de revue substantiels est passée de 16 % à 54 %. La plupart des PR de plus de 1 000 lignes reçoivent des remarques, et la plupart des petites reviennent sans rien. Les admins règlent chaque dépôt sur Quick, Standard ou Deep.

Chaque remarque doit recevoir une réponse : la corriger, ou résoudre le fil avec une raison. Une revue de sécurité distincte fonctionne de la même façon, et une remarque ouverte de l’une ou de l’autre bloque le merge. La CI bloque aussi, avec des dizaines de contrôles sur une pull request typique de la CLI. Le modèle de PR demande comment le changement a été testé et comment l’annuler. Claude peut le remplir, mais c’est la personne qui a demandé le changement qui le valide.

  1. 1Chercher

    Plusieurs agents cherchent des bugs en même temps

  2. 2Voter

    Publiée seulement si assez de votants la jugent réelle

  3. 3Filtrer

    Style, diagnostics et nettoyage écartés

  4. 4Publier

    ImportantNitPre-existing

    En ligne, triées par gravité

PR internes avec des commentaires de revue substantiels

Avant la research preview16 %

Avec Code Review54 %

Chaque remarqueCorrigée, ou résolue avec une raison. Une remarque ouverte de cette revue ou de la revue de sécurité bloque le merge.

Les carrés relèvent du schéma : l’article ne donne aucun chiffre par étape. Les deux barres sont à l’échelle sur un axe de 0 à 100 %.

C’est le changement qui fixe le niveau, pas l’auteur

Une correction de doc et un changement de l’auto-updater ne portent pas le même risque, alors ils n’ont pas droit à la même revue. L’article décrit trois niveaux :

  • Faible : docs, textes, fonctionnalités internes, ajouts derrière un flag. Aucune approbation humaine une fois la revue automatique et les contrôles de sécurité au vert.
  • Moyen : les changements produit ordinaires, et les zones sensibles comme le cache, l’auto-updater ou les prompts système. Une personne.
  • Élevé : le code le plus risqué, plus un petit ensemble de chemins qui en exigent toujours deux. Deux personnes.

Un classifieur lit le changement et choisit le niveau. Un second classifieur se demande si ce changement précis a besoin d’une personne même quand son niveau dit le contraire. Les chemins que les owners déclarent sensibles, et tout fichier de workflow CI, exigent toujours une personne.

Ce sont les règles autour du tableau qui le font tenir. Seuls les auteurs inscrits sur la liste de confiance du dépôt ont droit aux chemins allégés ; tous les autres ont besoin d’une deuxième personne. L’approbation d’un agent ne compte jamais comme celle d’une personne. La personne qui a lancé une PR écrite par un agent compte parmi ses relecteurs requis, comme si elle avait tapé le code. Et une approbation couvre un seul commit : un push d’agent, ou un merge résolu à la main, en exige une nouvelle.

Faible

Aucune personne

une fois la revue automatique et les contrôles de sécurité au vert

Docs, textes, fonctionnalités internes, ajouts derrière un flag

Moyen

Une personne

Changements produit ordinaires, et zones sensibles : cache, auto-updater, prompts système

Élevé

Deux personnes

Le code le plus risqué, et un petit ensemble de chemins qui en exigent toujours deux

Qui fixe le niveauLe changement, lu par un classifieur. Un second demande s’il faut quand même une personne.

Toujours une personneLes chemins que les owners déclarent sensibles, et tout fichier de workflow CI

L’approbation d’un agentNe remplace jamais celle d’une personne

Une approbation couvreUn commit. Un push d’agent ou un merge résolu à la main en exige une nouvelle.

ResponsableSur une PR écrite par un agent, la personne qui l’a lancée fait partie des relecteurs requis.

Le tableau des niveaux de l’article, puis les règles autour. Seuls les auteurs inscrits sur la liste de confiance d’un dépôt ont droit aux chemins allégés.

Les incidents servent de jeu de test

L’équipe a construit le jeu de test du relecteur à partir de vraies pannes. Elle a rassemblé d’anciennes PR qui avaient causé des incidents, avec leurs correctifs et leurs reverts, et fait confirmer chaque bug et son emplacement par des ingénieurs qui connaissent ce code. Le relecteur tourne contre ce jeu tous les jours. Chaque nouvel incident ajoute un cas, et chaque changement des prompts, des outils ou du modèle du relecteur est noté sur l’ensemble.

Attraper plus de bugs est facile si l’on accepte de signaler des non-bugs, alors l’équipe mesure aussi le bruit. Chaque commentaire est classé selon ce qu’en a fait la personne sur la PR : elle l’a corrigé, a dit qu’il était faux, a dit que le comportement était voulu, ou a jugé que ça n’avait pas d’importance. L’équipe fait aussi tourner le relecteur sur des PR connues pour être saines, et compte les signalements qui auraient poussé quelqu’un à faire un changement nuisible. La priorité est écrite noir sur blanc : les vrais bugs d’abord, moins de tours de revue ensuite.

Le jeu grandit

  1. Incident ou revertUn changement qui a cassé quelque chose
  2. Vérifié par des expertsDes ingénieurs qui connaissent le code confirment le bug et son emplacement
  3. Ajouté au jeuUn cas par incident

Chaque cas, chaque jour

Le relecteur change

  1. Changer le relecteurSes prompts, ses outils ou son modèle
  2. Éval quotidienneNotée sur chaque cas
  3. Le score monte ?On garde. Sinon, on jette.

Bruitcorrigéjugé fauxvoulusans importance

PrioritéLes vrais bugs d’abord, moins de tours de revue ensuite. Par écrit.

Les incidents alimentent le jeu, le jeu note chaque changement du relecteur, et ce que les gens font des commentaires tient le bruit en respect.

La revue doit converger

Le bruit coûte plus cher quand l’auteur est un agent. Une personne balaie un nit en quelques secondes. Un agent le corrige, ce qui veut dire un commit de plus et un tour de revue de plus. Un agent auteur et un agent relecteur peuvent s’occuper l’un l’autre indéfiniment : une pull request de la CLI a enchaîné plus de cinquante tours pendant une nuit avant que son auteur l’arrête.

Quand l’équipe a lancé git blame sur ce que le relecteur signalait sans arrêt, environ 59 % concernaient du code présent depuis le premier passage du relecteur. Il ne trouvait pas de nouveaux bugs. Il trouvait quelques vieux bugs de plus à chaque tour. L’équipe avait elle-même aggravé les choses, en lançant plusieurs tours par défaut parce que chaque passage attrape quelque chose de nouveau.

Alors elle a changé la re-revue :

  1. Un plafond de tours. Après trois tours, le relecteur demande à l’auteur de prendre du recul et de reconsidérer l’approche.
  2. Une re-revue limitée au diff après les premiers passages.
  3. Signaler la classe de bug, pour que l’auteur corrige chaque occurrence, pas une seule ligne.
  4. Pas de répétition des remarques déjà publiées.

Les vieux bugs sont toujours chassés, simplement pas sur votre PR : des agents de revue tournent aussi chaque nuit sur le code existant. Après le changement, les PR validées après un seul tour de revue et de correction sont passées de 65 % à 78 %, les PR nécessitant cinq tours ou plus sont tombées de 8,9 % à 1,5 %, et le nombre moyen de revues avant validation est tombé de 2,08 à 1,32.

  1. 01Un plafond de tours

    Après trois tours, prendre du recul et repenser l’approche

  2. 02Le diff seul

    Après les premiers passages, relire seulement le nouveau diff

  3. 03La classe de bug

    Pour que l’auteur corrige chaque occurrence, pas une ligne

  4. 04Pas de répétition

    Une remarque déjà publiée ne l’est pas une seconde fois

Validées après un tour de revue et de correction

Avant65 %

Après78 %

Cinq tours ou plus

Avant8,9 %

Après1,5 %

Revues moyennes avant validation

Avant2,08

Après1,32

Une nuitUne pull request de la CLI a enchaîné plus de cinquante tours avant que son auteur l’arrête.

Les quatre changements, puis les chiffres internes de l’équipe avant et après. Chaque paire de barres est à l’échelle de sa plus grande valeur.

Les humains gardent cinq tâches

Sortir un ingénieur senior d’un travail de fond pour attraper une erreur de routine coûte bien plus cher qu’une revue automatique. Alors les humains gardent les tâches que seuls des humains peuvent faire :

  • Décider s’il faut le construire : la direction, le goût et le périmètre. Une équipe qui a déclaré son goulot de revue résolu garde quand même une revue humaine pour les changements venus d’en dehors de l’équipe, pour que quelqu’un se demande si le changement doit exister.
  • Relire le code risqué, comme la facturation, l’auto-updater et les workflows CI.
  • Relire l’architecture qui pose un modèle que d’autres copieront.
  • Lire les preuves : la sortie des tests, la commande lancée et ce qu’elle a renvoyé, une capture d’écran, les remarques du relecteur.
  • Répondre du résultat. Une personne est responsable de chaque changement mis en production, peu importe qui l’a tapé.

La tâche des preuves s’accompagne d’une règle à voler : « Si vous ne savez pas dire ce que les contrôles rateraient, demandez une vraie revue plutôt qu’une approbation rapide. »

  1. S’il faut le construireDirection, goût et périmètre
  2. Le code risquéFacturation, auto-updater, workflows CI
  3. L’architectureLes choix qui posent un modèle que d’autres copient
  4. Les preuvesSortie des tests, la commande et ce qu’elle a renvoyé, une capture, les remarques
  5. Le résultatUne personne répond de chaque changement mis en production, peu importe qui l’a tapé

La règleSi vous ne savez pas dire ce que les contrôles rateraient, demandez une vraie revue plutôt qu’une approbation rapide.

Ce qui reste aux humains une fois la lecture de routine passée aux machines, dans l’ordre de l’article.

Qui le merge en répond

Le deuxième rôle de la revue était de diffuser le contexte. Lire le diff d’un collègue, c’est comme ça qu’on apprend le code. L’équipe n’a pas de remplacement formel, et dit que personne ne garde en tête un modèle complet de Claude Code, ni n’en a besoin. Quand on a besoin d’une partie du code, on demande à Claude une explication de cette tranche précise. Ça prend quelques minutes et ça correspond au code tel qu’il est aujourd’hui. Un changement de texte d’une ligne n’apprend presque rien. Une explication du module qu’on s’apprête à modifier en apprend beaucoup.

La responsabilité fonctionne de la même façon. Si vous mergez un changement petit ou moyen et qu’il casse, c’est généralement vous qui le réparez. Ça ne tourne pas mal parce que les changements sont petits, que les flags, les reverts et les déploiements progressifs annulent la plupart des erreurs en quelques minutes, que le rayon d’impact fixe la barre, que les régressions apparaissent vite dans la télémétrie et l’usage interne, et que les revues d’incident examinent le système, pas la personne.

Un code bon marché rend aussi bon marché le changement de cap. Quand quelqu’un dans le canal pointe une décision antérieure ou une voie plus simple, l’auteur ferme ou remanie la PR, et ce n’est pas vécu comme une perte. L’astuce, c’est de le soulever tôt dans le fil, pas en commentaire bloquant sur une PR terminée.

Apprendre le code, avant

Lire les diffs

Un changement de texte d’une ligne n’apprend presque rien

vs

Apprendre le code, maintenant

Demander une explication

Exactement la tranche que vous allez modifier, en quelques minutes, telle qu’elle est aujourd’hui

Ça marche parce quepetits changementstout est réversiblele rayon d’impact fixe la barreles régressions remontent vitepas de reproches

Changer de capLe soulever tôt dans le fil, pas en commentaire bloquant sur une PR terminée.

Un diff où une ligne a changé, à côté d’une explication de la partie que vous allez toucher.

À côté de ma propre boucle

Ma boucle est décrite sur Comment je travaille avec l’IA : d’abord une issue, un agent construit sur sa propre branche, il prouve que le changement fonctionne, un modèle d’un autre fournisseur donne un second avis, et une pull request ferme le tout. Deux de mes règles là-bas disent la même chose que cet article. « Vérifier ce que le modèle a produit, pas ce qu’il dit avoir fait », c’est leur « montrer le résultat au lieu de dire que c’est fini ». « Une relecture vide n’est pas une validation », c’est leur REVIEW.md qui demande un résumé disant clairement quand il n’y a rien à corriger.

Mon pipeline Forge plafonne déjà les tours plus durement qu’eux. Un problème bloquant signalé par son relecteur a droit à une correction de plus, puis la pull request s’ouvre. C’est dans la note sur OpenShell.

La différence, c’est la dernière étape. Sur cette page, chaque changement finit en pull request que je lis et que je merge, et dans ma note sur l’usine logicielle, la partie lente de mon installation, c’est ma file de revue. Leur tableau des niveaux vise exactement ça : une correction de doc n’a besoin de personne une fois les contrôles au vert, et le temps d’une personne va à la facturation, à la CI et à l’auto-updater.

La preuve d’abord

L’équipeClaude montre la sortie : tests, build, capture

MoiBuild et tests, captures dans un vrai navigateur à 320 px et sur desktop

Revue IA

L’équipeDes agents Claude cherchent, votent, puis publient par gravité

MoiUn modèle d’un autre fournisseur relit le changement

Rien trouvé

L’équipeLe résumé le dit clairement, avec un décompte

MoiUne relecture vide n’est pas une validation

Tours

L’équipeTrois, puis on repense l’approche

MoiForge : une correction de plus après un problème bloquant

Qui approuve

L’équipeLe changement fixe le niveau : zéro, une ou deux personnes

MoiChaque pull request, moi

Ma fileC’est sur la dernière ligne qu’elle s’accumule. Le tableau des niveaux est la pièce qui la vise.

Leurs couches à côté de ma boucle telle qu’elle est écrite sur /fr/ia.html. La ligne surlignée est celle qui diffère.

Essayez

L’article se termine par une checklist, et l’essentiel marche avec des outils que vous avez déjà :

  • Avant la PR : donnez à votre agent des contrôles qu’il peut exécuter, listés dans un CLAUDE.md court, plus des hooks pour les formateurs et les linters. Lancez /code-review et /security-review en local, ou un sous-agent à contexte neuf. Commencez un REVIEW.md et déplacez-y les commentaires qui reviennent.
  • Sur chaque PR : exigez la CI, ajoutez des sections Tests, Risques et Comment annuler au modèle de PR, mettez un relecteur IA sur un seul dépôt et ajustez REVIEW.md pendant quelques semaines avant d’élargir, et exigez que chaque fil de revue soit résolu. Plafonnez les tours, et ne relisez que le nouveau diff après les premiers.
  • Approbation : écrivez des niveaux de risque fixés par le changement, commencez strict et assouplissez avec des preuves. Utilisez CODEOWNERS et la protection de branche pour que l’authentification, la facturation, la CI, les workflows de release et les installeurs exigent toujours une personne. Ne laissez jamais l’approbation d’un bot remplir une place humaine, et invalidez les approbations à chaque nouveau commit.
  • Après le merge : une merge queue, des feature flags, l’usage interne d’abord, des déploiements progressifs et un retour arrière en une étape. Transformez les incidents et les reverts en jeu d’éval, et mesurez le temps humain avec les reverts comme garde-fou.
  1. 1Avant la PR

    • Des contrôles exécutables dans un CLAUDE.md court
    • Des hooks pour formateurs et linters
    • /code-review et /security-review en local
    • Un REVIEW.md pour les commentaires répétés
  2. 2Sur chaque PR

    • CI obligatoire
    • Tests, Risques et Comment annuler dans le modèle
    • Un relecteur IA sur un dépôt d’abord
    • Chaque fil résolu, tours plafonnés
  3. 3Approbation

    • Niveaux fixés par le changement, stricts d’abord
    • CODEOWNERS pour auth, facturation, CI, release, installeurs
    • Les approbations de bot ne comptent jamais
    • Invalidées à chaque nouveau commit
  4. 4Après le merge

    • Merge queue et feature flags
    • Usage interne d’abord, puis progressif
    • Retour arrière en une étape
    • Incidents et reverts comme éval

MesurerLe temps humain par changement, avec les reverts et les incidents comme garde-fou.

La checklist de la fin de l’article, raccourcie. L’ordre est le leur.

Pour aller plus loin :

Choisissez une pièce cette semaine, un REVIEW.md ou un plafond de tours, et dites-moi ce que ça change à votre file de revue.

Texte brut: claude-code-team-code-review.md · Flux Atom · Toutes les notes

Contact

Écrivez-moi.

b.bousnguar@gmail.com

Intégration SAP Commerce Cloud, MuleSoft et Salesforce · Nantes · FR / EN