feat(process): risk by changed hunks decides ship and informs show (#707)

The ship limits count lines and files but not what was touched: a
12-line pointerdown handler passed them like a typo and merged unread.
The track rule also lived twice - the guard computed the cycle limit in
bash while process-track.mjs computed the track, and the two disagreed
on multiple track labels. The packet still told authors to rebase
show/ship branches that merge cleanly.

- scripts/change-risk.mjs: one pure classifier over `git diff -U0` from
  the merge base. Class A lines only; comments, blank lines and pure
  renames give no risk; deletions do. Area and token rules per class
  (geometry, touch, migration, devices, perf, ux, visual render/ui),
  evidence as path:line, five per class.
- process-track.mjs: owner confirmation is a comment line
  "Трек: <x> — решение владельца" by the repo owner (latest wins, only
  for the current track); several track labels read as the strictest
  with a warning; cycleLimit, guardLimit and rebaseBeforeReview are the
  single source. `stage` makes the whole S7 track decision in one call:
  ship with risk and no confirmation is raised to show with evidence,
  a confirmed ship keeps merging without the model and records the risk
  for the batch review; show/ask get a risk note for the reviewer.
- _process.yml: the guard asks process-track.mjs for the limit and keeps
  no track logic; the track step calls the script once and only
  executes its raise flag and comment file; risk_note reaches the
  Review prompt, ship_risk reaches the hp:ship-merge comment (marker
  line unchanged).
- task-packet.mjs: track basis, limit and rebase policy; next step
  without the stale rebase line; risk with its consequence per track;
  required checks with reasons (ci:golden only on render risk);
  changelog and visual evidence - from the same exports.
- ship-review.mjs: the batch brief prints the risk line of a ship merge.
- Canon: PROCESS.md §5, §5.1, §10.4, §11.7, both digests, AGENTS.md.
- Registry anchors that watched the moved code are moved, not dropped.

Issue: #707
User-Visible: no
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018qZfe7YS4rqEMKoVeS3GKd
This commit is contained in:
Claude
2026-10-01 00:03:35 +00:00
committed by claude[bot]
parent a49f7095ce
commit 1d51beade1
15 changed files with 1750 additions and 161 deletions
+70 -8
View File
@@ -567,10 +567,19 @@ patch-id кандидата слияния: вердикт к работе за
- Аналитик предлагает трек в «Оценке» (§7.2) и ставит метку. По умолчанию —
`track:show`.
- Владелец ставит или меняет любую из трёх меток в любой момент; его метка
окончательна.
- Владелец ставит или меняет любую из трёх меток в любой момент. Трек он
подтверждает строкой `Трек: <ship|show|ask> — решение владельца` в начале
строки своего комментария (тире любое, регистр не важен, #707); окончательна
метка, подтверждённая строкой владельца. Метка без такой строки — предложение:
аналитика, агента или конвейера. Действует самая поздняя строка владельца и
только для текущего трека. Агент эту строку не пишет никогда: агенты и
конвейер действуют от учётной записи владельца, и по автору события их не
отличить.
- Повысить трек (`ship` → `show` → `ask`) вправе любой агент, с причиной в
комментарии. Понизить — только владелец.
- Несколько трековых меток сразу — дефект разметки: действует строжайшая
(`ask` > `show` > `ship`), пакет задачи и сводка конвейера печатают
предупреждение (#707).
- Трек пересматривается, когда владелец снял усложнявший пункт (#688):
аналитик предлагает понижение, решает владелец.
@@ -590,6 +599,33 @@ patch-id кандидата слияния: вердикт к работе за
проверяет и исполняет конвейер (§10.4, #696); код `ship` читает пакетное ревью
диапазона перед бетой (§11.7).
**Проверка риска по изменённым участкам** (#707). Рамки считают строки и файлы,
но не видят, что именно тронуто: обработчик `pointerdown` в двенадцать строк
проходит их так же, как опечатка. Поэтому на `S7` конвейер судит и изменённые
строки файлов класса A — дифф `git diff --unified=0` от merge-base с `dev`
(`scripts/change-risk.mjs`). Правило «участок» — любая изменённая строка кода в
файле из списка, правило «токен» — токен в изменённой строке; пустые строки,
комментарии и чистое переименование риска не дают, удаление кода — даёт.
Классы: `geometry`, `touch`, `migration`, `devices`, `perf`, `ux` и `visual`
(области `render` — путь отрисовки плана — и `ui` — стили интерфейса). Таблица
путей и токенов — эвристика и живёт в скрипте.
- `ship` с любым классом, кроме `visual`, без подтверждения владельца конвейер
повышает до `show` тем же путём, что при выходе за рамки: комментарий с
классами и доказательствами `путь:строка`. Подтверждённый владельцем `ship`
остаётся, риск уходит в пакетное ревью (§11.7). `visual` ship не повышает:
CSS-мелочь — законный ship. Выход за рамки повышает трек и при
подтверждённом `ship`, как прежде.
- На `show` риск — вопрос ревьюеру, маршрут не меняется: по каждому классу
ревьюер называет документ или AC, где поведение уже зафиксировано; не нашёл —
Medium «решать есть что — нужен `track:ask`» с названным критерием. `show`,
подтверждённый владельцем, ревьюер не повышает: вопрос уходит владельцу с
вариантом по умолчанию «повысить до `ask`». На `ask` ревьюер сверяет, что
каждый класс покрыт AC ТЗ.
- Автор видит те же классы и их следствие в пакете задачи
(`node scripts/task-packet.mjs --issue NN`) до `S7`: пакет и конвейер читают
одно правило.
**Подсказка аналитику.** `track:show` уместен, когда выполнено всё сразу:
- сложность и риск ≤ 3;
@@ -609,7 +645,9 @@ patch-id кандидата слияния: вердикт к работе за
подтверждать ощущением — только ссылкой на уже зафиксированное поведение. Если по
ходу выясняется, что решать есть что, трек повышается до `ask`: issue уходит в
`S3-spec` и получает полное ТЗ в теле issue по §7.1. Это не провал, а ранняя
диагностика.
диагностика. Проверка риска по участкам (выше) даёт признаку механическую опору:
рискованный участок повышает `ship` и требует от ревью `show` ссылки на
зафиксированное поведение.
**Что не меняется ни на одном треке:** issue и правило №1 (§1), трейлеры
коммитов, changelog для видимого изменения, зелёный Validate на точном SHA тега
@@ -630,6 +668,13 @@ patch-id кандидата слияния: вердикт к работе за
Validate с `full=true` на материале ревью (#697). Метка `ci:mutants` снята
(#709): мутанты в разработке не гоняются ни на каком треке.
**`ci:golden` ставится по сигналу, а не на глаз** (#707). Сигнал — визуальный
риск в пути отрисовки плана (класс `visual`, область `render`, §5): пакет задачи
рекомендует `ci:golden`, если сдвиг кадров намерен, а заметка ревьюеру без метки
просит либо её, либо запись в «чего не проверял». Правка стилей интерфейса
(`ui`), только комментариев или только тестов сигнала не даёт. Риск сам полного
набора не включает, `visual` тоже: `full=true` дают только метки.
**Прежние метки.** `trivial` и `small` читаются как `track:show`; продуктовая
задача без трековой метки — как `track:ask`; инфраструктурная задача (§1) без
трековой метки — как `track:show`. Новые задачи получают только `track:*`.
@@ -1209,6 +1254,15 @@ Matysh/houseplan-card/.github/workflows/_<имя>.yml@dev` с `secrets: inherit`
снимает `scripts/process-track.mjs` в стадии подготовки — по текущим меткам и
диффу от merge-base с `dev`, до ребейза. Прежние метки читаются по §5.1:
инфраструктурная задача без трековой метки — `show`, продуктовая — `ask`.
Шаг трека делает **один вызов** скрипта по меткам, диффу и комментариям issue
(#707): трек и его основание (строка владельца, §5), рамки `ship`, риск по
изменённым участкам, повышение `ship` → `show`, заметку риска в промпт ревью
(не длиннее 25 строк) и строку риска для комментария слияния `ship`. Bash шага
только исполняет: комментарий берёт из файла скрипта, метки меняет по его флагу.
Guard берёт трек и лимит циклов из того же скрипта (`process-track.mjs
limit`) и своей логики трека не держит; ответ compare API на 300 файлов и
больше инфраструктуру не доказывает — `ask`, лимит 4. Этап `spec`, отсутствие
ветки и инфраструктурный дифф дают пустой риск и прежнее поведение.
| | `ship` | `show` | `ask` |
|---|---|---|---|
@@ -1219,10 +1273,14 @@ Matysh/houseplan-card/.github/workflows/_<имя>.yml@dev` с `secrets: inherit`
Мутантов по диффу нет ни на одном треке (#709, §2.7). Рамки `ship`
(§5) проверяет тот же шаг; выход за них — комментарий в issue и замена
`track:ship` на `track:show` в этом же заходе. Слияние `ship` оставляет в issue
комментарий с машинным маркером `hp:ship-merge`. Это не вердикт ревью и так себя
не называет; по маркеру пакетное ревью находит задачи диапазона. Повторно
применимый зелёный вердикт (#499) главнее `ship`: код уже прочитан.
`track:ship` на `track:show` в этом же заходе; так же — рискованный участок без
подтверждения владельца (§5, #707), одним комментарием с нарушениями рамок.
Слияние `ship` оставляет в issue комментарий с машинным маркером `hp:ship-merge`.
Это не вердикт ревью и так себя не называет; по маркеру пакетное ревью находит
задачи диапазона. Если `ship` слит с риском (подтверждён владельцем или риск
только `visual`), комментарий несёт строку «Риск по участкам …» и машинную
`<!-- hp:ship-risk classes=… -->`; строка маркера `hp:ship-merge` не меняется.
Повторно применимый зелёный вердикт (#499) главнее `ship`: код уже прочитан.
В `dev` по-прежнему уезжает только SHA с зелёным Validate. Без ребейза до ревью
кандидат собирается один раз, при слиянии, и лёгкий Validate проходит там.
@@ -1573,7 +1631,11 @@ action ревью пускает ровно этого бота (`allowed_bots`,
`scripts/ship-review.mjs prepare`; ship-задач нет — модель не запускается;
- **суждение** — по строке ТЗ каждой задачи и её коммитам: делает ли код
заявленное и только его, не ломает ли соседнее, не вышла ли правка из ship по
смыслу. Правила ревьюера — `docs/process/REVIEWER.md`, «Пакетное ревью ship»;
смыслу. Под задачей бриф печатает строку риска из её комментария
`hp:ship-merge` (`hp:ship-risk`, #707): рискованные участки ship,
подтверждённого владельцем, конвейер не повышал — их первым читает пакетное
ревью. Комментарии до #707 строки не несут — риск не записан. Правила
ревьюера — `docs/process/REVIEWER.md`, «Пакетное ревью ship»;
- **выход** — `docs/reviews/SHIP-REVIEW-<тег>.md` в `dev` с машинным блоком:
задачи и счёт High/Medium/Low. У модели нет прав записи, документ публикует
детерминированный шаг.