Commit Graph
158 Commits
Author SHA1 Message Date
av c1dab24de1 учёт: закрыта задача drop-dead-dotenv-loader, заведена drop-dead-entrypoint-script 2026-08-23 21:14:30 +03:00
av b01bdabc37 снят мёртвый godotenv.Load() вместе с зависимостью
- переменных окружения наш рабочий код больше не читает нигде: ушли вызов, импорт и предупреждение на старте
- у оставленной строки .env в .gitignore и у запрета forbidigo переписаны причины: прежние называли живым снесённого читателя
- в документы записано, что барьеры против .env стоят без читателя, и правило парности .gitignore с .dockerignore
2026-08-23 21:06:30 +03:00
av 1385dd3f5d раскладка av-dev поднята до версии 5: метка прогона ушла из процесса
- docs/review.md: подраздел «Триггеры метки» заменён на «Когда звать глубокое
  ревью» — областями кода и перечнем необратимых мест проекта
- дубли инвариантов и перечня необратимого сведены к ссылкам на CLAUDE.md, а в
  database.md убрано разошедшееся число мест правки колонки
- шапка раздела перестала называть самый поздний артефакт ревью: строка
  протухала каждым прогоном
2026-08-23 20:11:48 +03:00
av 404be2bdd5 storage: заголовок требования о выдаче файла говорит то же, что тело
- «Файл отдаётся ссылкой» осталось от снятого решения: тело требования прямо
  отрицает выдачу значения на предъявителя, право даёт узнавание при каждом
  обращении
- слово «ссылка» перестало нести в одном требовании три смысла: указатель в
  базе, значение доступа и путь к файлу в журнале
2026-08-23 16:58:30 +03:00
av 31ce520c5b документы: сведены расхождения, найденные сверкой канона
- один факт — один дом: рецепт локального входа, правило чтения
  X-Forwarded-For, уровень строки журнала и опись опор изъятия сведены к
  своим домам, копии заменены ссылками
- форма [auth.test_headers] выровнена по образцу конфига в семи местах;
  сценарии intake и archive перестали ссылаться на сессию, которой сервис
  не выдаёт
- поправлены протухшие факты: ключ объекта строит ULID, а не UUID; сверку
  адреса пира зовут трое, а не двое; обзор capability access знает о
  задаче 2026-08-23
2026-08-23 16:41:06 +03:00
av 11269c1567 учёт: заведён урожай ревью входа по конфигу
- пять задач партии review-2026-08-23: многозначность Remote-Name и Remote-Email,
  мелочи входа, механизация правила о зависимостях конфига, снятие мёртвого
  читателя .env, управляющие знаки в расширении
- две существующие разведки дополнены находками того же прогона: адрес объекта в
  тексте отказа SpeechKit и выводимость имени копии из журнала
2026-08-23 14:03:52 +03:00
av 0aa9b3a567 security.md: защита от многозначного заголовка описана точнее
Отбой двух значений закрывает только Remote-User; Remote-Email берётся первым
и закрепляется за чужой учётной записью навсегда. Путь построен ревью
2026-08-23, правило распространяется на всю тройку отдельной задачей.
2026-08-23 13:41:53 +03:00
av 52fe31319a локальный вход задаётся конфигом: заголовки подставляет сам сервис
- в конфиг добавлены секция [auth.test_headers] и предохранитель [server] debug:
  заголовки входа подставляет слой транспорта, второго процесса локальный запуск
  больше не требует
- подкоманда devtools proxy удалена целиком: всё, ради чего её поднимали, делает
  сам сервис
- адресного предохранителя нет по решению владельца — цена названа в ADR и в
  модели угроз
2026-08-23 13:12:47 +03:00
av 75c6f0168a учёт: закрыт переезд хранилища, заведён урожай его ревью
- storage-without-pocketbase закрыта как реализованная: приёмка сошлась по всем
  пяти критериям записи и по двенадцати приёмочным свойствам рубрики ревью
  дизайна, работа лежит коммитом c9b7765
- урожай триажа ревью развёрнут в одиннадцать записей с тегом партии
  review-2026-08-23 и расставлен по зависимости, а не в конец списка
- находка про признак живости воркера слита в stalled-pipeline-metric: у неё та
  же причина — вставший конвейер неотличим от простоя
2026-08-23 08:41:49 +03:00
av c9b7765646 хранилище переехало с PocketBase на SQLite со своим каталогом файлов
- база своя: два пула, захват одним UPDATE ... RETURNING, шаги схемы на goose
  под файловым замком, одна миграция начальной схемы вместо семи прежних
