mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-30 11:49:16 +00:00
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:
@@ -6,62 +6,229 @@ House Plan is one HACS package with two parts plus a demo harness:
|
||||
- **Storage integration** (`custom_components/houseplan/`, Python) — the Home Assistant backend.
|
||||
- **Demo harness** (`demo/`) — a self-contained Playwright page (`demo/srv/demo.html`) that renders the card against a fake `hass`, used for screenshots and the `smoke_*.mjs` end-to-end suite.
|
||||
|
||||
Standard commands live in `package.json` scripts, `CONTRIBUTING.md`, and `docs/DEVELOPMENT.md`. Read `docs/ARCHITECTURE.md` and `docs/STATUS.md` before non-trivial changes.
|
||||
Issue and commit provenance is defined in repository-visible `PROCESS.md`;
|
||||
install its commit-message hook in every writable clone.
|
||||
## Read this first
|
||||
|
||||
**`docs/SCOPE.md` before anything else.** It was fixed with the owner and states
|
||||
its own authority: features are built, improved and accepted **only** if they
|
||||
serve a job listed there. It carries the mission, the three personas, the core
|
||||
user jobs and the out-of-scope list.
|
||||
|
||||
Its central consequence: **View mode is the product for two of the three
|
||||
personas.** Editors are admin-only tools and must never leak interactions into
|
||||
View.
|
||||
|
||||
For work that changes visible behaviour, also read `docs/USER-GUIDE.ru.md` —
|
||||
interface wording comes from there and is not invented, or the UI starts speaking
|
||||
developer.
|
||||
|
||||
Then `PROCESS.md` (the full process), `docs/STATUS.md` (where the release line
|
||||
is), and for non-trivial changes `docs/ARCHITECTURE.md` plus the canonical
|
||||
document of the subsystem you touch: `SUN.md`, `LIGHT.md`, `CANVAS.md`,
|
||||
`WALL-THICKNESS.md`, `UX-MODES.md`, `CONFIG-COMPATIBILITY.md`,
|
||||
`TOUCH-SUPPORT.md`.
|
||||
|
||||
Standard commands live in `package.json` scripts, `CONTRIBUTING.md` and
|
||||
`docs/DEVELOPMENT.md`.
|
||||
|
||||
## Canonical backlog and status
|
||||
|
||||
[GitHub Issues](https://github.com/Matysh/houseplan-card/issues) are the canonical
|
||||
task records: problem, scope, acceptance criteria and discussion.
|
||||
|
||||
**Status lives in labels:** `S1-new`, `S2-analysis`, `S3-spec`, `S4-spec-review`,
|
||||
`S5-ready`, `S6-in-progress`, `S7-code-review`, `S8-merged`, plus `blocked` on top
|
||||
of a status and `rejected` on a closed issue. Exactly one `S*` label per open
|
||||
issue. [GitHub Projects (v2)](https://github.com/users/Matysh/projects/1) is a
|
||||
human-facing view synchronised from the labels, not the source of truth.
|
||||
|
||||
Only issues **created by the owner** enter the process. The repository is public;
|
||||
outside reports may be malformed or invalid, carry no status labels, and are not
|
||||
picked up until the owner converts them into his own issue.
|
||||
|
||||
Specs, audits and ADRs may live under `docs/`, but must link to their issue and
|
||||
must not become a parallel task list. When repository documentation disagrees with
|
||||
Issues, the issue wins.
|
||||
|
||||
## Rule #1
|
||||
|
||||
> Changing product code without an issue is forbidden. Code changes only when the
|
||||
> issue exists and sits in "Ready for development" or later.
|
||||
|
||||
Check before touching product code:
|
||||
|
||||
```
|
||||
gh issue view <NN> --repo Matysh/houseplan-card --json number,state,labels
|
||||
```
|
||||
|
||||
The label must be one of `S5-ready`, `S6-in-progress`, `S7-code-review`. Anything
|
||||
else — refuse and say why. "Issue #83 is in `S2-analysis`, code is off limits.
|
||||
Start with the spec?" is the correct answer, not a smaller patch.
|
||||
|
||||
## Change classes
|
||||
|
||||
| Class | Paths | Issue required |
|
||||
|---|---|---|
|
||||
| **A — product** | `src/**`, `custom_components/houseplan/**/*.py`, `manifest.json`, `hacs.json`, i18n, `custom_components/**/translations/**` | yes |
|
||||
| **B — gates and tooling** | `test/**`, `tests_backend/**`, `demo/**`, `scripts/**`, `.github/workflows/**`, `rollup.config.mjs`, `tsconfig*.json` | yes; may reuse the issue it covers |
|
||||
| **C — documentation** | `docs/**`, `README*`, `CHANGELOG*`, `AGENTS.md` | not if it is part of its issue's DoD |
|
||||
| **D — generated** | `dist/**`, `custom_components/houseplan/frontend/**`, `demo/srv/assets/houseplan-card.js`, `demo/golden/baselines/**` | never changes on its own |
|
||||
|
||||
`PROCESS.md` §1 is the authority; it does not yet list `package.json`,
|
||||
`package-lock.json`, `.githooks/**`, the rest of `.github/**`, `.gitignore` or
|
||||
`pytest.ini`. Treat them as class B and tell the owner §1 needs the addition.
|
||||
|
||||
## Commits
|
||||
|
||||
Hooks install themselves: `package.json` runs `"prepare": "node
|
||||
scripts/install-hooks.mjs"`, so `npm ci` sets `core.hooksPath` in every fresh
|
||||
clone. Verify with `git config core.hooksPath` — expect `.githooks`.
|
||||
|
||||
Every non-merge commit carries **terminal** trailers:
|
||||
|
||||
```text
|
||||
Issue: #123
|
||||
User-Visible: yes
|
||||
```
|
||||
|
||||
One `Issue:` line per issue if a commit closes several. `User-Visible: no` for
|
||||
tests, refactors, tooling and documentation that does not change the product.
|
||||
`User-Visible: yes` requires edits to **both** changelogs — `docs/CHANGELOG.md`
|
||||
and `docs/CHANGELOG.ru.md` — in the same commit.
|
||||
|
||||
A commit touching `demo/golden/baselines/**` additionally requires:
|
||||
|
||||
```text
|
||||
Release: v1.62.0-beta.9
|
||||
Baseline-Reviewed: https://github.com/Matysh/houseplan-card/actions/runs/<run-id>
|
||||
```
|
||||
|
||||
Never invent a review link and never rewrite published history to satisfy
|
||||
trailers. `.githooks/commit-msg` and the `provenance` CI job both run
|
||||
`scripts/validate-commit-provenance.mjs`.
|
||||
|
||||
Branch: `issue/<NN>-slug`. Direct commits to `dev`, no PR — the owner's decision;
|
||||
CI checks after the fact, and a violation is fixed with a follow-up commit, never
|
||||
a force-push.
|
||||
|
||||
**Push after every task, not before a beta.** While work sits unpushed there is
|
||||
nothing to review, and reviewing twenty tasks at once is not review. `dev` may hold
|
||||
unreviewed code while a task is in flight; what matters is its state when the
|
||||
reviewer says it is accepted.
|
||||
|
||||
## Two-agent workflow
|
||||
|
||||
House Plan is developed by two agents: **Codex is the author** (analysis,
|
||||
estimate, spec, implementation) and **Claude is the reviewer** (estimate, spec,
|
||||
code). They exchange remarks through a local, git-ignored message bus —
|
||||
**read `.agents/PROTOCOL.md` before acting on any task**. It defines the
|
||||
message format, the estimate scales every agent must use, the three stages
|
||||
(`estimate` → `spec` → `code`), the three-round convergence limit and what gets
|
||||
published to GitHub.
|
||||
**Codex** writes analysis, specs and all product code. **Claude** reviews specs and
|
||||
code and owns infrastructure and distribution. The owner rules on disputes, closes
|
||||
issues and commands releases.
|
||||
|
||||
Two rules that matter even if you read nothing else:
|
||||
Author and reviewer are different models, which is what "a fresh session without
|
||||
implementation context" means in practice. The reviewer never edits product code;
|
||||
the author never grades their own work.
|
||||
|
||||
- write only into the *other* agent's inbox, never edit a file you did not
|
||||
create, and move a processed message to `.agents/archive/`;
|
||||
- "verified" without a command and its output is not evidence — from either side.
|
||||
The exchange happens in **issue comments** — there is no local message bus. Verdict
|
||||
format:
|
||||
|
||||
## Canonical backlog
|
||||
```text
|
||||
Verdict: green/yellow/red · cycle r<N>/4 · High: N · Medium: N → #… · Document: …
|
||||
```
|
||||
|
||||
GitHub is the only active backlog for House Plan:
|
||||
High blocks. Medium must become its own issue. Low is fixed or waived with a note
|
||||
in the review document. A yellow verdict is legitimate even when every acceptance
|
||||
criterion passes, if the change does not solve the stated scenario or degrades a
|
||||
neighbouring one.
|
||||
|
||||
- [GitHub Issues](https://github.com/Matysh/houseplan-card/issues) are the
|
||||
canonical task records: problem, scope, acceptance criteria and discussion.
|
||||
- [GitHub Projects (v2)](https://github.com/users/Matysh/projects/1) is
|
||||
the canonical prioritization and workflow-status view. Every open in-scope
|
||||
issue must be present there.
|
||||
**Four review cycles** (two on the light track). The counter lives in the document
|
||||
name, `-r1`…`-r4`; the fourth adds the `review-4` label. There is no fifth attempt:
|
||||
the owner splits the task, rejects it, or arbitrates.
|
||||
|
||||
Before starting planned work, find or create its issue and keep its description,
|
||||
labels and Project status current as decisions and implementation state change.
|
||||
Close an issue only after the result is verified. Specs, audits and ADRs may
|
||||
remain under `docs/`, but must link to their issue and must not become a parallel
|
||||
task list. When repository documentation disagrees with Issues or Project v2,
|
||||
the GitHub backlog wins.
|
||||
On the light track (`small`: complexity ≤3, one surface, no config migration, no
|
||||
new UX contract, no perf or touch impact — all at once) the spec lives in the issue
|
||||
body and the spec review is a comment. Code review is never skipped.
|
||||
|
||||
## Cursor Cloud specific instructions
|
||||
## Specs
|
||||
|
||||
The startup update script already runs `npm ci`, provisions a Python 3.13 backend venv at `.venv-backend`, and installs Playwright Chromium. You do not need to reinstall dependencies.
|
||||
`docs/specs/<NN>-<slug>.md`, linked to its issue in both directions. Required
|
||||
sections are in `PROCESS.md` §7.1, plus two product ones: which persona meets this,
|
||||
on which surface, at what moment; and what the person sees before and after, in one
|
||||
sentence without implementation terms.
|
||||
|
||||
- **Frontend** (from repo root): `npm run typecheck`, `npm test` (node:test, 424 tests at v1.60.0), `npm run build`. After building, keep both committed snapshots in sync — `cp dist/houseplan-card.js custom_components/houseplan/frontend/` and `cp dist/houseplan-card.js demo/srv/assets/`. CI enforces both comparisons byte-for-byte.
|
||||
- **Backend HA-harness tests need Python 3.13, not the system 3.12.** Run them with the venv: `.venv-backend/bin/python -m pytest tests_backend/ -q` (150 tests at v1.60.0: 100 pure + 50 HA harness). Running `python3 -m pytest tests_backend` without Home Assistant silently **skips** the `test_ha_*.py` harness tests (`conftest.py` ignores them when `homeassistant` is not importable) and runs only the pure set.
|
||||
- **Running the app / smoke suite**: build a fresh bundle and copy it into the demo assets first — `npm run build && cp dist/houseplan-card.js demo/srv/assets/houseplan-card.js` — then run `node demo/smoke_*.mjs`. The committed demo snapshot must remain byte-identical to `dist` (CI checks it); rebuilding first also guarantees the browser suite tests the current source in an uncommitted worktree. No real Home Assistant server is required: `demo/srv/demo.html` stubs `hass`, registries and `callService`.
|
||||
- **Golden images**: `npm run golden:capture` and `npm run golden:verify` refuse a stale demo bundle. Build and copy the current bundle first, then review `artifacts/golden/actual/` and `diff/`. Update baselines only with `npm run golden:accept -- --reviewed`, using the complete Linux CI artifact; never accept a partial scenario or images merely to make CI green. See `demo/golden/README.md`.
|
||||
- **Freshness contract**: the embedded fingerprint covers `src/` plus Rollup, TypeScript and package-lock build inputs. Benchmark and golden tooling must call `assertFreshDemoBundle` before recording any result; a missing or mismatched fingerprint is a hard failure, not a warning.
|
||||
- **Demo harness render quirk**: the fake `hass` in `demo.html` is set once, so opening the page directly in a browser renders the floor plan but **device icons only appear after a re-render** (an F5 refresh, or nudging `card.hass = {...card.hass}`). The smoke launcher `demo/serve.mjs` already does this nudge; a plain browser session does not. This is a harness limitation, not a card bug.
|
||||
- **Known environment-sensitive smoke**: `demo/smoke_opening_measure.mjs` fails two sub-checks (`place_dialog_x_magnetised`, `place_committed_x_center`) under the pinned Chromium — a `1e-6`-tolerance magnet-snap on the opening-*placement* path. It reproduces against the pristine committed bundle, so treat it as pre-existing/pixel-precision, not a regression you introduced.
|
||||
- **Owner's local Windows checkout is invisible here.** Path
|
||||
`C:\Users\Sergey\Downloads\dev\houseplan-dev` (workflow notes + often
|
||||
unpushed edits) is **not mounted** into managed Cloud Agent VMs. Do not
|
||||
expect to `ls` or diff that folder. To bring local work into the cloud
|
||||
agent: push a branch to GitHub and say its name, or run a **local** Cursor
|
||||
Agent / My Machines worker inside that checkout. Day-to-day source of truth
|
||||
for cloud sessions remains **`origin/dev`** (minors) and **`origin/main`**
|
||||
(releases) — see `docs/STATUS.md`.
|
||||
**Ambiguity is asked, not guessed.** A guess written as fact is the worst kind of
|
||||
defect: it passes review because it looks like a decision. Ask the owner in one
|
||||
batched issue comment, each question carrying a proposed default, and put `blocked`
|
||||
on top of `S3-spec` while waiting. Small or cheap calls are decided and recorded in
|
||||
an explicit "assumed, change freely" block at the end of the spec.
|
||||
|
||||
## Gates
|
||||
|
||||
```
|
||||
npm run typecheck
|
||||
npm test
|
||||
npm run build
|
||||
npm run inventory # the only correct way to get test counts
|
||||
```
|
||||
|
||||
Never copy test counts into documents by hand; they go stale in days.
|
||||
|
||||
After building, keep all three bundle snapshots in sync — CI compares them
|
||||
byte-for-byte:
|
||||
|
||||
```
|
||||
cp dist/houseplan-card.js custom_components/houseplan/frontend/houseplan-card.js
|
||||
cp dist/houseplan-card.js demo/srv/assets/houseplan-card.js
|
||||
```
|
||||
|
||||
During the implementation cycle only the fast gates run. `smoke`, `golden` and
|
||||
`performance_smoke` spin up Chromium and belong to the pre-beta run — which is then
|
||||
mandatory and complete.
|
||||
|
||||
**Backend.** A full Home Assistant harness cannot run on native Windows at all:
|
||||
Home Assistant imports the Unix-only `fcntl` module. Its canon is Linux CI or WSL.
|
||||
Locally only the pure subset runs; `python -m pytest tests_backend/ -q` without
|
||||
Home Assistant **silently skips** `test_ha_*.py` (`conftest.py` ignores them when
|
||||
`homeassistant` is not importable), so a green result proves nothing. Say so in the
|
||||
report instead of claiming the backend was verified. Cloud agents have the harness
|
||||
at `.venv-backend/bin/python`.
|
||||
|
||||
**Running the app / smoke suite**: build a fresh bundle and copy it into the demo
|
||||
assets first, then run `node demo/smoke_*.mjs`. No real Home Assistant server is
|
||||
required: `demo/srv/demo.html` stubs `hass`, registries and `callService`.
|
||||
|
||||
**Golden images**: `npm run golden:capture` and `npm run golden:verify` refuse a
|
||||
stale demo bundle. Build and copy first, then review `artifacts/golden/actual/` and
|
||||
`diff/`. Update baselines only with `npm run golden:accept -- --reviewed`, using the
|
||||
complete Linux CI artifact; never accept a partial scenario or images merely to make
|
||||
CI green. See `demo/golden/README.md`.
|
||||
|
||||
**Freshness contract**: the embedded fingerprint covers `src/` plus Rollup,
|
||||
TypeScript and package-lock build inputs. Benchmark and golden tooling must call
|
||||
`assertFreshDemoBundle` before recording any result; a missing or mismatched
|
||||
fingerprint is a hard failure, not a warning.
|
||||
|
||||
**CI is pinned to an exact SHA.** The release gate accepts only a `completed
|
||||
success` run for the candidate's SHA, not "the last green one"; a new push cancels
|
||||
an unfinished Validate for the same branch. Jobs: `provenance`, `hacs`, `hassfest`,
|
||||
`frontend`, `smoke`, `golden`, `performance_smoke`, `backend`.
|
||||
|
||||
**"Verified" without a named command and its result is not evidence.**
|
||||
|
||||
## Environments
|
||||
|
||||
**Local Windows checkout** is the day-to-day environment: Node 22 as in CI, Python
|
||||
3.13 in a venv, `gh` authenticated. `.venv-backend` does **not** exist there — it is
|
||||
provisioned only by cloud agent startup scripts, which also run `npm ci` and install
|
||||
Playwright Chromium.
|
||||
|
||||
Known environment-sensitive smoke: `demo/smoke_opening_measure.mjs` fails two
|
||||
sub-checks (`place_dialog_x_magnetised`, `place_committed_x_center`) under the pinned
|
||||
Chromium — a `1e-6`-tolerance magnet-snap on the opening-*placement* path. It
|
||||
reproduces against the pristine committed bundle, so treat it as
|
||||
pre-existing/pixel-precision, not a regression you introduced.
|
||||
|
||||
Demo harness render quirk: the fake `hass` in `demo.html` is set once, so opening the
|
||||
page directly in a browser renders the floor plan but **device icons only appear
|
||||
after a re-render** (an F5 refresh, or nudging `card.hass = {...card.hass}`). The
|
||||
smoke launcher `demo/serve.mjs` already does this nudge; a plain browser session does
|
||||
not. This is a harness limitation, not a card bug.
|
||||
|
||||
## Promotion rule
|
||||
|
||||
@@ -71,3 +238,10 @@ stable release commit is promotion-only: version fields, generated bundle
|
||||
snapshots and changelog/release metadata. Do not add feature source code in
|
||||
that commit. An explicit owner-requested emergency hotfix is the only exception
|
||||
and must be called out in the release handoff.
|
||||
|
||||
A `Release vX.Y.Z-beta.N candidate` commit is **not** promotion-only: it carries
|
||||
the work itself and follows the ordinary rules, trailers included.
|
||||
|
||||
Issues are closed in a batch when a beta ships, not when implementation ends: that
|
||||
way a bug found in the beta returns to the same task, and the beta announcement can
|
||||
list what went in. Status labels are stripped as the issues close.
|
||||
|
||||
+519
-38
@@ -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 закрывает релиз-менеджер после выпуска беты, не исполнитель.
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user