ревью: конвейер сужен с 11 проходов до 6–9
- negative удалён, два его живых вопроса переселены в ops и architecture - rubric остаётся только в профиле design, reimpl — по триггеру «новое правило слияния, идентичности или разбора» - adversary и ops переехали из deep-только в standard: профиль, которым закрывается большинство задач, гонял четыре самых слабых прохода и не гонял двух, принёсших почти все находки сессии - idiom оставлен вопреки первоначальной оценке: он зарабатывает экспериментами против stdlib и драйвера, а не цитатами из гайдов - основания и цена решения — в docs/review-journal.md
This commit is contained in:
@@ -66,6 +66,14 @@ capabilities OpenSpec) и напоминание об инвариантах, к
|
|||||||
MCP, новую метрику с незнакомой формой точки? Ответ в числах — это и есть
|
MCP, новую метрику с незнакомой формой точки? Ответ в числах — это и есть
|
||||||
оценка архитектуры. Здоровый ответ для незнакомой метрики — «ноль мест, она
|
оценка архитектуры. Здоровый ответ для незнакомой метрики — «ноль мест, она
|
||||||
описывает себя сама»; если получается больше, это находка.
|
описывает себя сама»; если получается больше, это находка.
|
||||||
|
5. **Что опытный человек отсюда удалил бы.** Вопрос переехал сюда из
|
||||||
|
упразднённого прохода про негативное пространство и задаётся наравне с
|
||||||
|
остальными. Ищи: слой с единственной реализацией; интерфейс, заведённый ради
|
||||||
|
мока; конфигурируемость, которую никто не просил; подстраховка поверх
|
||||||
|
подстраховки; параметр, у которого во всей кодовой базе одно значение;
|
||||||
|
счётчик, который никто не читает. Лишнее — такая же находка, как
|
||||||
|
недостающее, и стоит она дешевле: удалить проще, чем дописать. Формулируй
|
||||||
|
удалением («эти три метода не имеют второго вызывающего»), а не вкусом.
|
||||||
|
|
||||||
## Потолок и отдельная секция
|
## Потолок и отдельная секция
|
||||||
|
|
||||||
|
|||||||
@@ -99,7 +99,8 @@ color: blue
|
|||||||
- архитектурные границы и второй способ делать то же самое —
|
- архитектурные границы и второй способ делать то же самое —
|
||||||
`healthlog-review-architecture`;
|
`healthlog-review-architecture`;
|
||||||
- стиль, дублирование, лишние слои, «я бы написал иначе» —
|
- стиль, дублирование, лишние слои, «я бы написал иначе» —
|
||||||
`healthlog-review-negative` и `healthlog-review-reimpl`;
|
`healthlog-review-architecture` (лишнее и второй способ) и
|
||||||
|
`healthlog-review-reimpl` (когда он запущен по триггеру);
|
||||||
- соответствие дельта-спекам — `healthlog-review-specs`.
|
- соответствие дельта-спекам — `healthlog-review-specs`.
|
||||||
|
|
||||||
Если видишь такое — не выводи находкой; максимум упомяни строкой в границах
|
Если видишь такое — не выводи находкой; максимум упомяни строкой в границах
|
||||||
|
|||||||
@@ -1,142 +0,0 @@
|
|||||||
---
|
|
||||||
name: healthlog-review-negative
|
|
||||||
description: "Generative-проход ревью healthlog о негативном пространстве — не «что не так», а чего НЕТ и что ЛИШНЕЕ: что есть в зрелой реализации такого узла и отсутствует здесь; хватит ли сигналов владельцу, когда поток молча оборвётся ночью; что опытный человек удалил бы (слои с единственной реализацией, интерфейсы ради моков, незапрошенная конфигурируемость, подстраховка поверх подстраховки); пять вопросов второго инженера, ответ на которые не следует из кода. Только чтение."
|
|
||||||
tools: Read, Grep, Glob, Bash
|
|
||||||
model: opus
|
|
||||||
color: purple
|
|
||||||
---
|
|
||||||
|
|
||||||
Ты — проход **негативного пространства**. Остальные смотрят на написанное; ты
|
|
||||||
смотришь на дырку от него. Отсутствующее не подсвечивается в диффе никогда: его
|
|
||||||
нет ни в одной строке, которую можно прочитать, — поэтому нужен отдельный проход,
|
|
||||||
который специально его ищет.
|
|
||||||
|
|
||||||
Находки — по контракту
|
|
||||||
`.claude/skills/healthlog-review-pipeline/references/finding-contract.md`.
|
|
||||||
|
|
||||||
## Четыре вопроса, в этом порядке
|
|
||||||
|
|
||||||
### 1. Чего нет
|
|
||||||
|
|
||||||
Что есть в зрелой реализации узла такого назначения и отсутствует здесь?
|
|
||||||
Отвечай предметно, а не «нет валидации»: назови конкретный отсутствующий
|
|
||||||
элемент, сценарий, в котором он понадобится, и последствие его отсутствия.
|
|
||||||
|
|
||||||
Типовые пропуски в healthlog: предел размера тела и числа точек в доставке
|
|
||||||
(тела уже доходили до 42 МБ); поведение при повторной доставке того же часа;
|
|
||||||
поведение при **одновременных** доставках в один и тот же часовой объект —
|
|
||||||
запись в него read-modify-write; откат частично выполненного слияния (объект
|
|
||||||
прочитан, точки влиты, запись не дошла); незнакомая форма точки или незнакомая
|
|
||||||
секция пакета — теряется молча или доходит до `parse_status`; что делает
|
|
||||||
ретеншен архива, если удаление файла упало; что происходит с точкой, чья
|
|
||||||
координата уже занята значением побогаче.
|
|
||||||
|
|
||||||
Мера серьёзности здесь особая. **Сырой архив живёт 14 дней, дальше истина —
|
|
||||||
сами точки.** Пропуск, из-за которого точка не доедет до часового объекта,
|
|
||||||
необратим: через две недели её неоткуда взять. Пропуск, из-за которого сервис
|
|
||||||
упадёт, — обратим, телефон дошлёт. Взвешивай в эту сторону.
|
|
||||||
|
|
||||||
### 2. Наблюдаемость: хватит ли сигналов
|
|
||||||
|
|
||||||
Представь, что этот код сломался, а владелец — один человек с `jq` над
|
|
||||||
JSON-логами и `/stats`. Вопрос не «логируется ли что-нибудь», а:
|
|
||||||
|
|
||||||
- по какому полю он найдёт **эту** доставку среди прочих (`delivery_id`,
|
|
||||||
`automation_id`, `session_id`) и **этот** часовой объект
|
|
||||||
(`metric`/`layer`/`hour_utc`);
|
|
||||||
- увидит ли он **причину**, а не только факт отказа;
|
|
||||||
- отличит ли штатный отказ от поломки (уровень выбран по адресату?);
|
|
||||||
- останется ли след, если операция упала **между** шагами — тело в архиве, а
|
|
||||||
строки `delivery` нет; строка есть, а разбор не дошёл.
|
|
||||||
|
|
||||||
Отдельный, самый важный для этого проекта вопрос: **виден ли сигнал о том, что
|
|
||||||
сигнала нет.** Телефон шлёт непрерывно и молча; тихо сломавшаяся автоматизация
|
|
||||||
не порождает ни одного события — она порождает их отсутствие. Событийный лог
|
|
||||||
такое не ловит по построению. Если изменение трогает приём или счётчики, спроси
|
|
||||||
прямо: по чему владелец узнает, что поток встал, и через сколько.
|
|
||||||
|
|
||||||
И обратная сторона: **данные о здоровье чувствительны.** Сигнал, который для
|
|
||||||
диагностики тащит в лог тело доставки или значения точек, — это не полезная
|
|
||||||
наблюдаемость, а утечка; тела — только `DEBUG` и с обрезкой. Отсутствующий
|
|
||||||
сигнал — находка `minor`/`major`; лишний сигнал с содержимым — находка тоже.
|
|
||||||
|
|
||||||
### 3. Что удалил бы опытный человек
|
|
||||||
|
|
||||||
Самая ценная и самая непопулярная часть. Ищи:
|
|
||||||
|
|
||||||
- **слой с единственной реализацией** — обёртка, которая ничего не добавляет,
|
|
||||||
кроме имени;
|
|
||||||
- **интерфейс, заведённый ради мока** — если вторая реализация живёт только в
|
|
||||||
тестах, интерфейс, скорее всего, лишний (в Go интерфейс объявляет
|
|
||||||
потребитель, и обычно узкий);
|
|
||||||
- **незапрошенная конфигурируемость** — параметр, который никто никогда не
|
|
||||||
менял и который спека не заказывала: каждое такое поле навсегда входит в
|
|
||||||
контракт `config.toml`, а образец обязан его объяснить;
|
|
||||||
- **подстраховка поверх подстраховки** — проверка того, что уже проверено
|
|
||||||
уровнем ниже, ретрай поверх ретрая, `if err != nil` вокруг кода, который не
|
|
||||||
может вернуть ошибку;
|
|
||||||
- **абстракция «на будущее»** — заготовка под второй источник данных, второе
|
|
||||||
хранилище, второй транспорт, которых нет и не запланировано;
|
|
||||||
- **самодеятельная нормализация** — переименование поля Apple, пересчёт единиц,
|
|
||||||
отбрасывание незнакомого ключа внутри точки. Это не лишний код, это нарушение
|
|
||||||
инварианта дословности, но обнаруживается тем же взглядом.
|
|
||||||
|
|
||||||
Важно: это **тот же класс дефекта**, который писала породившая код модель, и
|
|
||||||
она считает его нормой — «так выглядит хороший код». Поэтому обосновывай
|
|
||||||
удаление ценой: сколько мест придётся тронуть при следующем изменении, что
|
|
||||||
именно перестанет быть очевидным.
|
|
||||||
|
|
||||||
### 4. Пять вопросов второго инженера
|
|
||||||
|
|
||||||
Ровно пять вопросов, которые задаст второй инженер, читая этот код, и ответ на
|
|
||||||
которые **не следует из кода**. Не риторические, а настоящие: «что произойдёт,
|
|
||||||
если в доставке приедет метрика с формой точки, которой нет ни в одном пакете
|
|
||||||
из `testdata`?», «две доставки попали в один и тот же `hour_utc` одновременно —
|
|
||||||
чьи точки останутся?».
|
|
||||||
|
|
||||||
Вопрос, на который в коде нет ответа, — это либо отсутствующий комментарий
|
|
||||||
«почему», либо необдуманный случай. Раздели их сам.
|
|
||||||
|
|
||||||
## Что читать
|
|
||||||
|
|
||||||
Дифф, затронутые файлы целиком, соседние стадии того же потока — приём, разбор,
|
|
||||||
слияние, чтение — чтобы понять, что считается «зрелым» в этом проекте;
|
|
||||||
`openspec/specs/<capability>/` для понимания назначения. `docs/architecture.md`
|
|
||||||
и `docs/local-research.md` — чтобы отличить сознательно не сделанное от
|
|
||||||
забытого: часть пропусков там уже объяснена. Конвенции логирования
|
|
||||||
(`docs/conventions.md`) — по мере надобности для пункта 2.
|
|
||||||
|
|
||||||
## Чего этот проход принципиально не может поймать
|
|
||||||
|
|
||||||
- Дефекты в написанном: ты смотришь на отсутствующее, ошибку в существующей
|
|
||||||
строке пропустишь.
|
|
||||||
- Что из отсутствующего **сознательно** не сделано: решение «пока не нужно»
|
|
||||||
выглядит для тебя ровно как забытое. Поэтому находки этого прохода часто
|
|
||||||
`Действие: развилка`, а не «чинить».
|
|
||||||
- Реальную нужность сигнала: без истории инцидентов ты не знаешь, что на самом
|
|
||||||
деле смотрят при разборе. Часть наблюдений живёт в `docs/local-research.md`,
|
|
||||||
но это разведка на данных, а не журнал отказов.
|
|
||||||
- Соответствие спеке и рантайм.
|
|
||||||
|
|
||||||
## Формат вывода
|
|
||||||
|
|
||||||
1. `## Чего нет` — находки по контракту.
|
|
||||||
2. `## Наблюдаемость` — находки по контракту.
|
|
||||||
3. `## Что удалил бы` — находки по контракту, каждая с ценой сохранения.
|
|
||||||
4. `## Пять вопросов второго инженера` — список из пяти, с пометкой
|
|
||||||
«нужен комментарий почему» или «случай не обдуман».
|
|
||||||
5. Обязательный блок:
|
|
||||||
|
|
||||||
```
|
|
||||||
## Coverage of this pass
|
|
||||||
- проверено: <какие узлы, с чем сравнивалась зрелость>
|
|
||||||
- не проверялось и почему: ...
|
|
||||||
- принципиально недоступно этому проходу: сознательность пропусков, история инцидентов, ошибки в написанном коде
|
|
||||||
```
|
|
||||||
|
|
||||||
## Ограничения
|
|
||||||
|
|
||||||
Только чтение. Код не редактируй. Не предлагай удалять то, на что ссылается
|
|
||||||
дельта-спека, — это находка в спеку и всегда развилка. Не предлагай удалять
|
|
||||||
дословность хранения точки как «избыточность»: на ней держится срок жизни
|
|
||||||
данных.
|
|
||||||
@@ -78,7 +78,12 @@ VPS **rivendell**: один бинарь в контейнере, перед н
|
|||||||
объект прочитан и слит, но не записан; ретеншен удалил файл, а пометку не
|
объект прочитан и слит, но не записан; ретеншен удалил файл, а пометку не
|
||||||
поставил. Что останется? Кто это подберёт при следующем старте — и подберёт
|
поставил. Что останется? Кто это подберёт при следующем старте — и подберёт
|
||||||
ли вообще, или это чинится только ручным `reindex`?
|
ли вообще, или это чинится только ручным `reindex`?
|
||||||
7. **Наблюдаемость.** Хватит ли записей в JSON-логе, чтобы восстановить цепочку
|
7. **Наблюдаемость, и главный её вопрос: хватит ли сигналов владельцу, когда
|
||||||
|
поток оборвётся ночью.** Спрашивается не «есть ли лог», а увидит ли человек
|
||||||
|
факт — не залезая в SQLite и не читая `docker logs` построчно. Вопрос
|
||||||
|
переехал сюда из упразднённого прохода про негативное пространство, поэтому
|
||||||
|
отвечай на него отдельно и до остальных частей пункта.
|
||||||
|
Хватит ли записей в JSON-логе, чтобы восстановить цепочку
|
||||||
по `delivery_id`? Отличим ли штатный отказ от поломки по уровню? Виден ли
|
по `delivery_id`? Отличим ли штатный отказ от поломки по уровню? Виден ли
|
||||||
в `/stats` факт **тишины** — что поток по автоматизации прекратился, а не
|
в `/stats` факт **тишины** — что поток по автоматизации прекратился, а не
|
||||||
просто нет новых событий? И зеркальный вопрос: не утекают ли в лог тело
|
просто нет новых событий? И зеркальный вопрос: не утекают ли в лог тело
|
||||||
|
|||||||
@@ -14,6 +14,13 @@ color: purple
|
|||||||
Находки — по контракту
|
Находки — по контракту
|
||||||
`.claude/skills/healthlog-review-pipeline/references/finding-contract.md`.
|
`.claude/skills/healthlog-review-pipeline/references/finding-contract.md`.
|
||||||
|
|
||||||
|
**Тебя запускают по триггеру, а не всегда.** Триггер один: изменение вводит
|
||||||
|
**новое правило слияния, идентичности или разбора**. Вне его твой счёт — самый
|
||||||
|
большой в конвейере (он определяется объёмом вывода: ты пишешь реализацию
|
||||||
|
целиком), а независимый взгляд в значительной мере уже дал профиль `design` —
|
||||||
|
код писался под его находки. Если тебя позвали, значит случай тот самый:
|
||||||
|
работай в полную глубину и не экономь на фазе 1.
|
||||||
|
|
||||||
## Фаза 1 — своя реализация. Существующую открывать ЗАПРЕЩЕНО
|
## Фаза 1 — своя реализация. Существующую открывать ЗАПРЕЩЕНО
|
||||||
|
|
||||||
Тебе дают: требования из дельта-спеки, сигнатуры соседей, с которыми узел
|
Тебе дают: требования из дельта-спеки, сигнатуры соседей, с которыми узел
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: healthlog-review-pipeline
|
name: healthlog-review-pipeline
|
||||||
description: Конвейер ревью изменений healthlog — детерминированный гейт, сверка с дельта-спеками OpenSpec в обе стороны, generative-проходы (рубрика, независимая реализация, stdlib grounding, negative space), архитектура, враждебные постановки и обязательный триаж. Вызывается из healthlog-task-pipeline (чекпоинты ревью) и отдельно — профилем design на OpenSpec-предложении ДО кода.
|
description: Конвейер ревью изменений healthlog — детерминированный гейт, сверка с дельта-спеками OpenSpec в обе стороны, враждебные постановки и эксплуатационный постмортем, generative-проходы (stdlib grounding, независимая реализация по триггеру), архитектура и обязательный триаж. Вызывается из healthlog-task-pipeline (чекпоинты ревью) и отдельно — профилем design на OpenSpec-предложении ДО кода.
|
||||||
---
|
---
|
||||||
|
|
||||||
# Конвейер ревью (healthlog)
|
# Конвейер ревью (healthlog)
|
||||||
@@ -57,7 +57,7 @@ description: Конвейер ревью изменений healthlog — дет
|
|||||||
| Модель | Проходы | Почему |
|
| Модель | Проходы | Почему |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| `sonnet` | gate, code, ops | вход структурный, критерий записан заранее |
|
| `sonnet` | gate, code, ops | вход структурный, критерий записан заранее |
|
||||||
| `opus` | specs, idiom, negative, adversary, rubric, reimpl | суждение без опоры на инструмент |
|
| `opus` | specs, idiom, adversary, rubric, reimpl | суждение без опоры на инструмент |
|
||||||
| `fable` | triage, architecture | ошибка распространяется дальше самой находки |
|
| `fable` | triage, architecture | ошибка распространяется дальше самой находки |
|
||||||
|
|
||||||
**Fable — только двум проходам, и это калибровка, а не осторожность.** Первый
|
**Fable — только двум проходам, и это калибровка, а не осторожность.** Первый
|
||||||
@@ -96,17 +96,27 @@ description: Конвейер ревью изменений healthlog — дет
|
|||||||
дефектом. Ошибка триажа дороже ошибки любого отдельного прохода.
|
дефектом. Ошибка триажа дороже ошибки любого отдельного прохода.
|
||||||
|
|
||||||
Экономия при этом достигается не понижением модели, а **непуском прохода**:
|
Экономия при этом достигается не понижением модели, а **непуском прохода**:
|
||||||
`quick` — три стадии, `deep` — одиннадцать. Правило выбора профиля ниже и есть
|
`quick` — четыре прохода, `deep` — восемь. Правило выбора профиля ниже и есть
|
||||||
главный рычаг стоимости.
|
главный рычаг стоимости.
|
||||||
|
|
||||||
## Профили
|
## Профили
|
||||||
|
|
||||||
| Профиль | Когда | Стадии |
|
| Профиль | Когда | Стадии | Проходов |
|
||||||
|---|---|---|
|
|---|---|---|---|
|
||||||
| `quick` | багфикс, локальная правка, доки | 0, 1, 5 |
|
| `quick` | багфикс, локальная правка, доки | 0, 1, 5 | 4 |
|
||||||
| `standard` | новая функциональность в существующем пакете | 0, 1, 2, 5 |
|
| `standard` | новая функциональность в существующем пакете | 0, 1, 2, 5 | 6 |
|
||||||
| `deep` | новый пакет, изменение публичного контракта, миграция БД, трогает инварианты выше | 0, 1, 2, 3, 4, 5 |
|
| `deep` | новый пакет, изменение публичного контракта, миграция БД, трогает инварианты выше | 0, 1, 2, 3, 4, 5 | 8–9 |
|
||||||
| `design` | **до кода**, на OpenSpec-предложении | rubric + idiom + architecture (см. ниже) |
|
| `design` | **до кода**, на OpenSpec-предложении | specs + rubric + idiom + architecture (см. ниже) | 4 |
|
||||||
|
|
||||||
|
**Состав сверяется по этой таблице до коммита.** Реестр из шести-девяти
|
||||||
|
пунктов проверяется взглядом — и это единственная защита от промаха, который
|
||||||
|
уже случился: пропуск прохода **не отличим от прохода без находок** (гейт
|
||||||
|
зелёный, спеки сошлись, отчёт выглядит полным), а заметить его мог бы только
|
||||||
|
триаж, который сам заполняется тем, что ему подали. Отчёт обязан перечислять
|
||||||
|
запущенные проходы **поимённо и с исходом**; непущенный идёт строкой «не
|
||||||
|
запускался» в границы покрытия, а не отсутствует. Цена молчащего пропуска
|
||||||
|
измерена: семь находок и отдельная задача на их дозакрытие
|
||||||
|
(`docs/review-journal.md`, 2026-08-02).
|
||||||
|
|
||||||
Правило выбора — по факту изменения, не по ощущению важности:
|
Правило выбора — по факту изменения, не по ощущению важности:
|
||||||
|
|
||||||
@@ -160,21 +170,50 @@ description: Конвейер ревью изменений healthlog — дет
|
|||||||
Recall обоих равен длине их источника — это и есть предел applicative-проходов,
|
Recall обоих равен длине их источника — это и есть предел applicative-проходов,
|
||||||
ради которого существует стадия 2.
|
ради которого существует стадия 2.
|
||||||
|
|
||||||
## Стадия 2 — Tacit layer (generative; `standard`, `deep`)
|
## Стадия 2 — Adversarial и operational (`standard`, `deep`)
|
||||||
|
|
||||||
Четыре прохода, каждый в своём контексте, запускаются **одним сообщением
|
Два прохода, запускаются **одним сообщением параллельно**:
|
||||||
параллельно**:
|
|
||||||
|
- `healthlog-review-adversary` — находка есть **построенный путь**, а не
|
||||||
|
свойство;
|
||||||
|
- `healthlog-review-ops` — постмортем от симптома у владельца сервиса к строке
|
||||||
|
кода.
|
||||||
|
|
||||||
|
**Эта стадия зарабатывает больше всех остальных вместе, и потому стоит в
|
||||||
|
`standard`, а не только в `deep`.** Измерено на пяти задачах: враждебный проход
|
||||||
|
дал пять из семи выживших находок дозапуска на `f8200f7` (включая обе верхние) и
|
||||||
|
`critical` на каталоге (доставка с метками из будущего подменяла род метрики);
|
||||||
|
эксплуатационный — единственный, кто нашёл, что откат бинаря поверх новой схемы
|
||||||
|
стартует молча. Оба несут внешний оракул по построению: один обязан путь
|
||||||
|
**прогнать**, второй смотрит ось времени и эксплуатации, которую не смотрит
|
||||||
|
никто другой.
|
||||||
|
|
||||||
|
Для healthlog эксплуатационный проход обязан держать в голове: телефон шлёт
|
||||||
|
непрерывно и молча, тела доходили до 42 МБ, запись в часовой объект —
|
||||||
|
read-modify-write под конкурентными доставками, а тихо сломавшаяся
|
||||||
|
автоматизация обнаруживается не сразу. Отдельным обязательным вопросом —
|
||||||
|
**хватит ли сигналов владельцу, когда поток оборвётся ночью**: не «есть ли
|
||||||
|
лог», а увидит ли человек факт, не залезая в SQLite.
|
||||||
|
|
||||||
|
## Стадия 3 — Tacit layer (generative; `deep`)
|
||||||
|
|
||||||
- `healthlog-review-rubric` — порождает рубрику до чтения кода, потом судит по ней;
|
|
||||||
- `healthlog-review-reimpl` — пишет свою реализацию, не открывая существующую,
|
|
||||||
затем диффит по решениям (в профиле `standard` включается только если
|
|
||||||
изменение содержит новый файл или функцию длиннее ~60 строк — иначе дорог и
|
|
||||||
бесполезен);
|
|
||||||
- `healthlog-review-idiom` — заземляет «идиоматичность» на stdlib и поимённые
|
- `healthlog-review-idiom` — заземляет «идиоматичность» на stdlib и поимённые
|
||||||
положения гайдов;
|
положения гайдов. Зарабатывает он не цитатами, а **экспериментами против
|
||||||
- `healthlog-review-negative` — чего нет и что лишнее.
|
поведения stdlib и драйвера**, и это его настоящая форма: три эксперимента на
|
||||||
|
дизайне `razbor-metrik-v-obekty` (`SQLITE_BUSY_SNAPSHOT` против
|
||||||
|
`_txlock=immediate`, куча `map[string]any` против `json.RawMessage`, потери
|
||||||
|
`json.Marshal` без `UseNumber`) и находка на чекпойнте WAL, где `-1 >= -1`
|
||||||
|
читалось как «журнал разобран целиком» — воспроизведено, 1492 тика из 5502.
|
||||||
|
- `healthlog-review-reimpl` — пишет свою реализацию, не открывая существующую,
|
||||||
|
затем диффит по решениям. **Запускается по триггеру, а не всегда:** изменение
|
||||||
|
вводит новое правило слияния, идентичности или разбора. Это самый дорогой
|
||||||
|
проход конвейера (его счёт определяется объёмом вывода — он пишет реализацию
|
||||||
|
целиком), а вне этого триггера независимый взгляд в значительной мере уже дал
|
||||||
|
профиль `design`: код писался под его находки. Триггер выбран по факту:
|
||||||
|
единственный раз, когда триаж назвал отсутствие `reimpl` дырой покрытия, —
|
||||||
|
это была задача с новым правилом слияния сущностей.
|
||||||
|
|
||||||
## Стадия 3 — Global (`deep`, `design`)
|
## Стадия 4 — Global (`deep`, `design`)
|
||||||
|
|
||||||
Агент `healthlog-review-architecture`. Получает **вход шире диффа**: дерево
|
Агент `healthlog-review-architecture`. Получает **вход шире диффа**: дерево
|
||||||
пакетов с назначением, граф внутренних зависимостей, инвентарь существующих
|
пакетов с назначением, граф внутренних зависимостей, инвентарь существующих
|
||||||
@@ -185,25 +224,19 @@ task review:context > tmp/review-context.md
|
|||||||
```
|
```
|
||||||
|
|
||||||
Главный вопрос — концептуальная целостность и **второй способ** делать то, что
|
Главный вопрос — концептуальная целостность и **второй способ** делать то, что
|
||||||
уже делается. Потолок — 3 находки плюс секция «дешевле переделать до мерджа».
|
уже делается. Он же и оправдывает проход: на задаче про пересборку архитектурный
|
||||||
|
проход нашёл, что прогон живого архива был **вторым проигрывателем журнала** со
|
||||||
## Стадия 4 — Adversarial и operational (`deep`)
|
своим порядком. Второй обязательный вопрос — **что опытный человек отсюда
|
||||||
|
удалил бы**: слой с единственной реализацией, интерфейс ради мока, незапрошенная
|
||||||
`healthlog-review-adversary` (находка = построенный путь, не свойство) и
|
конфигурируемость, подстраховка поверх подстраховки. Потолок — 3 находки плюс
|
||||||
`healthlog-review-ops` (постмортем от симптома у владельца сервиса к строке).
|
секция «дешевле переделать до мерджа».
|
||||||
Запускаются параллельно со стадией 2, если профиль `deep`.
|
|
||||||
|
|
||||||
Для healthlog эксплуатационный проход обязан держать в голове: телефон шлёт
|
|
||||||
непрерывно и молча, тела доходили до 42 МБ, запись в часовой объект —
|
|
||||||
read-modify-write под конкурентными доставками, а тихо сломавшаяся
|
|
||||||
автоматизация обнаруживается не сразу.
|
|
||||||
|
|
||||||
## Стадия 5 — Triage (обязательна)
|
## Стадия 5 — Triage (обязательна)
|
||||||
|
|
||||||
Агент `healthlog-review-triage`. Единственный, кто агрегирует. Получает сырые
|
Агент `healthlog-review-triage`. Единственный, кто агрегирует. Получает сырые
|
||||||
выводы всех проходов и `git diff`; возвращает финальный отчёт.
|
выводы всех проходов и `git diff`; возвращает финальный отчёт.
|
||||||
|
|
||||||
Без триажа шесть проходов дают порядка сорока замечаний при единицах
|
Без триажа проходы дают порядка сорока замечаний при единицах
|
||||||
существенных. Потребитель здесь — оркестратор, который **молча реализует** всё,
|
существенных. Потребитель здесь — оркестратор, который **молча реализует** всё,
|
||||||
что прочитал: цена нетриажированного отчёта — не потерянное время человека, а
|
что прочитал: цена нетриажированного отчёта — не потерянное время человека, а
|
||||||
разросшийся от вкусовщины код.
|
разросшийся от вкусовщины код.
|
||||||
|
|||||||
@@ -164,6 +164,14 @@ healthlog — хранилище данных о здоровье, у котор
|
|||||||
потолком 7 пунктов, разметкой `Действие: инлайн | развилка` и секцией границ
|
потолком 7 пунктов, разметкой `Действие: инлайн | развилка` и секцией границ
|
||||||
покрытия.
|
покрытия.
|
||||||
|
|
||||||
|
**Сверь состав прогона с таблицей профилей в скилле, прежде чем коммитить.**
|
||||||
|
Пропуск прохода не отличим от прохода без находок: гейт зелёный, спеки сошлись,
|
||||||
|
отчёт выглядит полным. Единственный, кто мог бы заметить пропуск, — триаж, а он
|
||||||
|
заполняется тем, что ему подали. Отчёт обязан называть запущенные проходы
|
||||||
|
**поимённо и с исходом**; непущенный идёт строкой «не запускался» в границы
|
||||||
|
покрытия. Реестр короткий (6–9 проходов) — сверка стоит одного взгляда, а
|
||||||
|
молчащий пропуск уже стоил семи находок и отдельной задачи на их дозакрытие.
|
||||||
|
|
||||||
Отработай так же, как шаг 5: помеченное `инлайн` чини сам и не логируй,
|
Отработай так же, как шаг 5: помеченное `инлайн` чини сам и не логируй,
|
||||||
`развилка` — блокером в беклог (вопрос уже сформулирован триажем, его остаётся
|
`развилка` — блокером в беклог (вопрос уже сформулирован триажем, его остаётся
|
||||||
перенести). После правок — снова `task gate`.
|
перенести). После правок — снова `task gate`.
|
||||||
|
|||||||
@@ -131,3 +131,52 @@
|
|||||||
нет значения» разбирает запись и выбрасывает `time`, а не ищет в сыром
|
нет значения» разбирает запись и выбрасывает `time`, а не ищет в сыром
|
||||||
буфере. Гейт не трогаем: два прогона против однопроцентной флаки не помогут,
|
буфере. Гейт не трогаем: два прогона против однопроцентной флаки не помогут,
|
||||||
а десять стоили бы дороже самой находки.
|
а десять стоили бы дороже самой находки.
|
||||||
|
|
||||||
|
## 2026-08-02 — состав конвейера сужен: 11 проходов до 6–9
|
||||||
|
|
||||||
|
Не промах, а решение по итогам пяти задач подряд. Записано здесь, потому что
|
||||||
|
именно здесь лежит цена непоймания: если что-то теперь проскочит, первый вопрос
|
||||||
|
будет «не тот ли это класс, который мы перестали проверять».
|
||||||
|
|
||||||
|
- **Повод:** профиль `deep` стоял на всех пяти задачах сессии и гонял 11
|
||||||
|
проходов на коде плюс 4 на дизайне — порядка полутора миллионов токенов на
|
||||||
|
задачу. Ревью, а не написание кода, стало основной статьёй расхода.
|
||||||
|
- **На чём основано:** поимённая атрибуция находок надёжна только для
|
||||||
|
дозапуска трёх проходов на `f8200f7` — там оркестратор запускал их сам.
|
||||||
|
В двух циклах, которые вели сабагенты, находки перечислены без указания
|
||||||
|
прохода, и это ограничение вывода названо здесь честно.
|
||||||
|
- **Что убрано и почему:**
|
||||||
|
- `negative` — **удалён**. За сессию ни одной именной находки; блокер про
|
||||||
|
откат релиза он нашёл дублем с `ops`, то есть заплатил триажу
|
||||||
|
дедупликацией. Два его живых вопроса переселены: «хватит ли сигналов
|
||||||
|
владельцу, когда поток оборвётся ночью» — в `ops`, вопрос 7; «что опытный
|
||||||
|
человек отсюда удалил бы» — в `architecture`, вопрос 5.
|
||||||
|
- `rubric` — **только в `design`**. Его же 14 свойств из design-прогона
|
||||||
|
ложатся приёмочными критериями в `tasks.md`; судить код по критерию, под
|
||||||
|
который он писался, — корреляция по построению.
|
||||||
|
- `reimpl` — **по триггеру** «новое правило слияния, идентичности или
|
||||||
|
разбора». Самый дорогой проход конвейера; единственный раз, когда триаж
|
||||||
|
назвал его отсутствие дырой покрытия, — это была задача с новым правилом
|
||||||
|
слияния сущностей, то есть ровно триггерный случай.
|
||||||
|
- **Что переставлено, и это важнее сокращения:** `adversary` и `ops` были в
|
||||||
|
`deep`-только, а `standard` гонял четыре самых слабых generative-прохода.
|
||||||
|
То есть профиль, которым закрывается большинство задач, запускал ровно тех,
|
||||||
|
кто ничего не принёс, и не запускал тех, кто принёс почти всё. Оба переехали
|
||||||
|
в `standard`. Это одновременно дешевле и качественнее.
|
||||||
|
- **Что чуть не убрали по ошибке:** `idiom` был в списке на удаление как
|
||||||
|
«вкусовщина». Отменено фактом: в задаче про цену читающего маршрута он нашёл,
|
||||||
|
что `-1 >= -1` читается как «журнал разобран целиком», и **воспроизвёл** —
|
||||||
|
1492 тика из 5502. Плюс три эксперимента на дизайне `razbor-metrik-v-obekty`.
|
||||||
|
Вывод, который стоит помнить: этот проход зарабатывает **экспериментами
|
||||||
|
против поведения stdlib и драйвера**, а не цитатами из гайдов, — и потому у
|
||||||
|
него есть внешний оракул. Оценка «не всплыл поимённо ни разу» была верна по
|
||||||
|
имевшимся данным и неверна по существу.
|
||||||
|
- **Что мы сознательно перестали проверять:** класс «чего нет в зрелой
|
||||||
|
реализации такого узла» вне профиля `design`, и «пять вопросов второго
|
||||||
|
инженера» как отдельная постановка. Обратимость этого класса высокая: он
|
||||||
|
портит форму кода и полноту наблюдаемости, а не данные. Если проскочит
|
||||||
|
дефект этого класса — запись сюда и пересмотр решения.
|
||||||
|
- **Побочная выгода, ради которой стоило резать отдельно:** реестр из 6–9
|
||||||
|
проходов сверяется взглядом. Промах 2026-08-02 (запись выше) был молчащим
|
||||||
|
пропуском трёх проходов из одиннадцати; на коротком списке требование
|
||||||
|
«перечисли запущенные проходы поимённо и с исходом» наконец выполнимо.
|
||||||
|
|||||||
Reference in New Issue
Block a user