хвост задачи: отражение молча, новое — по слову человека

Синк документации делил правки по документам, а делить их надо по роду.
Отражение сделанного (вливание дельт, миграция, компонент в обзоре) пишется
молча: без правки документ станет ложным. Новая запись и новая норма — ADR,
конвенция, записка разведки, инвариант, периметр, дефект в журнале — только
предлагаются, а пишет их третий такт шага 6 после слова человека.

Реплика при этом одна на весь хвост: вопрос про урожай ревью переехал с шага 5
на шаг 6 и слился с предложениями синка — решение одно, «что из найденного
переживёт задачу». Плановых стопов в сценарии решения стало ровно два, и оба
про решения человека.

Сверка документов получила счётчик: doc-healthcheck оставляет след ключом
[healthcheck] last в .av-dev.toml, синк считает по нему задачи с прошлого
прогона и говорит строкой. Прежде признак «десяток задач» держался в памяти,
то есть не срабатывал.

Журнал — тема 78.
This commit is contained in:
av
2026-08-23 19:06:06 +03:00
parent 3c89d7111d
commit a4bc9191e7
12 changed files with 462 additions and 62 deletions
@@ -381,6 +381,16 @@ ADR: список источников канон закрыл двумя — а
Нетронутые группируются одной строкой. Возврат приходит в этой же форме и уезжает
в доклад целиком: тронутое без нетронутого не отличается от невыполненного шага.
**Второе правило синка тоже действует: отражение пишется молча, новое
предлагается** (дом — раздел «Два рода правок» скилла `av-dev:doc-sync`). Здесь
оно почти ничего не стоит: обслуживание двигает **факты** — команды, шаги гейта,
зависимости поимённо, пути, имя ветки, числа настроек, — а факт в документе,
разошедшийся с кодом, это отражение по определению. Реплика человеку на этом
сценарии редка, и поводов у неё два: **новый запрет или инвариант в `CLAUDE.md`**
и **сужение проверок в `review.*`**. Второе спрашивать не надо — проверки сузил
человек, слово по ним сказано; первое надо, потому что запрет свяжет все будущие
задачи. Нового нет — реплики нет, и шаг кончается возвратом агента.
**Здесь этот шаг весит больше, чем в решении, и вот почему.** Обслуживание не
меняет поведения — значит, почти всё, что оно меняет, это документация: команды,
шаги гейта, зависимости поимённо, пути, имя основной ветки, настройки с числовым
@@ -281,6 +281,13 @@ git и читается диффом, а второй стоп на каждой
незачем. Но **названо должно быть каждое место, куда ты писал**, — доклад без
перечня адресов неотличим от доклада о ненаписанном.
**Правило «новое по слову» здесь тоже не задаёт второго вопроса**, хотя ответ
разведки — новое от первой до последней строки. Слово уже сказано **чекпоинтом
вариантов**: человек выбрал вариант и тем самым заказал запись. Спросить ещё раз
значило бы переспросить только что одобренное — и заодно предложить выбросить
работу, ради которой прогон и шёл. Что записать нового сверх выбранного —
например ADR по решению с ценой, — предлагается, как везде.
**Документов канона в проекте нет** — писать ответ некуда: назови это исходом,
предложи завести канон скиллом `av-dev:canon` и оставь ответ в докладе
целиком, чтобы работа не пропала. Заводить `docs/` мимо канона нельзя.
+113 -29
View File
@@ -28,14 +28,17 @@ flowchart TD
s3(["3. ЧЕКПОИНТ: объяснение<br/>в чём проблема, как решаем,<br/>чем рискуем"])
s4["4. opsx:apply — код, гейт,<br/>поведенческая верификация — агентом"]
s5["5. ревью кода — постоянный состав<br/>+ отработка замечаний агентом"]
s6["6. opsx:archive + синк документации —<br/>одним агентом"]
s6["6. opsx:archive + отражение в документах —<br/>одним агентом"]
s6q(["РЕПЛИКА: что заводим из нового —<br/>ADR, конвенция, задачи из урожая"])
s6b["6b. письмо одобренного и задачи —<br/>тем же агентом"]
s7["7. коммит работы — av-dev-git:commit"]
s8["8. закрыть задачу — av-dev:task-track,<br/>вторым коммитом учёта"]
in --> s1
s1 --> s2 --> s3 --> s4 --> s5 --> s6 --> s7 --> s8
s1 --> s2 --> s3 --> s4 --> s5 --> s6 --> s6q --> s6b --> s7 --> s8
s3 -.->|"скорректировать:<br/>правка спек и дизайна"| s3
s5 -.->|"находка отменяет дизайн:<br/>меняются дельта-спеки"| s3
s6 -.->|"нового нет:<br/>реплики нет"| s7
```
Схема — **сводка**: содержание каждого шага в его разделе ниже, и при
@@ -64,7 +67,8 @@ flowchart TD
и без дома названы в границах покрытия;
3. решение прошло чекпоинт и не разошлось с одобренным — либо разошлось, и
чекпоинт был пройден заново;
4. change заархивирован, дельты влиты в актуальные спеки;
4. change заархивирован, дельты влиты в актуальные спеки, и по **каждому**
документу канона назван исход — правка, предложение или отрицание с причиной;
5. коммит сделан в текущую ветку;
6. **критерии приёмки, если проект их дал, выписаны поимённо, и по каждому назван
оракул и наблюдаемый исход** — «прогнал вот это, увидел вот то». Это **доклад,
@@ -278,10 +282,15 @@ flowchart TD
откуда взялась.
**Задачи из урожая заводятся только тогда, когда человек сказал «заводим».**
Покажи список одной репликой и спроси. Сказал — зови `av-dev:task-track`, у него
на этот вход отдельный сценарий «задачи из ревью и аудита»: своя нарезка, свой
формат, свои правила дублей, и передавать находку туда надо дословно. Не сказал —
урожай остаётся строками доклада, и это исход, а не потеря.
Спрашивается это **не здесь, а на шаге 6** — там же, где спрашивается новое в
документах, и той же одной репликой: два вопроса подряд про одно и то же («что из
найденного заводим») стоили бы человеку двух переключений вместо одного. Сюда
урожай складывается, а не выносится.
Сказал «заводим» — зовёт `av-dev:task-track` агент шага 6, у него на этот вход
отдельный сценарий «задачи из ревью и аудита»: своя нарезка, свой формат, свои
правила дублей, и передавать находку туда надо дословно. Не сказал — урожай
остаётся строками доклада, и это исход, а не потеря.
**Молча беклог не наполняется.** Очередь работ ведёт человек, и задача, заведённая
за него по ходу чужого прогона, отнимает у него ровно то решение, ради которого
@@ -308,37 +317,62 @@ flowchart TD
единственный **независимый** артефакт о составе прогона: своей прозе здесь верить
нельзя — её написал тот, кто мог проход и пропустить.
### 6. Архивация и синк документации — одним агентом
### 6. Архивация и документы — отражение молча, новое по слову
**Оба шага уходят одному агенту, и это один запуск** (SKILL.md, «Кто пишет»).
Работа здесь письменная от начала до конца: `opsx:archive` вливает дельты в
актуальные спеки, `av-dev:doc-sync` правит документы канона, и обе правки идут по
Шаг идёт **в три такта**, и агент запускается в нём дважды. Причина одна: письмо
в документы бывает двух родов, а спрашивается только один.
**Копия.** Дом правила — раздел «Два рода правок» скилла `av-dev:doc-sync`.
Правится дом, а не этот файл.
<!-- копия: синк-род-правки из av-dev/skills/doc-sync/SKILL.md -->
- **Отражение** — документ уже описывает эту вещь, и без правки он **станет
ложным**: миграция написана, а `database.md` её не знает; компонент заведён, а
`architecture.md` перечисляет прежние. Такая правка ничего не решает, она
договаривает решённое на чекпоинте и уже стоящее в коде. **Пишется молча.**
- **Новое** — в каноне заводится запись или норма, которой не было: ADR, правило
в конвенциях, записка в `research/`, инвариант в `CLAUDE.md`, сдвиг периметра в
`security.md`, граница в `passport.md`, дефект в журнале `review.md`. Такая
запись переживёт задачу и свяжет следующие. **Пишется только по слову
человека.**
<!-- /копия: синк-род-правки -->
#### Такт первый — агент: архив и отражение
**Оба скилла уходят одному агенту, и это один запуск** (SKILL.md, «Кто пишет»).
Работа письменная от начала до конца: `opsx:archive` вливает дельты в актуальные
спеки, `av-dev:doc-sync` идёт по чек-листу и пишет отражение, и обе правки — по
чек-листам своих скиллов, а не по суждению оркестратора. Разнесённые по двум
запускам, они стоили бы двух заданий, двух возвратов и паузы между ними — при том
что второй шаг читает ровно то, что оставил первый.
запускам, они стоили бы двух заданий, двух возвратов и паузы между ними — при
том что второй читает ровно то, что оставил первый.
В задании: корень проекта, идентификатор change, база диффа и **порядок**
сначала `opsx:archive` с `openspec validate --strict` перед ним, затем
`av-dev:doc-sync`. Плюс требование довести гейт проекта до зелёного после правок:
документы у многих проектов гейт проверяет, и красный гейт здесь остановил бы
коммит следующим шагом.
`av-dev:doc-sync`.
**Вычитку языка зовёт сам `av-dev:doc-sync`** — агента `doc-wording` по пачке
правленых документов. Отдельным запуском её тянуть не надо, и в задании она не
называется: правило живёт в том скилле, а не здесь.
**Вычитка и гейт идут последним тактом, в котором писали.** Вернул непустой
список предложений — оба ждут третьего такта; список пуст — этот такт последний,
и оба идут в нём. Гонять гейт дважды подряд по одному дереву незачем, а вычитывать
пачку, которая сейчас пополнится, — тем более. Вычитку зовёт сам
`av-dev:doc-sync` (агента `doc-wording` по пачке правленого), и правило живёт в
том скилле; гейт до зелёного доводит агент, потому что красный гейт остановил бы
коммит следующим шагом — документы у многих проектов он проверяет.
**Возврат — адреса тронутого, исход валидации, чек-лист синка и исход гейта.**
Чек-лист уезжает в доклад целиком, и переписывать его своими словами нельзя — это
единственный след того, что каждый документ был назван.
**Возврат — чек-лист, адреса тронутого, исход валидации и исход гейта, если он
гонялся.**
Чек-лист уезжает в доклад целиком, и переписывать его своими словами нельзя —
это единственный след того, что каждый документ был назван.
**Правило, которое задаёт его форму, одно и оно жёсткое: принуждённое
отрицание.** Доклад обязан назвать
**каждый** документ канона — либо чем он обновлён, либо «не требуется, потому
что…». Нетронутые группируются одной строкой с общей причиной. Список триггеров
прозой уже проверен на живом проекте и дал 6 записей ADR на 43 изменения;
работает только обязательное отрицание. **Требование стоит в задании агента**
без него возврат придёт перечнем тронутого, а тронутое без нетронутого не
отличается от невыполненного шага.
отрицание.** Против **каждого** документа канона стоит одно из трёх — чем он
обновлён, что по нему предлагается, либо «не требуется, потому что…».
Нетронутые группируются одной строкой с общей причиной. Список триггеров прозой
уже проверен на живом проекте и дал 6 записей ADR на 43 изменения; работает
только обязательное отрицание. **Требование стоит в задании агента** без него
возврат придёт перечнем тронутого, а тронутое без нетронутого не отличается от
невыполненного шага.
**Список документов и их триггеров здесь не дублируется** — он в чек-листе скилла
`av-dev:doc-sync`, и копия уже однажды разошлась с оригиналом, потеряв два
@@ -349,6 +383,45 @@ flowchart TD
задачу нельзя: документ, заведённый мимо канона, окажется вторым домом ровно
тому, что канон потом заведёт своим.
#### Такт второй — одна реплика человеку на весь хвост
Покажи **одним списком** всё, что заводится нового:
- **предложения синка** — ADR, конвенция, записка в `research/`, инвариант,
периметр, дефект в журнал. Каждое строкой: что заведём, куда и на каком
основании;
- **урожай ревью с шага 5** — отложенные находки, из которых получаются задачи:
формулировка, оракул, откуда взялась.
Человек отвечает разом. **Нового нет — реплики нет**, и шаг кончился первым
тактом; у большинства задач так и выходит.
**Реплика одна, и делить её нельзя.** Спросить про ADR на синке, а про задачи
отдельно — значит взять с человека два переключения там, где решение одно: что из
найденного этой задачей переживёт её. Ровно поэтому вопрос про урожай и перенесён
сюда с шага 5.
**Спрашиваешь, а не советуешь по каждому пункту.** Основание уже названо строкой,
и второй абзац уговоров превращает реплику в чтение. Человек вправе ответить
«ничего» — это исход, а не потеря: находки остаются строками доклада.
#### Такт третий — тот же агент: письмо одобренного
Запускается **только если человек что-то одобрил**. В задании:
- **одобренные записи дословно** — формулировка, источник, основание; сочинять
заново нельзя, ADR цитирует решение из архивного `design.md`, а не пересказывает
его;
- **задачи из урожая** — вызовом `av-dev:task-track`, сценарий «задачи из ревью и
аудита», находка передаётся дословно вместе с оракулом;
- **вычитка** `doc-wording` по всей пачке правленого — и первого такта, и этого;
- **гейт проекта до зелёного** после правок.
**Отвергнутое не пишется никуда.** Ни в один документ, ни отдельной записью «от
такого-то отказались»: журнала отвергнутого канон не держит, и заведение его
здесь было бы ровно тем новым, которого человек только что не заказал. Отказ
идёт строкой доклада.
### 7. Коммит
Коммить **в текущую ветку** (`git rev-parse --abbrev-ref HEAD`), сам ветку не
@@ -397,6 +470,11 @@ change. Заводить запись задним числом, чтобы её
- **`Урожай`** — отложенные находки списком (формулировка, оракул, откуда
взялась) и **что человек по нему решил**: заведены задачи или список остался в
докладе;
- **что заведено нового в документах** — одобренное по именам записей, и **что
предложено и отвергнуто**, тоже по именам. Отказ виден только здесь: в
документы он не пишется;
- **сигнал сверки** — строка синка о том, сколько задач сделано с прошлого
прогона `av-dev:doc-healthcheck`, либо что сверки не было ни разу;
- **сколько находок ушло инлайном и сколько развилкой** — числом. По нему видно,
во что прогон обошёлся человеку;
- **одна строка границ покрытия**: какой режим гонялся, какие проходы не
@@ -420,6 +498,12 @@ change. Заводить запись задним числом, чтобы её
`av-dev:task-track` — по слову человека, у него на этот вход отдельный сценарий
«задачи из ревью и аудита». Каталога задач в
проекте нет — урожай остаётся списком в докладе, и это говорится строкой.
- **Стопов у сценария два, и оба про решения человека, а не про ход работ.**
Чекпоинт шага 3 решает форму решения **до** кода; реплика шага 6 решает, что из
найденного переживёт задачу. Между ними прогон идёт сам: правки инлайном чинятся
молча, отражение в документах пишется молча. Третьего стопа заводить нельзя —
прогон, останавливающийся чаще, теряет ровно то время, ради которого короткие
итерации и выбраны.
- **Способ решения ты не выбираешь.** Он приходит известным: из постановки, из
разведки, от человека. Выбор между двумя подходами с разной ценой делается в
разведке, у своего чекпоинта, — не по ходу этого сценария.