mirror of
https://github.com/Matysh/houseplan-card
synced 2026-10-02 04:38:55 +00:00
@@ -1,6 +1,6 @@
|
||||
# Индекс ревью
|
||||
|
||||
Генерируется `node scripts/reviews-index.mjs` (#635) — не редактировать руками. Документов: 234, issue: 114. Вердикт: 🟢 зелёный · 🟡 жёлтый · 🔴 красный · ⚪ не распознан (свободная форма старых документов). H/M — число High/Medium по строке вердикта или заголовкам находок. Файлы — пути, названные в находках; ищите по имени файла: `grep form-kit INDEX.md`.
|
||||
Генерируется `node scripts/reviews-index.mjs` (#635) — не редактировать руками. Документов: 235, issue: 115. Вердикт: 🟢 зелёный · 🟡 жёлтый · 🔴 красный · ⚪ не распознан (свободная форма старых документов). H/M — число High/Medium по строке вердикта или заголовкам находок. Файлы — пути, названные в находках; ищите по имени файла: `grep form-kit INDEX.md`.
|
||||
|
||||
| Issue | Документ | Этап · раунд | Вердикт | H | M | Находки | Файлы |
|
||||
|---|---|---|---|---:|---:|---|---|
|
||||
@@ -14,6 +14,7 @@
|
||||
| #730 | [CODE-REVIEW-730-r2.md](CODE-REVIEW-730-r2.md) | code · r2 | 🟢 зелёный | 0 | 0 | — | — |
|
||||
| #730 | [CODE-REVIEW-730-r3.md](CODE-REVIEW-730-r3.md) | code · r3 | 🟢 зелёный | 0 | 0 | — | — |
|
||||
| #730 | [CODE-REVIEW-730-r4.md](CODE-REVIEW-730-r4.md) | code · r4 | 🟢 зелёный | 0 | 0 | — | — |
|
||||
| #729 | [SPEC-REVIEW-729-r1.md](SPEC-REVIEW-729-r1.md) | spec · r1 | 🟢 зелёный | 0 | 0 | — | — |
|
||||
| #728 | [SPEC-REVIEW-728-r1.md](SPEC-REVIEW-728-r1.md) | spec · r1 | 🟡 жёлтый | 1 | 0 | 1. АС3/К3: заявленное различение причин validate-red и conflict «на текстах из констант…; 2. АС8: заявленное доказательство правки process-metrics.yml (fetch-depth: 0, timeout-m… | `wait-verdict.mjs` `review-doc-guard.mjs` `scripts/wait-verdict.mjs` `.github/workflows/_process.yml` `_process.yml` `_process-metrics.yml` `test/process-metrics.test.mjs` |
|
||||
| #728 | [SPEC-REVIEW-728-r2.md](SPEC-REVIEW-728-r2.md) | spec · r2 | 🟢 зелёный | 0 | 0 | — | — |
|
||||
| #728 | [CODE-REVIEW-728-r1.md](CODE-REVIEW-728-r1.md) | code · r1 | 🟢 зелёный | 0 | 0 | — | — |
|
||||
|
||||
@@ -0,0 +1,213 @@
|
||||
# SPEC-REVIEW-729-r1
|
||||
|
||||
Issue: #729 «Процесс: черновая реализация ask параллельно ревью ТЗ (изменение
|
||||
правила №1 — решение владельца)»
|
||||
Этап: spec (PROCESS.md §2.4) · Трек: ask · Заход: r1 · блокирующих циклов
|
||||
израсходовано 0 из 4
|
||||
|
||||
## Скоуп
|
||||
|
||||
ТЗ (тело issue, раздел `## ТЗ`) вводит новое исключение из правила №1: на
|
||||
`track:ask`, в статусе `S4-spec-review`, автор вправе вести локальный
|
||||
непушенный черновик продуктового кода (класс A) в рабочей копии, если каждый
|
||||
черновой коммит несёт трейлер `Spec-Draft: sha256:<хеш нормализованного тела
|
||||
issue>`. Правило 10 (`checkCommitEraStatuses`, `scripts/process-gate.mjs`)
|
||||
получает исключение, которое принимает такой коммит только если:
|
||||
|
||||
- трек на момент написания коммита — `ask`;
|
||||
- эпоха `S4`, в которую попадает коммит, закрыта именно `S5-ready`;
|
||||
- в этой эпохе есть зелёный `SPEC-REVIEW-<NN>-rK.md` (найден в `<head>` или
|
||||
`origin/dev`) с «Тело issue:», равным трейлеру коммита.
|
||||
|
||||
Исключение строится **поверх модели #738** (эпохи статуса для правила 10),
|
||||
которая на момент ревью ещё не смёржена (`S6-in-progress`) — ТЗ это прямо
|
||||
называет зависимостью («после `S8` #738») и критически для реализации не
|
||||
маскирует как решённый факт. Также правятся `scripts/task-packet.mjs` (права
|
||||
и раздел «Черновик» в пакете на `S4`/`S5`), тесты
|
||||
(`test/process-gate.test.mjs`, `test/task-packet.test.mjs`,
|
||||
`test/process-digests.test.mjs`) и канон (PROCESS.md §1, §2.4–2.6, §3 п.1,
|
||||
§7.2, §9, §10.2, новый §11.8, §12, `docs/process/AUTHOR.md`,
|
||||
`docs/process/REVIEWER.md`, `AGENTS.md`). Файлов класса A в этой задаче нет —
|
||||
трек `ask` взят явно (меняет правило №1 и публичный контракт процесса), что
|
||||
соответствует §5.1. Решение владельца на изменение правила №1 дано в теле
|
||||
issue текстом «по #729 - разрешаю» (01.10) — ревьюер судит исполнимость и
|
||||
проверяемость контракта, а не само разрешение, как и требует задание.
|
||||
|
||||
## Как проверялось
|
||||
|
||||
Раунд первый, документов ревью на #729 в дереве ещё нет — разбор полный.
|
||||
Метод — не поверить формулировкам «сверено с кодом», а перепроверить каждую
|
||||
построчную ссылку чтением текущего файла на материале ревью
|
||||
(`76558bf2a0bf72dcfed369743639c989b4099450`, рабочая копия уже на нём):
|
||||
|
||||
- `docs/SCOPE.md`, `AGENTS.md`, `docs/process/REVIEWER.md`, PROCESS.md §1,
|
||||
§2.3–2.7, §4, §5, §5.1, §7.1, §7.2, §8, §11.7, §12 — целиком по ссылкам
|
||||
промпта;
|
||||
- тело issue #729 целиком (раздел `## ТЗ`, все 11 подразделов) и его
|
||||
единственный комментарий («Оценка… трек ask…», решение владельца);
|
||||
- статус и зависимости: `gh issue view` для #738 (`S6-in-progress`, не
|
||||
смёржено — подтверждает, что ТЗ корректно называет его незавершённой
|
||||
зависимостью, а не фантомной), #707 и #726 (оба `S8-merged`, их контракт
|
||||
уже в `dev` — трековые метки, формат строки владельца, `trackFromLabels`);
|
||||
- `3b9f25ea` (SHA, с которым ТЗ сверяет «что сейчас») подтверждён как предок
|
||||
текущего `HEAD` (`git merge-base --is-ancestor`) и как коммит #727 — ссылка
|
||||
не мёртвая;
|
||||
- построчно сверены все ключевые ссылки раздела «Что сейчас (сверено с
|
||||
кодом)» с текущими файлами:
|
||||
- `scripts/process-gate.mjs`: `isInfrastructureRange` (строка 407),
|
||||
`checkCommitEraStatuses` (ровно строки 505–556, включая сигнатуру и
|
||||
`return out`), использование `statusOptional` и вызов правила 10 только
|
||||
при `!statusOptional` (строки 778, 788–797) — всё сходится дословно; эта
|
||||
функция сейчас реализует **старую**, безэпоховую модель (`readyAt` —
|
||||
первое когда-либо событие допустимого статуса), что ожидаемо: #738 ещё
|
||||
не смёржен, и ТЗ честно пишет будущий контракт «поверх» неё, а не выдаёт
|
||||
его за текущее поведение;
|
||||
- `scripts/review-doc-guard.mjs`: `normalizeIssueBody` (266–273),
|
||||
`issueBodyDigest` (276–278), `anchorIssueBodyFrom` (281–287),
|
||||
`issueBodyChanged` (298–308), `materialAnchorBlock` (315…, блок «Тело
|
||||
issue:» начинается на 335) — сходится;
|
||||
- `scripts/validate-commit-provenance.mjs`: `TRAILER`-регэксп (строка 9),
|
||||
`terminalTrailers` (42) — подтверждает заявление «любой трейлер вида
|
||||
`Имя: значение` в финальном блоке проходит, `Spec-Draft:` не ломает
|
||||
требование терминального `Issue:`»;
|
||||
- `scripts/task-packet.mjs`: `rightsFor` (33), `collectInputs` (404),
|
||||
строки 44 и 52 — ровно те тексты, что цитирует ТЗ («продуктовый код
|
||||
трогать НЕЛЬЗЯ…», «идёт ревью ТЗ: ждать вердикт…»); чтение ветки и
|
||||
`reviewDocs` — строки 409–412 (fetch/for-each-ref) и 437–438
|
||||
(`ls-tree`/`git show` по `docs/reviews`) — сходится;
|
||||
- `.github/workflows/_process.yml`: снятие хеша тела issue (645–657, блок
|
||||
`m.issueBodyDigest(`), публикация документа ревью **до** перестановки
|
||||
метки (шаг «Опубликовать документ ревью» на 1485 действительно идёт
|
||||
раньше шага «Переставить метку» на 1873; переход `S4→S5` — строка 1736,
|
||||
в ТЗ названа «:1735», расхождение на одну строку, не искажает факт) —
|
||||
сходится;
|
||||
- `scripts/process-track.mjs`: `trackFromLabels` (72–77, дефолт `ask` при
|
||||
пустом списке меток), `labelTrack` (88, инфраструктура-осведомлённая
|
||||
обёртка) — ТЗ сознательно берёт `trackFromLabels`, а не `labelTrack`:
|
||||
это корректно, потому что правило 10 судит только коммиты с файлом
|
||||
класса A, а такой коммит по определению §1 не принадлежит
|
||||
инфраструктурному диапазону — защита от «дефолт `show`» здесь не нужна;
|
||||
- PROCESS.md §5.1: «продуктовая задача без трековой метки — как
|
||||
`track:ask`» — цитата К3 п.2б «Событий нет → ask» дословно совпадает с
|
||||
каноном, а не придумана;
|
||||
- `test/process-gate.test.mjs`: тест `rule 10 pins DoR…` существует
|
||||
(строка 869, #311), AC #562-стиль прогона с временным git-репозиторием и
|
||||
подставным `gh` существует (строка 776) — оба ориентира плана автотестов
|
||||
реальны, не выдуманы;
|
||||
- `docs/reviews/` сейчас плоский каталог (`SPEC-REVIEW-<NN>-r<K>.md`,
|
||||
235 файлов, включая существующие `SPEC-REVIEW-651..742`), архив
|
||||
`legacy/reviews/<тег>/` наполняется только `reviews-archive.mjs` после
|
||||
стабильного релиза (прочитан целиком) — подтверждает «принято
|
||||
предположительно» п.5 (документы читаются только из `docs/reviews/` на
|
||||
`<head>`/`origin/dev`, `legacy/reviews/**` не участвует) и снимает
|
||||
опасение, что недавние коммиты «индекс после сдвига каталога» (#727,
|
||||
#730) могли переименовать путь `docs/reviews/SPEC-REVIEW-*` — не
|
||||
переименовали;
|
||||
- PROCESS.md §11 — секций 11.1–11.7 ровно семь, 11.8 свободен, коллизии
|
||||
анкоря заголовка не будет;
|
||||
- вручную прогнаны все граничные сценарии AC1–AC6 по описанным в ТЗ шкалам
|
||||
времени (две эпохи `S4`, повтор `S4` reconcile, два зелёных документа в
|
||||
одной эпохе, эпоха без `S5`, коммит вне `S4`) — результат (findings/
|
||||
отсутствие findings) в каждом случае соответствует порядку проверок
|
||||
а→д, который описывает К3 п.2, расхождений не найдено;
|
||||
- проверено отсутствие файлов класса A в диапазоне (`git diff --stat
|
||||
3b9f25ea..HEAD -- src/ custom_components/` — пусто), что подтверждает
|
||||
заявление ТЗ «Файлов класса A нет».
|
||||
|
||||
## Находки
|
||||
|
||||
Нет. Блокирующих (High) и находок в скоупе (Medium) не обнаружено.
|
||||
|
||||
## Что проверено и корректно
|
||||
|
||||
- Обязательные разделы §7.1 — полный комплект: сценарий (три персоны:
|
||||
агент-автор, владелец, ревьюер ТЗ — корректная адаптация для процессной, не
|
||||
продуктовой задачи), что человек увидит до/после, проблема, скоуп/не-скоуп,
|
||||
контракт поведения (К1–К5), UX, модель данных и миграция, i18n, критерии
|
||||
приёмки AC1–AC10 с доказательством и oracle, план автотестов (включая
|
||||
отдельный блок «чем краснеет»), риски, откат, release-артефакты.
|
||||
- Каждый AC однозначен и привязан к конкретному тестовому файлу и
|
||||
конкретному входу/выходу (явные хеши `H`/`H1`/`H2`/`H3`, временные метки,
|
||||
ожидаемый текст находки) — ни один не сформулирован описательно без
|
||||
оракула.
|
||||
- Защитные AC (AC1–AC6 — гард по трейлеру, эпохе, треку, соответствию
|
||||
документу) имеют явный отрицательный случай либо в столбце
|
||||
«Доказательство/Oracle» самой таблицы, либо в отдельном перечне «чем
|
||||
краснеет» — пустого третьего столбца нет ни у одной защитной строки.
|
||||
- Продуктовых вопросов владельцу нет, и это обоснованно: единственный
|
||||
продуктовый вопрос задачи — само изменение правила №1 — уже решён
|
||||
владельцем явной строкой в теле issue («по #729 - разрешаю»), остальное —
|
||||
технические решения, корректно вынесенные в «Принято предположительно»
|
||||
(11 пунктов), а не выданные за факт. `docs/SCOPE.md` эту задачу не
|
||||
ограничивает: она процессная, ни одной строки Core user jobs не касается,
|
||||
как и соседние #726/#727/#728/#738.
|
||||
- Зависимость на #738 названа честно и не замаскирована: #738 сейчас
|
||||
`S6-in-progress` (проверено `gh issue view`), контракт эпох, на который
|
||||
опирается К3, в коде ещё не существует (`checkCommitEraStatuses` на
|
||||
текущем HEAD — дочерняя, безэпоховая модель) — ТЗ прямо пишет «DoR #729
|
||||
требует `S8` у #738» и даёт план на случай расхождения формулировок
|
||||
(строить поверх фактического кода #738, AC5 держит тесты #738
|
||||
неизменными). Это дисциплинирует порядок работы, а не создаёт скрытую
|
||||
невыполнимость спецификации.
|
||||
- Технический выбор `trackFromLabels` вместо «единой» `labelTrack` в К3 п.2б
|
||||
корректен по смыслу §1 (коммит класса A не может принадлежать
|
||||
инфраструктурному диапазону), а не недосмотр совместимости функций.
|
||||
- Ссылки на существующие тестовые ориентиры (`:776`, `:869` в
|
||||
`test/process-gate.test.mjs`) и на существующие функции хеша/якоря
|
||||
(`review-doc-guard.mjs`) реальны, не фантомны.
|
||||
- Откат описан верно: ревёрт коммита задачи возвращает правило №1 без
|
||||
исключения; уже прошедшие Validate черновые коммиты границей диапазона
|
||||
(#703) повторно не судятся — соответствует существующей модели ревью.
|
||||
|
||||
## Чего не проверял
|
||||
|
||||
- `npx tsc --noEmit`, `npm test`, `npm run build` не гонял: зависимости
|
||||
(`node_modules`) не установлены — на этапе spec они не ставятся (#696), что
|
||||
подтверждено (`npm run typecheck` на материале даёт только ошибки
|
||||
`Cannot find module 'lit'`/`'polyclip-ts'`, то есть отсутствие `npm ci`, а
|
||||
не дефект кода). У задачи #729 нет диффа продуктового или тестового кода —
|
||||
ветки `issue/729-*` не существует ни локально, ни на origin, класс A в
|
||||
диапазоне `3b9f25ea..HEAD` отсутствует (проверено `git diff --stat`) —
|
||||
гонять эти гейты не над чем.
|
||||
- Мутанты по диффу не запрашивались (см. заголовок задачи) и не применимы:
|
||||
диффа продуктового кода нет.
|
||||
- Смоки, golden, `pytest tests_backend`, инварианты модели, performance — не
|
||||
применимы: задача не трогает `src/**`, `demo/**`, Python, геометрию.
|
||||
- Не проверял, останется ли сопоставление «реализатор пишет исключение в
|
||||
`checkCommitEraStatuses` рядом с кодом #738» дословно жизнеспособным после
|
||||
фактического код-ревью #738 — это риск следующего раунда (код-ревью #729),
|
||||
явно признанный в разделе «Риски» ТЗ и ограниченный требованием AC5 «тесты
|
||||
#738 неизменны».
|
||||
- Не проверял форматирование трейлера `Spec-Draft` хуком `commit-msg` в
|
||||
реальном git-хуке (его и не должно быть — К2 прямо говорит, что формат
|
||||
судит правило 10 при push, а не `commit-msg`) — это заявлено как принятое
|
||||
предположение, а не как факт текущего кода, и реализация ещё не
|
||||
существует.
|
||||
- Не проверял живое поведение `process-gate.mjs --issues` на реальном GitHub
|
||||
API (сетевой вызов `gh`) — AC1–AC5 рассчитаны на unit-фикстуры с
|
||||
инъекцией timeline/документов, AC6 — на временный git-репозиторий с
|
||||
подставным `gh`, как и у #562; живой прогон по плану тестов не требуется
|
||||
для приёмки ТЗ.
|
||||
|
||||
## Вердикт
|
||||
|
||||
Зелёный. ТЗ полно по §7.1, каждый AC однозначен и привязан к оракулу,
|
||||
многочисленные ссылки «сверено с кодом» перепроверены построчным чтением
|
||||
текущих файлов и подтвердились без расхождений, продуктовый вопрос (само
|
||||
изменение правила №1) уже решён владельцем, остальные решения корректно
|
||||
зафиксированы как технические допущения. Зависимость на не смёрженный #738
|
||||
названа прямо и не выдаётся за готовую базу. Находок нет.
|
||||
|
||||
---
|
||||
|
||||
<!-- material-anchors: сгенерировано конвейером (#414) -->
|
||||
|
||||
## Материал раунда
|
||||
|
||||
- Ветка: `dev`, коммит `76558bf2a0bf` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
|
||||
- Дерево материала: `e4d6aac31897c3f952332ec219cff7fbd5e9c793`
|
||||
```
|
||||
git log --all --format='%H %T' | grep e4d6aac31897
|
||||
```
|
||||
- Тело issue: `94cd1bca3f851c8c9d9fc64b3b6227fb2fd3dac9f47715053a95dd133ae40bed`
|
||||
- Вердикт конвейера: `green` · High 0 · маршрут `fix`
|
||||
Reference in New Issue
Block a user