старший долг: развилка тремя основаниями, вопросы тем, версия раскладки 5
Третий заход по находкам ревью — то, что старше темы 78 и тянулось с тем 74–77. Оснований у развилки три во всех местах: конвейер называл два, а устав триажа, контракт находок, сценарий решения и журнал — три. Там же сказано, чем третье отличается: по первым двум оркестратор урезает изменение до остатка, третье отменяет одобрение и возвращает на чекпоинт. Вопросы проекта по темам достались проходам, которые эти темы закрывают: review-code, review-specs и review-autotests получили обязанность отвечать дословно и строку в блоке покрытия. Прежде конвейер обещал их каждому проходу, а знал о них только приёмник тем. Глубокое ревью приведено к уставам, которые зовёт: глубина у проходов разная — доказательство у тех двоих, что держат машину, разбор у architecture и code; у триажа три вызывающих, а не два режима, и потолка в 7 пунктов там нет. Версия раскладки поднята до 5 с записью журнала: скелет docs/review.md потерял подраздел «Триггеры метки» ещё темой 77, а миграции проектам никто не дал. Сняты остатки меток в task-track и в config-skeleton, уезжающем в чужой проект. Перечень осей досчитал три оси: глубина темы, разметка действия, род правки. Журнал — тема 81.
This commit is contained in:
@@ -340,7 +340,12 @@ kebab-case.** Причина не эстетическая: имя файла с
|
||||
проекте нет дома, сюда не пишется: её и так называет план каждого прогона.
|
||||
|
||||
**Журнал дефектов:** запись на каждый воспроизведённый дефект с пометкой
|
||||
**проскочил / пойман ревью**. Проскочившие — проверочный набор для калибровки конвейера,
|
||||
**проскочил / пойман ревью**. Запись — новое, и заводится она по слову человека
|
||||
(`av-dev:doc-sync`, «Два рода правок»): «на каждый» задаёт **обязанность
|
||||
предложить**, а не право записать молча. Человек отказал — записи нет, и
|
||||
калибровка конвейера по этому дефекту не состоится; это его решение и его цена.
|
||||
|
||||
Проскочившие — проверочный набор для калибровки конвейера,
|
||||
выборка по пометке. Пойманные с оракулом — лучшая опора для прохода: проектные,
|
||||
воспроизводимые, однажды оказавшиеся правдой.
|
||||
|
||||
|
||||
@@ -22,6 +22,44 @@
|
||||
|
||||
---
|
||||
|
||||
## Версия 5 — 2026-08-23
|
||||
|
||||
**Метка задачи снята из процесса целиком**, и вместе с ней — подраздел «Триггеры
|
||||
метки» в `docs/review.md`. Состав прогона ревью стал постоянным: он один и тот же
|
||||
на всякой задаче, выбирать нечего, и признаки, по которым метка поднималась,
|
||||
перестали что-либо решать. На месте подраздела — **«Когда звать глубокое ревью»**:
|
||||
те же наблюдения проекта, но адресованные другому решению — звать ли
|
||||
`av-dev:code-deep-review` по области кода.
|
||||
|
||||
**Что переехало в проекте.** Скелет `docs/review.md`, раздел настройки конвейера:
|
||||
подраздел «Триггеры метки» заменён подразделом «Когда звать глубокое ревью» —
|
||||
**двумя списками**: области, которые смотрят целиком (узлы с частым возвратом,
|
||||
места с историей инцидентов, код под дорогое решение), и **необратимое здесь** —
|
||||
что в этом проекте после мерджа не откатывается обратной правкой. Второй список
|
||||
работает и в цикле задачи: находка в таком месте уходит человеку развилкой, а не
|
||||
чинится молча. Само правило — в [canon.md](canon.md), раздел `review.md`.
|
||||
|
||||
**Что сделать проекту.**
|
||||
|
||||
1. **Переписать подраздел в `docs/review.md`.** Заголовок «Триггеры метки»
|
||||
становится «Когда звать глубокое ревью», содержимое — два списка выше.
|
||||
Признаки, годные только для выбора метки («больше N файлов», «затронуто больше
|
||||
одного слоя»), выбрасываются: состава прогона они не меняют. Что из прежнего
|
||||
списка называло **необратимое место** — переносится во второй список дословно.
|
||||
2. **Пройти по документам** — `grep -rniE "small|medium|large|метк" docs/`.
|
||||
Найденное в `review.md`, `conventions/` и `adr/` правится по смыслу: описание
|
||||
прошлого решения остаётся как свидетельство, действующая инструкция —
|
||||
переписывается или снимается.
|
||||
3. **Поднять версию** — `docs.py bump`, последним шагом.
|
||||
4. `docs.py check` — до отсутствия дрейфа.
|
||||
|
||||
**Чего делать не надо.** Заводить ключ `[docs] healthcheck_last` руками: он
|
||||
необязательный и появится сам первым прогоном `av-dev:doc-healthcheck`. Править
|
||||
прошлые записи журналов и архивные change — тоже: метка, стоявшая в них, верна
|
||||
как свидетельство о том дне.
|
||||
|
||||
---
|
||||
|
||||
## Версия 4 — 2026-08-13
|
||||
|
||||
Слово **провенанс** снято из словаря языка проектных текстов и заменено русским.
|
||||
|
||||
@@ -31,8 +31,8 @@ description: "Глубокое ревью области кода — не за
|
||||
**Вход этому скиллу копят проходы цикла.** Строка «отложено в
|
||||
`av-dev:code-deep-review`» в границах покрытия называет тему, место и запуск,
|
||||
которым это проверяется; триаж сводит такие строки в отдельную секцию отчёта.
|
||||
Второй источник — сигнал «это изменение просит глубокого ревью», который подаёт
|
||||
`review-code`.
|
||||
Второй источник — сигнал «это изменение просит глубокого ревью»: его подаёт
|
||||
`review-code` всегда и `review-basics`, когда запускается.
|
||||
|
||||
## Когда звать
|
||||
|
||||
@@ -119,16 +119,20 @@ capability — одним адресом или несколькими. Скил
|
||||
|
||||
## Состав прогона
|
||||
|
||||
Состав **постоянный**, и глубина у всех проходов одна — **доказательство**.
|
||||
Постоянен и состав цикла задачи, но он другой и мельче: разница между скиллами не
|
||||
в старательности, а в том, что здесь запускают, меряют и строят путь.
|
||||
Состав **постоянный**, но глубина у проходов **разная, и это не небрежность**.
|
||||
Доказательство дают те двое, что держат машину: `review-adversary` прогоняет
|
||||
падающий тест, `review-ops` снимает числа замером. `review-architecture` и
|
||||
`review-code` машину не держат — они дают **разбор на входе шире диффа**, и
|
||||
выдать доказательство им нечем. Постоянен и состав цикла задачи, но он другой и
|
||||
мельче: разница между скиллами не в старательности, а в том, что здесь запускают,
|
||||
меряют и строят путь.
|
||||
|
||||
| Проход | Тема | Что делает |
|
||||
|---|---|---|
|
||||
| `review-adversary` | `security` | строит путь и **прогоняет** падающий тест |
|
||||
| `review-ops` | `operations` | снимает числа замером: удержание, рост, деградация |
|
||||
| `review-architecture` | `architecture` | концептуальная целостность на входе шире диффа |
|
||||
| `review-code` | `conventions` и техника | читает код **как код**, целиком, а не диффом |
|
||||
| `review-code` | `conventions`, техника, инварианты | читает код **как код**, целиком, а не диффом; потолков здесь нет |
|
||||
| `review-triage` | — | единственный сток: дедуп, оракулы, потолок |
|
||||
|
||||
**Гейта здесь нет, и это не пропуск.** Гейт судит изменение — красный он или
|
||||
|
||||
@@ -43,8 +43,8 @@ context: |
|
||||
Пересказа этих документов здесь нет намеренно: второй дом факта расходится с
|
||||
первым молча, и заметно это становится в предложении, которое уже написано.
|
||||
|
||||
Ревью: правило выбора метки и состав проходов здесь не пересказываем — их дом
|
||||
скилл av-dev:code-review, проектная настройка — docs/review.md.
|
||||
Ревью: состав проходов и глубину тем здесь не пересказываем — их дом скилл
|
||||
av-dev:code-review, проектная настройка — docs/review.md.
|
||||
|
||||
Конвенции кода: механизированное проверяет гейт, прозой остаётся
|
||||
docs/conventions/. Ни состав шагов гейта, ни перечень конвенций здесь не
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: code-review
|
||||
description: "Конвейер ревью изменения, устроенный по темам: документ проекта либо заводит тему ревью, либо питает чужую тему источником, либо процессный и в ревью не читается вовсе. Ядро тем — requirements, autotests, conventions, architecture, security, operations; список тем открытый, свои темы проект заводит документом. Состав прогона постоянный, метки у него нет: гейт (autotests), сверка со спекой (specs), разбор кода и конвенций (code), триаж; приёмник тем (basics) идёт, когда у проекта есть свои темы. Цикл задачи проверяет корректность и механику против записанного критерия — дельта-спеки, конвенции, инварианты CLAUDE.md, вывод инструментов. Темы риска и устройства — security, operations, architecture — закрыты в цикле только сверкой с записанными инвариантами: их разбор, доказательство запуском и суждение о форме решения живут в скилле av-dev:code-deep-review, который идёт по области кода и время от времени. Порядок прогона — граф зависимостей: гейт открывает проходы с мнением, триаж — единственный сток. Находки по умолчанию чинятся инлайн и молча; человеку уходит только необратимое и то, что меняет дельта-спеки, а задачи из урожая заводятся по его слову. Проектная специфика приходит из документов канона проекта. Вызывается из скилла av-dev:code-resolve после apply. Второй вызов идёт от сценария обслуживания: без change, фиксированным планом (autotests, operations, плюс conventions, если тронут код)."
|
||||
description: "Конвейер ревью изменения, устроенный по темам: документ проекта либо заводит тему ревью, либо питает чужую тему источником, либо процессный и в ревью не читается вовсе. Ядро тем — requirements, autotests, conventions, architecture, security, operations; список тем открытый, свои темы проект заводит документом. Состав прогона постоянный, метки у него нет: гейт (autotests), сверка со спекой (specs), разбор кода и конвенций (code), триаж; приёмник тем (basics) идёт, когда у проекта есть свои темы. Цикл задачи проверяет корректность и механику против записанного критерия — дельта-спеки, конвенции, инварианты CLAUDE.md, вывод инструментов. Темы риска и устройства — security, operations, architecture — закрыты в цикле только сверкой с записанными инвариантами: их разбор, доказательство запуском и суждение о форме решения живут в скилле av-dev:code-deep-review, который идёт по области кода и время от времени. Порядок прогона — граф зависимостей: гейт открывает проходы с мнением, триаж — единственный сток. Находки по умолчанию чинятся инлайн и молча; человеку уходит только необратимое, трогающее инвариант CLAUDE.md и меняющее дельта-спеки, а задачи из урожая заводятся по его слову. Проектная специфика приходит из документов канона проекта. Вызывается из скилла av-dev:code-resolve после apply. Второй вызов идёт от сценария обслуживания: без change, фиксированным планом (autotests, operations, плюс conventions, если тронут код)."
|
||||
---
|
||||
|
||||
# Конвейер ревью
|
||||
@@ -188,7 +188,9 @@ description: "Конвейер ревью изменения, устроенны
|
||||
|
||||
**Проектная тема закрывается `basics`**, и только она. Именных проходов конечное
|
||||
число, а тем — сколько заведёт проект; приёмник обязателен, иначе открытость
|
||||
списка была бы обещанием без механизма. Темы **ядра** он не держит вовсе:
|
||||
списка была бы обещанием без механизма. Темы **ядра** он не держит **в цикле
|
||||
задачи** — на прогоне обслуживания план сценария даёт ему `operations`, и это
|
||||
единственное исключение (раздел «Прогон без change»). В цикле:
|
||||
`requirements` закрывает `specs`, `conventions` и технику — `code`, а риск и
|
||||
устройство — тот же `code` сверкой с инвариантами. Отсюда правило состава:
|
||||
**`basics` запускается тогда и только тогда, когда ему есть что принимать** — см.
|
||||
@@ -322,9 +324,12 @@ charter'а, а модель потом двигает калибровка, и
|
||||
|
||||
## Состав прогона — постоянный
|
||||
|
||||
**Ступени нумерованы и наружу не выходят.** Прогон ревью один, и зовёт его
|
||||
**Ступени нумерованы, и наружу выходит одна.** Прогон ревью один, и зовёт его
|
||||
`av-dev:code-resolve` после того, как код написан; членение внутри прогона —
|
||||
ступени, и знать их снаружи не нужно. Перечень осей процесса целиком —
|
||||
ступени, и знать их снаружи не нужно. Исключение единственное и названное:
|
||||
**ступень 1**, автотесты, — на неё ссылаются снаружи, потому что она умеет
|
||||
засчитать чужой прогон гейта по отпечатку дерева, и вызывающему надо знать, куда
|
||||
этот отпечаток едет. Перечень осей процесса целиком —
|
||||
[shared/axes.md](../../shared/axes.md).
|
||||
|
||||
**Состав не выводится ни из чего: он один и тот же на всякой задаче.** Гейт,
|
||||
@@ -487,7 +492,7 @@ flowchart TD
|
||||
|---|---|---|
|
||||
| `autotests` | да | запускает инструменты проекта — но он источник графа и один по построению |
|
||||
| `triage` | да | проверяет оракул `major` запуском — но он сток и тоже один |
|
||||
| `specs`, `code`, `basics`, `rubric` | нет | читают и рассуждают, ничего не исполняют |
|
||||
| `specs`, `code`, `basics` | нет | читают и рассуждают, ничего не исполняют |
|
||||
|
||||
**В цикле задачи цепочки за машину нет.** Оба прохода, что её держали —
|
||||
`adversary` и `ops`, — переехали в скилл `av-dev:code-deep-review`; там правило
|
||||
@@ -504,8 +509,10 @@ flowchart TD
|
||||
державшихся на таких замерах; у каждого проекта они свои и лежат в журнале
|
||||
`docs/review.md`.
|
||||
|
||||
Проект вправе пометить «держит машину» и другой проход — в `docs/review.md`,
|
||||
разделе настройки конвейера. Снимать пометку с перечисленных нельзя.
|
||||
Проект вправе пометить «держит машину» и другой проход — строкой в подразделе
|
||||
**«Недоступно проверке»** файла `docs/review.md`: своего подраздела у пометки нет,
|
||||
и заводить его канон не станет ради одного проекта. Читает её тот, кто строит
|
||||
порядок прогона, то есть этот скилл. Снимать пометку с перечисленных нельзя.
|
||||
|
||||
### Находка «переделать форму» — прогон повторяется целиком
|
||||
|
||||
@@ -554,7 +561,7 @@ flowchart TD
|
||||
|
||||
## Прогон без change — сценарий обслуживания
|
||||
|
||||
Третий вызывающий конвейера — сценарий обслуживания скилла `av-dev:code-resolve`
|
||||
Второй вызывающий конвейера — сценарий обслуживания скилла `av-dev:code-resolve`
|
||||
(тулчейн и сборка, зависимости, гит-хуки, перенос, чистка). Он приходит **без
|
||||
change**: у работы, не меняющей поведения, дельта-спек нет по построению.
|
||||
|
||||
@@ -709,7 +716,7 @@ change**: у работы, не меняющей поведения, дельт
|
||||
|
||||
**Технический разбор — не тема, а обязанность прохода, и он единственный.**
|
||||
Остальные читают код как материал для своей оптики: `specs` — против требований,
|
||||
`basics` — против отказов окружения, `architecture` — против устройства. «Здесь
|
||||
`basics` — против отказов окружения проекта. «Здесь
|
||||
ошибка в логике» не говорит больше никто, и до недавнего времени не говорил
|
||||
никто вовсе: `code` был проходом только по конвенциям, а дефект ловился разве что
|
||||
случайно. Это была самая крупная дыра конвейера, и стоила она дороже любой
|
||||
@@ -789,9 +796,9 @@ change»: сверять исход с планом триаж обязан и
|
||||
ущербу × вероятности → потолок 7 пунктов в основном списке.
|
||||
|
||||
**Разметку действия ставит он же, и умолчание у неё одно — `инлайн`.** Развилку
|
||||
получает только то, что инлайном чинить нельзя: находка по необратимому месту и
|
||||
находка, чья правка меняет дельта-спеки. Остальное чинится молча — см. «Что
|
||||
происходит с находками дальше».
|
||||
получает только то, что инлайном чинить нельзя, и оснований у неё три: правка
|
||||
меняет дельта-спеки, находка сидит в необратимом месте, находка трогает инвариант
|
||||
`CLAUDE.md`. Остальное чинится молча — см. «Что происходит с находками дальше».
|
||||
|
||||
**Он же собирает строки «отложено в `av-dev:code-deep-review`».** Проход, упёршийся
|
||||
в предел цикла — нужен замер, нужен прогнанный путь, нужен вход шире диффа, —
|
||||
@@ -821,11 +828,17 @@ change»: сверять исход с планом триаж обязан и
|
||||
|
||||
- **`Действие: развилка`** — вопросом с вариантами и ценой каждого туда, где
|
||||
проект держит вопросы (это знает вызвавший скилл, а не конвейер ревью).
|
||||
Помечается так **только** то, что инлайном чинить нельзя: находка по
|
||||
необратимому месту (миграция, формат на диске, публичный контракт) и находка,
|
||||
чья правка меняет **дельта-спеки** — то есть отменяет одобренное человеком.
|
||||
Оркестратор при этом не останавливается: он урезает изменение до остатка и
|
||||
доводит его.
|
||||
Помечается так **только** то, что инлайном чинить нельзя, и оснований ровно
|
||||
три: находка по **необратимому** месту (миграция, формат на диске, публичный
|
||||
контракт), находка, трогающая **инвариант** `CLAUDE.md`, и находка, чья правка
|
||||
меняет **дельта-спеки** — то есть отменяет одобренное человеком.
|
||||
|
||||
По первым двум основаниям оркестратор **не останавливается**: он урезает
|
||||
изменение до остатка и доводит его. Третье старше: правка, меняющая
|
||||
дельта-спеки, отменяет одобрение, и оркестратор **возвращается на чекпоинт**
|
||||
(`av-dev:code-resolve`, `references/solve.md`, шаг 5). Вопрос в запись при этом
|
||||
остаётся, но возврата не заменяет — иначе одобренный дизайн переделывался бы
|
||||
молча.
|
||||
- **урожай** — находка реальная, но не для этого мерджа: отложенный `major`,
|
||||
развилка, решённая «потом», пачка `nit`. Конвейер отдаёт её **списком** в
|
||||
отчёте: формулировка, оракул, откуда взялась (какой проход, какой change).
|
||||
|
||||
@@ -98,7 +98,8 @@
|
||||
**Кто какой документ читает — из документа не выводится, а назначается планом.**
|
||||
Документ питает тему (это записано на стороне канона, таблица «Роли документов и
|
||||
темы ревью»), а тему на этом прогоне закрывает тот, кто назван в составе прогона; вся
|
||||
раскладка «тема → проход → глубина» — в `SKILL.md` этого скилла и больше нигде.
|
||||
раскладка «тема → кто закрывает → против чего» — в `SKILL.md` этого скилла и
|
||||
больше нигде.
|
||||
**Списка читателей не ведёт никто, и это не пробел.** Он жил бы на стороне
|
||||
канона, а документ живёт дольше, чем раскладка проходов: список разошёлся бы с
|
||||
конвейером молча и при этом выглядел актуальным. Однажды уже разошёлся.
|
||||
|
||||
@@ -150,6 +150,12 @@ check` и его скрипт; здесь начинается там, где к
|
||||
этого делать нечего. Его отсутствие значит «сверки не было ни разу», и синк
|
||||
говорит это отдельной строкой.
|
||||
|
||||
**Правку следа коммитит тот, кто позвал прогон.** Своего коммита у скилла нет:
|
||||
он правит документы, заводит задачи и ставит след — всё это уезжает одним
|
||||
коммитом разбора, и `last` в нём указывает на **прежний** `HEAD`, то есть на
|
||||
состояние, которое сверяли. Оставить правку незакоммиченной нельзя: счёт пойдёт
|
||||
от коммита, которого в истории нет.
|
||||
|
||||
**Позвал одного агента из двух — след всё равно ставится, но в докладе назван
|
||||
неполным.** Иначе следующая сверка отсчитывалась бы от прогона, который смотрел
|
||||
половину.
|
||||
|
||||
@@ -244,20 +244,22 @@ stateDiagram-v2
|
||||
**напоминает** — беклог, заведённый до появления типа, законен, и переоформлять
|
||||
его «заодно» здесь не просят.
|
||||
|
||||
**Тип не выбирает метку ревью и глубину проверки.** Профиль выбирается по факту
|
||||
изменения, а не по типу задачи: `chore` бывает миграцией схемы, `fix` — правкой
|
||||
публичного контракта. Правило «предписание процесса в теле задачи снимается»
|
||||
типом не отменяется, а подтверждается: он описывает работу, а не то, как её
|
||||
проверять. **Стадия проекта их тоже не выбирает**: изменение на стройке ничем не
|
||||
проще того же изменения на доработке, и метку ему по-прежнему назначает разметка.
|
||||
**Тип не выбирает состав ревью и глубину проверки — и не выбирает их больше
|
||||
никто.** Состав прогона постоянный: он один и тот же на всякой задаче
|
||||
(`av-dev:code-review`, «Состав прогона»). Прежде состав считала метка `small` ·
|
||||
`medium` · `large`, и тогда эта строка отвечала на живой вопрос «не задаёт ли её
|
||||
тип»; метки нет, и вопрос снят вместе с ней. Правило «предписание процесса в теле
|
||||
задачи снимается» типом не отменяется, а подтверждается: он описывает работу, а
|
||||
не то, как её проверять. **Стадия проекта состава тоже не выбирает**: изменение
|
||||
на стройке ничем не проще того же изменения на доработке.
|
||||
|
||||
**Одно исполнителю тип всё же говорит — каким сценарием работу вести, и то не
|
||||
один.** Скилл `av-dev:code-resolve` выбирает сценарий связкой из двух
|
||||
признаков: тип **предлагает** (`chore` — обслуживание, `research` — разведка),
|
||||
а подтверждает его предмет работы — есть ли что менять в спеках. Признаки
|
||||
разошлись — работа останавливается, и тип меняется здесь, командой `edit --type`,
|
||||
а не переклеивается исполнителем по ходу. Метку и глубину это по-прежнему не
|
||||
задаёт: их называет разметка изменения, а на прогоне без change — сам сценарий.
|
||||
а не переклеивается исполнителем по ходу. Состава ревью это по-прежнему не
|
||||
задаёт: он постоянный, а на прогоне без change его называет сам сценарий.
|
||||
|
||||
## Как написана задача
|
||||
|
||||
@@ -567,9 +569,9 @@ python3 $tk adopt scan --from … --stage S | apply --plan … # разова
|
||||
**каждая давать видимую пользу**, а у штурма исход «выкинуть» — полноправный.
|
||||
|
||||
Там же **шов**: где резать, когда допустимых мест несколько. Коротко — по
|
||||
границе, которая одна поднимает метку ревью выше остальных; и не резать, когда
|
||||
обе половины остаются в одной метке, потому что несокращаемый костяк проверок
|
||||
платится за каждую задачу отдельно.
|
||||
границе, где **меняется род работы**; и резать пореже, потому что костяк ревью
|
||||
разрез удваивает **всегда** — состав прогона постоянный и от размера половин не
|
||||
зависит. Выигрыш даёт не проверка, а то, что половина доводится и мерджится сама.
|
||||
|
||||
### Вычитка: два прохода, а не один
|
||||
|
||||
@@ -633,9 +635,10 @@ python3 $tk adopt scan --from … --stage S | apply --plan … # разова
|
||||
- **свойство репозитория в рамках** — номер миграции, хеш, версия зависимости:
|
||||
в лежалой задаче протухает молча и становится ложной рамкой. Снимается;
|
||||
снимок берётся при постановке, а не при заведении;
|
||||
- **предписание процесса в теле** — «делать с такой-то меткой ревью», «взять
|
||||
такой-то агент»: это второй дом для правила выбора и путь понизить требования
|
||||
решением, принятым до проектирования. Снимается;
|
||||
- **предписание процесса в теле** — «прогнать глубоким ревью», «взять такой-то
|
||||
агент», «этой задаче хватит короткой проверки»: это второй дом для правила
|
||||
выбора и путь понизить требования решением, принятым до проектирования.
|
||||
Снимается;
|
||||
- **тип, разошедшийся с задачей** — задача заводилась починкой, а после разбора
|
||||
оказалось, что поведение никогда и не было заявлено: это `feature`, а не `fix`.
|
||||
Правится `edit <slug> --type …`; тип, оставшийся от прошлой формулировки, врёт
|
||||
|
||||
Reference in New Issue
Block a user