# Dedoublonner Liste

> >

- **Type:** Skill
- **Install:** `agentstack add skill-hugrowth98-superfounder-os-dedoublonner-liste`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [hugrowth98](https://agentstack.voostack.com/s/hugrowth98)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [hugrowth98](https://github.com/hugrowth98)
- **Source:** https://github.com/hugrowth98/superfounder-os/tree/main/10_Skills/construire-liste/sous-skills/dedoublonner-liste

## Install

```sh
agentstack add skill-hugrowth98-superfounder-os-dedoublonner-liste
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

Deux sources sur la même cible se recouvrent à 30 ou 60 % : sans dédoublonnage, la même personne reçoit deux séquences, chaque doublon coûte un enrichissement, et un client en cours reçoit un message froid. On dédoublonne avant d'enrichir, après avoir fusionné, et avant d'envoyer.

## Ressources

- `{SKILL_BASE}/ressources/regles-dedup.md` : clés et normalisation, priorité des sources par colonne, croisement CRM, fichiers de référence (`--contre`), plafond par entreprise, journal des doublons.
- `{SKILL_BASE}/ressources/hygiene-liste.md` : la normalisation des colonnes qui rend les clés comparables.

## Méthode

1. Lisez chaque fichier, mappez ses colonnes vers `docs/conventions-gtm.md` section 8, comptez les lignes par fichier et par `source`.
2. Normalisez les clés : `linkedin_url` en `https://www.linkedin.com/in/` (minuscules, avec `www.`, sans paramètres ni barre finale), `email` en minuscules, `domaine` nu, `prenom` et `nom` sans accent ni majuscule, `entreprise` sans suffixe juridique.
3. Dédoublonnez les personnes : `linkedin_url` d'abord, puis `email`, puis `domaine` + `prenom` + `nom`. Les entreprises : `domaine`, puis `linkedin_entreprise_url`, puis `entreprise` normalisée. Un match sur `telephone` ou sur nom + titre + ville se montre à l'utilisateur avant de fusionner.
4. Fusionnez les colonnes des lignes en doublon : la valeur vérifiée la plus récente gagne, une cellule vide ne gagne jamais, LinkedIn gagne sur `titre` et `entreprise`, l'`email_statut` FullEnrich le plus fiable (`DELIVERABLE`, puis `HIGH_PROBABILITY`, puis `CATCH_ALL`) gagne sur tout autre email, `source` concatène avec `+`. Si les lignes portent un `score_icp`, la plus haute reste et le fichier se rescore ensuite.
5. Croisez avec HubSpot si branché (`--hubspot`, par `email`, puis par `domaine` au niveau entreprise) : chaque ligne reçoit `dans_crm`, `hubspot_contact_id`, `hubspot_entreprise_id` et `hubspot_lifecycle` ; `--exclure-crm` met `exclu = oui` sur ce qui est déjà dans HubSpot. Le script ne calcule aucune catégorie (client, affaire ouverte, churné, perdu) : les clients et les perdus s'exportent avec `crm lire --statut gagnes` et `crm lire --statut perdus` (les perdus de moins de 3 mois se filtrent sur `date_cloture`), et ces fichiers se passent en `--contre`. "Client" se définit par une affaire gagnée dans cet export, jamais par `hubspot_lifecycle`, qui s'affiche sans décider.
6. Croisez avec les fichiers de référence en `--contre` : le fichier `ne_plus_contacter` (bounces durs, désabonnés, "pas intéressé", `ne_plus_contacter = oui` écrit par `verifier-reponses`) et les dernières listes envoyées. Il n'y a pas de fenêtre de 90 jours automatique : la règle "pas recontacté avant 90 jours" se tient à la main, en passant les listes envoyées sur la période en `--contre`.
7. Appliquez le plafond par entreprise : `--max-par-entreprise 5` (valeur par défaut) garde 5 personnes au plus par `domaine`, meilleur `score_icp` puis ligne la plus remplie, et marque les autres `exclu = oui`, `raison_exclusion = plafond 5 par entreprise`, journalisées.
8. Écrivez le fichier fusionné et le journal des doublons, puis rendez le rapport : lignes par source, doublons par clé, lignes dans HubSpot, lignes dans les fichiers de référence, plafond, lignes gardées, points d'hygiène vus (emails de test, entreprises "Test", libellés en double par casse). Posez la question des lignes `dans_crm = oui` sans affaire : on les exclut (`--exclure-crm`) ou on les garde annotées ? Next step : `qualifier-comptes` si le fichier n'a pas de `tier`, sinon `trouver-email` sur les lignes sans adresse, puis `nettoyer-verifier`.

## Exécution

| Étape | Verbe | Skill d'exécution | Entrée | Sortie |
|---|---|---|---|---|
| 1 à 4 et 7 | `dedoublonner` (dans la liste, `--max-par-entreprise 5`) | `dedoublonner` | un ou plusieurs CSV avec `linkedin_url`, `email`, `domaine`, `prenom`, `nom`, `entreprise`, `source`, `date_extraction` | un CSV fusionné (les doublons fusionnent, une ligne par fusion dans le journal), `exclu`, `raison_exclusion = plafond 5 par entreprise`, `source` concaténée |
| 5 | `dedoublonner --hubspot` (`--exclure-crm` pour exclure) et `lire_crm` | `dedoublonner`, `crm` (`lire --statut gagnes`, puis `perdus`) | `email`, `domaine` des lignes gardées ; les exports CRM en `--contre` | `dans_crm`, `hubspot_contact_id`, `hubspot_entreprise_id`, `hubspot_lifecycle` ; `exclu`, `raison_exclusion = deja dans HubSpot (contact)` ou `(entreprise)`, `= deja dans crm_clients-gagnes_.csv` |
| 6 | `dedoublonner --contre ` | `dedoublonner` | `linkedin_url`, `email`, `domaine` + `nom` | `exclu`, `raison_exclusion = deja dans ` |

Sortie : `dedoublonner__.csv` et `dedoublonner___doublons.csv` (journal). Si HubSpot n'est pas branché, l'étape 5 se limite aux fichiers de référence et le rapport le dit ; rien n'est deviné.

## Repères

| Repère | Valeur |
|---|---|
| Doublons attendus entre deux sources | 30 à 60 % |
| Clés personnes, dans l'ordre | `linkedin_url`, `email`, `domaine` + `prenom` + `nom` |
| Clés entreprises, dans l'ordre | `domaine`, `linkedin_entreprise_url`, `entreprise` normalisée |
| Perdu récent | moins de 3 mois depuis `date_cloture` de l'export `crm lire --statut perdus`, à passer en `--contre` |
| Fermé-perdu réapprochable | après 3 mois, signalé ; recommandé après 6 mois |
| Fenêtre "déjà contacté" | 90 jours, tenue à la main : les listes envoyées sur la période passent en `--contre` |
| Plafond par entreprise | 5 (`--max-par-entreprise`), dont 2 à 4 sur un tier A, 1 à 2 sur un B, 1 sur un C |
| Lots de recherche HubSpot | 100 emails par appel, 90 domaines |

## Template

```
Dédoublonnage : , 
Entrée :  ( ,  ) =  lignes
Doublons : linkedin_url , email , domaine + nom  =  fusionnés -> 
HubSpot (--hubspot) : dans_crm  ()
Référence (--contre) : clients gagnés , perdus , ne_plus_contacter , listes envoyées  =  exclus
Plafond 5 par entreprise :  exclus
Gardées :  sur     Journal : dedoublonner___doublons.csv
Hygiène : , , 
Question : les  dans_crm = oui sans affaire, on exclut ou on garde annotés ?
```

## Règles

- Le dédoublonnage passe avant tout enrichissement et avant tout envoi.
- Aucune ligne perdue sans trace : un doublon fusionne et laisse une ligne dans le journal, une exclusion porte `exclu = oui` et sa raison.
- Jamais de fusion sur le nom seul sans domaine, ni sur le titre.
- "Client" = une affaire gagnée dans l'export `crm lire --statut gagnes`. `hubspot_lifecycle` s'affiche, il ne décide pas.
- Une cellule remplie n'est écrasée que par une valeur plus récente et vérifiée.
- Les identifiants de pipelines et d'étapes HubSpot se relisent à chaque run : ils changent.
- Le garde-fou "ne pas recontacter" de l'outil d'envoi est un filet, jamais la méthode.
- Aucune écriture dans HubSpot pendant un dédoublonnage : on lit, on ne modifie pas.

## Exemples

- "J'ai trois exports, fusionne-les" : mapping des colonnes, normalisation, dédoublonnage par les trois clés, fusion des colonnes par priorité ; réponse attendue : un CSV, le décompte par source et par clé, le journal.
- "Qui dans cette liste est déjà dans mon CRM ?" : `--hubspot` par email et domaine, `crm lire` pour les gagnés et les perdus en `--contre` ; réponse attendue : le nombre de `dans_crm`, les clients et perdus exclus, la liste prospectable, la question sur les `dans_crm` sans affaire.
- "Enlève les gens que j'ai déjà contactés" : `--contre` avec les listes envoyées des 90 derniers jours et le fichier `ne_plus_contacter` ; réponse attendue : les lignes marquées `deja dans `, le reste prêt pour `trouver-email` puis `nettoyer-verifier`.

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [hugrowth98](https://github.com/hugrowth98)
- **Source:** [hugrowth98/superfounder-os](https://github.com/hugrowth98/superfounder-os)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-hugrowth98-superfounder-os-dedoublonner-liste
- Seller: https://agentstack.voostack.com/s/hugrowth98
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
