- адреса приложения переехали в своё пространство `/app/`, опрос готовности убран целиком: рубеж и причину остановки владелец узнаёт карточкой записи, текст — отдельным адресом названного вида - заведена единая точка отображения доменной ошибки и слой, приводящий к той же форме отказы библиотеки: тело несёт машиночитаемый код рядом с сообщением - у записи появились имя файла отправителя, длительность и размер своими колонками, а у ленты владельца — свой индекс: без него страница сканировала весь архив сервиса
12 KiB
Ревью дизайна — app-json-contract
Метка large, режим «по графу». Разметка: размер крупное, сложность
незнакомое; метку назвал агент review-scope до написания артефактов.
Состав по метке: specs (режим «дизайн ДО кода»), rubric, architecture плюс
вопрос автору о трёх формах решения. Гейта на этой стадии нет — кода не
существует; триажа нет — сток стадии это отработка замечаний.
Что найдено и что с этим сделано
Находок пятнадцать на три прохода, пересечения сведены.
Отработано правкой спек и дизайна
| Находка | Проход | Правка |
|---|---|---|
Инвариант «запись не теряется молча» и два требования pipeline ссылались на убранный опрос готовности |
specs | заведена дельта pipeline; карточка обязана нести рубеж, признак остановки и причину; в план добавлена правка CLAUDE.md |
Состав полей карточки не нормирован, хотя на него ссылается intake |
specs | карточка = элемент страницы плюс перечень доступных видов; имена полей названы поимённо |
| Перечень значений рубежа потерян вместе с убранным требованием | specs | возвращён нормой «принадлежит перечню рубежей конвейера», без перечисления порознь |
| Коды отказа на адресах чтения не заказаны; потерян запрет на разницу ответов без сессии | specs | перечень кодов закрыт и назван; 401 до всякого чтения записи; сценарий возвращён |
«Вид текста» в archive значил форму показа, в storage — вид; вычитанный текст недостижим |
specs | один закрытый перечень transcript/literary/replicas |
| Признак наличия текста булев, а состояние «текст есть, реплик нет» достижимо | rubric | перечень доступных видов вместо признака |
«Текста ещё нет» без названного кода сливалось бы с 404 чужой записи |
rubric, specs | код 409, сценарий на отличие от 404 |
| Тело отказа несло только русскую фразу | rubric | два поля: машиночитаемый код из закрытого перечня и сообщение |
| Имена и единицы двух колонок из трёх не названы перед необратимым шагом схемы | rubric, architecture | original_filename, duration_ms, size_bytes; неизвестная длительность отличима от нулевой |
| Потолок размера страницы не назван — параметр обходит постраничность | rubric, specs | умолчание, потолок, усечение, 400 на негодное значение |
| Отказ по превышению размера тела шёл мимо единой формы | rubric | своя доменная ветвь, код 413, предел в теле числом |
| Имена полей ответа не названы нигде | architecture | названы; форма страницы взята той же, какой её отдаёт хранилище |
| Отбор «в работе» — второй толкователь рубежей, остановленная запись выпадала из обеих половин | architecture, specs | три состояния вместо двух; предикаты выводятся из дескриптора рубежа; правило archrules на нового потребителя |
Ветви 401, 403, 413 отсутствуют в таблице docs/conventions/errors.md, объявленной источником единой точки |
architecture | шаг плана на правку конвенции |
| Два адреса обещаны дизайном, но не названы спекой | specs | обещание снято: названным считается то, что стоит требованием |
Ушло на чекпоинт человеку
Три развилки — каждая расходится с тем, что владелец назвал в постановке, и каждая необратима после мерджа.
- Длительность и размер колонками записи против батч-разрешения строки файла. Обе величины уже лежат строкой файла; довод «по строке на запись списка» опровергается собственным шагом плана — темы разрешаются одним запросом на страницу. Цена ошибки: две вечные колонки-копии в применённом шаге схемы, равенство которых не держит ничто.
- Перечень известных расширений в
GET /app/config. У сервиса нет понятия «принимаемые форматы» — единственный такой перечень сужает метку метрики и имеет другой смысл. Приложение прочитает перечень как «что можно загружать» и станет единственным местом, где это правило существует. - Постраничное чтение номером страницы против курсора. Приём пишет в голову той же ленты, которую читает список: запись, заведённая между двумя страницами, сдвигает окно — один элемент придёт дважды, другой не придёт никогда, и оба раза молча.
Второй круг: разметка и сверка после чекпоинта
Правки после чекпоинта тронули дельта-спеки, поэтому повторены разметка и та часть ревью дизайна, которой правка касается. Рубрика и архитектурный проход не перезапускались намеренно: принятые правки — их же собственные рекомендации, и судить их своим отчётом они не могут.
Разметка не сдвинулась — крупное, незнакомое, large, теми же пятью
источниками. Правка синхронизировала спеки с решениями, уже стоявшими в дизайне,
а не добавила площадь или неизвестность.
Повторная сверка дала пять находок, все отработаны:
| Находка | Правка |
|---|---|
MODIFIED требования pipeline вырезало обоснование двух сторожей — задача failure-verdict-vs-retry прочла бы урезанную норму |
предложение возвращено целиком, сменён только держатель нормы |
| Критерии приёмки остались на прежней модели текста и вернули бы в код две уже закрытые находки: булев признак наличия текста и «тот же вид репликами»; оракул формы сравнивал не ту пару | критерии и шаги плана приведены к спеке, правка помечена в самом критерии |
| Половина имён публичного контракта осталась бы за кодом — поля тела отказа и сам перечень кодов, поля пределов и «кто вошёл», имя признака повтора, имена параметров запроса | все названы спекой поимённо |
| Два предела из объявляемых не имели проверяемого источника; имя «частота опроса готовности» протухало вместе с убираемым адресом | частота выведена из настройки ограничителя, перечень расширений — из меток метрики за вычетом audio, предел переименован в «частоту опроса карточки» |
| Паспорт, модель угроз и архитектура остались бы описывать убранные адреса, и плана правки на них не было | заведены три шага плана |
Второго чекпоинта не было, и это осознанно: ни одна из пяти находок не меняла решения, принятого человеком, — все они приводили спеки и план в согласие с уже принятым.
Что осталось названным, но не закрытым: имя капабилити archive совпадает
словом с каталогом заархивированных change и с тем, как паспорт зовёт весь
сервис. Имя оставлено — каталоги разные, слово в проекте своё.
Границы покрытия стадии
- Метка
large, режим «по графу»; проходов три, все вернулись, потолок не срабатывал ни у одного —rubricвывел 8 из 8 построенных,architectureупёрся в свои 3 и объявил это,specsпотолка не имеет на этой метке. - Кода не существует: ничего не запускалось, кроме
openspec validate --strict. Гейт на этой стадии не гоняется по построению. - Команды сборки карты проекта в
Taskfile.ymlнет — архитектурный проход собирал инвентарь понятий грепом, и такой инвентарь беднее подготовленного. docs/adr/иdocs/research/прогоном не открывались: процессные документы. Расхождение изменения с записанным решением этой стадией не ловится — это работа сверки документации.- Альтернативной реализации, с которой можно сдиффить решения, у конвейера нет: проход независимой реализации упразднён решением о стоимости.
- Что будет с этим на живых данных, не проверял никто: данных нет, стадия — стройка.