docs: align AGENTS.md and PROCESS.md with the actual process

Publishes the 538-line process canon into the repository, replacing the
51-line provenance stub that pointed at a non-existent .agents/PROTOCOL.md.
Rewrites AGENTS.md: product context first, labels as the canonical status,
rule #1 with the status check, change classes, trailers, push cadence,
Codex/Claude roles and review cycle limits.

Issue: #112
User-Visible: no
This commit is contained in:
Matysh
2026-08-13 10:30:00 +03:00
parent f339398f56
commit 53da8a1773
2 changed files with 737 additions and 82 deletions
+519 -38
View File
@@ -1,57 +1,538 @@
# House Plan change provenance
# Процесс работы над House Plan
This file is the repository-visible minimum process contract. The detailed
two-agent workflow lives in `.agents/PROTOCOL.md` in the owner's checkout;
contributors and fresh agents must still be able to discover the rules below
from a plain clone.
> **Статус документа:** черновик 3 (2026-08-12), на согласование владельцу.
> Решения владельца, зафиксированные в этой редакции: прямые коммиты в `dev` без
> PR · канон статуса — **метки** · лёгкий трек для мелких задач **включён**.
>
> **Область действия:** обязателен для владельца и для любого агента (Cowork,
> Cursor Cloud, Codex, локальные сессии). Читается сразу после `AGENTS.md`, до
> `docs/STATUS.md`.
>
> **Приоритет источников:** GitHub Issues + Project v2 — канонический бэклог.
> Статус живёт в метках issue. При расхождении документации с GitHub побеждает
> GitHub; при расхождении процесса и привычки побеждает процесс.
## Before changing code
---
Every product, test, documentation or release change must belong to a GitHub
issue in the canonical House Plan Project. Keep scope and acceptance criteria
there; a local spec supports an issue but does not replace it.
## 1. Основное правило
## Commit trailers
**Изменение продуктового кода без issue запрещено.** Код меняется только тогда,
когда issue существует и находится в статусе «Готово к разработке» или дальше.
Исключения — только §11, и каждое оставляет след.
Every non-merge commit carries:
Правило работает лишь при точной границе «продуктового кода», иначе спор
переносится на границу:
```text
Issue: #123
User-Visible: yes
| Класс | Что входит | Нужен ли issue |
|---|---|---|
| **A. Продукт** | `src/**`, `custom_components/houseplan/**/*.py`, `manifest.json`, `hacs.json`, `src/i18n/*.json`, `custom_components/**/translations/*` | **Да, обязательно.** Только из «Готово к разработке» или дальше |
| **B. Гейты и инструменты** | `test/**`, `tests_backend/**`, `demo/**`, `scripts/**`, `.github/workflows/**`, `rollup.config.mjs`, `tsconfig*.json` | **Да.** Может использовать issue того изменения, которое покрывает; самостоятельная работа над гейтом получает свой issue (тип «техдолг») |
| **C. Документация** | `docs/**`, `README*`, `CHANGELOG*`, `AGENTS.md` | Документирование A/B в том же коммите — часть DoD своего issue. Самостоятельная работа над документацией — свой issue |
| **D. Сгенерированное** | `dist/**`, `custom_components/houseplan/frontend/**`, `demo/srv/assets/houseplan-card.js`, `demo/golden/baselines/**` | Никогда не меняется само по себе. Коммит **только** класса D допустим лишь как релизный промоушен или как принятие эталонов с доказательством ревью |
Практический смысл таблицы: «я только поправил тест» и «я только пересобрал
бандл» перестают быть лазейками.
---
## 2. Жизненный цикл
Семь рабочих статусов и два служебных. Фазы тестирования в цикле сознательно
**нет**: найденные позже дефекты заводятся отдельными issue и проходят цикл
заново. Issue закрывается после выпуска беты.
```
Новое → Аналитика и оценка → ТЗ в работе → ТЗ на ревью ⟲ → Готово к разработке →
→ В разработке → Код-ревью ⟲ → Закрыт (после выпуска беты)
служебные: Заблокировано (parking) Отклонено (закрыт)
⟲ — возврат на правки, не более 4 циклов (§4)
```
Use `User-Visible: no` for refactoring, tests, build tooling and documentation
that do not change product behaviour. A commit that changes reviewed golden
baselines additionally carries both:
### 2.1 Новое — заведение задачи
```text
Release: v1.2.3-beta.1
Baseline-Reviewed: <CI run or artifact reference>
- **Кто:** любой — владелец, агент, пользователь (Telegram, GitHub).
- **Вход:** проблема в пользовательских терминах; как проявляется или зачем нужно.
Решение **не требуется** и не приветствуется.
- **Запрещено:** ставить приоритет, оценивать, писать ТЗ, начинать код.
### 2.2 Аналитика и оценка
Задача разбирается, продуктовое «да» ещё не дано.
- **Кто:** агент-аналитик готовит, владелец решает.
- **Чек-лист**, результат — комментарием в issue:
1. дубликаты проверены (ссылки на похожие issue);
2. в скоупе по `docs/SCOPE.md` и `docs/TOUCH-SUPPORT.md`;
3. **пользовательская ценность 1–10** и **ценность для разработки** — что
упрощает или разблокирует;
4. **сложность и риск 1–10** — трудоёмкость плюс вероятность задеть смежное;
5. приоритет **P1/P2/P3**;
6. тип: баг / фича / техдолг;
7. затронутые поверхности (модули, диалоги, бэкенд, i18n);
8. лёгкий трек — да/нет по критериям §5.
- **Приоритет и ценность — поля владельца.** Агент предлагает, владелец
утверждает; иначе агенты приоритизируют сами и P1 разрастается.
- **Выход:** «ТЗ в работе» либо «Отклонено» с записанной причиной.
### 2.3 ТЗ в работе — написание ТЗ
- **Кто:** автор ТЗ, назначает себя. Статус означает «занято».
- **Артефакт:** `docs/specs/<NN>-<slug>.md`, где `NN` — **номер issue**.
Многоэтапная задача: `<NN>-<slug>-stage<N>.md`.
- **Лёгкий трек:** ТЗ пишется в теле issue, файл не создаётся (§5).
- **Выход:** полная первая редакция по §7.
### 2.4 ТЗ на ревью
- **Ревьюер ≠ автор.** Ревьюер получает issue и ТЗ, без устных пояснений автора.
Его задача — не согласиться, а найти, где ТЗ не выполнимо или не проверяемо.
- **Артефакт:** `docs/reviews/SPEC-REVIEW-<NN>-r<N>.md`, вердикт
зелёный / жёлтый / красный. Лёгкий трек — комментарий в issue.
- **High-находки блокируют.** Medium/Low — либо правятся, либо становятся
отдельными issue со ссылкой; «оставили в тексте ревью» не считается закрытием.
- **Выход:** «Готово к разработке» либо возврат в «ТЗ в работе» — не более
4 циклов (§4).
### 2.5 Готово к разработке (DoR)
Не работа, а **очередь**: единственный статус, из которого можно трогать код.
Все пункты обязательны:
- ТЗ существует, ревью ТЗ зелёное, ссылки issue ↔ ТЗ на месте;
- **AC1…ACn** — пронумерованные проверяемые критерии приёмки; у каждого указано,
чем он доказывается: `unit` / `backend` / `smoke` / `golden` / «ревью кода»;
- перечислены затронутые файлы и модули;
- i18n: ключи en + ru перечислены;
- миграция и compatibility-поля решены по `docs/CONFIG-COMPATIBILITY.md`;
- влияние на производительность и бюджеты названо (или явно «нет»);
- влияние на touch по `docs/TOUCH-SUPPORT.md` (View и киоск — блокирующие);
- release-артефакты по правилу `docs/specs/README.md` (changelog RU+EN,
документация, golden/скриншоты, performance/security);
- **откат**: как выключить или вернуть назад (флаг Labs, обратная миграция);
- открытых продуктовых вопросов нет; риски перечислены.
Если хоть один пункт не выполнен — статус не «Готово к разработке», как бы ни
хотелось начать.
### 2.6 В разработке — реализация
- **Занятие (claim):** назначить себя, поставить метку, комментарий
«Взял: <роль> · сессия <id> · ветка `issue/<NN>-<slug>`».
- **WIP-лимиты:** не более **1** issue в «В разработке» на исполнителя, не более
**3** одновременно на цикл релиза, не более **2** в «Код-ревью».
- **Трассируемость:** ветка `issue/<NN>-<slug>`; каждый коммит несёт трейлеры
`Issue: #<NN>` и `User-Visible: yes|no`.
- **Автотесты — часть реализации, а не отдельная фаза.** Каждый AC, помеченный
`unit`/`backend`/`smoke`/`golden`, получает свою проверку здесь же.
«Тестирование вне жизненного цикла» означает отсутствие фазы ручного
тестирования, а не отсутствие тестов.
- **Скоуп не расширяется.** Найденное по пути становится новым issue в «Новое».
Если находка блокирует — текущий issue уходит в «Заблокировано» со ссылкой.
Попутных правок «раз уж я здесь» не бывает.
- **Документация — в том же коммите,** что и поведение (действующая политика
`docs/STATUS.md`): changelog RU+EN для пользовательского, `STATUS.md` для
состояния, `DEVELOPMENT.md` для новых грабель, `ARCHITECTURE.md` для дизайна.
- **Выход:** локальный гейт зелёный (§8), хендофф-комментарий (§7.2).
### 2.7 Код-ревью
- **Ревьюер ≠ исполнитель**, свежая сессия без контекста реализации.
- **Артефакт:** `docs/reviews/CODE-REVIEW-<tag|NN>-r<N>.md` в действующем
формате: скоуп, как проверялось (таблица гейтов с результатами), находки
High/Medium/Low с воспроизведением, что проверено и корректно, чего не проверял.
- **Ревьюер отвечает за AC.** Раз ручного тестирования в цикле нет, именно ревью
кода отвечает на вопрос «оно вообще работает»: каждый AC либо доказан
автотестом — и ревьюер убедился, что **тест умеет падать**, — либо разобран по
коду с явной записью «проверено чтением, не исполнением».
- **High блокируют.** Medium **обязаны** превратиться в issue.
- **Выход:** очередь на пре-релиз либо возврат в «В разработке», не более
4 циклов (§4).
### 2.8 Закрытие после выпуска беты
- **Вход:** изменение вошло в опубликованную бету/RC, CI Validate зелёный на
**точном SHA** тега (промоушен-правило: ни одна фича не попадает в стабильный
релиз, не побывав в бете).
- **Закрывает** релиз-менеджер, не исполнитель. Комментарий закрытия: тег беты,
ссылка на прогон CI, ссылка на бюллетень changelog.
- **Стабильный релиз статусов не двигает** — issue уже закрыты; релизный коммит
promotion-only, changelog ссылается на закрытые issue.
- **Что приходит потом:** дефект, найденный на стенде, дома или пользователем, —
**новый issue** типа «баг» со ссылкой на исходный. Исходный не переоткрывается.
### 2.9 Заблокировано / Отклонено
- **Заблокировано:** обязательна ссылка на блокирующий issue или внешнюю причину
и дата пересмотра. Без причины статус не ставится.
- **Отклонено:** закрытие с записанной причиной (вне скоупа, дубликат, цена не
оправдана). Тихое закрытие без причины запрещено.
---
## 3. Правила
Продолжение черновика владельца. Каждое правило проверяемо — глазами или машиной.
1. **Никаких изменений в код, если нет issue** и он не помечен «Готово к
разработке» или дальше.
2. **Issue не может быть взят в разработку**, пока у него нет ТЗ с зелёным ревью,
пронумерованных AC с указанием доказательства и назначенного исполнителя.
3. **Issue не может быть взят дважды.** Занятие фиксируется назначением, меткой и
комментарием с именем ветки. У одного исполнителя одновременно не более одного
issue в разработке.
4. **Статус меняется до действия, а не после.** Взял — поставил метку; отдал на
ревью — поставил метку. Метка, поставленная задним числом, — дефект процесса.
5. **Ровно одна метка статуса** на issue в любой момент. Ноль или две — дефект,
еженедельная гигиена его показывает.
6. **Автор не ревьюит своё** — ни ТЗ, ни код. Никто не переводит свою работу через
ревью-гейт.
7. **Ревью возвращает не более 4 раз.** Пятый заход — решение владельца: разделить,
отклонить или арбитраж (§4).
8. **High блокирует. Medium становится issue.** Low либо правится, либо снимается
решением ревьюера с записью в документе.
9. **Скоуп не расширяется.** Всё найденное вне ТЗ — новый issue, а не попутная
правка. Блокирующая находка отправляет текущий issue в «Заблокировано».
10. **Каждый коммит класса A и B несёт трейлер `Issue: #NN`**, ветка называется
`issue/NN-slug`, а `User-Visible: yes` требует правок в **обоих** changelog в
том же коммите.
11. **Документация — в том же коммите, что поведение.** Отдельным «допишу потом»
коммитом документация не бывает.
12. **Сгенерированное не коммитится само по себе.** Только релизный промоушен или
принятие эталонов со ссылкой на прогон CI.
13. **Golden-эталоны принимаются только** `npm run golden:accept -- --reviewed` по
полному Linux-артефакту. Принятие ради зелёного CI — нарушение процесса.
14. **Issue закрывается после выпуска беты** с зелёным CI на точном SHA. Не
раньше, не «по факту наличия кода», не исполнителем.
15. **Закрытый issue не переоткрывается.** Новый дефект — новый issue со ссылкой.
16. **Стабильный релиз — promotion-only:** версии, сгенерированные бандлы,
changelog и release-метаданные. Продуктового кода там нет.
17. **История `dev` не перезаписывается.** На неё ссылаются теги. Нарушение
исправляется следующим коммитом плюс issue с меткой `процесс` — не
force-push'ем.
18. **AC доказывает автотест или запись ревьюера.** Фразы «проверил локально, всё
работает» в процессе не существует: либо тест, который умеет падать, либо
честное «проверено чтением, не исполнением».
19. **Параллельных бэклогов нет.** Планы, разборы и приоритеты живут в issue;
файловые отчёты — разовые и датированные.
20. **Аварийный хотфикс — только решением владельца** и только по §11.2.
---
## 4. Лимит циклов ревью: 4
Оба ревью-гейта возвращают задачу на правки не более **4 раз**. Счётчик виден в
имени документа: `-r1` … `-r4`; на четвёртом заходе ставится метка `ревью-4`.
- **Что считается циклом:** отправка на ревью → вердикт с блокирующими находками
→ возврат. Уточняющий вопрос без вердикта циклом не считается.
- **Исчерпание лимита — не «пятая попытка», а разбор.** Задача уходит владельцу,
решение одно из трёх:
1. **разделить** — issue закрывается как «заменён», вместо него 2–3 меньших с
ясным скоупом (частый настоящий диагноз: ТЗ было слишком большим);
2. **отклонить** — цена решения оказалась выше ценности;
3. **арбитраж владельца** — владелец фиксирует решение в issue, оно принимается
как есть; несогласие ревьюера записывается, но не блокирует.
- **Граница между «циклом» и «новым багом»:** до закрытия беты находка ревьюера —
возврат на правки; после закрытия — новый issue. Иначе лимит 4 обходится
заведением issue вместо возврата.
- Для лёгкого трека лимит ревью ТЗ — **2** цикла: задача на три часа, которую
переписывают трижды, лёгкой не была.
---
## 5. Лёгкий трек (метка `малое`)
**Критерии — все одновременно:**
- сложность и риск ≤ 3;
- одна поверхность (один диалог, один модуль, один эндпоинт);
- нет миграции конфига и новых compatibility-полей;
- нет нового UX-контракта — меняется поведение в рамках уже описанного;
- нет влияния на производительность и на touch-контракт.
**Что упрощается:**
- ТЗ пишется **в теле issue** по шаблону: проблема · контракт · AC1…ACn с
доказательством · откат. Файл в `docs/specs/` не создаётся;
- ревью ТЗ — комментарий второго агента, отдельный документ не нужен;
- лимит ревью ТЗ — 2 цикла.
**Что не упрощается:** issue, оценка, статусы, трейлеры коммитов, changelog,
**код-ревью и его документ**, закрытие после беты. Код-ревью не пропускается
никогда — именно оно в этом процессе заменяет тестирование.
Если по ходу выясняется, что критерий нарушен (появилась миграция, задело второй
модуль) — метка `малое` снимается, issue возвращается в «ТЗ в работе» и получает
нормальный файл ТЗ. Это не провал, это ранняя диагностика.
---
## 6. Роли
Один агент может исполнять несколько ролей в разных issue, но **не две роли в
одном артефакте**.
| Роль | Делает | Не имеет права |
|---|---|---|
| Аналитик | разбор, оценки, поверхности | окончательно ставить приоритет |
| Автор ТЗ | `docs/specs/NN-*.md` или ТЗ в issue | ревьюить своё ТЗ |
| Ревьюер ТЗ | `docs/reviews/SPEC-REVIEW-NN-rN.md` | править ТЗ вместо автора |
| Разработчик | код, автотесты, документация, changelog | ревьюить свой код, принимать golden |
| Ревьюер кода | `docs/reviews/CODE-REVIEW-*-rN.md`, проверка AC | править продуктовый код |
| Релиз-менеджер | пре-релиз, стабильный релиз, закрытие issue | добавлять код в релизный коммит |
| Владелец | приоритет, ценность, скоуп, отклонение, арбитраж, хотфикс | — |
**Правило разделения:** ревьюер работает состязательно. Ему передаётся тег или
диапазон коммитов и ТЗ — не рассказ автора о том, как всё хорошо.
**Принято по умолчанию, поправь если не так:** ревьюер — отдельная сессия
(Cowork / Codex / Cursor Cloud), выбор чередуется, лишь бы это была не та сессия,
что делала артефакт; релиз-менеджер — владелец.
---
## 7. Артефакты и трассируемость
### 7.1 Цепочка
```
issue #NN
↔ ТЗ docs/specs/NN-slug.md (или тело issue при `малое`)
↔ ревью ТЗ docs/reviews/SPEC-REVIEW-NN-rN.md (или комментарий при `малое`)
↔ ветка issue/NN-slug
↔ коммиты трейлеры Issue: #NN · User-Visible: yes|no
↔ ревью кода docs/reviews/CODE-REVIEW-<tag|NN>-rN.md
↔ changelog бюллетень RU+EN со ссылкой на #NN
↔ бета тег, зелёный CI на точном SHA → закрытие
```
Never invent a review reference merely to pass a gate. Baselines are accepted
only from the complete Linux CI artifact via `golden:accept -- --reviewed`.
Обязательные разделы ТЗ: проблема · скоуп и **не-скоуп** · контракт поведения ·
UX · модель данных и миграция · i18n · критерии приёмки AC1…ACn с указанием
доказательства · план автотестов · риски · откат · release-артефакты.
## Prerelease naming
### 7.2 Шаблоны комментариев
Use `beta.1` through `beta.9`, then continue the same version line with
`rc.1`. GitHub/HACS prerelease discovery orders `beta.10` behind `beta.9`, so
the publisher rejects beta numbers greater than nine before creating a tag.
Короткие и однообразные, чтобы читались и человеком, и машиной.
Install dependencies once per clone; the `prepare` script activates the
repository hook automatically:
- **Аналитика:** `Оценка: ценность N/10 · сложность N/10 · P<1-3> · тип ·
поверхности: … · дубликаты: … · лёгкий трек: да/нет`
- **Занятие:** `Взял: <роль> · сессия <id> · ветка issue/NN-slug`
- **Хендофф:** `Сделано: … · Файлы: … · Гейты: <команда → результат> ·
НЕ сделано: … · Риски: … · Следующий статус: … · Новые issue: #…`
- **Вердикт ревью:** `Вердикт: зелёный/жёлтый/красный · цикл r<N>/4 · High: N ·
Medium: N → #… · Документ: docs/reviews/…`
- **Закрытие:** `Выпущено в <тег беты> · CI: <ссылка> · Changelog: <ссылка>`
```bash
npm install
### 7.3 Расхождения с текущим состоянием, которые надо закрыть
1. **Ревью живут вне репозитория.** 20+ файлов `CODE-REVIEW-*.md` и
`SPEC-REVIEW-*.md` лежат только в личной папке владельца. Агент, пришедший
через месяц, не видит, почему решение принято именно так, и повторяет
разобранную ошибку. → `docs/reviews/`.
2. **Статус ТЗ дублирует статус issue.** `docs/specs/README.md` держит колонку
«Статус ТЗ» со своим словарём («черновик решения», «в реализации»,
«реализовано»). Два источника статуса уже расходятся. Колонку убрать, оставить
таблицу «issue ↔ ТЗ».
---
## 8. Гейты
**Локальный гейт перед выходом из «В разработке»** — минимальный набор,
покрывающий изменённые поверхности (действующее правило владельца):
```
npx tsc --noEmit
npm test
npm run build && cmp dist/houseplan-card.js custom_components/houseplan/frontend/houseplan-card.js \
&& cmp dist/houseplan-card.js demo/srv/assets/houseplan-card.js
node demo/smoke_<целевые>.mjs
npm run golden:verify # если менялся визуал
python -m pytest tests_backend -q # py3.13, если менялся бэкенд
```
The hook checks message provenance locally; `validate.yml` enforces the same
terminal-trailer contract for every non-merge commit in a push or PR, so
`--no-verify`, rebases and fresh clones cannot bypass it. Test, build and release gates remain
the commands documented in `CONTRIBUTING.md` and `docs/TESTING.md`.
**Гейт беты** (условие закрытия issue): CI Validate зелёный на точном SHA тега.
## Release history
**Гейт стабильного релиза:** полный локальный прогон плюс Validate и Full
Performance зелёные на точном SHA; статусов issue не касается.
Do not rewrite published commits to add missing trailers. Record the gap in an
audit and enforce this contract on future work. Promotion-only stable commits
remain subject to the same Issue/User-Visible trailers.
---
## 9. Метки — канонический статус
Статус читается из меток: их видно в списке issue и их читает любой токен с
доступом к Issues, в отличие от Project v2, который требует отдельного скоупа.
Project v2 остаётся человеческим представлением и синхронизируется по меткам.
| Метка | Статус |
|---|---|
| `S1-новое` | Новое |
| `S2-аналитика` | Аналитика и оценка |
| `S3-тз` | ТЗ в работе |
| `S4-тз-ревью` | ТЗ на ревью |
| `S5-к-разработке` | Готово к разработке |
| `S6-в-разработке` | В разработке |
| `S7-код-ревью` | Код-ревью |
| `заблокировано` | Заблокировано (поверх статусной метки) |
| `отклонено` | Отклонено, issue закрыт |
Модификаторы: `малое` (лёгкий трек), `hotfix`, `процесс`, `ревью-4`,
приоритет `P1`/`P2`/`P3`, тип `баг`/`фича`/`техдолг`.
Правила: ровно одна `S*`-метка; закрытый issue статусных меток не несёт;
`заблокировано` не заменяет статус, а дополняет его.
---
## 10. Механизация при прямых коммитах в `dev`
Решение владельца — работать без PR. Значит, GitHub не может ничего заблокировать
на своей стороне: **основной гейт переезжает на клиента, CI остаётся страховкой.**
### 10.1 Хуки, которые невозможно забыть поставить
`.githooks/` в репозитории, `core.hooksPath` выставляется автоматически при
установке зависимостей:
```json
"scripts": { "prepare": "node scripts/install-hooks.mjs" }
```
`npm ci` вызывает `prepare` сам — значит, хуки появляются в каждом окружении,
включая свежий контейнер облачного агента, без отдельного шага в инструкции.
- **`commit-msg`** — отклоняет коммит без `Issue: #NN`, если тронут класс A или B;
проверяет `User-Visible`.
- **`pre-push`** — прогоняет `scripts/process-gate.mjs` по всему пушимому
диапазону. Это и есть блокирующий гейт вместо PR.
### 10.2 Что проверяет `process-gate.mjs`
Офлайн, без GitHub API:
1. трейлер `Issue: #NN` у каждого коммита класса A/B;
2. имя ветки `issue/NN-slug` соответствует трейлерам;
3. для класса A существует `docs/specs/NN*-*.md` со ссылкой на issue — **или**
issue помечен `малое` (для этого нужен этап 2, до него — исключение по списку);
4. `User-Visible: yes` → правки в обоих changelog в том же коммите;
5. коммит только класса D невалиден без `Release: vX.Y.Z` либо
`Baseline-Reviewed: <ссылка на прогон CI>`;
6. релизный коммит не содержит изменений в `src/` и `custom_components/**/*.py`;
7. документов ревью на один issue не больше четырёх (`-r1`…`-r4`).
С токеном GitHub (PAT уже есть у релизных скриптов):
8. `--issues` тянет каждый упомянутый issue и требует метку из
{`S5-к-разработке`, `S6-в-разработке`, `S7-код-ревью`}; закрытый или
отсутствующий issue — отказ (fail closed);
9. `npm run release:prerelease -- --issues=…` отказывается, если у issue нет
зелёного вердикта код-ревью;
10. закрытие issue и снятие статусных меток автоматизируются по факту публикации
беты — в `publish-prerelease.yml`, а не по памяти человека.
### 10.3 Страховка и разбор
- **Тот же `process-gate.mjs` — job в `validate.yml`.** При прямом push проверка
догоняющая: код уже в `dev`, CI краснеет после. Это принятая цена отказа от PR.
- **Нарушение не откатывается force-push'ем** (правило 17): исправляющий коммит
плюс issue с меткой `процесс`. Починить надо проверку, а не только симптом.
- **Еженедельная гигиена** (workflow): issue в «Новое» дольше 14 дней и в
«В разработке» дольше 7; issue класса A в `S5` без ТЗ; issue с нулём или двумя
`S*`-метками; коммиты без трейлера за неделю — **цель 0**; rework rate и число
issue, дошедших до `ревью-4`; **баги, заведённые после закрытия беты** — прямая
цена отказа от фазы тестирования.
---
## 11. Исключения
### 11.1 Лёгкий трек
См. §5 — это не исключение из правила №1, а более дешёвый путь по тем же статусам.
### 11.2 Аварийный хотфикс (метка `hotfix`, решение владельца)
Разрешено писать код до появления issue. Обязательно:
- issue создан в **той же сессии до коммита**, метка `hotfix`;
- ТЗ «как сделано» + раздел «почему нельзя было ждать»;
- в течение 24 часов задача ретроспективно проходит код-ревью;
- аварийность названа явно в релизном хендоффе (действующее правило `AGENTS.md`).
### 11.3 Гигиена репозитория
Механические изменения без изменения поведения (форматирование, мёртвые файлы)
идут под квартальный umbrella-issue «Гигиена репозитория»; каждый коммит
ссылается на него. Трассируемость 1:1 сохраняется.
---
## 12. Запрещено
- код без issue или из статуса раньше «Готово к разработке»;
- ТЗ, написанное после кода (кроме §11.2, и тогда с пометкой «как сделано»);
- ревью своей работы; перевод своей работы через ревью-гейт;
- пятый цикл ревью вместо разбора по §4;
- заведение issue вместо возврата на правки, чтобы обойти лимит циклов;
- принятие golden-эталонов ради зелёного CI или по частичному артефакту;
- закрытие issue до выпуска беты с зелёным CI;
- переоткрытие закрытого issue вместо нового бага;
- Medium-находки, оставленные как TODO в документе ревью;
- **параллельные бэклоги** в файлах (`BACKLOG-*.md`, «планы» в docs);
- ревью-документы вне репозитория;
- попутные правки «раз уж я здесь»;
- фича или материальное изменение поведения в стабильном релиз-коммите;
- force-push в `dev`;
- ручное копирование на домашний инстанс.
**Нарушение процесса — тоже issue** (метка `процесс`): если правило удалось
нарушить незаметно, виновата проверка.
---
## 13. Внедрение
1. Создать метки §9; разметить 38 открытых issue. Всё, что по
`docs/specs/README.md` «в реализации», но не прошло ревью, — в честный статус.
2. Перенести существующие `CODE-REVIEW-*.md` и `SPEC-REVIEW-*.md` в
`docs/reviews/`; убрать колонку «Статус ТЗ» из `docs/specs/README.md`.
3. Завести issue на сам гейт (класс B, техдолг): `scripts/process-gate.mjs`,
`.githooks/`, `prepare`-скрипт, job в `validate.yml`. По новому процессу он
сам обязан пройти ТЗ → ревью → реализацию.
4. Закрыть текущий долг ревью: `beta.2…beta.4` без код-ревью, среди них две новые
фичи (#90, #94).
5. Завести issue на находку «смок `visual_continuity` не умеет падать» из разбора
11.08 — это ровно тот класс дефектов, который в процессе без ручного
тестирования стоит дороже всего.
6. `BACKLOG-2026-08-11.md` объявить разовым отчётом: решения — в issue.
7. Добавить в `AGENTS.md` блок §14.
---
## 14. Блок для AGENTS.md
```markdown
## Процесс: код только через issue
Изменение продуктового кода без issue запрещено. Код меняется только из статуса
«Готово к разработке» или дальше. Полные правила, критерии статусов и гейты —
`docs/PROCESS.md`, читать до начала работы.
Жизненный цикл (статус = метка issue): `S1-новое` → `S2-аналитика` → `S3-тз` →
`S4-тз-ревью` → `S5-к-разработке` → `S6-в-разработке` → `S7-код-ревью` →
закрытие после выпуска беты. Оба ревью возвращают на правки не более 4 циклов;
пятый заход — разбор у владельца (разделить / отклонить / арбитраж).
- ветка `issue/<NN>-<slug>`, коммиты с трейлерами `Issue: #NN` и `User-Visible: yes|no`;
- работаем прямыми коммитами в `dev`, без PR: блокирующий гейт — локальный
`pre-push` (ставится автоматически через `npm ci`), CI — страховка. Force-push
в `dev` запрещён;
- автор ≠ ревьюер, ни для ТЗ, ни для кода;
- фазы ручного тестирования нет: автотесты пишутся в реализации, AC проверяет
код-ревью, найденные позже дефекты — новые issue типа «баг»;
- мелкие задачи (метка `малое`, сложность ≤3): ТЗ в теле issue, ревью ТЗ
комментарием, код-ревью — как обычно;
- найденное вне скоупа — новый issue, а не попутная правка;
- issue закрывает релиз-менеджер после выпуска беты, не исполнитель.
```