- транспорт переписан на net/http: свои слои, свой ограничитель частоты,
  отдача файла с проверкой владельца; панель /_/ и пространство /api/ исчезли
- по находкам ревью: журнал не пишет путь под корнем приложения, ключ бюджета
  читается справа налево, узнавание известного идёт читающим пулом
2026-08-23 08:06:04 +03:00
av 1edf8cb225 записан подход к проектированию: чистая архитектура и тактические шаблоны DDD
- architecture.md: раздел «Слои и модель домена» — таблица слоёв с колонкой «чего не знает», шаблоны со своим сегодняшним предметом в коде, запрет анемичной модели
- CLAUDE.md: раздел «Проектирование» с подходом и ссылкой на раздел архитектуры
- названо, что чистоту домена не держит ни одно правило archrules
2026-08-22 21:05:13 +03:00
av ad5b5e377f записано решение уйти с PocketBase на SQLite со своим каталогом файлов
- разведка storage-without-pocketbase: шесть ролей библиотеки в этом коде, отпавший довод перевода, шесть модулей достижимы только через неё
- ADR-2026-08-22-storage-without-pocketbase заменяет три записи: перевод в PocketBase, очередь коллекцией, файл за защищённым полем
- задача storage-without-pocketbase встала первой строкой плана стройки
2026-08-22 21:00:14 +03:00
av a8fb4793be закрыта задача trusted-header-login
- две записи, ссылавшиеся на убранный oidc-login, переписаны
- dev-run-task переведена с отдельного cmd/devadmin на подкоманду cmd/devtools
2026-08-22 20:25:13 +03:00
av 7f33c957e5 вход переехал на доверенный заголовок Authelia вместо собственного OIDC
- пришедшего называет заголовок Remote-User от прокси, и верят ему только с
  адреса из перечня trusted_proxies; своего входа у сервиса не осталось — ни
  корня /auth, ни кук, ни срока сессии, ни секрета клиента в конфиге и в базе
- учётная запись заводится первым обращением: EnsureUser в пакете хранилища,
  шаг схемы 202608220001 с колонкой provider_login и снятыми правилами users
- cmd/oidcstub заменён на cmd/devtools с подкомандой proxy; заодно закрыт
  унаследованный DL3066 — пользователь образа назван числом
2026-08-22 20:24:22 +03:00
av e4441f3c49 tasks: вход переезжает на заголовки прокси, пять задач про OIDC закрыты
- заведена `trusted-header-login` и поставлена в голову очереди
- пять задач про механику OIDC закрыты как отменённые ею
- `dev-run-task` и `api-tokens` переписаны под новый вход
2026-08-22 17:43:18 +03:00
av 2bb252e018 tasks: владельца панели заводит отдельная команда, а не ключ конфига
- admin-owner-from-config закрыта: решение владельца 2026-08-15, ключ конфига
  не заводится, требование спеки storage остаётся в силе
- dev-run-task вобрала cmd/devadmin и стоит первой строкой: инструмент и шаг
  порознь не нужны, поэтому едут одной задачей
2026-08-15 20:49:50 +03:00
av 97c6c7c440 tasks: заведены задачи про владельца панели из конфига и команду локального запуска
- admin-owner-from-config первой строкой: сервис заводит владельца панели
  по ключу конфига; задача отменяет требование спеки storage, и это названо
  в рамках
- dev-run-task следом: task dev поднимает сервис и заглушку разом, гасит
  оба по Ctrl+C; зависит от ключа конфига
2026-08-15 20:39:45 +03:00
av daa4c3b6e4 oidcstub: записано решение не заводить заглушке своих тестов
- решение владельца 2026-08-15: пакет в образ не едет, отказ громкий,
  а путь входа проверен подставным провайдером в тестах транспорта
2026-08-15 20:18:58 +03:00
av 91138dd39a точки входа переехали в cmd/, заведена заглушка OIDC для локального входа
- main.go и journal_route_test.go переехали в cmd/transcriber без правок
  содержимого; образ собирает ./cmd/transcriber поимённо
- cmd/oidcstub отвечает на /authorize, /token и /userinfo, проверок не делает
  и слушает петлевой адрес: войти без Authelia стало чем
- ступень сборки приложения переехала на node:24 с alpine — musl ждёт ответа
  на AAAA, которого нет, и npm ci висел вместо отказа
