Aller au contenu principal

Telemetrie

MailCopilot collecte une petite quantite de donnees diagnostiques et d'usage anonymes lorsque vous activez Envoyer un diagnostic et des donnees d'usage anonymes dans Parametres -> A propos. Cette page documente exactement ce qui est collecte et -- aussi important -- ce qui ne l'est jamais.

Ce que nous ne collectons jamais

En aucune circonstance, MailCopilot ne transmet :

  • Le contenu de vos messages (objet, corps, pieces jointes, brouillons)
  • Vos adresses e-mail ni celles de vos contacts
  • Les noms ou chemins de dossiers sur votre serveur IMAP
  • Les noms de fichiers de pieces jointes
  • Le texte de vos requetes de recherche
  • Le contenu des conversations ou de la memoire de l'assistant IA
  • Les hotes, ports ou identifiants de vos serveurs

Comment les donnees sont acheminees

Toute la telemetrie est envoyee a Sentry, notre plateforme de monitoring d'erreurs et de performance. Lorsque vous desactivez l'interrupteur dans Parametres, le pipeline est entierement contourne -- rien n'est envoye. Si vous activez la journalisation de debogage, les memes evenements apparaissent aussi dans votre main.log local pour que vous puissiez verifier exactement ce qui serait transmis.

Identifiant d'installation anonyme

Au premier demarrage, MailCopilot genere un UUID aleatoire et le stocke dans le fichier de configuration local. Ce UUID ne quitte jamais votre appareil. A la place, ce qui est transmis est un hash SHA-256 -- tronque a 16 caracteres hexadecimaux -- que nous appelons install_id_hash. Il est attache a chaque evenement de telemetrie en tant que Sentry user id pour que nous puissions repondre a des questions du type « combien d'installations distinctes utilisent la version X » ou « le crash Y affecte-t-il 1 ou 100 utilisateurs ». Ce hash est :

  • Anonyme -- il n'est pas derive de, ni correle avec, une adresse e-mail de compte, une empreinte d'appareil, une adresse IP ou un identifiant materiel.
  • Stable entre versions -- la meme installation conserve le meme hash apres une mise a jour automatique, de sorte que les metriques de retention survivent aux changements de version.
  • Non reversible -- il n'existe aucune correspondance de notre cote entre le hash et l'UUID ou votre appareil.
  • Supprime quand vous desactivez la telemetrie -- basculer l'interrupteur sur off efface immediatement l'identifiant cote client Sentry et arrete toute transmission ulterieure.

Nous utilisons cet identifiant comme un outil d'analyse web utiliserait un identifiant de visiteur anonyme : il nous permet de compter des installations distinctes plutot que des evenements totaux. Cette difference est la raison meme pour laquelle la telemetrie est utile -- sans elle, une installation bruyante ressemblerait a cent installations calmes.

Evenements

Cycle de vie de l'application

EvenementTypeAgregeTagsObjectif
app.session_startedeventnonversion, platform, theme, lang, accounts_count, install_id_hashUne fois au demarrage. Porte install_id_hash pour DAU/MAU.
app.session_endedhistogramnonreason, install_id_hashUne fois a l'arret normal. value_ms = duree de la session.
app.updatedeventnonfrom_version, to_versionUne fois apres l'installation d'une nouvelle version par auto-update.
app.startup_mshistogramnonaccounts_countTemps entre app.whenReady et la premiere BrowserWindow visible.

Synthese d'usage

EvenementTypeAgregeTagsObjectif
usage.session_summaryeventnonsearch_used, compose_used, snooze_used, read_later_used, ai_used, rules_used, templates_used, followup_used, install_id_hashBitmap de fin de session : quelles fonctionnalites ont ete utilisees au moins une fois ?

Mise en route

EvenementTypeAgregeTagsObjectif
onboarding.wizard_openedeventnonfirst_runL'utilisateur a ouvert l'assistant d'ajout de compte.
onboarding.method_selectedeventnonmethodChoix entre OAuth et IMAP/SMTP manuel.
onboarding.autoconfig_resulteventnonsuccess, providerSondage de l'autoconfiguration termine -- les parametres IMAP/SMTP ont-ils ete trouves ?
onboarding.connection_test_resulteventnonkind, success, failure_kindTest de connectivite IMAP ou SMTP termine.
onboarding.google_oauth_resulteventnonsuccess, failure_kindLe flux Google OAuth2 s'est termine.
onboarding.account_savedeventnonprovider, auth_typeIdentifiants du compte ecrits dans keytar/electron-store.
onboarding.first_headers_sync_completedhistogramnonprovider, folder_count_bucketTemps entre account_saved et la fin de la premiere synchro d'en-tetes (value_ms).
onboarding.first_message_openedeventnontime_since_sync_bucketL'utilisateur a ouvert son premier message apres la connexion.

Redaction

EvenementTypeAgregeTagsObjectif
compose.openedeventnonsource, has_draftFenetre de redaction ouverte ; suit le point d'entree.

File d'envoi

