На что уходит время, когда продукты ведёт один человек: 698 коммитов за пять недель
Код по моей архитектуре пишет агент, и пишет быстро. Поэтому вопрос «как быстро ты пишешь код» для меня потерял смысл. Интереснее другой: на что уходит время, когда код больше не узкое место. Чтобы не отвечать по ощущениям, я взял историю коммитов с 20 августа по 25 сентября и разметил каждый коммит по тому, зачем он сделан.
Что посчитано
Пять продуктов, все уже работают у пользователей, плюс этот сайт. Считались коммиты основных веток, без слияний.
| Продукт | Что это | Коммитов |
|---|---|---|
| bazito | агрегатор объявлений из Telegram-каналов в 11 странах | 317 |
| AstraBrain | AI-астрология на настоящих эфемеридах, веб и Telegram, 10 языков | 154 |
| TZ Portal | конструктор ТЗ по 44-ФЗ и справочники закупок | 104 |
| Aviozo | travel-карта для пар и компаний: визы, билеты, горящие рейсы | 90 |
| Signage CMS | CMS музейной инсталляции на два экрана | 20 |
| этот сайт | статьи и страницы кейсов | 13 |
Всего 698 коммитов за 37 дней. Облачных сессий агента за тот же период было 92, и это не вся работа: часть шла локально.
Разметка ручная, одна метка на коммит, по его главной цели:
- данные: чтобы продукт говорил правду. Разбор цен, категории, география, справочники, даты;
- поиск и рост: индексация, редиректы, аналитика, воронка, переводы и посадочные под поиск, внешние статьи;
- эксплуатация: надёжность, память, стоимость, копии базы, сторожа, сборка и выкладка, разбор инцидентов;
- функции и интерфейс: новое для пользователя и правки экранов;
- записи: документы передачи, отчёты, список открытых задач;
- безопасность и право: RLS, ограничения частоты, закрытие роботов, правовые страницы.
| Тип работы | Коммитов | Доля |
|---|---|---|
| Данные | 173 | 24,8% |
| Поиск и рост | 165 | 23,6% |
| Эксплуатация | 137 | 19,6% |
| Функции и интерфейс | 94 | 13,5% |
| Записи | 80 | 11,5% |
| Безопасность и право | 49 | 7,0% |
Две оговорки. Коммит не час: однострочная правка и двухдневное расследование весят одинаково. И граница между ростом и функциями размыта: посадочная страница с живым калькулятором ушла в рост. Если отдать функциям половину роста, они вырастут до четверти с небольшим, не больше.
У каждого продукта свой перекос. bazito на 46% состоит из правок данных. У AstraBrain и TZ Portal около 40% ушло в поиск. У Aviozo больше всего эксплуатации, 28%. Функций больше половины только у Signage CMS, где за период собирали сцены новой инсталляции: 13 коммитов из 20.
Данные: продукт должен говорить правду
Это самая большая доля. В bazito на неё пришлось 145 коммитов из 317: цена, период, валюта, категория, город. Как проверяется каждая такая правка, я разбирал в статье про калибровку разбора цен. Здесь важно другое: этот поток не кончается. Объявления пишут люди, и каждый новый город, язык и привычка записи требуют своей правки, от казахского «пәтер» до черногорского «u Budvi».
В других продуктах данные ломаются тише. В AstraBrain у части страниц знаменитостей оказались неверные даты рождения, а значит, неверный знак Солнца у живого человека. Где дату удалось найти и вычитать, её записали, за один заход 67 дат. Страницы при этом остаются закрытыми, пока текст разбора не перепишут под верную карту. Где источник слабый, страницу закрыли от индексации, а не пересчитали на сомнительной дате.
В Aviozo похожий вопрос возник с визовыми страницами: какая дата стоит на странице, дата загрузки данных или дата проверки человеком. Это разные вещи, и выдавать одну за другую в разметке для поисковика нельзя.
Эксплуатация: поломки, которые молчат
Самые дорогие поломки периода не показали ни одной ошибки на экране.
В bazito пропуска в чаты переехали в базу, и функция, которая находит чат, стала возвращать объект двух разных форм. Сбор падал на первой же строке, ещё до чтения сообщений. В журнале это выглядело как единичная ошибка одного канала, а на деле таких строк было 18 172 за сутки от 77 чатов. Четверо суток 126 чатов из 179 не принесли ни одного сообщения, и приток упал примерно вчетверо. Чем лучше работал новый кэш, тем больше чатов он выключал.
В AstraBrain 11 сентября у провайдера модели закончился баланс, и генерация встала. Гороскопы за 11-е перезапустили вручную, а 10-е догнать было уже нельзя.
В TZ Portal за семь ночных часов 13 сентября на страницы кодов пришло 5 464 запроса к 5 253 разным адресам, две трети от SEO-роботов Semrush и Ahrefs. Каждый новый адрес означает рендер и запись в кэш на Vercel, то есть этот обход оплачивает владелец сайта. Роботов закрыли в robots.txt и отказом на nginx, до того как запрос доходит до Vercel.
Поэтому часть эксплуатации составляют сторожа, а не починки: сторож конвейера в bazito пишет владельцу, если цикл простаивает, а ночные копии базы у bazito и TZ Portal вывозятся с сервера.
Безопасность ломает то, что работало
49 коммитов, 7%. Меньше всех, но две истории этого периода хорошо показывают, почему такие правки нельзя выкатывать вслепую.
В AstraBrain на всех таблицах включили row-level security. Окно ожидания оплаты узнавало о платеже через подписку Supabase Realtime на платёжную таблицу, а Realtime подчиняется RLS. Подписка замолчала, и человек, который уже заплатил, оставался на экране ожидания. Доступ ему при этом выдавался, ломалась только автоматика окна. Выбор был такой: открыть анонимной роли таблицу с суммами и историей покупок или убрать причину. Ожидание перевели на опрос своего маршрута, который отдаёт наружу только флаг. Заодно выяснилось, что подписка была хуже опроса: она срабатывала и на запись о недоплате и закрывала экран как после успешной оплаты.
В Aviozo кнопка «История цены» показывала «данных пока мало» при 1 106 635 строках в таблице. Миграция применилась частично: таблица создалась, а отключение RLS для неё нет. При включённой RLS без политик API отдаёт ответ 200 и пустой список, а не ошибку. В документ передачи записан урок: пустой ответ не доказывает, что таблица пуста.
Выводы агента это гипотезы
Самая полезная привычка этих недель: не действовать по записанному выводу, пока его не перемерили. Агент пишет выводы уверенно, аудит тоже. Вот пять случаев за период, когда замер опроверг запись.
| Что было записано | Что показал замер |
|---|---|
| Пересборка bazito теряет 1333 вертикали | Потерь нет. На сервере лежала старая версия кода, которая молча съедала параметр, а текущий код даёт 1695 вертикалей вместо 618 |
| LCP мобильной главной TZ Portal 4,6 с | 1,97 с по медиане пяти прогонов. Порог 2,5 с пройден, день на оптимизацию не потрачен |
| На лендинге TZ Portal 70% отказов | 66 из 103 визитов оказались прямыми заходами роботов из США. По России отказов 18% |
| Гео-локаль в AstraBrain не нужна | Нужна. Английский стоит в браузере по умолчанию у людей, которые им не пользуются, и русский посетитель уезжал на /en |
| 1248 визовых страниц Aviozo проверены человеком | Проверены 18. У 1232 ссылка от робота, и дату загрузки нельзя выдавать за проверку |
В AstraBrain ошибочный вывод оставили в записях вместе с разбором, а не стёрли. Цена такого вывода в том, что по нему потом не делают нужную работу. В истории с пустой таблицей Aviozo версии трижды строились на предположении, что таблица видна такой, какая она есть. Всё решил счётчик, который вернул сам писатель данных.
Это и есть мой ответ на вопрос, который задают про код от ИИ: смотрю ли я, что он делает. Каждую строку я не читаю. Я смотрю на замеры: контрольную выборку, которая не должна измениться, счётчик из самого процесса, медиану нескольких прогонов.
Записи: сессии не помнят друг друга
80 коммитов, 11,5%, это документы: список открытых задач, документы передачи, инструкции для следующей сессии. Сессии агента идут параллельно и начинаются с нуля, и общая память у них одна: репозиторий.
Две из пяти историй в таблице выше связаны именно с этим. Гео-локаль в AstraBrain выкатила другая сессия, пока в записях стоял вывод, что она не нужна. Разметку визовых страниц в Aviozo в тот же день чинила параллельная сессия. В команде это решают стендапом, а у меня эту роль играет записанное состояние, которое сверяется с кодом.
Что из этого следует
Тому, кто нанимает: скорость написания кода больше не показатель. Показатель в том, сколько проверок стоит между кодом и пользователем и кто их ставит.
Фаундеру с MVP: 4–6 недель уходят на сборку до релиза. Эти пять недель почти целиком пришлись на время после релиза, потому что все пять продуктов уже работали. Новые функции заняли седьмую часть коммитов. Остальное ушло на то, чтобы работающий продукт говорил правду, не падал молча, находился в поиске и не открывал лишнего. Эту работу стоит закладывать в план с первого дня, а не после первого инцидента.
Разметка сделана вручную по сообщениям коммитов основных веток пяти продуктов и этого сайта с 20 августа по 25 сентября 2026 года, одна метка на коммит. Большую часть коммитов делает агент в моих сессиях, задачу ставлю и результат принимаю я. Числа примеров взяты из сообщений самих коммитов. Адреса серверов, ключи и названия каналов в статье не приводятся.