2026-08-15 20:15:57 +03:00
av 63a13404df заведена задача про сканер уязвимостей в зависимостях приложения 2026-08-15 19:02:36 +03:00
av 8c18abc24e закрыта задача spa-skeleton 2026-08-15 18:53:24 +03:00
av 663021f712 приложение собрано каркасом и вшито в бинарник
- заведён каталог web/ — Vue 3, роутер пятой версии, сборка Vite; собранное
  вшивается через go:embed и раздаётся корневым маршрутом: разметка на
  неизвестном пути вне корней сервиса, отказ контракта внутри корня
- перечень корней сервиса стал единой точкой и порождает регистрацию маршрутов,
  а не описывает её; журнал раздачи пишет исход и длину пути, но не сам путь
- шаг front зовёт Node контейнером docker — Biome, юнит-тесты Vue и сборка
  входят в гейт, а в Dockerfile появилась ступень приложения
2026-08-15 18:51:05 +03:00
av c6ffda9aac web-ui.md: ссылка на закрытую задачу заменена ссылкой на спеку archive 2026-08-15 13:54:12 +03:00
av a5bc322814 закрыта задача json-api-for-spa 2026-08-15 13:52:06 +03:00
av 3a2da3004b приём и чтение записей сведены к одному контракту приложения
- адреса приложения переехали в своё пространство `/app/`, опрос готовности
  убран целиком: рубеж и причину остановки владелец узнаёт карточкой записи,
  текст — отдельным адресом названного вида
- заведена единая точка отображения доменной ошибки и слой, приводящий к той же
  форме отказы библиотеки: тело несёт машиночитаемый код рядом с сообщением
- у записи появились имя файла отправителя, длительность и размер своими
  колонками, а у ленты владельца — свой индекс: без него страница сканировала
  весь архив сервиса
2026-08-15 13:51:23 +03:00
av 79ff12548f tasks: спроектирован контракт приложения и переставлена голова очереди
- json-api-for-spa: адреса приложения уехали в своё пространство /app/,
  приём стал POST /app/audiorecords, опрос /api/status/:id убран, заведены
  список, карточка, текст, /app/me и /app/config; имя файла отправителя
  легло своей колонкой рядом с заголовком
- три действия над записью — правка заголовка, возврат в работу и журнал
  событий — собраны задачей audiorecord-actions
- голова очереди: контракт, каркас, экран загрузки, список, действия
- в прежних задачах поправлены адреса, рубежи конвейера и остатки Telegram
2026-08-15 09:06:11 +03:00
av d88e56efcb claude.md: объявлена стадия стройки и выкладка с чистого листа
- на сервере данных нет и сервис остановлен, совместимость с ним не требуется
- запрет на боевой каталог и на переписанный шаг схемы этим не снимается
2026-08-15 08:12:18 +03:00
av b4b19db6e4 tasks: заведён урожай ревью remove-telegram-intake
- шесть записей по кластерам причин: журнал под внешним значением, нулевой
  код ответа в журнале, затирание вложения бедным ответом, открытый анониму
  адрес подтверждения почты, рубеж расшифровки без работы, пределы длительности
- находка про код 500 у отказа приёма дописана в json-api-for-spa: там живёт
  единая точка отображения доменной ошибки
- telegram-account-link и bot-api-only-through-bot-client оставлены с оговоркой,
  что предмета у них нет до возвращения входа
2026-08-15 07:46:16 +03:00
av 8f7c3a057a удалён вход Telegram, владелец записи стал обязателен в схеме
- убраны клиент бота, транспорт обновлений, отправитель сообщений, сборка
  входа при старте, секция настроек и зависимость go-telegram-bot-api; из
  конвейера ушла доставка ответа отправителю — исход виден опросом готовности.
  Колонки адресата и значение источника остались в схеме: применённые шаги не
  переписываются
- шаг 202608140003 запрещает пустого владельца у аудиозаписи и у файла;
  существующие строки он не проверяет, и это принято сознательно — искать их
  надо запросом до выкладки
- ревью нашло два пред-существующих дефекта, оба закрыты: пустой второй ответ
  распознавателя стирал сохранённую расшифровку, а пустая расшифровка перестала
  быть заметной вместе с убранной доставкой. Попутно поднят golang.org/x/image
  до v0.45.0 — красный шаг vulns, воспроизводился и на чистом master
