Saltar al contenido principal

Telemetria

MailCopilot recopila una pequena cantidad de datos anonimos de diagnostico y de uso cuando activas Enviar diagnosticos y datos de uso anonimos en Ajustes -> Acerca de. Esta pagina documenta exactamente que se recopila y -- igual de importante -- que no se recopila nunca.

Lo que nunca recopilamos

En ningun caso MailCopilot transmite:

  • El texto de tus mensajes (asunto, cuerpo, adjuntos, borradores)
  • Tus direcciones de correo ni las de tus contactos
  • Nombres o rutas de carpetas en tu servidor IMAP
  • Nombres de archivos de adjuntos
  • El texto de tus consultas de busqueda
  • El contenido de las conversaciones del asistente IA o de su memoria
  • Hosts, puertos o credenciales de servidores

Como se enrutan los datos

Toda la telemetria se envia a Sentry, nuestra plataforma de monitorizacion de errores y rendimiento. Cuando desactivas el interruptor en Ajustes, la canalizacion se omite por completo: no se envia nada. Si activas el registro de depuracion, los mismos eventos aparecen ademas en tu archivo local main.log para que puedas inspeccionar exactamente que se transmitiria.

Identificador de instalacion anonimo

En el primer arranque, MailCopilot genera un UUID aleatorio y lo guarda en el archivo de configuracion local. Ese UUID nunca sale de tu dispositivo. Lo que se transmite en su lugar es un hash SHA-256 del mismo, truncado a 16 caracteres hexadecimales, al que llamamos install_id_hash. Se adjunta a cada evento de telemetria como Sentry user id para que podamos responder a preguntas como «cuantas instalaciones distintas usan la version X» o «el crash Y afecta a 1 usuario o a 100». El hash es:

  • Anonimo: no se deriva ni se correlaciona con un email de cuenta, una huella del dispositivo, una direccion IP ni un identificador de hardware.
  • Estable entre versiones: la misma instalacion conserva el mismo hash tras una autoactualizacion, de modo que las metricas de retencion sobreviven a los cambios de version.
  • No reversible: en nuestro lado no existe correspondencia entre el hash y el UUID original ni con tu dispositivo.
  • Se descarta al desactivar la telemetria: poner el interruptor de Ajustes en off limpia inmediatamente el identificador en el cliente Sentry y detiene cualquier transmision posterior.

Usamos este identificador como una herramienta de analitica web usaria un visitor id anonimo: nos permite contar instalaciones distintas en lugar de eventos totales. Esa diferencia es justamente lo que hace que la telemetria sea util: sin ella, una instalacion ruidosa pareceria igual a cien tranquilas.

Eventos

Ciclo de vida de la app

EventoTipoAgregadoEtiquetasProposito
app.session_startedeventnoversion, platform, theme, lang, accounts_count, install_id_hashUna vez por arranque. Lleva install_id_hash para DAU/MAU.
app.session_endedhistogramnoreason, install_id_hashUna vez al cierre normal. value_ms = duracion de la sesion.
app.updatedeventnofrom_version, to_versionUna vez tras instalar una nueva version por autoactualizacion.
app.startup_mshistogramnoaccounts_countTiempo desde app.whenReady hasta el primer BrowserWindow visible.

Resumen de uso

EventoTipoAgregadoEtiquetasProposito
usage.session_summaryeventnosearch_used, compose_used, snooze_used, read_later_used, ai_used, rules_used, templates_used, followup_used, install_id_hashMapa de bits al cierre: que funciones se usaron al menos una vez.

Onboarding

EventoTipoAgregadoEtiquetasProposito
onboarding.wizard_openedeventnofirst_runEl usuario abrio el flujo de anadir cuenta.
onboarding.method_selectedeventnomethodEl usuario eligio entre OAuth o IMAP/SMTP manual.
onboarding.autoconfig_resulteventnosuccess, providerSondeo de autoconfiguracion finalizado: ¿se encontraron los ajustes IMAP/SMTP?
onboarding.connection_test_resulteventnokind, success, failure_kindTest de conectividad IMAP o SMTP finalizado.
onboarding.google_oauth_resulteventnosuccess, failure_kindFlujo de Google OAuth2 finalizado.
onboarding.account_savedeventnoprovider, auth_typeCredenciales de la cuenta escritas en keytar/electron-store.
onboarding.first_headers_sync_completedhistogramnoprovider, folder_count_bucketTiempo desde account_saved hasta la primera sincronizacion completa de cabeceras (value_ms).
onboarding.first_message_openedeventnotime_since_sync_bucketEl usuario abrio su primer mensaje tras iniciar sesion.

Redaccion

EventoTipoAgregadoEtiquetasProposito
compose.openedeventnosource, has_draftVentana de redaccion abierta; rastrea el punto de entrada.

Cola de envio

EventoTipoAgregadoEtiquetasProposito
send_queue.enqueuedeventnoscheduled, send_and_archive, has_attachments, body_size_bucketMensaje saliente anadido a send_queue (inmediato o programado).
send_queue.senthistogramnoscheduledTiempo desde el encolado hasta la entrega exitosa: SMTP para la mayoria de cuentas, Microsoft Graph para Outlook (value_ms).
send_queue.failedeventnofailure_kindIntento de envio fallido de forma permanente (la cola se rinde). Cubre tanto SMTP como Microsoft Graph.
send_queue.retriedeventnoattempt_numberError de envio transitorio: mensaje reprogramado. Cubre tanto SMTP como Microsoft Graph.

Avisos de destinatario erroneo

EventoTipoAgregadoEtiquetasProposito
misdirection.promptedeventnokindRedaccion mostro el dialogo de advertencia.
misdirection.outcomeeventnooutcome, kindEl usuario respondio al aviso.

Plantillas

EventoTipoAgregadoEtiquetasProposito
template.appliedeventnovar_countEl usuario inserto una plantilla en la redaccion.

Recordatorios de seguimiento

EventoTipoAgregadoEtiquetasProposito
followup.createdeventnoduration_days_bucketSe asocio un recordatorio de seguimiento a un mensaje saliente.

Busqueda

EventoTipoAgregadoEtiquetasProposito
search.duration_mshistogramnoscope, folder_role, account_count, sort, pagination, len_bucket, token_count, result_bucket, duration_bucket, zero_resultsLatencia extremo a extremo de la busqueda FTS (lado main, antes del merge remoto). Se sustituira por search.completed en PR 2.
search.erroreventnoscope, kindEl manejador de busqueda lanzo: cancelacion del usuario o fallo real.

Indexador de cuerpos

EventoTipoAgregadoEtiquetasProposito
body_indexer.tick.duration_mshistogramnoindexed, folders_scannedUn tick completo del indexador a traves de todas las carpetas.
body_indexer.coverage_pctgaugenototal_messages, indexed_messagesFraccion de mensajes en cache cuyo body_text esta indexado.
body_indexer.backloggaugeno--Numero absoluto de mensajes en cache aun sin body_text.
body_indexer.folder_erroreventnofolder_role, error_streak, backoff_msEl indexador acumulo errores en una carpeta y entro en backoff.

Mantenimiento del indice de texto completo

EventoTipoAgregadoEtiquetasProposito
fts.optimize.duration_mshistogramnosegments_before, segments_after, reductionPasada FTS5 optimize: tiempo y numero de segmentos antes/despues.
fts.optimize.failedeventnoreasonFTS5 optimize lanzo un error.

Sincronizacion de cabeceras

EventoTipoAgregadoEtiquetasProposito
sync.headers.wall_mshistogramnofolder_role, upsert_ms, other_ms, batches, rows, max_batch_msEjecucion completa de syncFolderHeaders: separa upsert del resto para perfilar.
sync.headers.coalescedeventnofolder_roleUn intento duplicado de syncFolderHeaders se enganchó a una ejecución en curso.

Instrumentacion de apertura de mensajes

EventoTipoAgregadoEtiquetasProposito
mail.openhistogramnocache_hit_level, body_size_bucket, attachments_countLatencia de extremo a extremo de la apertura de un mensaje, observada desde el renderer (desde el clic hasta el renderizado del cuerpo). La etiqueta cache_hit_level indica que nivel de cache sirvio el cuerpo: memory, db, eml, imap o imap_timeout.
net.message_details.wall_mshistogramnocache_hit_levelTiempo de pared del manejador IPC net:messageDetails en el proceso principal. Aisla la latencia del servidor del ruido del viaje de ida y vuelta renderer a main. Una muestra por rama terminal (memory, db, eml, imap, imap_timeout).
imap.pool_queue_wait_mseventnorequester, wait_ms_bucketTiempo de espera para adquirir una conexion del pool IMAP por cuenta. Se emite solo cuando la espera supera 500 ms, para que los paneles capturen la cola larga sin ruido de adquisiciones rapidas.

Renovacion de tokens OAuth de IMAP

EventoTipoAgregadoEtiquetasProposito
imap.auth_refresh_attempteventnoproviderRenovacion del token OAuth disparada por un fallo de autenticacion IMAP (XOAUTH2 / AUTHENTICATE).
imap.auth_refresh_successeventnoproviderLa renovacion tuvo exito: el reintento IMAP usara el token recien obtenido.
imap.auth_refresh_failureeventnoprovider, reasonLa renovacion fallo: el error de autenticacion original se propaga al llamador.
imap.auth_refresh_suppressedeventnoreasonEl cooldown por cuenta suprimio un intento de renovacion para evitar tormentas de peticiones a /token cuando un refresh token ha sido revocado.
imap.idle_auth_refreshedeventnoproviderEl bucle IDLE se recupero de un fallo de autenticacion en mitad del ciclo via una renovacion in-loop: la entrega push siguio sin el backoff de 60 min.
imap.auth_refresh_exhaustedeventnoprovider, consecutiveEl bucle IDLE activo el storm-brake: N renovaciones consecutivas tuvieron exito en el proveedor pero IMAP siguio rechazando los tokens nuevos, asi que volvemos al backoff de autenticacion habitual.

