From 1385dd3f5dd263c0037855073bce096609e8c888 Mon Sep 17 00:00:00 2001 From: Anton Vakhrushev Date: Sun, 23 Aug 2026 20:11:48 +0300 Subject: [PATCH] =?UTF-8?q?=D1=80=D0=B0=D1=81=D0=BA=D0=BB=D0=B0=D0=B4?= =?UTF-8?q?=D0=BA=D0=B0=20av-dev=20=D0=BF=D0=BE=D0=B4=D0=BD=D1=8F=D1=82?= =?UTF-8?q?=D0=B0=20=D0=B4=D0=BE=20=D0=B2=D0=B5=D1=80=D1=81=D0=B8=D0=B8=20?= =?UTF-8?q?5:=20=D0=BC=D0=B5=D1=82=D0=BA=D0=B0=20=D0=BF=D1=80=D0=BE=D0=B3?= =?UTF-8?q?=D0=BE=D0=BD=D0=B0=20=D1=83=D1=88=D0=BB=D0=B0=20=D0=B8=D0=B7=20?= =?UTF-8?q?=D0=BF=D1=80=D0=BE=D1=86=D0=B5=D1=81=D1=81=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - docs/review.md: подраздел «Триггеры метки» заменён на «Когда звать глубокое ревью» — областями кода и перечнем необратимых мест проекта - дубли инвариантов и перечня необратимого сведены к ссылкам на CLAUDE.md, а в database.md убрано разошедшееся число мест правки колонки - шапка раздела перестала называть самый поздний артефакт ревью: строка протухала каждым прогоном --- .av-dev.toml | 2 +- docs/database.md | 7 ++-- docs/review.md | 89 ++++++++++++++++++++++++++++-------------------- 3 files changed, 56 insertions(+), 42 deletions(-) diff --git a/.av-dev.toml b/.av-dev.toml index c48c47a..b1f6c9c 100644 --- a/.av-dev.toml +++ b/.av-dev.toml @@ -1,7 +1,7 @@ # Раскладка av-dev в этом проекте: версия и настройки проверок. # Файл ведут скиллы плагина, править руками можно — комментарии свои. -version = 4 # версия раскладки; обратной совместимости нет, есть «приведён» и «нет» +version = 5 # версия раскладки; обратной совместимости нет, есть «приведён» и «нет» [docs] # каталог миграций: по нему docs.py сверяет схему с database.md diff --git a/docs/database.md b/docs/database.md index 798f042..8d3afbc 100644 --- a/docs/database.md +++ b/docs/database.md @@ -362,10 +362,9 @@ Crockford. Выдаёт их приложение единой точкой `int назначения, найденное по имени колонки. У аудиозаписи поля одного типа идут длинным непрерывным рядом, и позиционный список дал бы сдвиг на одно поле, который компилируется молча и кладёт идентификатор файла в колонку текста. - Перечень задан двумя местами — `writeOwnedByPipeline` вместе с `writeRecord` и - `readRecordColumns`, — плюс шагом схемы; правило правки и его серьёзность — - инвариант в [CLAUDE.md](../CLAUDE.md), сверку держат правила - `internal/archrules`. + Перечень мест, где правится колонка, и серьёзность правила — инвариант + «Колонки записи правятся в трёх местах» в [CLAUDE.md](../CLAUDE.md), + «Инварианты»; сверку держат правила `internal/archrules`. - **Перечень рубежей объявлен одним дескриптором** — `internal/entity/stage.go`. Из него выводятся выбор шага, отбор захвата, срок протухания и предел простоя: рубеж, забытый в отборе, не выдаётся ни одному воркеру никогда, а пустой прогон diff --git a/docs/review.md b/docs/review.md index 1dc2d32..b8995e4 100644 --- a/docs/review.md +++ b/docs/review.md @@ -2,10 +2,11 @@ ## Как настроен конвейер -Артефакты прогонов лежат в `openspec/changes/archive//review/` — под именем -`triage.md` либо `report.md`: имя менялось по ходу, и оба встречаются. Самый -ранний — `fix-http-handler-tests` 2026-08-11, самый поздний — -`start-without-telegram-token` 2026-08-13. +Артефакты прогонов лежат в `openspec/changes/archive//review/`; имя файла +менялось по ходу — `triage.md`, `report.md`, `design-review.md`, +`code-review.md`, `triage-<дата>.md`. Самый ранний — `fix-http-handler-tests` +2026-08-11; самый поздний здесь не называется: строка протухала бы с каждым +прогоном, и смотреть его надо в самом архиве. Конвейер прогонялся и на работе, шедшей без своего изменения openspec; артефакта в архиве у таких прогонов нет, и урожай их виден только записями журнала ниже. @@ -33,8 +34,8 @@ Пробел повторился на прогоне `config-test-headers-login` 2026-08-23, и это уже не единичный случай: строки о потолке не дал ни один из шести проходов, а -заметил это снова только триаж. Прогон при этом шёл с меткой `large`, то есть с -самым широким составом, — и разница с прошлым разом ровно в числе проходов, +заметил это снова только триаж. Состав прогона при этом был самым широким из +тогда доступных, — и разница с прошлым разом ровно в числе проходов, промолчавших одинаково. Читать пробел надо как границу покрытия каждого прогона, а не как свойство одного из них. @@ -263,43 +264,57 @@ - `architecture`: не зовётся ли на каждый запрос то, что меняет состояние приложения, — сборка роутера хранилища оказалась именно такой. -### Триггеры метки +### Когда звать глубокое ревью -Проектная конкретизация правила выбора метки. Умолчание — `medium`. +Проектная конкретизация признаков, по которым зовут `av-dev:code-deep-review`. +Что за признаками следует и каким составом идёт прогон, решает сам скилл ревью; +здесь только места этого проекта. -**Крупное здесь** (поднимает до `large`, ось объёма): +**Смотрим целиком** (область кода, а не дифф задачи): -- изменение, трогающее конвейер задач целиком: состояние, воркер, шаг сервиса и - колонку разом; -- замена хранилища — любой её кусок; -- смена модели очереди: захват, повторы и воркеры разом; -- каркас приложения: сборка фронтенда, раздача статики и шаг гейта разом; -- изменение, убирающее или возвращающее вход приёма целиком. +- **вход и разграничение доступа** — звенья `internal/controller/http` + (узнавание, требование учётной записи, ограничитель частоты, подстановка + заголовков отладочного запуска) вместе со спекой + [access](../openspec/specs/access/spec.md). Возвращаются сюда чаще, чем куда бы + то ни было ещё, и журнал дефектов ниже это показывает: закрытая поверхность, в + которую не мог войти никто; проверка, читавшая живую карту заголовков вместо + ответа; анонимный запрос, навсегда замедлявший запись; путь анонима, уехавший в + журнал; ключ бюджета ограничителя, который выбирал тот, кого ограничивают. С + 2026-08-22 барьер держит заголовок от прокси, изъятие у него одно — отладочный + запуск ([security.md](security.md), «Периметр»), — а настоящей Authelia в + прогоне нет (см. «Недоступно проверке»); +- **пакет хранилища** `internal/adapter/repo/sqlite` — здесь живёт инвариант + «Колонки записи правятся в трёх местах» ([CLAUDE.md](../CLAUDE.md), + «Инварианты», major): места, цена забытого и то, чем держится сверка, названы + там. Смотрится целиком потому, что компилятор не видит ни одного из мест; +- **конвейер расшифровки** `internal/service` вместе с дескриптором рубежа + `internal/entity/stage.go` — здесь живёт инвариант «Рубеж объявляется одним + дескриптором» ([CLAUDE.md](../CLAUDE.md), «Инварианты», major), и цена + забытого рубежа названа там. Сюда же дефекты о потере уже полученного: пустой + второй ответ распознавателя, стиравший сохранённую расшифровку, и остановка + сервиса, хоронившая конвертируемую запись; +- **распознаватель** `internal/adapter/recognizer/yandex` — единственное место, + чья ошибка стоит денег ([CLAUDE.md](../CLAUDE.md), «Запреты», «Yandex Cloud за + деньги»). Живым прогоном оно не проверяется вовсе (см. «Недоступно + проверке»), и разбор остаётся единственным способом судить о нём. -**Незнакомое здесь** (поднимает до `large`, ось формы решения): +**Необратимое здесь.** Перечень необратимого один и лежит в +[CLAUDE.md](../CLAUDE.md), «Работа»; здесь — только места кода, которых его +пункты касаются, и правило прохода: находка в таком месте уходит человеку +развилкой, а не чинится молча. -- вход через OIDC и разграничение доступа: как связать чат Telegram с учётной - записью, до начала работы назвать нельзя; -- всё, что делается на выбранном фреймворке впервые: правила - [conventions/web-ui.md](conventions/web-ui.md) выведены из выбора и из замера - на пробном экране, а не из написанного кода, и первая же задача проверяет их - собой — форма решения нащупывается по ходу; -- установка на телефон: service worker перехватывает запросы, и что он кэширует, - до работы назвать нельзя; -- работа с записями в несколько часов: потолки внешних сервисов не замерены, - форма решения зависит от замера; -- приём дорожки из видео и форматов, которых `ffmpeg` не берёт текущей командой; -- всё, что требует записи в `research/` прежде, чем начать. +- применённый шаг схемы — `internal/adapter/repo/sqlite/migrations`; +- формат файла на диске и раскладка каталога данных — + `internal/adapter/repo/sqlite`, `store.go`; +- публичный контракт HTTP API — `internal/controller/http`; +- имя ключа конфига — `internal/config`; +- действие с боевыми данными и с Yandex Cloud, ротация секрета — + `internal/adapter/recognizer/yandex`. -**Мелкое здесь** (опускает до `small`): - -- новая метрика в `internal/metrics`; -- правка `config.example.toml` и умолчаний `defaultConfig()` без нового поля; -- правка документов канона. - -Помни отрицательный тест: миграция, формат файла на диске, публичный контракт -API и имя не откатываются обратной правкой после мерджа — какими бы маленькими -ни были, они не `small`. +Строка, уже ушедшая в журнал контейнера или меткой метрики, из перечня не +берётся: её необратимость записана инвариантами о секрете и о содержимом записи +([CLAUDE.md](../CLAUDE.md), «Инварианты», оба critical), и правка кода помогает +там только следующей записи. ### Недоступно проверке