2026-08-15 07:24:35 +03:00
av 97ceb7bb69 заведена задача failure-verdict-vs-retry 2026-08-14 20:38:12 +03:00
av 9a964f2efc закрыта задача record-centric-model 2026-08-14 20:20:58 +03:00
av 1576d06735 внутренняя модель перестроена вокруг аудиозаписи
- audiorecords вместо transcribe_jobs: приложения (texts, structures,
  recognitions, record_events, topics) живут своими коллекциями, ссылки на
  исходник и на приведённую копию перестали переставляться
- рубеж называет достигнутое, отказ стал признаком остановки с причиной, а
  сторожей стало двое: число отказов и время в рубеже
- воркеры потеряли специализацию, их число задаётся [pipeline] workers, шаг
  выбирается по рубежу, а захват отдаёт идентификатор и признак захвата
2026-08-14 20:20:33 +03:00
av d079f03350 заведена задача на перестройку модели вокруг аудиозаписи
- центральная сущность — аудиозапись: файлы, тексты, структура реплик и темы
  живут отдельными строками, поля очереди перестают соседствовать с содержимым,
  а провайдерское уезжает в свою таблицу
- конвейер становится цепочкой рубежей с остановкой признаком: рубеж не
  стирается, и запись перезапускается с места остановки
- воркеры теряют специализацию, их число задаётся конфигом
2026-08-14 16:46:40 +03:00
av a67cdee382 закрыта задача record-ownership 2026-08-14 12:19:19 +03:00
av 8af8ec2e54 у записи появился владелец: чужую больше не отдают
- колонка `owner` связью с `users` в обеих коллекциях новым шагом схемы
  `202608140001`; чтение задачи сужено владельцем, и чужая, ничья и
  несуществующая дают один ответ; правило просмотра файлов сужено им же
- приём по HTTP берёт владельца из сессии, а предъявителя без учётной записи
  пользователя отвергает до чтения тела: позже пришлось бы убирать уложенный
  файл, а уборки файлов сервис не умеет. Выборка воркера владельцем не сужается
- удаление учётной записи с записями отвергается стражем, и вешает его сама
  сборка хранилища: сборка, забывшая его позвать, теряла защиту молча
2026-08-14 12:18:11 +03:00
av b7d4660aef канон: раскладка повышена до версии 4
- слово «провенанс» снято из словаря проектных текстов: у числа теперь
  «происхождение», у вопроса и находки — «откуда»
- правлены форма вопроса в docs/review.md, шапка раздела об OIDC в
  docs/research/pocketbase.md и две записи задач; формулировки прошли
  вычитку агентами doc-wording и task-wording
- архив openspec/changes/archive/ не тронут: слово, верное на день записи,
  остаётся свидетельством
2026-08-14 09:51:01 +03:00
av 62b2829cba go: тулчейн поднят до 1.26.6
- директива `go` в go.mod — единственное место, где назван патч: шаг гейта
  сверяет мажор и минор, поэтому `golang:1.26-alpine` в Dockerfile и «Go 1.26»
  в CLAUDE.md и README.md остались верными
- директива toolchain не заведена: она стала бы пятым местом с версией и
  уронила бы сверку
- достижимых из кода уязвимостей у govulncheck больше нет; недостижимая
  GO-2026-5932 в golang.org/x/crypto/openpgp остаётся объявленной
2026-08-14 09:50:50 +03:00
av e660617ba0 закрыта задача config-example-toml 2026-08-14 09:32:24 +03:00
av ce0ae76977 config: образец переименован в config.example.toml
- имя приведено к конвенции, которая сама называла его расхождением;
  ссылки поправлены в README, CLAUDE.md, конвенциях, docs/review.md и двух
  записях задач
- в шапке docs/conventions/config.md заодно поправлен второй пункт перечня:
  проверки на старте у `[auth]` и `[telegram]` уже есть
- архив openspec/changes/archive/ не тронут: это запись о прошлом
2026-08-14 09:32:03 +03:00
av 312caf0fa3 tasks: тип login-url-from-collection-settings сменён на feature
- задача оказалась шире chore: у нормированного адреса входа появляется
  новый исход отказа, а обязательность проверочного кода PKCE переезжает
  в настройки провайдера в хранилище
- дальше она идёт сценарием решения, следующим прогоном
2026-08-14 08:45:44 +03:00
av cd57b68215 config: включение Telegram разведено с ключом доступа
- в секции [telegram] заведён обязательный ключ enabled: умолчания у него нет,
  файл без него негоден; bot_token стал только ключом доступа и при
  enabled = false не читается вовсе, а пустой при enabled = true роняет старт
