Хвосты (цифровой след)
Сервис проверки цифрового следа: находим где засветились твои данные и помогаем убрать. Next 15 + FastAPI + ARQ, стенд на cfru:3140. Результат скана только после подтверждения владения кодом.
готовS1 · Каркас6/7
Цель: Монорепо, compose, миграции, сид источников, CI, стенд на cfru по IP
готовS2 · Скан по бесплатным источникам8/8
Цель: 5 бесплатных коллекторов, ARQ-оркестрация, SSE, капча и лимиты
готовS3 · Подтверждение владения и результат7/8
Цель: Код на почту и телефон, блокировка перебора, экран скана с живой лентой, экран результата с пейволом
готовS4 · Лендинг и продвижение6/6
Цель: Все блоки лендинга, живой счётчик из базы, страницы источников, карта сайта, разметка, llms.txt
готовS5 · Кабинет6/6
Цель: Регистрация и вход, обзор, находки с фильтрами, мои данные, честное удаление аккаунта
готовS6 · Разбор находок моделью6/6
Цель: Промпты файлами, sanitize перед вызовом, сводка и приоритеты, учёт стоимости
готовS7 · Портрет вместо списка5/6
Цель: Человек вводит несколько данных и получает картину, как его видит интернет, а не перечень ссылок
готовS8 · Домен, админка, дорогой вид7/7
Цель: Подключить 24хвосты.рф, сделать админку с метриками, юрдокументы, блог для поиска и переделать посадочную под дорогой сервис
готовS9 · Мониторинг и подписка7/7
Цель: Планировщик, дедупликация, алерты, перепроверка убранного через 90 дней
В РАБОТЕS10 · Машина продвижения7/8
Цель: Страницы источников из базы, статьи, регионы, проверка попадания в ИИ-выдачу
планS11 · Админка0/0
Цель: Дашборд, пользователи, источники, очередь оператора, расходы, аудит-лог
задач нет
планS12 · Деньги и юрконтур0/0
Цель: ЮKassa, вебхуки, чеки, PDF-отчёт, документы, уведомление в РКН
задач нет
планS13 · Браузерный агент0/0
Цель: Playwright-runner, политика доменов, бюджет шагов, фолбэк с коллектора
задач нет
планS14 · Нагрузка и прод0/0
Цель: Кэш на сутки, бэкапы, мониторинг, тест на 100 сканов, домен и TLS
задач нет
Ворклог (места остановки)
Спринт 10, продвижение. Главное: страницы источников перестали быть одинаковыми. У каждого из семи свой разбор, написанный руками, и свои цифры из базы на каждый показ: доля проверок с находкой, какие поля раскрываются чаще, разбивка по серьёзности. По утечкам 84 процента проверок находят хоть что-то, такой статистики нет больше ни у кого, это наши собственные наблюдения. Добавлены два разбора, всего семь статей, карта сайта 22 ссылки, llms.txt 111 строк. Региональные страницы решено не делать: за ними нет региональных данных, отличались бы только названием города, а это дорвеи, за которые понижается весь домен. Тесты 104 зелёные.
→ Проверка попадания в ИИ-выдачу заблокирована индексацией: десять контрольных вопросов и методика записаны в docs, проверка руками сразу после открытия. Следующие спринты 11 админка и 13 браузерный агент. Спринт 12, деньги и юрконтур, отложен владельцем до закрытия остальных.
По замечаниям владельца: с экрана проверки не было пути назад в кабинет и не было видно, как дополнить свои данные. Возврат добавлен для вошедших, им же убрано предложение сохранить уже сохранённый результат. Дополнение проверки выведено в интерфейс: блок после находок, добавляешь телефон или ещё почту, найденное не перепроверяется. Проверено на живой базе: дополнение телефоном подняло только те источники, которым телефон нужен, три источника по нику повторно не запускались. Скан с дополнением обошёлся в 36 копеек.
→ Почта и оплата отложены до закрытия остальных спринтов по решению владельца. Следующий спринт 10, машина продвижения: региональные страницы, ещё разборы, проверка попадания в ИИ-выдачу по контрольным вопросам.
Закрыт спринт 9, наблюдение. Планировщик раз в час поднимает подписки с наступившим сроком и ставит обычный скан. Запись находки различает вставку и обновление, поэтому событие создаётся только про новое. Первый скан событий не даёт: иначе кабинет заводится и сразу приносит три десятка сообщений. Убранное и снова найденное получает статус вернулось и второе обращение рядом со старым, прежнее не переоткрывается. В кабинете вкладка Что изменилось со счётчиком непрочитанного и настройкой частоты. Отправка наружу отделена от создания события: события копятся, канал включится настройкой. Проверено на живой базе, 104 теста зелёные, тестовый аккаунт удалён без сирот. Отдельно сделаны фавиконка и иконка для телефона, логотип приведён к той же геометрии.
→ Спринт 9 закрыт не полностью честно: письмо о новой находке не уходит, потому что ящика на домене нет. Это же держит индексацию и боевое окружение. Следующий по роадмапу спринт 10, машина продвижения: региональные страницы, ещё статьи, проверка попадания в ИИ-выдачу по контрольным вопросам.
Домен 24хвосты.рф подключён с TLS, сайт готов под поиск и ИИ-выдачу. Nginx отдаёт домен в веб на 3140, для живого потока проверки буферизация выключена отдельной секцией. Сертификат до 3 ноября, продлевается сам. Адрес сайта уходит в сборку образа: карта сайта, robots и canonical пекутся на билде и в рантайме не меняются. Шапка и подвал стали общими компонентами вместо двенадцати копий, разборы наконец появились в навигации. Разметка организации, статей, крошек и инструкции собрана в lib/schema.ts и стоит на всех публичных страницах. Написаны две статьи под живые запросы: как проверить утечку и как запретить рекламные звонки, всего пять. У каждой короткие ответы в конце, они же уезжают в llms.txt для ассистентов. Три новые картинки в Kie на 9 рублей: две обложки и баннер для соцсетей, всего потрачено 18 из 30 рублей бюджета. Обложка в статье больше не занимает весь экран.
→ Индексация закрыта осознанно: боевое окружение принудительно требует подтверждения владения адресом, а отправлять код нечем. Порядок такой: почта или SMS, затем боевое окружение, затем robots. Дальше по роадмапу спринт 9, мониторинг и подписка: планировщик перепроверок, алерты о новых находках, перепроверка убранного через 90 дней.
Добавлены фирменный знак, превью отчёта и картинки. Лого сделал вектором, а не картинкой от модели: след из трёх штрихов, растворяющийся к точке, читается даже в фавиконе и перекрашивается под тему одной переменной. Превью отчёта на лендинге свёрстано интерфейсом, а не скриншотом: скриншот устаревает в день изменения экрана, а это живёт вместе с продуктом и остаётся чётким на любом экране. Цифры в превью из настоящей проверки, данные человека убраны. Через Kie сгенерированы три обложки для блога в тёмном стиле с янтарными акцентами (база рассыпается в частицы, тающий цифровой след, портрет из точек данных): 18 кредитов, примерно 9 рублей из выделенных 30. Картинки пришли по 2 МБ, что убило бы скорость загрузки, поэтому сжаты в webp: 2012 КБ стали 121 КБ, суммарно 300 КБ на три обложки. Стоковых иллюстраций намеренно нет: в теме приватности они удешевляют.
→ Домен 24хвосты.рф проверен трижды, включая RDAP и публичные резолверы: в зоне .рф его нет, NS у регистратора не прописаны. Нужно действие владельца в панели регистратора: A-запись на 80.90.184.203. Как появится, поднимаю TLS и переключаю окружение в боевое.
Сделан весь список владельца, кроме домена. Посадочная переделана под дорогой вид: тёмная тема, глубина подсветкой и сеткой, оживающие счётчики, приподнимающиеся карточки. По замечанию владельца убрал с лендинга технические названия сборщиков, теперь там четыре понятных направления. Собрана админка: себестоимость проверки, расходы по провайдерам, воронка, статистика источников, люди. Написаны юридические документы под наш сервис (политика, согласие на обработку и на действия от имени человека, оферта) с честной пометкой о черновике до проверки юристом. Запущен блог: три разбора под реальные запросы, с коротким ответом первым абзацем и разметкой для поиска и для ИИ-ответов. Карта сайта выросла до 18 страниц. 92 теста зелёные.
→ Домен 24хвосты.рф ждёт делегирования: как появятся NS, поднимаю TLS и переключаю окружение в боевое. Дальше по решению владельца: поиск по фото, HIBP (даст международный слой, но две из пяти найденных баз у него отсутствуют), почта и SMS для подтверждения, оплата и юрконтур.
Доделано по плану владельца: утечки теперь показываются по каждому сервису отдельно (название, дата, состав утёкшего), а не одной строкой «нашли в пяти базах». Формулировка честная: источник отдаёт состав полей общим списком по всем базам, поэтому пишем «суммарно по твоим утечкам», а не приписываем чужие поля конкретному сервису. Починен учёт расходов: раньше в журнал попадала только цена модели, теперь пишется и стоимость поиска, скан честно стоит 0.19 рубля. Сделан генератор готовых требований: прекратить рекламные звонки по части 1 статьи 18 закона о рекламе плюс отзыв согласия по 152-ФЗ, и отдельно заявление об удалении данных с сайта. Юридический каркас в шаблоне, модель к этим письмам не подпускается: выдуманная ссылка на статью хуже, чем отсутствие письма. Сделано дополнение проверки: добавил телефон к готовому скану, запустился только DaData по новому номеру, старое не перегонялось.
→ Оценка HIBP по фактам: у него 1022 базы, но из пяти найденных по нашей почте двух российских (Level.travel, dns-shop.ru) там нет. Пересечение около двух третей, HIBP добавит международный слой за 4.39 доллара в месяц, но не перевернёт картину.
Стенд передан владельцу на тестирование. Заведён аккаунт для входа, вход проверен. Порядок теста: заходить в кабинет и запускать проверку изнутри него, тогда она попадает в историю; с главной без входа проверка остаётся анонимной. Кода подтверждения на стенде не спрашивают, находки открываются сразу. Ограничение: три проверки в сутки с адреса, дальше 429. Портрет появляется отдельно, через 20-40 секунд после конца проверки, страница дорисовывает его сама.
→ Ждём обратную связь по портрету: что попало мимо, каких блоков не хватает, где формулировки врут. Дальше по решению владельца: поиск по фото (2-4 рубля за запрос, нужна граница с распознаванием лиц) и активность соцсетей. Платное (почта, SMS, оплата, юрконтур) отложено до готовности к проду.
Продукт развёрнут по описанию владельца: не список находок, а портрет, каким человека видит интернет. В одну проверку принимается несколько данных, подключены поиск Яндекса и справочники DaData, результат выдаётся разделами с выводами о профессии и занятиях. Поиск сразу показал силу: по одному нику нашлись профиль на Хабр Карьере, профиль в Тинькофф Инвестициях, форум, страница игрока в бадминтон, отзывы на Флампе, агрегатор соцпрофилей с именем и городом. Ничего из этого наш ник-скан не видел. Главная работа была не в подключении, а в фильтрации: без правила «искомое должно быть в ссылке или заголовке» поиск по адресу почты тащил страницы самого Gmail, мусора было больше половины. Отдельно поправил правило продукта: запрет на платные источники в бесплатном скане заменён бюджетом, потому что поиск стоит 15 копеек, а без него продукт не показывает главного. Скан с поиском 15 копеек, разбор портрета 2.6 копейки. 92 теста зелёные.
→ Осталось из описанного владельцем: поиск по фото (2-4 рубля за запрос, нужно решение по деньгам и по границе с распознаванием лиц) и определение активности соцсетей. Государственные реестры сознательно вычеркнуты: API ФССП закрыт, а долги человек про себя и так знает. Полный разбор источников в docs/11-istochniki-issledovanie.md.
Спринт 5 закрыт: кабинет работает. Регистрация и вход, обзор с историей проверок, находки с фильтрами, свои данные, выгрузка и удаление аккаунта. Главный критерий приёмки проверен запросом в базу: удаление аккаунта стирает всё по-настоящему, после него ноль строк во всех таблицах и старая кука мертва. Ради этого сессии хранятся в базе, а не только в подписанной куке. Два дефекта нашёл и починил: проверка, запущенная из кабинета, оставалась анонимной и не попадала в историю; и обзор показывал «пока чисто» с нулевым риском, пока последняя проверка ещё шла. Честно записал продуктовое расхождение: кабинет показывает все находки, а на экране проверки стоит пейвол, то есть пейвол обходится регистрацией. Городить ограничение, которое нельзя снять деньгами, до появления оплаты нечестно. 89 тестов зелёные.
→ Всё бесплатное по роадмапу сделано: каркас, скан, подтверждение владения, лендинг с продвижением, кабинет, разбор моделью. Дальше по плану идёт платное и требует решений владельца: движок удаления (нужна доменная почта и SMTP), российские источники (часть платная), оплата и юрконтур, SMS. Долги в docs/SCOPE-CUTS-LOG.md, среди важных: нет восстановления пароля, нет разделов удалений и мониторинга, CI не проверен без репозитория на GitHub.
Модель переведена с claude-sonnet-5 на deepseek/deepseek-v4-flash по решению владельца. Замер на одном и том же скане: 1.24 рубля против 0.03 рубля, то есть в сорок раз дешевле, качество текста сопоставимое. Разбор находок это пересказ готовой структуры человеческим языком, а не рассуждение, поэтому дорогая модель тут не нужна. Проверено живьём: тон на ты сохранился, длинных тире нет, находки по нику честно помечены как «может быть просто совпадение».
→ Начат спринт 5: кабинет. Регистрация, обзор, находки с фильтрами, мои данные, честное удаление аккаунта.
Спринт 6 закрыт: находки разбирает модель. Ключ OpenRouter и прокси взяты из Контент Завода, запросы идут через tinyproxy, иначе провайдер отказывает по региону. На экране результата появились сводка «Что это значит» и нумерованный порядок действий с оценками времени. Текст вышел живой: модель сама помечает необязательные действия и честно пишет, что находка по нику может быть не про тебя. Принципиально: цифру риска модель не считает, ей отдают готовое число, иначе одинаковые находки давали бы разный результат. Две вещи починил кодом, а не промптом: модель оборачивает JSON в markdown вопреки строгому формату (разбор теперь выдерживает три формы ответа), и ставит длинные тире вопреки прямому запрету (чистится валидатором). Первый прогон упал на разборе и отработал запасной текст, то есть страховка тоже проверена живьём. Стоимость разбора 1.24 рубля на скан при потолке 8. Вся отладка спринта стоила 4.16 рубля.
→ Осталось из бесплатного: спринт 5 (кабинет: регистрация, разделы, история проверок, честное удаление аккаунта). Платное отложено по решению владельца до готовности к проду: почта и SMS, платные источники, оплата, юрконтур. Долги спринта в docs/SCOPE-CUTS-LOG.md: нет кнопки переразобрать, объяснения по источникам хранятся, но не показываются, курс доллара зашит числом.
Спринт 4 закрыт. По решению владельца подтверждение владения на стенде выключено настройкой, чтобы не ждать доменной почты и SMS. Важно: в бою настройка игнорируется, выключить подтверждение при HVOSTY_ENV=prod нельзя даже случайно, иначе сервис превращается в пробивалку. Интерфейс тоже честен: пока код не спрашивают, форма его не обещает. Собран лендинг целиком: семь блоков, живой счётчик из базы (12 проверок, 48 следов, 5 источников), тарифы, вопросы с разметкой. Сделаны страницы источников, которые собираются из справочника сами, карта сайта из базы на 7 страниц, robots и индексация по окружению, llms.txt с живыми фактами для ИИ-ответов. Грабли спринта: страницы рендерились на этапе сборки образа, когда API ещё не поднят, и уезжали с нулями, а карта сайта без источников. Перевёл на рендер по запросу. Лендинг отдаётся за 39 мс. 75 тестов зелёные.
→ Всё бесплатное по плану сделано. Дальше по роадмапу спринт 5 (кабинет: регистрация, разделы, честное удаление аккаунта) и спринт 6 (разбор находок моделью через OpenRouter, это уже платно и требует ключа). Платные развилки ждут решения владельца: почта и SMTP, провайдер SMS, ключ OpenRouter, платные источники, репозиторий на GitHub для CI.
Спринт 3 закрыт: собран полный путь от главной до пейвола, проверен вживую в браузере. Человек вводит почту, видит живую ленту источников, вводит код и получает три находки, остальное за пейволом. Подтверждение владения работает как задумано: до кода API не отдаёт ни ссылок, ни значений, только счётчики. Код хранится хешем, три попытки, блокировка на десять минут, после неё не проходит и верный код. Риск считает код, а не модель. Три дефекта нашёл и починил по скриншотам: кнопка ломалась в две строки, форма кода ждала конца скана вместо параллельного ввода, и гонка в живом потоке, из-за которой быстрый источник навсегда оставался в состоянии «ждёт». Закрыт долг первого спринта: package-lock.json есть, сборка идёт через npm ci. 71 тест зелёный.
→ Развилка для владельца: нужен почтовый ящик и SMTP, иначе письма с кодом не уходят и наружу сервис открывать нельзя. Отдельно решение по SMS, это платно, без него проверка по телефону не завершается. Дальше спринт 4: полный лендинг со всеми блоками, живой счётчик убранных записей, каркас продвижения (карта сайта, разметка, llms.txt, страницы под источники). CI по-прежнему ждёт репозитория на GitHub.
Спринт 2 закрыт: скан работает на живых данных. Пять бесплатных источников, оркестрация через очередь, живой поток событий, ограничение по адресу, дедупликация. Скан по реальной почте: 14.6 секунды, критичная находка по утечкам (5 баз, среди них dns-shop.ru, Level.travel, Bookmate) и четыре аккаунта по нику. Себестоимость ноль. Три вещи, которые нашли и починили по факту, а не по догадке: User-Agent с кириллицей ронял вообще все запросы (заголовки HTTP только ascii, поймал тест); скан занимал 51 секунду вместо 20, вылечено частичным сбором по бюджету времени; и главное, ложные находки, коллектор по нику давал 30 несуществующих профилей, потому что часть сайтов отвечает 200 на любой ник. Прогнали калибровку заведомо несуществующим ником, разобрали каждый сайт поимённо, теперь по фейку ноль находок. Отдельно: находки по нику, выведенному из почты, помечаются как «возможно твой», выдавать их за подтверждённые нечестно. 57 тестов зелёные, линт чистый.
→ Спринт 3: подтверждение владения кодом на почту и телефон, блокировка перебора, экран сканирования с живой лентой и экран результата с пейволом. Сейчас ответ API уже разделён на «до кода» и «после кода», но кода никто не шлёт, поэтому находки закрыты всегда. Долги в docs/SCOPE-CUTS-LOG.md: капча без провайдера, нет package-lock.json у веба, названия источников в потоке событий техническими ключами. CI по-прежнему не проверен: репозитория на GitHub нет, gh не авторизован, нужен вход владельца.
Спринт 1 (каркас) собран и поднят на cfru: http://80.90.184.203:3140. Монорепо: packages/core (модели, настройки, логи), apps/api (FastAPI), apps/worker (ARQ), apps/web (Next 15, Tailwind 4, две темы), infra (compose, два Dockerfile, deploy.sh). Схема 14 таблиц одной миграцией, включая добавленную verification_codes под подтверждение владения и audit_log. Сид пяти бесплатных источников идемпотентный. 14 тестов зелёные. По дороге починили четыре реальные вещи: Alembic просил psycopg2 (перевели на asyncpg вместо второго драйвера), Tailwind 4.0.0 конфликтовал со свежим нативным модулем (синхронизировали на 4.3.3), логи uvicorn и arq шли мимо JSON и мимо затирания секретов (затянули в общий конвейер через ProcessorFormatter), healthcheck веба падал из-за резолва localhost в ::1 при сервере на IPv4 (адрес явный). Приёмка спринта закрыта по всем пунктам кроме CI.
→ Открыт один пункт приёмки: CI не проверен, репозиторий на GitHub не заведён, нужно решение владельца заводить ли и приватным ли. Дальше спринт 2: базовый класс коллектора, реестр, пять бесплатных коллекторов, оркестрация ARQ, SSE-канал, капча и лимиты. Долг из спринта 1 записан в docs/SCOPE-CUTS-LOG.md: нет package-lock.json у веба (уже обожглись на версиях), mypy в CI не блокирует, один образ на api и worker, бэкапов базы нет.
Разобрали пакет ТЗ из 10 документов, нашли 8 дыр и противоречий. Согласованы решения: название Хвосты; результат скана открывается только после подтверждения владения кодом, иначе сервис работает как пробивка по чужому номеру и противоречит собственному legal; бесплатный скан только на бесплатных источниках, платные API обсуждаются отдельно с ценами; текст через OpenRouter claude-sonnet-5 вместо прямого Anthropic (в ТЗ была несуществующая модель claude-sonnet-4-6); право на забвение в три ветки на выбор пользователя; деньги и юрконтур в конец; две темы переключателем, светлая на лендинге и тёмная в кабинете; SEO и GEO оба контура с первого дня; maigret не копируем из-за GPL-3.0. Собран репозиторий: CLAUDE.md, docs/DECISIONS.md с 12 решениями, docs/ACCEPTANCE.md с поведенческими критериями по всем спринтам, docs/10-seo-geo.md, переписаны 06-frontend (дизайн-система, токены, тон на ты) и 08-roadmap (14 спринтов). Роадмап заведён в дашборд, задачи расписаны по спринтам 0 и 1.
→ Ждём ок владельца на план спринта 0, дальше код каркаса. Открыто: домен (hvosty.ru занят, нужна альтернатива), состав платных API с ценами, проверка доступности российских источников перед спринтом 7.