mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-29 03:09:36 +00:00
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
539 lines
39 KiB
Markdown
539 lines
39 KiB
Markdown
# Процесс работы над House Plan
|
||
|
||
> **Статус документа:** черновик 3 (2026-08-12), на согласование владельцу.
|
||
> Решения владельца, зафиксированные в этой редакции: прямые коммиты в `dev` без
|
||
> PR · канон статуса — **метки** · лёгкий трек для мелких задач **включён**.
|
||
>
|
||
> **Область действия:** обязателен для владельца и для любого агента (Cowork,
|
||
> Cursor Cloud, Codex, локальные сессии). Читается сразу после `AGENTS.md`, до
|
||
> `docs/STATUS.md`.
|
||
>
|
||
> **Приоритет источников:** GitHub Issues + Project v2 — канонический бэклог.
|
||
> Статус живёт в метках issue. При расхождении документации с GitHub побеждает
|
||
> GitHub; при расхождении процесса и привычки побеждает процесс.
|
||
|
||
---
|
||
|
||
## 1. Основное правило
|
||
|
||
**Изменение продуктового кода без issue запрещено.** Код меняется только тогда,
|
||
когда issue существует и находится в статусе «Готово к разработке» или дальше.
|
||
Исключения — только §11, и каждое оставляет след.
|
||
|
||
Правило работает лишь при точной границе «продуктового кода», иначе спор
|
||
переносится на границу:
|
||
|
||
| Класс | Что входит | Нужен ли 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)
|
||
```
|
||
|
||
### 2.1 Новое — заведение задачи
|
||
|
||
- **Кто:** любой — владелец, агент, пользователь (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 → закрытие
|
||
```
|
||
|
||
Обязательные разделы ТЗ: проблема · скоуп и **не-скоуп** · контракт поведения ·
|
||
UX · модель данных и миграция · i18n · критерии приёмки AC1…ACn с указанием
|
||
доказательства · план автотестов · риски · откат · release-артефакты.
|
||
|
||
### 7.2 Шаблоны комментариев
|
||
|
||
Короткие и однообразные, чтобы читались и человеком, и машиной.
|
||
|
||
- **Аналитика:** `Оценка: ценность N/10 · сложность N/10 · P<1-3> · тип ·
|
||
поверхности: … · дубликаты: … · лёгкий трек: да/нет`
|
||
- **Занятие:** `Взял: <роль> · сессия <id> · ветка issue/NN-slug`
|
||
- **Хендофф:** `Сделано: … · Файлы: … · Гейты: <команда → результат> ·
|
||
НЕ сделано: … · Риски: … · Следующий статус: … · Новые issue: #…`
|
||
- **Вердикт ревью:** `Вердикт: зелёный/жёлтый/красный · цикл r<N>/4 · High: N ·
|
||
Medium: N → #… · Документ: docs/reviews/…`
|
||
- **Закрытие:** `Выпущено в <тег беты> · CI: <ссылка> · Changelog: <ссылка>`
|
||
|
||
### 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, если менялся бэкенд
|
||
```
|
||
|
||
**Гейт беты** (условие закрытия issue): CI Validate зелёный на точном SHA тега.
|
||
|
||
**Гейт стабильного релиза:** полный локальный прогон плюс Validate и Full
|
||
Performance зелёные на точном SHA; статусов issue не касается.
|
||
|
||
---
|
||
|
||
## 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 закрывает релиз-менеджер после выпуска беты, не исполнитель.
|
||
```
|