ревью двумя проходами: 20 находок, все починены
Два независимых сабагента на av-dev-pm и av-dev-pipeline. Две находки нашли оба. Главная — моя же перестановка закрытия за коммит сломала reopen и батч. close печатал «дорога назад из git», а reopen искал коммит удаления, которого в новом порядке ещё нет: шаг 11 последний, учёт остаётся незакоммиченным. Проверено прогоном — отказ кодом 2 на свежезакрытой задаче. Тем же грязным деревом ломались rebase и worktree remove в батче: каждая закрывшая задачу ветка уехала бы в провалившиеся. Починено с обеих сторон: reopen берёт текст из HEAD, если коммита удаления нет, а шаг 11 коммитит учёт вторым коммитом. Вторая — канонический пример docs/.pm.json убивал tasks.py. Четыре документа показывали ключ tasks.sections, которого скрипт не знает: неизвестный ключ это код 3 на любой команде. Проект, заведённый по канону дословно, остался бы без работы с задачами, а docs.py при этом печатал «канон соблюдён». Секции живут в заголовках индекса и второго дома не получают. Остальные восемнадцать: init писал конфиг в упразднённый .tasks.json; looks_like_tasks не видел переименованный индекс; урожай спринта терял автотег после sprint close; ответ на вопрос по инструкции оставлял задачу незабираемой; adopt требовал недостижимого зелёного; путь отчёта триажа не переживал archive; review-specs не имел режима для стыка после слияния; три остатка «шаг 9а» несли предкоммитную позицию закрытия; sprint.md отрицал сам себя в пункте «Сделана». Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: review-specs
|
||||
description: "Сверка изменения с дельта-спеками в обе стороны — spec→code (каждое требование реализовано и подтверждено тестом) и, что важнее, code→spec (поведение, которое код имеет, а спека не заказывала: тихие ветки, самодеятельные дефолты, проглоченные ошибки, отброшенные поля, ретраи «на всякий случай»). Плюс границы спеки — что она не определяет и что пришлось домыслить. Работает в двух режимах: дизайн/спеки ДО кода и код против спек ПОСЛЕ apply. Только чтение."
|
||||
description: "Сверка изменения с дельта-спеками в обе стороны — spec→code (каждое требование реализовано и подтверждено тестом) и, что важнее, code→spec (поведение, которое код имеет, а спека не заказывала: тихие ветки, самодеятельные дефолты, проглоченные ошибки, отброшенные поля, ретраи «на всякий случай»). Плюс границы спеки — что она не определяет и что пришлось домыслить. Работает в трёх режимах: дизайн/спеки ДО кода, код против спек ПОСЛЕ apply и стык после слияния нескольких задач, когда change уже заархивированы. Только чтение."
|
||||
tools: Read, Grep, Glob, Bash
|
||||
model: opus
|
||||
color: cyan
|
||||
@@ -43,6 +43,12 @@ Development на OpenSpec). Оптика — требования, а не ст
|
||||
намерение, а спека нормирует. Расхождение между proposal и дельтой — само по себе
|
||||
находка.
|
||||
|
||||
**Исключение — режим 3 (ниже): живого change нет.** Тогда источник требований —
|
||||
**актуальные** `openspec/specs/<capability>/spec.md`, а дельты поднимаются из
|
||||
архива (`openspec/changes/archive/<id>/specs/`) как свидетельство о намерении
|
||||
каждой слитой задачи. Задание обязано назвать этот режим явно; не названо —
|
||||
работаешь по режиму 1 или 2 и говоришь в границах покрытия, что change не нашёл.
|
||||
|
||||
Дополнительно поднимаешь: `design.md` и `tasks.md` change, затронутые актуальные
|
||||
спеки, инварианты из `CLAUDE.md`. Если тема ещё не перенесена в спеки и живёт
|
||||
только в `docs/architecture.md` — источник истины там, и это фиксируется в
|
||||
@@ -120,6 +126,27 @@ Development на OpenSpec). Оптика — требования, а не ст
|
||||
скажи об этом прямо, с последствием. Такая находка всегда `Действие: развилка`:
|
||||
менять спеку — решение человека.
|
||||
|
||||
## Режим 3 — стык после слияния нескольких задач
|
||||
|
||||
Зовётся финальной сверкой `task-batch`: несколько задач влиты в основную ветку,
|
||||
их change **уже заархивированы**, живой дельта-спеки не существует. Предмет —
|
||||
**только то, что появилось от слияния**, а не capability целиком заново: каждая
|
||||
задача уже проверена в своём worktree, и повторение даст те же находки дороже.
|
||||
|
||||
Ищешь ровно три вещи:
|
||||
|
||||
- **отменённое требование** — одна задача его выполнила, соседняя незаметно
|
||||
сняла; в актуальной спеке требование есть, в интегрированном коде его больше
|
||||
нет;
|
||||
- **два описания одного поведения** — два архивных change по-разному нормировали
|
||||
одно и то же, и актуальная спека собрала из них противоречие;
|
||||
- **осиротевшее поведение** — код, пришедший от слияния (разрешение конфликта,
|
||||
правка при rebase), которого не заказывал ни один из change.
|
||||
|
||||
База — интегрированный дифф основной ветки против точки, с которой батч начался.
|
||||
В границах покрытия скажи прямо: **capability целиком в этом режиме не
|
||||
сверялась**, проверялись стыки.
|
||||
|
||||
## Чего этот проход принципиально не может поймать
|
||||
|
||||
- Качество формы решения: код может точно соответствовать спеке и быть плохим.
|
||||
|
||||
Reference in New Issue
Block a user