Перейти к основному содержимому

Телеметрия

MailCopilot собирает небольшое количество анонимных диагностических данных и сведений об использовании, когда вы включаете переключатель Отправлять анонимную диагностику и сведения об использовании в Настройки → О программе. На этой странице описано ровно то, что собирается, и — что не менее важно — то, что не собирается никогда.

Что мы никогда не собираем

Ни при каких обстоятельствах MailCopilot не передаёт следующее:

  • Текст ваших писем (тема, тело, вложения, черновики)
  • Ваши email-адреса или адреса ваших контактов
  • Имена и пути папок на вашем IMAP-сервере
  • Имена файлов вложений
  • Текст поисковых запросов
  • Содержимое чатов с AI или AI-памяти
  • Хосты серверов, порты или учётные данные

Как маршрутизируются данные

Вся телеметрия отправляется в Sentry — нашу платформу мониторинга ошибок и производительности. Когда вы выключаете переключатель в Настройках, конвейер обходится полностью — ничего не отправляется. Если включить отладочное логирование, те же события дополнительно появляются в локальном main.log, чтобы вы могли просмотреть, что именно было бы отправлено.

Анонимный идентификатор инсталляции

При первом запуске MailCopilot генерирует случайный UUID и сохраняет его в локальном конфигурационном файле. Этот UUID никогда не покидает ваше устройство. Вместо него передаётся SHA-256 хеш — обрезанный до 16 шестнадцатеричных символов — который мы называем install_id_hash. Он прикрепляется к каждому телеметрическому событию как Sentry user id, чтобы мы могли отвечать на вопросы вроде «сколько уникальных установок работает на версии X» или «на сколько пользователей повлиял краш Y — на одного или сотню». Хеш:

  • Анонимен — не выводится из и не сопоставляется с email аккаунта, отпечатком устройства, IP-адресом или аппаратным идентификатором.
  • Стабилен между релизами — одна и та же установка сохраняет тот же хеш при автообновлении приложения, поэтому метрики удержания переживают апдейты версий.
  • Необратим — на нашей стороне нет способа сопоставить хеш обратно с UUID или вашим устройством.
  • Сбрасывается при выключении телеметрии — переключение тумблера в Настройках в положение «выкл» немедленно очищает идентификатор у Sentry-клиента и останавливает дальнейшие передачи.

Мы используем этот идентификатор так же, как веб-аналитика использует анонимный visitor id: он позволяет считать уникальные инсталляции, а не общее число событий. Эта разница и есть причина, по которой телеметрия вообще полезна — без неё одна шумная установка выглядела бы так же, как сотня тихих.

События

Жизненный цикл приложения

СобытиеТипАгрегируетсяТегиНазначение
app.session_startedeventнетversion, platform, theme, lang, accounts_count, install_id_hashОдин раз при запуске приложения. Несёт install_id_hash для DAU/MAU.
app.session_endedhistogramнетreason, install_id_hashОдин раз при штатном завершении. value_ms = длительность сессии.
app.updatedeventнетfrom_version, to_versionОдин раз после установки автообновлением новой версии.
app.startup_mshistogramнетaccounts_countВремя от app.whenReady до первого видимого BrowserWindow.

Сводка использования

СобытиеТипАгрегируетсяТегиНазначение
usage.session_summaryeventнетsearch_used, compose_used, snooze_used, read_later_used, ai_used, rules_used, templates_used, followup_used, install_id_hashБитовая карта «какие фичи хотя бы раз использовали в сессии», на её конец.

Онбординг

СобытиеТипАгрегируетсяТегиНазначение
onboarding.wizard_openedeventнетfirst_runПользователь открыл мастер добавления аккаунта.
onboarding.method_selectedeventнетmethodПользователь выбрал OAuth или ручную IMAP/SMTP-настройку.
onboarding.autoconfig_resulteventнетsuccess, providerЗавершилась автоконфигурация — нашли ли мы IMAP/SMTP-настройки?
onboarding.connection_test_resulteventнетkind, success, failure_kindЗавершился тест связи IMAP или SMTP.
onboarding.google_oauth_resulteventнетsuccess, failure_kindЗавершился Google OAuth2-поток.
onboarding.account_savedeventнетprovider, auth_typeУчётные данные аккаунта записаны в keytar/electron-store.
onboarding.first_headers_sync_completedhistogramнетprovider, folder_count_bucketВремя от account_saved до завершения первой синхронизации заголовков (value_ms).
onboarding.first_message_openedeventнетtime_since_sync_bucketПользователь открыл своё первое письмо после входа в аккаунт.

Написание

СобытиеТипАгрегируетсяТегиНазначение
compose.openedeventнетsource, has_draftОкно написания открыто; отслеживается точка входа.

Очередь отправки

СобытиеТипАгрегируетсяТегиНазначение
send_queue.enqueuedeventнетscheduled, send_and_archive, has_attachments, body_size_bucketИсходящее письмо добавлено в send_queue (немедленно или по расписанию).
send_queue.senthistogramнетscheduledВремя от постановки в очередь до успешной доставки — SMTP для большинства аккаунтов, Microsoft Graph для Outlook (value_ms).
send_queue.failedeventнетfailure_kindПопытка отправки окончательно провалилась (очередь сдалась). Покрывает оба пути: SMTP и Microsoft Graph.
send_queue.retriedeventнетattempt_numberВременная ошибка отправки — письмо переставлено в очередь. Покрывает оба пути: SMTP и Microsoft Graph.

Предупреждения о неверном получателе

СобытиеТипАгрегируетсяТегиНазначение
misdirection.promptedeventнетkindВ Compose показан диалог-предупреждение о возможной отправке не туда.
misdirection.outcomeeventнетoutcome, kindПользователь отреагировал на это предупреждение.

Шаблоны

СобытиеТипАгрегируетсяТегиНазначение
template.appliedeventнетvar_countПользователь вставил шаблон в окно написания.

Напоминания follow-up

СобытиеТипАгрегируетсяТегиНазначение
followup.createdeventнетduration_days_bucketК исходящему письму прикреплено follow-up-напоминание.

Поиск

СобытиеТипАгрегируетсяТегиНазначение
search.duration_mshistogramнетscope, folder_role, account_count, sort, pagination, len_bucket, token_count, result_bucket, duration_bucket, zero_resultsСквозная задержка FTS-поиска (на стороне main, до слияния с серверными результатами). Будет заменено на search.completed в PR 2.
search.erroreventнетscope, kindОбработчик поиска бросил исключение — пользователь отменил или реальный сбой.

Индексатор тел

СобытиеТипАгрегируетсяТегиНазначение
body_indexer.tick.duration_mshistogramнетindexed, folders_scannedОдин полный тик индексатора по всем папкам.
body_indexer.coverage_pctgaugeнетtotal_messages, indexed_messagesДоля кэшированных писем, у которых проиндексирован body_text.
body_indexer.backloggaugeнетАбсолютное число кэшированных писем, у которых ещё нет body_text.
body_indexer.folder_erroreventнетfolder_role, error_streak, backoff_msИндексатор столкнулся с серией ошибок по папке и ушёл на backoff.

Обслуживание полнотекстового индекса

СобытиеТипАгрегируетсяТегиНазначение
fts.optimize.duration_mshistogramнетsegments_before, segments_after, reductionПроход FTS5 optimize: время и количество сегментов до/после.
fts.optimize.failedeventнетreasonFTS5 optimize упал с ошибкой.

Синхронизация заголовков

СобытиеТипАгрегируетсяТегиНазначение
sync.headers.wall_mshistogramнетfolder_role, upsert_ms, other_ms, batches, rows, max_batch_msПолный прогон syncFolderHeaders — разделение upsert и прочего для профилирования.
sync.headers.coalescedeventнетfolder_roleПараллельная попытка syncFolderHeaders подцепилась к уже идущему прогону.

Инструментирование открытия писем

СобытиеТипАгрегируетсяТегиНазначение
mail.openhistogramнетcache_hit_level, body_size_bucket, attachments_countСквозная задержка открытия письма, наблюдаемая со стороны renderer (от клика до отрисовки тела). Тег cache_hit_level кодирует, из какого уровня кэша получено тело: memory, db, eml, imap или imap_timeout.
net.message_details.wall_mshistogramнетcache_hit_levelWalltime IPC-обработчика net:messageDetails на стороне основного процесса. Изолирует серверную латентность от шума round-trip renderer→main. Одна выборка на терминальный путь (memory, db, eml, imap, imap_timeout).
imap.pool_queue_wait_mseventнетrequester, wait_ms_bucketВремя ожидания получения соединения из per-account пула IMAP. Испускается только при ожидании свыше 500 мс, поэтому дашборды видят длинный хвост без шума от быстрых захватов.

Обновление OAuth-токенов IMAP

СобытиеТипАгрегируетсяТегиНазначение
imap.auth_refresh_attempteventнетproviderЗапущено обновление OAuth-токена в ответ на ошибку аутентификации IMAP (XOAUTH2 / AUTHENTICATE).
imap.auth_refresh_successeventнетproviderОбновление успешно — повтор IMAP-запроса пойдёт уже со свежим токеном.
imap.auth_refresh_failureeventнетprovider, reasonОбновление не удалось — исходная ошибка аутентификации поднимается выше.
imap.auth_refresh_suppressedeventнетreasonPer-account cooldown подавил попытку обновления, чтобы не штормить запросами /token, когда refresh-токен отозван.
imap.idle_auth_refreshedeventнетproviderЦикл IDLE восстановился после mid-cycle ошибки аутентификации через in-loop обновление токена — push-доставка вернулась без 60-минутного auth-backoff.
imap.auth_refresh_exhaustedeventнетprovider, consecutiveЦикл IDLE сработал на storm-brake — N подряд успешных обновлений на стороне провайдера, но IMAP всё равно отверг свежие токены, поэтому переходим к обычному auth-backoff.

Удержание кэша

СобытиеВидАгрегированТегиНазначение
cache.eml_prunedeventнетcount_bucket, freed_bytes_bucketПлановая очистка удалила файлы .eml старше настроенного срока хранения. Количества и объёмы передаются только в виде диапазонов — точные пути и числа не передаются.
cache.folder_index_disabledeventнетcount, roleПапка была исключена из полнотекстового поиска — автоматически для Junk/Spam/Trash при первой регистрации или вручную через контекстное меню папки. role: spam, trash или manual.

Сигналы безопасности кэша и потери данных

СобытиеТипАгрегируетсяТегиНазначение
db.mass_delete_messageseventнетfolder_role, reason, deleted_count_bucket, watermark_preservedВыполнен папочный DELETE FROM messages. Каждый call site сообщает причину, чтобы регрессию-«потеря кэша» можно было отличить от штатного UIDVALIDITY-bump.
imap.stale_wipe_guard_trippedeventнетfolder_role, providerЗащита от mass-delete отказала в очистке локального кэша папки, потому что mailbox.exists вернулся не-числом. Всплеск означает проблему провайдера/связи, а не реальную потерю данных.
db.shutdown_wal_checkpoint_mshistogramнетbusy, reclaimed_kb_bucket, okДлительность PRAGMA wal_checkpoint(TRUNCATE) перед закрытием — гарантирует, что закоммиченные, но не чекпойнтнутые записи переживут перезапуск.

Шлюз stdio MCP (защита renderer-to-RCE)

СобытиеТипАгрегируетсяТегиНазначение
mcp.stdio.connect_attemptedeventнетapproved_sourceТранспорт stdio MCP вот-вот будет запущен — фиксируется один раз на успешный connect после прохождения approval и allowlist гейтов.
mcp.stdio.connect_blockedeventнетreasonПодключение или сохранение stdio отклонено гейтом (not_approved, unapproved_command, forbidden_field, forbidden_env_key, env_disabled).
mcp.stdio.approval_grantedeventнетsource, scopeПользователь дал согласие на stdio MCP (глобальное включение или per-connection); source различает env vs native-confirm, scope — global vs per-connection.
mcp.stdio.env_sanitized_on_loadeventнетcount_bucketМиграция настроек удалила запрещённые loader-hook env-ключи из сохранённых MCP-подключений при загрузке. Срабатывает не более одного раза на запуск.

Аудит AI-действий (барьер preview → apply)

СобытиеТипАгрегируетсяТегиНазначение
ai.action.preview_createdeventнетkind*_preview MCP-инструмент зарегистрировал ожидающее мутирующее действие, ждущее клика «Apply».
ai.action.appliedeventнетkind*_apply MCP-инструмент успешно выполнил ранее подтверждённое мутирующее действие.
ai.action.rejectedeventнетkind, reasonВызов *_apply отклонён на гейте валидации (preview отсутствует/истёк, токен не совпал, kind mismatch, нет callback или превышен rate-limit).
ai.action.expiredeventнетkindОжидающее мутирующее действие истекло, не дождавшись клика Apply (TTL).
ai.action.apply_duration_mshistogramнетkindДлительность успешного apply — сколько занимает базовая мутация (DB / IMAP / SMTP).

Шлюз исходящего egress AI

СобытиеТипАгрегируетсяТегиНазначение
ai.egress.blockedeventнетtool_name, account_idВнешний egress-вызов (например, WebSearch, WebFetch, общий внешний MCP-тул) был отклонён, пока пользовательские email-данные находились в области видимости — либо отфильтрован из toolset SDK, либо остановлен runtime-гейтом.
ai.egress.allowed_onceeventнетtool_name, account_idПользователь дал одноразовое согласие на egress, и AI этим воспользовался. Помогает отделить «пользователи регулярно переопределяют» от «гейт держит, попытки в основном инъекционные».

Производительность IPC

СобытиеТипАгрегируетсяТегиНазначение
ipc.slow_mshistogramда (окно 10 с)channel, duration_bucketIPC-обработчик длился дольше порога «медленно».

Отзывчивость UI

СобытиеТипАгрегируетсяТегиНазначение
ui.freeze.renderer_mshistogramда (окно 10 с)duration_bucket, inflight_count, top_inflightЦикл событий renderer'а был заблокирован дольше порога заморозки.
ui.freeze.main_mshistogramда (окно 10 с)duration_bucket, inflight_count, top_inflightЦикл событий main-процесса был заблокирован (через perf_hooks delay).

Контакты

Вопросы или сомнения по поводу того, что мы собираем? Откройте issue на github.com/mailcopilot/mailcopilot или свяжитесь с командой напрямую через форму обратной связи в Настройки → О программе.