Retencion del cache

EventoTipoAgregadoEtiquetasProposito
cache.eml_prunedeventnocount_bucket, freed_bytes_bucketLa purga de retencion elimino archivos .eml mas antiguos que el limite configurado. Los recuentos y los tamanos se transmiten solo como rangos — no se envian rutas ni numeros exactos.
cache.folder_index_disabledeventnocount, roleUna carpeta fue excluida de la busqueda de texto completo — automaticamente para Junk/Spam/Papelera en el primer registro, o manualmente mediante el menu contextual de carpeta. role: spam, trash o manual.

Senales de seguridad del cache y de perdida de datos

EventoTipoAgregadoEtiquetasProposito
db.mass_delete_messageseventnofolder_role, reason, deleted_count_bucket, watermark_preservedSe emitio un DELETE FROM messages a nivel de carpeta. Cada llamador suministra un motivo para distinguir una regresion que borra una cache sana de un bump UIDVALIDITY legitimo.
imap.stale_wipe_guard_trippedeventnofolder_role, providerLa proteccion mass-delete se nego a vaciar la cache local de la carpeta porque mailbox.exists no era numerico. Un pico aqui apunta a un problema del proveedor o de conexion, no a perdida real de datos.
db.shutdown_wal_checkpoint_mshistogramnobusy, reclaimed_kb_bucket, okDuracion del PRAGMA wal_checkpoint(TRUNCATE) que ejecutamos antes de salir, para que las escrituras committed-pero-no-checkpointed sobrevivan al reinicio.

Puerta stdio MCP (proteccion renderer-a-RCE)

EventoTipoAgregadoEtiquetasProposito
mcp.stdio.connect_attemptedeventnoapproved_sourceEl transporte stdio MCP esta a punto de arrancar: se emite una vez por connect exitoso tras pasar las puertas de aprobacion y allowlist.
mcp.stdio.connect_blockedeventnoreasonConexion o guardado stdio rechazado por la puerta (not_approved, unapproved_command, forbidden_field, forbidden_env_key, env_disabled).
mcp.stdio.approval_grantedeventnosource, scopeEl usuario concedio la aprobacion stdio MCP (activacion global o por conexion); source distingue env vs native-confirm, scope distingue global vs por conexion.
mcp.stdio.env_sanitized_on_loadeventnocount_bucketLa migracion de ajustes elimino claves de entorno loader-hook prohibidas de las conexiones MCP persistidas al cargar. A lo sumo una vez por arranque.

Auditoria de acciones de IA (barrera preview -> apply)

EventoTipoAgregadoEtiquetasProposito
ai.action.preview_createdeventnokindUna herramienta MCP *_preview registro una accion mutadora pendiente, esperando el clic Apply del usuario.
ai.action.appliedeventnokindUna herramienta MCP *_apply ejecuto con exito una accion mutadora confirmada previamente.
ai.action.rejectedeventnokind, reasonUna llamada *_apply fue rechazada en la puerta de validacion (preview ausente/expirado, token ausente o no coincidente, kind mismatch, callback ausente o rate limit).
ai.action.expiredeventnokindUna accion mutadora pendiente expiro sin que el usuario hiciera clic en Apply (TTL).
ai.action.apply_duration_mshistogramnokindDuracion de un apply exitoso: cuanto duro la mutacion subyacente (DB / IMAP / SMTP).

Puerta de salida (egress) de IA

EventoTipoAgregadoEtiquetasProposito
ai.egress.blockedeventnotool_name, account_idUna llamada a una herramienta de salida (por ejemplo, WebSearch, WebFetch, una herramienta MCP externa generica) fue rechazada mientras los datos de correo del usuario estaban en el alcance: filtrada del toolset del SDK o detenida por la puerta en runtime.
ai.egress.allowed_onceeventnotool_name, account_idEl usuario otorgo un consentimiento puntual para la salida y la IA lo uso. Permite distinguir «los usuarios anulan rutinariamente» de «la puerta aguanta, los intentos son sobre todo por inyeccion».

Rendimiento de IPC

EventoTipoAgregadoEtiquetasProposito
ipc.slow_mshistogramsi (ventana 10 s)channel, duration_bucketEl manejador IPC supero el umbral «lento».

Capacidad de respuesta de la UI

EventoTipoAgregadoEtiquetasProposito
ui.freeze.renderer_mshistogramsi (ventana 10 s)duration_bucket, inflight_count, top_inflightEl bucle de eventos del renderer estuvo bloqueado mas que el umbral de congelacion.
ui.freeze.main_mshistogramsi (ventana 10 s)duration_bucket, inflight_count, top_inflightEl bucle de eventos del proceso main estuvo bloqueado (medido con perf_hooks delay).

Contacto

¿Preguntas o dudas sobre lo que recopilamos? Abre una incidencia en github.com/mailcopilot/mailcopilot o contacta con el equipo directamente a traves del formulario de comentarios en Ajustes -> Acerca de.