From 94fa66b262fdffae71d03b14c0454bc6482f655c Mon Sep 17 00:00:00 2001 From: Anton Vakhrushev Date: Thu, 13 Aug 2026 19:20:25 +0300 Subject: [PATCH] =?UTF-8?q?resolve:=20=D0=BF=D0=BE=D1=81=D1=82=D0=B0=D0=BD?= =?UTF-8?q?=D0=BE=D0=B2=D0=BA=D1=83=20=D1=82=D0=B5=D0=BA=D1=81=D1=82=D0=BE?= =?UTF-8?q?=D0=BC=20=D0=B2=D0=B7=D1=8F=D0=BB=D0=B8=20=D0=BF=D0=BE=D0=BB?= =?UTF-8?q?=D0=BD=D0=BE=D0=BF=D1=80=D0=B0=D0=B2=D0=BD=D1=8B=D0=BC=20=D0=B2?= =?UTF-8?q?=D1=85=D0=BE=D0=B4=D0=BE=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Задачу часто нужно решить прямо по описанию в разговоре, без файла в каталоге — так её берёт и opsx:propose. Скилл вход текстом объявлял, но прорабатывала его одна разведка: у решения и обслуживания шаг «прочитать задачу» читал разделы записи, шаг закрытия закрывал запись, признак обслуживания опирался на объявленный автором тип, а критерии приходили «от проекта». Форм постановки теперь две, и они равноправны. Отпадают ровно те шаги, у которых пропал предмет: ready гонять нечего, закрывать нечего. Ни один шаг с предметом не выпал — гейт, ревью, синк, чекпоинт и коммит идут как обычно, а сценарий, метку и глубину форма не выбирает. Взамен пропавшего — названное вслух первой репликой: как понята постановка, каким типом её считаешь и где проводишь границу. Человек, написавший текст, сидит в этом же разговоре и поправляет одной фразой; названный после работы тип не признак, а объяснение готового диффа. По сценариям: решение добирает недостающие критерии приёмки на чекпоинте и считает их данными только после ответа; обслуживание объявляет их отсутствие строкой (чекпоинта у него нет) и само называет границы, которых текст не дал; разведка увязана с общим правилом, а её шаг закрытия отпал с оговоркой про единственный след — записанный ответ. Записи в каталог скилл по-прежнему не заводит: ни перед работой, ни задним числом ради закрытия. Похожую строку беклога не разыскивает. Перечень осей пополнен формой постановки: по ней ветвятся готовность, источник типа и наличие закрытия. --- README.md | 6 ++ av-dev/shared/axes.md | 11 +++- av-dev/skills/code-resolve/SKILL.md | 58 +++++++++++++++++-- .../code-resolve/references/maintain.md | 44 ++++++++++++-- .../code-resolve/references/research.md | 12 +++- .../skills/code-resolve/references/solve.md | 20 ++++++- 6 files changed, 136 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 5c87ff1..2325b35 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,12 @@ сценария три, и выбирает сценарий сам скилл, прочитав постановку:** классифицировать задачу до вызова человек всё равно не может — «есть ли очевидный способ решения» и «меняется ли спека» видно после чтения записи. + **Форм постановки две, и обе полноправны:** запись каталога и просто текст, + переданный вызовом, — так же берёт постановку `opsx:propose`. Текстом идут все + три сценария; отпадают ровно те шаги, у которых пропал предмет: `ready` гонять + нечего, закрывать нечего, а тип, границы и понимание постановки называются + вслух первой репликой — человек, написавший текст, рядом и правит одной фразой. + Записи в каталог скилл при этом не заводит ни до работы, ни задним числом. **Решение** идёт циклом SDD с чекпоинтом после ревью дизайна: объяснение человеческим языком, повод скорректировать ход. **Обслуживание** (тип `chore`: тулчейн и сборка, зависимости, гит-хуки, diff --git a/av-dev/shared/axes.md b/av-dev/shared/axes.md index 113692a..a7d483d 100644 --- a/av-dev/shared/axes.md +++ b/av-dev/shared/axes.md @@ -18,6 +18,7 @@ | --- | --- | --- | | стадия проекта | `build` `support` | `task-track/SKILL.md`, «Две стадии» | | тип записи | `feature` `fix` `chore` `research` | `task-track/SKILL.md`, «Тип записи» | +| форма постановки | запись каталога · текст | `code-resolve/SKILL.md`, «Вход» | | сценарий | решение · обслуживание · разведка | `code-resolve/SKILL.md`, «Развилка» | | метка | `small` `medium` `large` | `code-review/SKILL.md`, «Метки» | | режим прогона | с меткой · без метки | здесь, ниже | @@ -42,6 +43,8 @@ | стадия проекта | тип записи — **не влияет, и это записано явно** | `task-track/SKILL.md`, «Две стадии» | | стадия проекта | как серьёзность находки ложится в список | `task-track/references/from-review.md` | | стадия проекта | где сценарии кладут свой исход и чем закрывают переходное состояние | `code-resolve/references/research.md`, `task-track/references/adopt.md` | +| форма постановки | проверку готовности, кто называет тип, есть ли шаг закрытия | `code-resolve/SKILL.md`, «Постановка текстом» | +| форма постановки | сценарий, метку и глубину — **не влияет, и это записано явно** | там же: развилка у обеих форм общая | | тип записи | сценарий — **предлагает**, подтверждает предмет работы | `task-track/SKILL.md`, «Тип записи» | | тип записи | метку и глубину — **не влияет, и это записано явно** | там же | | сценарий | режим прогона: обслуживание идёт без метки | `code-resolve/references/maintain.md` | @@ -70,9 +73,11 @@ стройке — обычное дело (первые шаги плана заводят гейт и сборку), и идёт он там так же, как на доработке. -**Стадия проекта × категория документа и × коды выхода.** Не влияет: категория — -свойство документа, коды — общий словарь скриптов. Названо потому, что перечень -объявлен полным, и клетка без ответа читается как забытая. +**Стадия проекта × категория документа, × коды выхода и × форма постановки.** Не +влияет: категория — свойство документа, коды — общий словарь скриптов, а форму +постановки выбирает тот, кто зовёт скилл, и на стройке она такая же, как на +доработке. Названо потому, что перечень объявлен полным, и клетка без ответа +читается как забытая. **Режим прогона × severity.** Триаж обязателен всегда, в том числе без метки. Но часть оснований `critical` — построенный путь к отказу, замер — добывается diff --git a/av-dev/skills/code-resolve/SKILL.md b/av-dev/skills/code-resolve/SKILL.md index c538cbb..f5a532d 100644 --- a/av-dev/skills/code-resolve/SKILL.md +++ b/av-dev/skills/code-resolve/SKILL.md @@ -1,6 +1,6 @@ --- name: code-resolve -description: "Взять одну задачу и довести её до закрытия. Одна точка входа, три сценария, и выбирает сценарий сам скилл, прочитав постановку. Способ известен и меняется поведение — сценарий решения: цикл Spec Driven Development (opsx propose → разметка → ревью дизайна → чекпоинт с объяснением человеческим языком → opsx apply → ревью кода → archive → синк документации → коммит → закрытие). Способ известен, а спека не меняется (тип chore: тулчейн, зависимости, сборка, гит-хуки, перенос, чистка) — сценарий обслуживания: правка → гейт со сверкой состава проверок → ревью фиксированным планом без change (autotests, operations, плюс conventions, если тронут код) → синк документации → коммит → закрытие; планового стопа нет, change не заводится. Нашлась дельта-спека — задача оказалась шире своего типа: стоп с объяснением простым языком и двумя решениями человека, переформулировать запись в fix или feature и решать её процессом того типа следующим прогоном либо прекратить работу. Способа нет, постановка мутная, тип research — сценарий разведки: вопрос и рамки → чтение документов, кода и внешних источников (можно opsx:explore) → чекпоинт вариантов: 2–4 способа решить, цена каждого, что становится невозможным, рекомендация → ответ уезжает в документы канона, исход — в задачи → вычитка написанного → коммит → закрытие. Разведка кода не пишет и change не заводит, а выбранный способ реализуется следующим прогоном. На входе путь к файлу задачи, её слаг или просто текст. Использовать, когда просят взять, сделать или решить задачу, обновить зависимости или сборку, разобраться, изучить, сравнить подходы, проработать сырую идею, ответить на вопрос из беклога." +description: "Взять одну задачу и довести её до закрытия. Одна точка входа, три сценария, и выбирает сценарий сам скилл, прочитав постановку. Способ известен и меняется поведение — сценарий решения: цикл Spec Driven Development (opsx propose → разметка → ревью дизайна → чекпоинт с объяснением человеческим языком → opsx apply → ревью кода → archive → синк документации → коммит → закрытие). Способ известен, а спека не меняется (тип chore: тулчейн, зависимости, сборка, гит-хуки, перенос, чистка) — сценарий обслуживания: правка → гейт со сверкой состава проверок → ревью фиксированным планом без change (autotests, operations, плюс conventions, если тронут код) → синк документации → коммит → закрытие; планового стопа нет, change не заводится. Нашлась дельта-спека — задача оказалась шире своего типа: стоп с объяснением простым языком и двумя решениями человека, переформулировать запись в fix или feature и решать её процессом того типа следующим прогоном либо прекратить работу. Способа нет, постановка мутная, тип research — сценарий разведки: вопрос и рамки → чтение документов, кода и внешних источников (можно opsx:explore) → чекпоинт вариантов: 2–4 способа решить, цена каждого, что становится невозможным, рекомендация → ответ уезжает в документы канона, исход — в задачи → вычитка написанного → коммит → закрытие. Разведка кода не пишет и change не заводит, а выбранный способ реализуется следующим прогоном. На входе путь к файлу задачи, её слаг или просто текст постановки: размеченная запись не обязательна — текст берётся так же, как его берёт opsx:propose, и текстом идут все три сценария. Использовать, когда просят взять, сделать или решить задачу — хоть записью из каталога, хоть описанием прямо в разговоре, — обновить зависимости или сборку, разобраться, изучить, сравнить подходы, проработать сырую идею, ответить на вопрос из беклога." --- # Работа над одной задачей @@ -114,7 +114,13 @@ description: "Взять одну задачу и довести её до за Ничего из этого не задано — попроси у вызывающего и остановись; сам в беклог не лезь и приоритеты не интерпретируй: что делать дальше, решает не этот скилл. -**Запись из каталога сперва проверяется на готовность, и проверяет её машина.** +**Форм постановки две, и обе полноправны:** запись каталога задач и текст, +переданный вызовом. Форма — не сценарий: развилка ниже у них общая, и текст +принимают все три сценария. + +### Запись из каталога + +**Запись сперва проверяется на готовность, и проверяет её машина.** Вызови Skill `av-dev:task-track` и попроси прогнать `ready <слаг>`: он смотрит тип, пустой ли раздел вопросов и собраны ли разделы схемы типа. Судить это глазами нельзя — ровно тот случай, где машина дешевле и точнее, а цена ошибки отложенная: недостающие критерии приёмки обнаружатся на приёмке, @@ -127,9 +133,43 @@ description: "Взять одну задачу и довести её до за **Отказ `ready` сценарий не выбирает.** Запись `research` без раздела «Вопрос» (сырьё) — отказ и здесь: у неё нет вопроса, и разведывать нечего. -Каталога задач в проекте нет или задача пришла текстом — прогонять -нечего. Тогда прочитай постановку сам и скажи строкой, что готовность машиной не -проверялась; работу при этом не останавливай. +Каталога задач в проекте нет — прогонять нечего, и постановка приходит текстом +по построению: дальше по разделу ниже. + +### Постановка текстом + +**Текст — вход, а не урезанный режим.** Ровно так берёт постановку +`opsx:propose`: предложение делается из фразы человека, а не из заранее +размеченной записи. Требовать записи там, где работа уместилась в разговор, +значит заводить учёт ради учёта — след у прогона остаётся и без неё: коммит, а у +решения ещё и заархивированный change. + +**Первой репликой покажи, как ты понял постановку** — рядом с названным +сценарием, одной-двумя фразами: что считаешь предметом работы и где проводишь +границу. Запись толкуется по разделам, текст — молча, и расходится он с замыслом +ровно там, где его никто не показал. Человек, написавший текст, сидит в этом же +разговоре и поправляет одной фразой; автора записи, написанной месяц назад, +рядом нет, и потому текстовая постановка проверяется дешевле, а не хуже. + +Что несёт запись и чем это заменяется, когда её нет: + +| Что несёт запись | Чем заменяется у текста | +| --- | --- | +| готовность, проверенную машиной | читаешь постановку сам и говоришь строкой, что `ready` не гонялся | +| тип, объявленный автором | тип называешь ты — вслух, первой репликой, вместе со сценарием | +| критерии приёмки с оракулами | те, что есть в тексте; недостающие [решение](references/solve.md) добирает на чекпоинте, [обслуживание](references/maintain.md) объявляет строкой отсутствующими | +| адрес, куда ляжет ответ разведки | назначаешь сам и по канону, а не по удобству — [research.md](references/research.md), шаг 1 | +| закрытие как след работы | закрывать нечего, и шаг закрытия отпадает вместе с записью | + +**Записи в каталог этот скилл не заводит — ни перед работой, ни задним числом +ради закрытия.** Граница «беклогом не владеет» действует и здесь. Работа не +уместилась в прогон, её надо ставить в очередь или из неё выросла пачка — скажи +это строкой и предложи `av-dev:task-track`: заводит он и по своим правилам. + +**Похожую запись в беклоге не ищешь.** Человек назвал работу текстом — значит, +предмет прогона этот текст, а не строка индекса, которая на него похожа. +Наткнулся на такую строку по ходу — скажи о ней строкой доклада и не закрывай: +закрытие записи это приёмка, и поручали её не тебе. ## Развилка: какой сценарий @@ -211,14 +251,18 @@ description: "Взять одну задачу и довести её до за ```mermaid flowchart TD in["вход: файл, слаг или текст"] + form{"форма постановки"} ready["ready: готовность записи
av-dev:task-track"] + plain["понимание, тип и границы —
первой репликой; ready не гонится,
закрывать потом нечего"] fork{"есть очевидный
способ решения?"} fork2{"меняется ли
спека?"} solve["сценарий решения
references/solve.md
код, ревью, архив, коммит"] main["сценарий обслуживания
references/maintain.md
правка, ревью, синк, коммит"] res["сценарий разведки
references/research.md
ответ в документы и задачи"] - in --> ready --> fork + in --> form + form -->|"запись каталога"| ready --> fork + form -->|"текст"| plain --> fork fork -->|"да"| fork2 fork -->|"нет"| res fork2 -->|"да"| solve @@ -348,6 +392,8 @@ change, у второго — сверенный состав гейта и си он; - **исход** одним из четырёх слов своего сценария и, если он не благополучный, чем ограничен результат; +- **постановка пришла текстом** — сказать это прямо: как она понята, что `ready` + не гонялся и что закрывать было нечего; - что сделано, какие вопросы записаны и куда; - чего проверить или узнать **не удалось**. diff --git a/av-dev/skills/code-resolve/references/maintain.md b/av-dev/skills/code-resolve/references/maintain.md index c37c029..deb5cec 100644 --- a/av-dev/skills/code-resolve/references/maintain.md +++ b/av-dev/skills/code-resolve/references/maintain.md @@ -49,6 +49,24 @@ либо отправил бы в полный цикл ради пустого change, либо принял бы как исключение, а исключения не исполняются. +### Постановка текстом — тип называешь ты, и называешь вслух + +Первый признак приходит от автора записи; **текст типа не несёт** (SKILL.md, +«Постановка текстом»). Оба признака тогда твои, и связка выродилась бы в одно +суждение — то самое, ради разведения которого она и заведена. + +Разведённость здесь восстанавливается местом, а не вторым автором: **тип и +предмет работы называются до начала работы, первой репликой** — «иду +обслуживанием: считаю это `chore`, потому что …; спека не меняется, потому что +…». Человек, написавший текст, читает это раньше первой правки и поправляет +одной фразой. Названный **после** работы тип не признак, а объяснение уже +сделанного: к этому моменту у тебя есть готовый дифф, и он всегда подтверждает +тот тип, под который писался. + +Не назвал — признака нет вовсе, и сценарий выбрал сам себя. Это ровно тот +случай, где «самый частый способ соврать этим сценарием» (раздел «Тонкости») +ничего не стоит: автора, чей тип можно было бы опровергнуть, здесь нет. + ## Дельта нашлась по ходу — стоп, и у него свой порядок Признак тот же, что на шаге 7 сценария решения: **меняется ли то, что записано в @@ -96,7 +114,11 @@ **процессом своего типа**: сценарием решения, следующим прогоном. Формат записи правит `av-dev:task-track`, а не ты: у нового типа своя схема разделов, и готовность её проверит `ready` — той же машиной, что и на входе. Прогон - обслуживания на этом кончается, исход — «меняется спека»; + обслуживания на этом кончается, исход — «меняется спека». + **Постановка пришла текстом — переформулировать нечего:** человек либо + запускает следующий прогон тем же текстом, и он пойдёт решением, либо заводит + запись через `av-dev:task-track`, если работа должна пережить разговор. Выбор + между этими двумя — его, не твой: заводить запись сам этот скилл не вправе; - **прекратить работу** — человек не готов расширять задачу сейчас. Исход тот же, запись остаётся как была, вопрос записывается там, где проект держит вопросы. @@ -214,10 +236,19 @@ ADR: список источников канон закрыл двумя — а (конфиг и его образцы, версия зависимости, команда сборки, файл CI), и **«Критерии приёмки»** — с оракулами. +**Постановка пришла текстом — этих двух разделов нет, и оба нужны тебе тем же +составом.** Границы назови сам и покажи в первой реплике, вместе с типом: +обслуживание чаще прочих сценариев расползается, а границы у него лежат не в +коде, и невидимая граница расползание не удержит. Критериев приёмки в тексте +может не быть вовсе — тогда скажи строкой, что их нет и приёмка идёт по докладу. +Сочинить их себе здесь нельзя даже так, как это делает решение: чекпоинта, на +котором человек их утвердит, у обслуживания нет. + Здесь же обе проверки признака: тип предлагает, отсутствие дельт подтверждает -(раздел «Признак — связка»). И здесь же — проверка на незнакомое: если форма -правки не известна до начала, а нащупывается по ходу, объявляй исход **нужна -разведка** и не начинай. +(раздел «Признак — связка»); постановка текстом типа не объявляла — тогда +называешь его ты, и вслух (раздел «Постановка текстом»). И здесь же — проверка +на незнакомое: если форма правки не известна до начала, а нащупывается по ходу, +объявляй исход **нужна разведка** и не начинай. **Проверка на «заодно».** Обслуживание любит склеиваться в пачку — обновить зависимости, переписать сборку и убрать мёртвый код одной задачей. Не мерджится @@ -376,6 +407,9 @@ Change ты не передаёшь — его нет. `закрыта задача `. Каталога задач в проекте нет — ничего не выдумывай: скажи, что учёт остаётся за владельцем, и назови исход. +**Постановка пришла текстом — шага нет вовсе**: записи не было, закрывать нечего, +след работы — коммит шага 6. Заводить запись задним числом ради закрытия нельзя. + ## Границы: чего обслуживание не делает - **Не меняет поведения.** Обнаружилось, что меняет, — стоп с исходом «меняется @@ -401,6 +435,8 @@ Change ты не передаёшь — его нет. Общее ядро доклада — в SKILL.md; сверх него сценарий обязан назвать: - **что подтвердило признак** — тип записи и то, что дельта-спек не нашлось; + постановка пришла текстом — **тип назвал ты**, и это говорится прямо, вместе с + границами, которые ты объявил себе сам; дельта нашлась — **какой тип предложен, с причиной, и что человек выбрал**: переформулировать или прекратить; - **что стало иначе для разработчика** — одной фразой, адресуясь ему, а не diff --git a/av-dev/skills/code-resolve/references/research.md b/av-dev/skills/code-resolve/references/research.md index 05f31b2..590b99e 100644 --- a/av-dev/skills/code-resolve/references/research.md +++ b/av-dev/skills/code-resolve/references/research.md @@ -52,7 +52,10 @@ **Разведка пришла текстом — сформулируй вопрос сам одной фразой и покажи формулировку в первой же реплике.** Разведка, чей вопрос не назван вслух, -признаётся удавшейся любым результатом. +признаётся удавшейся любым результатом. Это частный случай общего правила +(SKILL.md, «Постановка текстом»): у разведки показать надо не только предмет +работы, но и сам вопрос, потому что предмет разведки — он и есть. Вместе с +вопросом называются рамки и адрес ответа (шаг 1). ## Ход работы @@ -368,6 +371,13 @@ git и читается диффом, а второй стоп на каждой учёт, а не про работу: `закрыта задача `. Правило «одна разведка — один коммит» про работу, а учёт — не работа. +**Разведка пришла текстом — шага нет вовсе**: записи не было, закрывать нечего. +Следом работы здесь служит не код, а **записанный по названному адресу ответ** — +он уехал в коммит шагом 7, и потому отсутствие записи разведке ничем не грозит. +Ответ записать было некуда и он остался в докладе — вот это как раз тот случай, +когда от прогона не осталось ничего: скажи об этом прямо, а не одной строкой +среди прочих. + Каталога задач в проекте нет — **ничего не выдумывай**: скажи в докладе, что учёт задач остаётся за владельцем, и назови исход. diff --git a/av-dev/skills/code-resolve/references/solve.md b/av-dev/skills/code-resolve/references/solve.md index 68cba56..44bf3a3 100644 --- a/av-dev/skills/code-resolve/references/solve.md +++ b/av-dev/skills/code-resolve/references/solve.md @@ -90,6 +90,14 @@ flowchart TD в `tasks.md` change. Файл задачи может быть удалён до коммита, а критерии обязаны его пережить. +**Постановка пришла текстом** (SKILL.md, «Постановка текстом») — записи нет, +читаешь сам текст. Критерии в нём бывают редко: выпиши то, что там есть, а +недостающие **предложи на чекпоинте шага 5** и считай их данными только после +ответа человека. Сам себе критерии не проставляешь — правило то же, что и с +записью: они приходят снаружи, и подсунуть их себе значит назначить себе приёмку. +Человек критериев не назвал — скажи строкой, что задача идёт без них и приёмка +пойдёт по объяснению чекпоинта. + Здесь же проверка на «крупнее задачи»: видно, что одним заходом это не мерджится, — объявляй исход **до** заведения change. @@ -193,7 +201,11 @@ flowchart TD - **чего мы намеренно не делаем** и почему — граница scope ловится хуже всего; - **чем рискуем и что осталось нерешённым** — сюда съезжаются развилки, накопленные до этого места, и находки ревью с пометкой `развилка`; -- **что дальше**, если возражений нет. +- **что дальше**, если возражений нет; +- **критерии приёмки, если постановка пришла текстом и не назвала их** — + предложенными, а не принятыми: человек их подтверждает или правит здесь же. + Это единственное место, где исполнитель вообще может их предложить, и работает + оно только потому, что решает всё равно человек. Проверка на «простой язык» одна и механическая, и она общая у чекпоинтов всех трёх сценариев — поэтому её дом здесь, а у соседей помеченные копии: @@ -371,6 +383,12 @@ flowchart TD работу: `закрыта задача `. Это второй коммит осознанно: правило «одна задача — один осмысленный коммит» про работу, а учёт — не работа. +**Постановка пришла текстом — шага нет вовсе, и это не пропуск.** Записи не +существовало, закрывать нечего, а следом работы служат коммит и заархивированный +change. Заводить запись задним числом, чтобы её тут же закрыть, нельзя: учёт +получил бы задачу, которой никто не ставил, и закрытие без единой минуты +открытого состояния. Скажи это строкой и переходи к докладу. + Каталога задач в проекте нет — **ничего не выдумывай**: скажи в докладе, что учёт задач остаётся за владельцем, и назови исход.