EvenementTypeAgregeTagsObjectif
send_queue.enqueuedeventnonscheduled, send_and_archive, has_attachments, body_size_bucketMessage sortant ajoute a send_queue (immediat ou planifie).
send_queue.senthistogramnonscheduledTemps entre l'ajout en file et la livraison reussie -- SMTP pour la plupart des comptes, Microsoft Graph pour Outlook (value_ms).
send_queue.failedeventnonfailure_kindTentative d'envoi definitivement echouee (la file a abandonne). Couvre les chemins SMTP et Microsoft Graph.
send_queue.retriedeventnonattempt_numberErreur d'envoi transitoire -- message reprogramme. Couvre les chemins SMTP et Microsoft Graph.

Avertissements de mauvais destinataire

EvenementTypeAgregeTagsObjectif
misdirection.promptedeventnonkindLa fenetre de redaction a affiche le dialogue d'avertissement.
misdirection.outcomeeventnonoutcome, kindL'utilisateur a repondu a l'avertissement.

Modeles

EvenementTypeAgregeTagsObjectif
template.appliedeventnonvar_countL'utilisateur a insere un modele dans la redaction.

Rappels de relance

EvenementTypeAgregeTagsObjectif
followup.createdeventnonduration_days_bucketUne relance a ete attachee a un message sortant.

Recherche

EvenementTypeAgregeTagsObjectif
search.duration_mshistogramnonscope, folder_role, account_count, sort, pagination, len_bucket, token_count, result_bucket, duration_bucket, zero_resultsLatence de bout en bout d'une recherche FTS (cote main, avant fusion distante). Sera remplace par search.completed en PR 2.
search.erroreventnonscope, kindLe gestionnaire de recherche a leve une erreur -- soit annulation utilisateur, soit echec reel.

Indexeur de corps

EvenementTypeAgregeTagsObjectif
body_indexer.tick.duration_mshistogramnonindexed, folders_scannedUn cycle complet de l'indexeur sur tous les dossiers.
body_indexer.coverage_pctgaugenontotal_messages, indexed_messagesFraction des messages en cache dont body_text est indexe.
body_indexer.backloggaugenon--Nombre absolu de messages en cache encore sans body_text.
body_indexer.folder_erroreventnonfolder_role, error_streak, backoff_msL'indexeur a rencontre une serie d'erreurs sur un dossier et est passe en backoff.

Maintenance de l'index plein-texte

EvenementTypeAgregeTagsObjectif
fts.optimize.duration_mshistogramnonsegments_before, segments_after, reductionPasse FTS5 optimize : duree et nombre de segments avant/apres.
fts.optimize.failedeventnonreasonFTS5 optimize a leve une erreur.

Synchronisation des en-tetes

EvenementTypeAgregeTagsObjectif
sync.headers.wall_mshistogramnonfolder_role, upsert_ms, other_ms, batches, rows, max_batch_msExecution complete de syncFolderHeaders -- separation upsert / autre pour le profilage.
sync.headers.coalescedeventnonfolder_roleUne tentative syncFolderHeaders doublee s'est rattachee a une execution en cours.

Instrumentation de l'ouverture des messages