- выключенный вход даёт подъём одним входом без единого обращения к Telegram и
  записью INFO вместо прежнего WARN: это выбор владельца, а не отклонение
- отказ разбора файла настроек больше не пересказывает toml — её ParseError
  несёт в тексте разбираемое значение, и оборванная строка секретного ключа
  уносила его в журнал; теперь называются путь, строка, столбец и последний ключ
2026-08-13 21:46:14 +03:00
av 903941f587 docs: точного числа накопленного в документах больше нет
- CLAUDE.md, «Язык»: ссылаться можно на конкретную запись или на весь корпус
  разом, но не на их количество — число протухает молча, машина его не считает.
  Изъятие названо: неизменное число и историческое в записи о прошлом остаются.
- Сняты счёты capability, прогонов ревью, типизированных ошибок, воркеров,
  сверок документов и правил линтера в docs/, спеке pipeline и CLAUDE.md.
- Заодно исправлено то, что этот же счёт и скрывал: типизированных ошибок три,
  а не две — LostAcquisitionError был потерян из перечня.
2026-08-13 19:23:00 +03:00
av 4c87220d90 docs: поправлен маркер канона и записано правило о живом прогоне
- architecture.md: маркер над таблицей компонентов ссылался на
  несуществующую capability delivery; теперь на intake, pipeline и storage,
  и названо непереехавшее — приём из Telegram и деление текста по словам.
- review.md: проход, поднявший сервис, обязан его остановить, а меряющий —
  убедиться, что отвечает его сборка. Цена правила уже заплачена: оставленный
  процесс держал порт, и замеры ушли к прежней сборке.
2026-08-13 19:15:57 +03:00
av edcf8ede70 закрыта задача local-run-without-telegram-token 2026-08-13 19:10:28 +03:00
av b733a84d6a telegram: сервис поднимается без бота и работает одним входом
- Клиент бота собирается один раз и достаётся отправителю и транспорту;
  разрез прошёл по «ответил ли Telegram»: ответ «такого бота нет» роняет
  старт, недоступность даёт подъём без Telegram (ADR-2026-08-13). Ожидание
  при сборке ограничено сроком — иначе молчащий Telegram вешал подъём.
- Недоставленный ответ не роняет шаг: пишется с job_id и считается метрикой,
  уровень по причине — WARN для неподнятого входа, ERROR для неназванного
  адресата. Заведены transcriber_intake_up и transcriber_undelivered_reply_count.
- Закрыта утечка токена в журнал: отказ разбора адреса рождается раньше
  обращения к клиенту, то есть мимо чистки на его границе.
2026-08-13 19:10:08 +03:00
av 863ba3b42e tasks: local-run-without-telegram-token переведена в feature
- Тип сменён с chore: подъём без токена бота меняет наблюдаемое поведение и
  требует нормы, которой в openspec/specs нет.
- В тело записан второй предмет работы — судьба задачи из Telegram, дошедшей до
  ответа при отсутствующем боте; он же стал четвёртым критерием приёмки.
2026-08-13 16:59:44 +03:00
av 220a4374b1 docs: раздел линтеров назван «Код проверок и подавления»
- Прежнее имя «Проверки о самих проверках» читалось против запрета в CLAUDE.md,
  хотя правила в нём — линтеры над кодом проверок, то есть тот же один уровень.
2026-08-13 16:52:52 +03:00
av ec136b50fb scripts: снесены проверки шага сверки версий Go
- Двадцать сценариев шага были единственной проверкой над проверкой в проекте;
  запрет CLAUDE.md остался без исключений.
- Ссылки на файл сняты в памятке, конвенции линтеров, журнале ревью и статусе
  ADR о спеке toolchain; норма шага живёт комментариями в самом скрипте.
2026-08-13 16:51:15 +03:00
av 54268b5933 CLAUDE.md: запрет на проверки над проверками
- Уровень проверки один: линтеры и тесты судят код сервиса, судить их самих
  проект не берётся; названы попавшие под запрет виды работ.
- Пересказ решения в go-linters.md и review.md заменён ссылкой на дом.
2026-08-13 16:47:54 +03:00
av 539ed926cb docs: сняты проверки над проверками
- Из «Любой узел» в review.md убраны три свойства о годности самих проверок:
  мутация теста, мутация оракула критерия, требование без сценария.
- Из go-linters.md снята «Лестница механизации», ссылки на неё переписаны
  в конвенциях, их индексе и журнале дефектов.
2026-08-13 16:45:12 +03:00