Files
dev-skills/av-dev/skills/code-resolve/references/research.md
T
av 6b162c421d граница: правило стало про раскладку проекта, а не про соседний плагин
Дом shared/plugin-boundary.md переехал в shared/absence.md: отсутствовала всё
это время не установка плагина, а часть раскладки проекта, и узнавалась она
следом на диске. Перечень внешнего сократился до двух — opsx и av-dev-git.
Ветки «плагина нет» переписаны на «этой части в проекте нет»; там, где ветка
существовала только ради неразрешимого пути в чужое дерево, она снята вовсе.

Внутриплагинные копии языка и словаря сопровождения сняты: два справочника по
213 строк и один по 34 заменены ссылкой на общий дом. Копии остались там, где
текст обязан лежать внутри промпта, — в уставах вычитки. Заодно починены пути
$CLAUDE_PLUGIN_ROOT и относительные ссылки, разъехавшиеся с новыми именами
каталогов.
2026-08-13 10:18:04 +03:00

394 lines
33 KiB
Markdown

# Сценарий «разведка»
Отвечает на вопрос задачи и записывает ответ туда, где он переживёт переписку.
Исход — **знание**: уточнённые документы и уточнённые задачи. **Кода этот
сценарий не пишет и change не заводит.**
Сценарий выбирается развилкой на входе скилла ([SKILL.md](../SKILL.md), раздел
«Развилка: какой сценарий») и называется вслух первой репликой. Здесь только его
ход; общее для обоих сценариев — вход, обращение к соседним плагинам, правило
необратимого, доклад — живёт в SKILL.md и тут не пересказывается.
**Разведка кончается своим исходом, а не переходом к коду.** Выбранный способ
реализует сценарий решения, и запускает его **человек**, следующим прогоном по
уточнённой записи. Причина не в церемонии: разведка только что переписала
постановку, и брать её в работу тем же заходом значит решать за человека, стоит
ли делать это сейчас, — а это приоритет, и он не наш.
## OpenSpec здесь не предпосылка
**OpenSpec этому сценарию не нужен**, и это единственное место скилла, где он не
предпосылка. Разведка не заводит change и не пишет дельта-спеки: её артефакты —
документы канона и записи каталога задач. Скилл `opsx:explore` полезен и зовётся,
когда плагин в проекте есть; не разрешился — разведка идёт чтением документов,
кода и внешних источников, и это говорится строкой доклада, а не отменяет
работу.
## Кого зовёт этот сценарий
`av-dev:doc-sync` (ответ уезжает в документы канона), `av-dev:task-track`
(задачи заводятся и уточняются), `av-dev-git:commit`. Правило обращения к соседям
и ветка «вызов не разрешился» — общие, они в [SKILL.md](../SKILL.md).
**Отсутствие канона бьёт по разведке сильнее, чем по решению**, и сказать об этом
строкой мало: без документов у ответа нет дома, и знание осядет в переписке.
Назови исход и предложи `av-dev:doc-canon`; работу не останавливай, но адрес
ответа тогда выбираешь сам и говоришь об этом вслух.
## Что этот сценарий требует от входа
Вход общий у обоих сценариев (SKILL.md, раздел «Вход»); своего здесь три условия.
**Паспорт читается раньше кода.** Граница домена и «чем проект **не** является»
отсекают половину вариантов до того, как их начнут сравнивать, — а сравнение
вариантов и есть работа этого сценария.
**Сырьё — `research` без раздела «Вопрос» — не берётся.** Исход «не доведена» с
причиной «запись это сырьё»: у неё нет вопроса, а разведка без вопроса
превращается в чтение всего подряд с отчётом «интересно, но неприменимо».
Дописывать вопрос за автора не твоя работа — этим занят штурм сырья в
`av-dev:task-track`. Назови, чего не хватает, и остановись.
**Разведка пришла текстом — сформулируй вопрос сам одной фразой и покажи
формулировку в первой же реплике.** Разведка, чей вопрос не назван вслух,
признаётся удавшейся любым результатом.
## Ход работы
```mermaid
flowchart TD
in["вход: файл, слаг или текст"]
s1["1. вопрос и рамки<br/>сырьё без «Вопроса» — отказ"]
s2["2. разведка: документы, код,<br/>внешние источники, opsx:explore"]
s3(["3. ЧЕКПОИНТ: варианты<br/>2–4 способа, цена каждого,<br/>что становится невозможным"])
s4["4. ответ в документы канона<br/>av-dev:doc-sync"]
s5["5. задачи: завести и уточнить<br/>av-dev:task-track"]
s6["6. вычитка написанного:<br/>документы и записи задач"]
s7["7. гейт проекта, затем коммит<br/>av-dev-git:commit"]
s8["8. закрыть разведку — av-dev:task-track,<br/>вторым коммитом учёта"]
out["исход назван: знание, задачи,<br/>отказ или «не доведена»"]
in --> s1 --> s2 --> s3
s3 -->|"выбран способ,<br/>отказ или знание"| s4
s3 -.->|"вопрос не тот"| s1
s4 --> s5 --> s6 --> s7 --> s8 --> out
```
Схема — **сводка**: содержание каждого шага в его разделе ниже, и при расхождении
прав текст.
## Плановый стоп сценария
**До чекпоинта умолчание прежнее — делать, а не спрашивать.** Развилка, найденная
по ходу разведки, не задаётся отдельным вопросом: она копится в чекпоинт, который
рядом и стоит дёшево.
Стоп здесь один, и стоит он **перед записью**. Причина в цене: пока варианты
живут в контексте, смена решения стоит абзаца; записанный в документы и разложенный
на задачи выбор стоит правки документов и разбора беклога. Второго стопа — «покажи,
что именно уедет в документы» — нет намеренно: всё, что пишет разведка, лежит в
git и читается диффом, а второй стоп на каждой разведке вырождается в ритуал
одобрения.
**Правило необратимого действует и здесь** (SKILL.md, «Когда спрашивать вне
чекпоинта»), и разведка обманчива: она кажется безобидной, а замер лезет туда, где
живут данные — прогон на боевой базе, запрос к внешнему платному источнику. Здесь
ошибка не откатывается правкой текста.
## Границы: чего разведка не делает
- **Кодом.** Ни строки, включая «маленький черновик, чтобы проверить». Замер,
требующий кода, — это отдельная задача, и её нужно назвать, а не написать по
ходу. Исключение ровно одно и оно не про изменение системы: одноразовый
**читающий** прогон (запрос, замер, скрипт в песочнице), чей результат уезжает
в ответ с провенансом и который ничего не оставляет в репозитории.
- **Приоритетом.** Заведённая задача встаёт в конец своей секции; где ей стоять
в очереди, решает человек на груминге (`av-dev:task-groom`). Разведка, сама
ставящая свой исход первым в беклоге, назначает приоритет тому, что только что
придумала.
- **Форматом задач и документов.** Индексы и документы руками не правятся: их
ведут `av-dev:task-track` и `av-dev:doc-sync`. Твоё — содержание ответа, их —
форма и дом.
- **Определением ценности.** «Нужно ли это делать вообще» — вопрос человека.
Разведка отвечает «как это можно сделать и чего каждый способ стоит».
- **Решением задачи.** Выбранный способ реализует сценарий решения, и запускает
его человек следующим прогоном. Перейти в него по ходу нельзя — это тот самый
переход, ради невозможности которого сценарии и разведены.
## Наблюдаемые исходы сценария
Четыре, и каждый обязан быть назван в докладе прямо. Первые три — это те самые
«заведены задачи, записано знание, отказ», которыми кончается разведка по
определению типа `research`:
- **способ выбран** — ответ записан, задачи заведены или уточнены, они готовы к
взятию. Дальше сценарий решения, следующим прогоном, и запускает его человек;
- **знание записано** — вопрос закрыт, задач он не породил: ответ ценен сам по
себе (замер, устройство внешнего формата, «так работает и менять не нужно»);
- **отказ** — проверили, проблемы нет либо подход отвергнут. **Полноправный
исход, а не пустая работа**: «не делаем и вот почему» экономит всю работу,
которая иначе была бы сделана. Причина записывается — без неё через квартал
разведку закажут заново;
- **не доведена** — вопроса нет (сырьё), рамки исчерпаны без ответа, или человек
на чекпоинте не одобрил ни одного варианта. Названо, что успели узнать и до
какой границы.
## Определение сделанного для разведки
У сценария решения оно своё (SKILL.md); здесь — короткое и другое. Разведка
сделана, когда верно всё:
1. **ответ записан по адресу, который назвала задача** — раздел «Куда ляжет
ответ». Адреса не было, а вопрос был — ты назначил адрес сам и сказал об этом
строкой;
2. **у каждого числа провенанс** — команда или условия, которыми оно получено.
Число без источника проход ревью обязан читать как условие, а не как замер, и
разведка, оставившая голые числа, вредна: по ним будут решать;
3. **отвергнутые варианты названы с причиной**. Отвергнутое без причины
возвращается на следующей разведке как новая идея;
4. задачи, которые исход породил, заведены — или явно сказано, что не породил;
5. **написанное вычитано** — документы агентом `doc-wording`, записи задач
проходами `task-form` и `task-wording`, каждый по своей пачке;
6. написанное закоммичено, разведка закрыта.
## Шаги
### 1. Вопрос и рамки
Прочитай запись. У типа `research` два обязательных раздела, и оба нужны тебе
прямо сейчас: **«Вопрос»** — на что отвечаем, **«Куда ляжет ответ»** — по какому
адресу он ляжет. Адрес назван заранее не из аккуратности: ответ, не имеющий дома,
остаётся в переписке, и через квартал разведку заказывают заново.
**Адрес назначает автор записи, а не ты.** Запись из каталога без него до тебя
не доходит: `ready` требует непустыми оба раздела и откажет — это стоп со
строкой, чего не хватает, а не повод дописать за автора. Иначе исполнитель сам
назначает себе приёмку, а приёмка разведки — это и есть записанный по названному
адресу ответ.
**Адрес назначаешь ты ровно в одном случае** — когда записи нет вовсе: разведка
пришла текстом или в проекте нет учёта задач. Тогда скажи об этом строкой, а
выбирай по канону, а не по удобству:
| Что узнали | Дом ответа |
| --- | --- |
| наблюдение о внешнем мире, замер с провенансом | `docs/research/` |
| решение с ценой: намеренный отказ, дорогой откат | `docs/adr/` |
| факт об устройстве системы | тема `architecture` (или своя тема проекта) |
| граница домена, «чем проект **не** является» | `passport` |
| ответ нужен только этой работе | тело самой записи |
Раздел **«Рамки»**, если он есть, — это граница разведки: сколько копаем, какие
источники, что заведомо вне. Рамок нет, а вопрос широкий — **назначь их сам и
покажи в первой реплике**. Разведка без рамок утекает: она всегда может узнать
ещё немного, и признак «достаточно» изнутри не виден.
Здесь же проверка на «не тот вопрос»: если из записи видно, что отвечать надо на
другое, скажи это сразу, а не после разведки.
### 2. Разведка
Порядок чтения — от дешёвого к дорогому, и он не произволен:
1. **документы канона проекта** — половина вопросов уже отвечена там, и разведка,
начатая с кода, переоткрывает написанное;
2. **код и его история**`git log` по узлу отвечает на «почему так» чаще, чем
кажется;
3. **внешние источники** — документация формата, чужой опыт, спецификации;
4. **замер** — если вопрос про числа. Числа снимаются с провенансом, иначе они
бесполезны на следующем шаге.
**Скилл `opsx:explore`** — законный инструмент этого шага, если плагин в проекте
есть: он держит форму размышления и не даёт ему растечься. **В explore не пишем
код.** Вызов не разрешился — работай чтением, скажи это строкой.
Развилку разведки **не записывай вопросом** — она и есть предмет следующего шага.
### 3. Чекпоинт: варианты
**Остановись и покажи человеку способы решить.** Это плановый стоп сценария и
единственное место, где разведка ждёт ответа.
Форма — короткая, экран текста:
- **вопрос**, на который отвечаем, одной фразой (он уже есть в записи);
- **2–4 варианта**, не больше. Больше четырёх — это не выбор, а список: человек
не сравнит, а признает свою неспособность сравнить и попросит рекомендацию.
У каждого варианта: в чём суть простыми словами, **что даёт**, **чего стоит**,
**что становится невозможным** (это ловится хуже всего и стоит дороже всего);
- **рекомендация с причиной**. Человек чаще соглашается, чем выбирает заново;
- что известно **недостоверно** и как это проверить, если проверять дёшево;
- **что уедет в документы и в задачи**, если возражений нет, — одной строкой.
Это не второй стоп, а предупреждение: человек видит объём последствий там же,
где принимает решение.
Что нельзя: приносить варианты, различающиеся только реализацией; прятать
отвергнутое (отвергнутый вариант с названной причиной — половина будущего ADR);
приносить один вариант и называть это выбором.
Проверка на простой язык та же, что у чекпоинта решения: **в тексте нет `SHALL`,
нет имён файлов и функций там, где вещь называется по-русски, и нет слов, которых
нет в паспорте проекта.**
Исходы чекпоинта:
- **выбран способ** — идёшь на шаг 4, исход разведки будет «способ выбран». Кода
ты по нему не пишешь: сценарий кончается записью и коммитом;
- **ответ и есть результат** — идёшь на шаг 4, исход «знание записано» или
«отказ»;
- **вопрос не тот** — возвращаешься на шаг 1: переформулируй вопрос и скажи, что
из разведанного остаётся в силе;
- **ни один вариант не одобрен** — исход «не доведена» с причиной. Записывается
всё равно то, что узнано (шаг 4): выброшенная разведка будет заказана заново.
### 4. Ответ в документы канона
**Вызови Skill `av-dev:doc-sync`**: он владеет содержимым документов канона.
Передай ему ответ, адрес из шага 1 и провенанс каждого числа — писать содержание
за тебя он не будет, но дом и форму держит он. Вычитка языка — тоже его агент, но
момент её назван отдельно, шагом 6: пачка собирается из шагов 4 и 5 и до конца
пятого не полна.
**Что именно уезжает:**
- **ответ на вопрос** — по адресу из шага 1;
- **отвергнутые варианты с причинами.** Это половина будущего ADR и единственная
защита от повторной разведки того же самого;
- **решение с ценой — в ADR**, если оно проходит триггер канона (дорогой откат,
намеренный отказ, пересмотр прежнего решения). У разведки, кончившейся без
кода, `design.md` не будет никогда, поэтому здесь ADR цитирует **записку
разведки**, а не архивный change; канон это допускает прямо, и в записи
источник называется.
**Правило принуждённого отрицания здесь не действует.** Это не синк: разведка
трогает те документы, которых коснулся её ответ, и перебирать весь канон ей
незачем. Но **названо должно быть каждое место, куда ты писал**, — доклад без
перечня адресов неотличим от доклада о ненаписанном.
**Документов канона в проекте нет** — писать ответ некуда: назови это исходом,
предложи завести канон скиллом `av-dev:doc-canon` и оставь ответ в докладе
целиком, чтобы работа не пропала. Заводить `docs/` мимо канона нельзя.
### 5. Задачи: завести и уточнить
**Вызови Skill `av-dev:task-track`.** Он владеет форматом, дедупом и индексами;
путь к его скрипту не выясняй и индексы руками не правь.
Что просишь сделать:
- **уточнить саму разведку** — если её вопрос по ходу изменился;
- **уточнить существующие задачи** — разведка часто отвечает не «что делать», а
«что в поставленном неверно»: постановка, границы в разделе «Затрагивает»,
критерии приёмки;
- **завести новые задачи**, если исход их породил. Формулировки приноси готовыми:
заголовок, «зачем», тип, границы. Нарезку на независимо полезные части и
проверку на дубли делает он — у него на это свои правила и свой сценарий.
**Пачку задач показывай списком, прежде чем заводить.** Разведка — самый лёгкий
способ надуть беклог: она порождает идеи быстрее, чем кто-либо успевает их
оценивать, а заведённая задача живёт, пока её кто-то не выкинет руками.
Плагина нет — задачи остаются **списком формулировок в докладе**, и это говорится
строкой: учёт работ остаётся за владельцем.
### 6. Вычитка написанного — до гейта, не после
Разведка правит **две вещи сразу**: документы канона (шаг 4) и записи каталога
задач (шаг 5). Обе — текст, и портится он в момент письма, а машина этого не
видит: `docs.py check` и `tasks.py check` смотрят форму раскладки, а не залог,
оценку без факта, жаргон и термин, которого нет в паспорте проекта.
Пачка **собирается только сейчас**, и поэтому шаг стоит здесь: раньше пятого шага
она не полна, а после коммита вычитка уже правит закоммиченное.
- **Документы** — агент `doc-wording`, владеет им `av-dev:doc-sync` (раздел
«Вычитка»). Пачка — адреса, названные на шаге 4, включая `docs/adr/` и
`docs/research/`.
- **Записи задач** — два прохода, сперва `task-form`, затем `task-wording`;
владеет ими `av-dev:task-track` (раздел «Вычитка: два прохода»). Пачка —
заведённые и уточнённые на шаге 5 записи. Заголовок и «зачем» правятся **не
молча**: покажи предложенное вместе с тем, что было.
**Что не правилось, то не вычитывается.** Разведка, кончившаяся одним документом
и ни одной задачей, зовёт один проход, и это не пропуск — это названная строкой
пачка. Скилл-владелец уже прогнал свою пачку по ходу шага — назови это и второй
раз тот же файл не гоняй.
**Судей канона — `doc-consistency` и `doc-code-drift` — здесь не зови.** Они
идут на весь канон разом, стоят дорого, и владеет ими `av-dev:doc-healthcheck`,
момент вызова которого выбирает человек. Нужно суждение о согласованности — скажи
строкой и предложи `healthcheck`, а не зови агентов сам.
Ни один проход ничего не правит: они возвращают готовые формулировки,
подставляешь их ты — и уже с подставленными идёшь на гейт.
Плагина нет — вызов не разрешится: скажи строкой, что написанное не вычитывал
никто, и обходного пути не выдумывай.
### 7. Гейт и коммит
**Сперва гейт проекта** — тот же, что гоняет сценарий решения, и по той же
причине: разведка только что правила документы канона и индексы задач, а это
ровно то, что машина умеет проверить (`docs.py check`, `tasks.py check --dir`,
битые ссылки). Красный гейт чинится здесь, а не оставляется следующему прогону:
он придёт за код и получит чужую поломку в наследство.
Гейта в проекте нет — скажи строкой, что записанное не проверял никто.
Коммить **в текущую ветку** (`git rev-parse --abbrev-ref HEAD`), сам ветку не
создавай и не переключай, ничего не пушь.
Сообщение — по-русски, **скиллом `av-dev-git:commit`**: форму сообщения держит
он, и здесь она не пересказывается. Вызов не разрешился — напиши сообщение сам и
скажи строкой, что форму коммита не сверял никто.
Одна разведка — один осмысленный коммит: записанный ответ и заведённые задачи
уезжают вместе, потому что порознь они полуправда.
### 8. Закрыть разведку — после коммита, не раньше
**Вызови Skill `av-dev:task-track`** и попроси закрыть запись: ответ записан —
`close --implemented`, ушла без ответа — `close --reason`, и строка уезжает в
кладбище.
**Порядок обязателен.** Закрытие удаляет файл задачи; сделанное до коммита оно
оставило бы разведку закрытой без единого следа работы, если шаг 7 упадёт. У
разведки это опаснее, чем у решения: следом работы там служит код, а здесь —
только записанный ответ. Закрытая разведка без него не оставляет следа вообще —
файл задачи удалён, ответ был в переписке.
**Закрытие тоже коммитится — вторым коммитом, тут же.** Сообщение короткое, про
учёт, а не про работу: `закрыта задача <slug>`. Правило «одна разведка — один
коммит» про работу, а учёт — не работа.
Плагина в проекте нет — **ничего не выдумывай**: скажи в докладе, что учёт задач
остаётся за владельцем, и назови исход.
## Доклад разведки
Общая форма доклада — в SKILL.md; у разведки он свой, потому что докладывать
нечего из того, о чём спрашивают решение (ни метки ревью, ни критериев приёмки,
ни архивного change). Коротко, и в нём обязательно:
- **исход** одним из четырёх слов;
- **вопрос и ответ** — по фразе на каждое. Ответ, который не сворачивается во
фразу, — признак того, что разведка отвечала не на один вопрос;
- **куда записано** — перечнем адресов, а не «документация обновлена»;
- **какие задачи заведены и уточнены** — слагами;
- **что вычитано и чем** — пачка документов и пачка записей, каждая со своими
проходами; не вычитанное называется прямо, вместе с причиной;
- **что осталось неизвестным** и чего это стоит: разведка без этой строки
сообщает «выяснено», не сообщая, что именно осталось не выяснено;
- **рамки**, если они ограничили работу: докуда копали и почему остановились.
## Тонкости
- **Ответ «зависит от» — не ответ.** Если разведка кончилась развилкой, её исход
— варианты с ценой, а не пересказ обеих сторон без рекомендации.
- **Отрицательный результат записывается так же тщательно, как положительный.**
Соблазн не писать его велик: кажется, что писать нечего. Через квартал именно
этой записи и не хватит.
- **Чужую разведку не переоткрывай молча.** Нашёл в `docs/research/` или в
`docs/adr/` ответ на свой вопрос — исход «знание записано» со ссылкой, и это
лучшая из возможных разведок: она стоила одного чтения.