EvenementTypeAgregeTagsObjectif
mail.openhistogramnoncache_hit_level, body_size_bucket, attachments_countLatence de bout en bout de l'ouverture d'un message, observee cote renderer (du clic jusqu'au rendu du corps). Le tag cache_hit_level indique le niveau de cache qui a servi le corps : memory, db, eml, imap ou imap_timeout.
net.message_details.wall_mshistogramnoncache_hit_levelTemps wall du gestionnaire IPC net:messageDetails cote processus principal. Isole la latence serveur du bruit du trajet aller-retour renderer vers main. Un echantillon par branche terminale (memory, db, eml, imap, imap_timeout).
imap.pool_queue_wait_mseventnonrequester, wait_ms_bucketTemps d'attente pour acquerir une connexion dans le pool IMAP par compte. Emis uniquement lorsque l'attente depasse 500 ms, afin que les tableaux de bord capturent la longue queue sans bruit des acquisitions rapides.

Rafraichissement des jetons OAuth IMAP

EvenementTypeAgregeTagsObjectif
imap.auth_refresh_attempteventnonproviderRafraichissement du jeton OAuth declenche par un echec d'authentification IMAP (XOAUTH2 / AUTHENTICATE).
imap.auth_refresh_successeventnonproviderLe rafraichissement a reussi -- la nouvelle tentative IMAP utilisera le jeton frais.
imap.auth_refresh_failureeventnonprovider, reasonLe rafraichissement a echoue -- l'erreur d'authentification d'origine remonte a l'appelant.
imap.auth_refresh_suppressedeventnonreasonLe cooldown par compte a empeche une tentative de rafraichissement, pour eviter des rafales de requetes /token quand un refresh token a ete revoque.
imap.idle_auth_refreshedeventnonproviderLa boucle IDLE s'est remise d'un echec d'authentification en cours de cycle via un rafraichissement in-loop -- la livraison push reprend sans le backoff de 60 min.
imap.auth_refresh_exhaustedeventnonprovider, consecutiveLa boucle IDLE a declenche le storm-brake : N rafraichissements consecutifs ont reussi cote fournisseur mais IMAP a continue a rejeter les jetons frais, donc on retombe sur le backoff d'authentification ordinaire.

Retention du cache

ÉvénementTypeAgrégéTagsObjectif
cache.eml_prunedeventnoncount_bucket, freed_bytes_bucketLa purge de retention a supprime des fichiers .eml plus anciens que la limite configuree. Les quantites et les tailles sont regroupees en intervalles — aucun chemin ni nombre exact n'est transmis.
cache.folder_index_disabledeventnoncount, roleUn dossier a ete exclu de la recherche plein-texte — automatiquement pour Junk/Spam/Corbeille a la premiere enregistrement, ou manuellement via le menu contextuel du dossier. role : spam, trash ou manual.

Signaux de securite du cache et de perte de donnees

EvenementTypeAgregeTagsObjectif
db.mass_delete_messageseventnonfolder_role, reason, deleted_count_bucket, watermark_preservedUn DELETE FROM messages a la portee du dossier a ete emis. Chaque site d'appel fournit une raison pour distinguer une regression qui efface un cache sain d'un bump UIDVALIDITY legitime.
imap.stale_wipe_guard_trippedeventnonfolder_role, providerLa protection mass-delete a refuse de purger le cache local du dossier parce que mailbox.exists est revenu non numerique. Un pic indique un probleme de fournisseur ou de connexion, pas une perte de donnees utilisateur.
db.shutdown_wal_checkpoint_mshistogramnonbusy, reclaimed_kb_bucket, okDuree du PRAGMA wal_checkpoint(TRUNCATE) execute avant la fermeture pour garantir que les ecritures committees mais non checkpointees survivent au redemarrage.

Garde stdio MCP (protection renderer-vers-RCE)

EvenementTypeAgregeTagsObjectif
mcp.stdio.connect_attemptedeventnonapproved_sourceLe transport stdio MCP est sur le point d'etre lance -- emis une fois par connect reussi apres les portes d'approbation et d'allowlist.
mcp.stdio.connect_blockedeventnonreasonLa connexion ou la sauvegarde stdio a ete refusee par la garde (not_approved, unapproved_command, forbidden_field, forbidden_env_key, env_disabled).
mcp.stdio.approval_grantedeventnonsource, scopeL'utilisateur a accorde l'approbation stdio MCP (activation globale ou par connexion) ; source distingue env vs native-confirm, scope distingue global vs par connexion.
mcp.stdio.env_sanitized_on_loadeventnoncount_bucketLa migration de configuration a retire les cles d'env loader-hook interdites des connexions MCP persistantes au chargement. Au plus une fois par lancement.

Audit des actions IA (barriere preview -> apply)

EvenementTypeAgregeTagsObjectif
ai.action.preview_createdeventnonkindUn outil MCP *_preview a enregistre une action mutante en attente du clic Apply de l'utilisateur.
ai.action.appliedeventnonkindUn outil MCP *_apply a execute avec succes une action mutante precedemment confirmee.
ai.action.rejectedeventnonkind, reasonUn appel *_apply a ete rejete a la porte de validation (preview manquant/expire, jeton manquant ou non concordant, kind mismatch, callback manquant ou rate limit).
ai.action.expiredeventnonkindUne action mutante en attente a expire sans que l'utilisateur ait clique Apply (TTL).
ai.action.apply_duration_mshistogramnonkindDuree d'un apply reussi -- combien de temps a pris la mutation sous-jacente (DB / IMAP / SMTP).

Garde de sortie reseau de l'IA

EvenementTypeAgregeTagsObjectif
ai.egress.blockedeventnontool_name, account_idUn appel d'outil sortant (par ex. WebSearch, WebFetch, un outil MCP externe generique) a ete refuse pendant que les donnees email de l'utilisateur etaient dans le perimetre -- soit filtre du toolset SDK, soit arrete par la garde runtime.
ai.egress.allowed_onceeventnontool_name, account_idL'utilisateur a accorde un consentement ponctuel pour la sortie reseau et l'IA en a use. Permet de distinguer "les utilisateurs court-circuitent regulierement" de "la garde tient, les tentatives sont surtout des injections".

Performance IPC

EvenementTypeAgregeTagsObjectif
ipc.slow_mshistogramoui (fenetre 10 s)channel, duration_bucketLe gestionnaire IPC a depasse le seuil « lent ».

Reactivite de l'UI

EvenementTypeAgregeTagsObjectif
ui.freeze.renderer_mshistogramoui (fenetre 10 s)duration_bucket, inflight_count, top_inflightLa boucle d'evenements du renderer a ete bloquee plus longtemps que le seuil de gel.
ui.freeze.main_mshistogramoui (fenetre 10 s)duration_bucket, inflight_count, top_inflightLa boucle d'evenements du processus main a ete bloquee (via le delay de perf_hooks).

Contact

Des questions ou des reserves sur ce qui est collecte ? Ouvrez une issue sur github.com/mailcopilot/mailcopilot ou contactez l'equipe directement via le formulaire de retour dans Parametres -> A propos.