docs(skills): плейбук — вкусовая линза ревьюера доведена до механизма

- Зачем:
  - решение 2026-07-23 «в линзу Клод-ревьюера — осмысленность кода» жило только в уроках и в памяти другого проекта, в заготовки промптов не попало: прогон #18 собрал старую линзу, и ревьюер не был обязан спрашивать, не дичь ли решение.
  - общий вывод прогона: решение, записанное только в уроки, следующим прогоном не исполняется — ехать может лишь механизм, который подшивается в промпт.
- Что:
  - prompt-templates.md: в заготовку line-task.md добавлен блок Taste — формально верное, но по сути неправильное считается находкой, три примера и правило оценки серьёзности по цене жизни с кодом; разрез по родословной переведён с цитаты фразы на именованный блок.
  - SKILL.md: описание линии «по задаче» больше не расходится с заготовкой — названа уместность решения и дана отсылка за точными словами.
  - lessons.md: две датированные записи (вкусовая линза; казусы координации прогона #18) и открытый вопрос о рефакторинге заготовок линий.
- Проверка:
  - слепое ревью правок Опусом по критериям /writing-great-skills: CHANGES_REQUIRED, 5 MAJOR — сокращение списка примеров, ведущее слово, разрез блоком, устаревшая копия в SKILL.md; все замечания по своим правкам закрыты, структурные вынесены в открытый вопрос по решению пользователя.
  - подтверждено ревью: расширение линзы не пустышка — прежний текст был целиком про соответствие постановке.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Dmitry DementievandClaude Opus 5 committed 2026-07-31 13:36:33 +03:00
1 parent ef09a7832b
commit 6e67ccc1df
3 files changed
+87 -1

No files matched your search

@@ -184,7 +184,8 @@ description: >-
родословной, чем исполнитель (у нас — Клод при Codex-исполнителе; родословной, чем исполнитель (у нас — Клод при Codex-исполнителе;
одиночную линию выбирай по родословной, не по цене); **обычное и одиночную линию выбирай по родословной, не по цене); **обычное и
сложнее** — два слепых ревью параллельно с разведёнными фокусами: одна сложнее** — два слепых ревью параллельно с разведёнными фокусами: одна
линия «по задаче» (соответствие постановке, критериям, границам), другая линия «по задаче» (соответствие постановке, критериям, границам и
уместность решения — точные слова в заготовке линии), другая
«по коду» (корректность, инварианты, регрессии, честность тестов) — «по коду» (корректность, инварианты, регрессии, честность тестов) —
разность семейств даёт разные находки, разность фокусов страхует от разность семейств даёт разные находки, разность фокусов страхует от
дублирования, когда семейства сходятся. Промпт — **общий блок один на дублирования, когда семейства сходятся. Промпт — **общий блок один на
@@ -443,3 +443,77 @@ Workflow», либо для каждой роли карты заводится
compose down`); отдельных событий эскалации в `--json`-логе нет — compose down`); отдельных событий эскалации в `--json`-логе нет —
успешные команды выглядят обычными `completed`. Кавеаты в успешные команды выглядят обычными `completed`. Кавеаты в
`codex-exec.md` обновлены, пометка «боем не обкатано» снята. `codex-exec.md` обновлены, пометка «боем не обкатано» снята.
## 2026-07-31: решение о вкусовой линзе неделю не доезжало до механизма
Прогон clickstream-data-platform, тикет #18 (пробные DAG в Airflow).
Решение 2026-07-23 («в линзу Клод-ревьюера — осмысленность кода») жило в
записи уроков и в памяти ТОГО проекта, но в `prompts/`/`prompt-templates.md`
не попало. Оркестратор собрал линию TASK `cat`'ом из заготовки — и ревьюер
не был обязан спрашивать «не дичь ли это». Пользователь заметил это сам,
по ходу прогона, дословно: «Бывает когда сделано формально правильно, а по
сути - дичь».
Урок общий: решение, записанное только в уроки, следующим прогоном не
исполняется. Память пообъектная — в другой репозиторий она не едет; ехать
может лишь механизм, который подшивается в промпт. Поглощено 2026-07-31:
`prompt-templates.md`, заготовка `line-task.md` + оговорка о родословной.
Вторая половина того же решения (узкую перепроверку после триажа отдавать
линзе, видящей дифф триажа целиком) сработала: перепроверка ушла той же
линии TASK, и ей отдельно задан вопрос про `tests/dag-probes-unit.py` —
файл, которого в тикете не было и который исполнитель добавил на починке.
Две сильнейшие находки линии TASK в этом прогоне — из класса, который
новая формулировка называет прямо, а старая не называла: молчаливый опрос
`1800 × docker compose exec` (выглядит как 90 с, на деле ~8 мин при 0,36 с
на итерацию) — несоразмерность; пробник, не проверявший, на каком шарде
оказался его маркер, — проверка без доказательства своего утверждения.
Правки того же дня прошли слепое ревью по `/writing-great-skills`
(CHANGES_REQUIRED, 5 MAJOR): пять примеров в линзе сокращены до трёх с
ведущим словом `Taste:`, разрез по родословной переведён с цитаты фразы на
блок целиком, снята устаревшая копия описания линзы в SKILL.md. Ревью
подтвердило, что само расширение линзы не пустышка: прежний текст был
целиком про соответствие постановке, и вкусовая находка уезжала бы в
«вне скоупа».
## 2026-07-31: казусы координации (прогон #18, тот же день)
- Молчание субагента ≠ смерть. Клод-ревьюер шёл 59 минут, не сбрасывая
транскрипт на диск (153 байта с момента старта). Оркестратор счёл его
мёртвым и поднял дубль — тот писал бы вердикт в ТОТ ЖЕ путь и затёр бы
находки; спасло только то, что уведомление пришло раньше. Правила:
признак жизни — уведомление харнесса, не размер журнала; замене давай
ДРУГОЙ путь вердикта; в обёртке проси писать индекс инкрементально.
- Отчёт ревьюера о состоянии среды — не факт. Линия CODE вернула «все
долгоживущие службы здоровы», а `kafka` и `prometheus` лежали `exited`:
их погасил её же страж и не поднял. `docker compose ps` без `-a`
погашенных не показывает вовсе — легко принять за здоровый стенд.
- Две линии ревью на одном живом стенде мешают друг другу: стражи гасят
службы и роняют таблицы, параллельная линия получает загрязнённые
прогоны (заметили обе, независимо). Либо стенд одной линии, либо явный
запрет ломающих команд второй.
Эти четыре правила пока живут только здесь — то есть повторяют ровно тот
отказ, который диагностирует запись выше. Поглощение — в рефакторинге
(см. открытый вопрос ниже).
### Открытый вопрос 2026-07-31: рефакторинг заготовок линий
Решение пользователя: скилл важный и работает регулярно, структурные
правки — отдельной осознанной работой, не походя. Накопилось на один
заход:
- `line-task.md` / `line-code.md` не содержат ни одного `{{...}}` — это
константы, но лежат не в `prompts/`, и оркестратор перепечатывает их
Write'ом каждый прогон. Тот самый канал дрейфа, ради которого правка
2026-07-31 и делалась. Перенести в `prompts/`, подшивать `cat`'ом;
блок `Taste:` — отдельным файлом, тогда разрез по родословной станет
выбором файла, а не пересказом границы.
- Четыре правила координации выше поглотить в механизм: два — в обёртку
вызова Клод-ревьюера (свой путь вердикта, инкрементальная запись), два —
в «Сбои координации» SKILL.md (проверка среды своими руками, стенд не
делить между линиями).
- Заодно проверить остальные заготовки на то же расхождение «константа
живёт в документации вместо `prompts/`».
@@ -147,6 +147,11 @@ shared code}}
FINDING PREFIX: TASK FINDING PREFIX: TASK
Lens: compliance with the statement, acceptance criteria, boundaries, Lens: compliance with the statement, acceptance criteria, boundaries,
intended observable result. intended observable result.
Taste: formally correct but substantively wrong is a finding — work out of
proportion to the task, an added artifact that does not earn its
existence, a check that passes without proving its own claim. Grade a
taste finding by the cost of living with the code, not by whether it
breaks a test.
``` ```
```markdown ```markdown
@@ -160,6 +165,12 @@ Lens: correctness, invariants, regressions, security, test honesty.
распределение: Codex — CODE (дефекты нового кода), Клод — TASK (уровень распределение: Codex — CODE (дефекты нового кода), Клод — TASK (уровень
задачи и архитектуры). задачи и архитектуры).
Блок `Taste:` едет с **родословной**, а не с буквой линии: он адресован
Клоду (решение пользователя 2026-07-23, запись в
[lessons.md](lessons.md)). При обычном распределении и у одиночного
ревьюера он уже на месте — обоих ведёт Клод. Поменялись родословными —
переставь блок целиком туда, где Клод.
Вариант для **этапа 2** (ревью постановки, кода изменений ещё нет) — тот же Вариант для **этапа 2** (ревью постановки, кода изменений ещё нет) — тот же
boilerplate, другой параметрический блок: boilerplate, другой параметрический блок: