- go-1-26-upgrade вобрал критерии gate-go-version-sync: версия правится и сверяется одним заходом - gate-go-version-sync ушла в REJECTED с причиной
16 KiB
16 KiB
Беклог
Что можно взять. Одна задача = один файл items/<slug>.md
- строка здесь. Целей тут нет — они в ROADMAP.md: беклог — то, что берут,
роадмап — то, подо что берут. Порядок строк значим:
это очередь, и первая строка — то, что делают следующим. Порядок
назначает человек на груминге, машина его не выводит. Одно исключение
производно от типа — сырьё (
researchбез раздела «Вопрос») стоит в конце: его не берут. Ведётся скилломtasks.
Секция одна — полок домена у проекта нет, и делить очередь на две значило бы держать два порядка вместо одного.
Тип записи стоит первым полем меты и решает, что у неё может быть:
✨ feature 🐞 fix 🧹 chore 🔬 research
Секции «блокеры» здесь нет и не заводится: блокер — это состояние (работа не может продолжаться ни одной задачей), оно живёт до ответа человека, а его следы — вопросами в файлах задач.
Очередь
- 🐞 Убирать записанный файл, когда приём отказал на середине — Отказ чтения метаданных и отказ записи на диск оставляют файл в каталоге хранения без задачи и без учёта: сопоставить его не с чем, удалять приходится руками.
- 🧹 Задать таймауты обращениям к внешним сервисам — Ни у Telegram, ни у Object Storage, ни у SpeechKit нет таймаута: молчащий собеседник держит шаг конвейера до истечения часового захвата.
- ✨ Пускать в приложение только после входа через OIDC — HTTP API открыт наружу без аутентификации: любой из интернета заводит задачи за наши деньги и читает чужие расшифровки по идентификатору.
- ✨ Привязать запись к владельцу и отдавать только свои — У задачи и файла нет владельца, поэтому знание UUID задачи и есть право её читать.
- ✨ Сопоставить пользователя Telegram с учётной записью — Белый список сверяется с именем пользователя Telegram, которое владелец меняет в любой момент, а записи из бота ни с кем не связаны.
- ✨ Свести приём и чтение записей к одному контракту для приложения — Сегодняшний API отвечает 404 на любую ошибку чтения и 500 на любую ошибку приёма: строить на нём экраны нечем.
- ✨ Пускать скрипты в API по личным токенам — Вход через OIDC закрывает API целиком, а скрипту браузерная сессия недоступна: автоматизировать загрузку станет нечем.
- ✨ Собрать каркас приложения и раздать его из бинарника — Экранов нет и собирать их нечем: ни сборки фронтенда, ни раздачи статики в проекте не существует.
- ✨ Сделать экран загрузки записи и её состояния — Первое, ради чего приложение открывают: отдать файл и увидеть, что с ним происходит.
- ✨ Сделать экран списка своих записей и чтения текста — Расшифровка сегодня доходит одним сообщением и теряется в переписке; вернуться к ней через неделю нечем.
- ✨ Удалять запись со всеми уровнями текста по требованию владельца — Ни файлы, ни расшифровки не удаляются вовсе: убрать запись сегодня можно только руками в базе и в каталоге на сервере.
- ✨ Узнавать уже загруженный файл по хеш-сумме — Один и тот же файл, отправленный дважды, распознаётся дважды и оплачивается дважды: приём не смотрит на содержимое вовсе.
- ✨ Принимать до десяти файлов одной загрузкой — Приём берёт один файл в запросе, а с телефона выбирают пачку сразу: десять записей значат десять заходов на экран загрузки.
- ✨ Показывать ход загрузки записи на экране — Гигабайтный файл уходит на сервер молча: до ответа сервера экран не отличает идущую загрузку от зависшей.
- ✨ Сделать приложение устанавливаемым на телефон — Приложение, живущее вкладкой браузера, теряется среди прочих: ярлыка на экране у него нет.
- ✨ Сделать экран настроек и хранить настройки по пользователю — Настроек у пользователя нет вовсе: уровни текста и канал уведомлений задаются общим конфигом сервиса.
- ✨ Считать заголовок, темы и пересказ внешней моделью — Расшифровка доходит стеной текста: ни заголовка, ни тем, ни пересказа сервис не считает, и клиента языковой модели в нём нет.
- ✨ Отдавать вычитанный текст рядом с сырым — Сырая расшифровка идёт без знаков препинания, с повторами и словами-паразитами: читать её подряд тяжело, а другого уровня текста нет.
- ✨ Отправлять готовый текст через apprise и ntfy — Пользователь веба узнаёт о готовности только опросом с открытого экрана.
- ✨ Слать готовый текст на почту из учётной записи — Адрес почты приходит вместе с входом через OIDC, но почтового отправителя в сервисе нет.
- ✨ Считать объём, минуты и расход по каждому пользователю — Ни объём, ни длительность, ни обращения к платным сервисам никуда не записываются: восстановить расход задним числом не из чего.
- ✨ Сделать страницу статистики для владельца — Собранный учёт читается только запросом к базе руками: ни страницы, ни признака владельца в приложении нет.
- 🔬 Потолки SpeechKit по длине записи и по формату — Потолок длины записи и перечень принимаемых форматов неизвестны, а цель про долгие записи без них не начинается.
- 🔬 Потолки приёма, конвертации и заливки по длине записи — Из пяти звеньев задача speechkit-limits замерила только модель распознавания: где отваливается шестичасовая запись до неё, неизвестно.
- ✨ Отклонять на приёме запись сверх потолка — Запись сверх потолка принимается молча и висит в конвейере до истечения часового захвата, а человек всё это время ждёт текста.
- ✨ Резать длинную запись на фрагменты и продолжать с места остановки — Шаг конвейера повторяется целиком: перезапуск на пятом часу шестичасовой записи начинает распознавание заново и оплачивает его второй раз.
- ✨ Отдавать текст в сотни килобайт файлом, а не сотней сообщений — Отправитель Telegram режет текст по 4000 знаков: расшифровка шестичасовой записи придёт сотней сообщений подряд.
- 🔬 Загрузка большого файла частями — Гигабайтный файл едет одним запросом, и обрыв на девяноста процентах начинает его заново.
- 🧹 Покрыть тестами разбор вывода ffprobe — Проверки приёма перестали звать настоящий ffprobe 2026-08-11, а своего теста у адаптера метаданных нет: разбор JSON и отличие «программы нет в PATH» от «обработка отказала» не проверяет ничто.
- 🧹 Покрыть тестами шаги конвейера и захват задачи — Тестовых файлов в проекте два, и оба мимо конвейера: потеря ссылки на файл, двойной ответ пользователю и гонка при захвате не поймаются ничем.
- 🧹 Разобрать мелочи http-транспорта — Маршруты зарегистрированы дважды, и переименование пути в main.go проходит проверки зелёным; обработчик пишет в журнал через стандартный log и дублирует запись, уже сделанную сервисом.
- 🧹 Переименовать образец конфига в config.example.toml — Конвенция называет config.dist.toml объявленным расхождением, но тут же пишет это имя как правило — документ противоречит сам себе, а образец расходится с конвенцией.
- 🔬 Стоит ли брать OpenTelemetry вместо голого Prometheus — Метрик одиннадцать штук на пять счётчиков, трассировки нет вовсе: путь одной записи по конвейеру собирается только чтением логов глазами.
- 🧹 Обновить Go до 1.26 и сверять версию шагом гейта — Модуль объявляет go 1.25.0, образ собирается на golang:1.25-alpine, на машине разработки стоит 1.26.5, и расхождение этих чисел не ловит ни один шаг гейта: разъехавшийся Dockerfile прошёл весь конвейер зелёным.
- 🧹 Ловить уязвимости в зависимостях шагом гейта — govulncheck находит две достижимые уязвимости в клиентах Yandex, а ни гейт, ни список «чего в гейте нет» о нём не знают: узнать о третьей будет неоткуда.
- 🧹 Считать покрытие изменённых строк шагом гейта — Свойство «изменённое место покрыто хоть одним тестом» записано в docs/review.md, но не механизировано: за две задачи подряд непокрытые шаги ловили руками.
- 🧹 Прервать шаг конвейера отменой контекста — Воркер читает ctx только между итерациями: остановка контейнера ждёт конца шага, а на занятом писателе один запрос к хранилищу держится до 9,5 секунды при мягком таймауте в 5.
- 🧹 Разобрать мелочи слоя хранилища — Три мелочи ниже потолка триажа: цикл воркера пишет потерю захвата уровнем ERROR и считает её отказом, тип ошибки заведён там, где конвенция просит sentinel, а FileName несёт два разных смысла.
- 🔬 Уведомление SpeechKit о готовности вместо опроса — Шаг проверки дёргает операцию раз в 5 секунд всё время распознавания: часовая запись даёт порядка 720 обращений к платному сервису вместо одного ответа.
- 🔬 Адрес объекта в тексте отказа SpeechKit — Текст отказа операции приходит от Yandex и уезжает в журнал и в колонку error_text: если он несёт URI объекта, из журнала снова собирается ссылка на чужую запись.
- 🔬 Квота по общему размеру загруженного на пользователя — Паспорт и security.md запрещают отказы по квоте пользователю, а заметка владельца просит квоту по умолчанию 5 ГБ — открытое противоречие с границей домена, которое владелец решил не разбирать сейчас.