diff --git a/DECISIONS.md b/DECISIONS.md index 397918e..334c499 100644 --- a/DECISIONS.md +++ b/DECISIONS.md @@ -134,12 +134,12 @@ jellybit это уже подтвердила на 43 изменениях. а настоящее ADR-рассуждение (отказ от DuckDB) лежит в разделе «Открытые вопросы» файла `architecture.md`, потому что больше некуда. - **Два плана.** `docs/plan.md` healthlog («порядок и его обоснование», 11 шагов) - и `/PLAN.md` из `av-dev-tasks` («линия целей с обоснованием порядка - прозой») — один артефакт под двумя именами. + и `/PLAN.md` из `av-dev-tasks` («цели с обоснованием очереди прозой») + — один артефакт под двумя именами. - **Дубли спек у jellybit.** Из шести файлов `docs/specs/` три (`recognition`, `review-ux`, `workflow`) описывают поведение, уже покрытое capability в `openspec/specs/`. -- **`docs/drafts/` раскладывается без остатка:** `roadmap.md` → линия целей, +- **`docs/drafts/` раскладывается без остатка:** `roadmap.md` → цели в «порядок», `conventions-backlog.md` → задачи `[idea]`, `logical-title-model.md` (293 строки, итог «сущность `title` не вводим») → намеренный отказ, то есть ADR. @@ -156,7 +156,7 @@ jellybit это уже подтвердила на 43 изменениях. порядок больше. Чинить надо не дом, а индекс и критерий промоута. **E. `docs/plan.md` растворяется в `/PLAN.md`.** Файл удаляется, 11 шагов -становятся линией целей, ссылки в `CLAUDE.md` и паспорте переводятся. +становятся целями в «порядке», ссылки в `CLAUDE.md` и паспорте переводятся. **F. Пути жёсткие, оба проекта приводятся к одному виду.** Плагин знает раскладку поимённо; указателя вида `.docs.json` нет. @@ -910,3 +910,34 @@ HTML-комментарии, невидимые в отрендеренном ma 53. **Запись в журнал версий канона проверка не заменяет.** Она видит, что копия отстала, но не видит, что проект уже унёс старую версию к себе. Это остаётся на человеке и сказано в обоих домах. + +## 13. Секции `PLAN.md` переименованы (2026-08-03) + +### Что было + +Секции назывались **«линия»** и **«кусты»** — метафора, требующая расшифровки +при каждом употреблении. В текстах она и расшифровывалась: «звено упорядоченной +линии продукта», «тематический куст — цель, в последовательность не встающая». +Если название приходится объяснять рядом с каждым употреблением, объясняет не +название. + +### Решено + +**SS. «порядок» и «темы».** Заголовок называет ровно то свойство, которым секции +различаются: в первой очередь значима и обоснована прозой, во второй порядка нет +вовсе. Расшифровывать нечего — правило написано в самом имени. + +**TT. Записи в журнал версий канона не требуется — канон этих имён не знает.** +`canon.md` называет файл `docs/tasks/PLAN.md` и ничего не говорит о его секциях: +их дом — заголовки `##` индекса, а умолчание живёт в `tasks.py`. Версия канона +поэтому не меняется, и проект вправе называть секции по-своему. Причина названа +вслух, потому что соблазн повысить версию «на всякий случай» здесь сильный, а +повышение обязало бы каждый проект что-то делать — при том что делать нечего. + +### Что из этого следует + +54. **Умолчание одно и живёт в `DEFAULT_PLAN_SECTIONS`.** Имена секций + по-прежнему настраиваются `--plan-sections`, а домом остаются заголовки `##` + индекса — переименование не трогает механику, только умолчание и тексты. +55. **Метафора — плохое имя для секции индекса.** Секция читается человеком без + контекста, часто из вывода `list`, и второго шанса объяснить себя у неё нет. diff --git a/av-dev-pm/skills/canon/references/changelog.md b/av-dev-pm/skills/canon/references/changelog.md index 70ca69c..a18f8a5 100644 --- a/av-dev-pm/skills/canon/references/changelog.md +++ b/av-dev-pm/skills/canon/references/changelog.md @@ -27,7 +27,7 @@ upgrade` идёт по записям снизу вверх от версии п 3. `docs/specs/` разобрать: поведение — в `openspec/specs/`, обзор — в `docs/architecture.md`, знание о чужих системах — в `docs/research/`. Дубли capability удалить, сверив поимённо. -4. `docs/plan.md` → `docs/tasks/PLAN.md` линией целей. +4. `docs/plan.md` → `docs/tasks/PLAN.md`, шаги плана — целями в «порядок». 5. `BRIEF.md` → `docs/passport.md`. 6. `docs/backlog/` → `docs/tasks/`. 7. `docs/review-journal.md` или `docs/review/journal.md` → `docs/review.md`, diff --git a/av-dev-pm/skills/init/SKILL.md b/av-dev-pm/skills/init/SKILL.md index 6a4d2c9..aa39663 100644 --- a/av-dev-pm/skills/init/SKILL.md +++ b/av-dev-pm/skills/init/SKILL.md @@ -48,8 +48,8 @@ description: Завести новый проект — сессия вопро проекте нельзя откатить — деплой, выкладка наружу, перезапись данных. 5. **Чем краснеет гейт.** Какие проверки обязательны; что красит безусловно; чего в гейте намеренно не будет и кто тогда это гоняет. -6. **Первые цели.** Направления, а не задачи: три-пять целей линии с - обоснованием порядка прозой. +6. **Первые цели.** Направления, а не задачи: три-пять целей в «порядок», с + обоснованием очереди прозой. ### Как вести diff --git a/av-dev-pm/skills/session/references/cadence.md b/av-dev-pm/skills/session/references/cadence.md index b35a865..b75f57a 100644 --- a/av-dev-pm/skills/session/references/cadence.md +++ b/av-dev-pm/skills/session/references/cadence.md @@ -170,7 +170,7 @@ ## Шаг 4. Выбор цели и набор спринта -1. **Покажи состояние целей**: линия `PLAN.md` с обоснованием порядка, кусты, и +1. **Покажи состояние целей**: «порядок» `PLAN.md` с обоснованием очереди, темы, и по каждой цели-кандидату — сколько под ней задач без открытых вопросов (`list --goal <слаг>`). Цель без готовых задач набором не станет: её сперва надо декомпозировать. diff --git a/av-dev-pm/skills/tasks/SKILL.md b/av-dev-pm/skills/tasks/SKILL.md index a189480..ab460cf 100644 --- a/av-dev-pm/skills/tasks/SKILL.md +++ b/av-dev-pm/skills/tasks/SKILL.md @@ -48,7 +48,7 @@ description: Ведение задач и целей как каталога mar ``` docs/tasks/ items/ задачи и цели файлами, .md, слаги английские - PLAN.md оглавление целей: линия (упорядоченная) и кусты + PLAN.md оглавление целей: порядок (значим) и темы (без порядка) BACKLOG.md что можно взять — только задачи, целей здесь нет SPRINT.md текущий спринт: цель, набор, дата REJECTED.md ушедшее БЕЗ реализации, с причиной и датой @@ -80,10 +80,10 @@ docs/tasks/ ## Цели **Цель — такой же файл в `items/`, тип `[goal]`**, перечисленный в `PLAN.md`: -либо звено упорядоченной **линии** продукта (с обоснованием порядка прозой), -либо тематический **куст** — цель, в последовательность не встающая («прочность -слияния», «журнал и пересборка»). Без второй части половина целей была бы нигде -не перечислена: находки ревью не служат ничему из линии. +либо цель из секции **порядок** — там очередь значима и обоснована прозой, — либо +**тематическая**, в порядок не встающая («прочность слияния», «журнал и +пересборка»). Без второй секции половина целей была бы нигде не перечислена: +находки ревью не служат ничему из порядка. - **Список задач цели выводится, а не хранится.** В теле цели — зачем она и что считается её завершением; перечня задач там нет. Он был бы третьим индексом и @@ -205,7 +205,7 @@ python3 $tk adopt scan --from … | apply --plan … # разовая адап работа — цель (`--type goal`). 4. **Цель задачи.** У каждой задачи должен быть `--goal <слаг>`: задача вне цели не попадёт ни в один спринт. Подходящей цели нет — либо она заводится - (`--type goal` кустом), либо это сигнал, что задача никому не служит и + (`--type goal` в «темы»), либо это сигнал, что задача никому не служит и заводить её не надо. У идеи цели может не быть — она проставляется, когда идея становится задачей. 5. `add …`, затем допиши тело редактором: одна фраза, критерии приёмки с diff --git a/av-dev-pm/skills/tasks/references/adopt.md b/av-dev-pm/skills/tasks/references/adopt.md index 949429c..6f6f076 100644 --- a/av-dev-pm/skills/tasks/references/adopt.md +++ b/av-dev-pm/skills/tasks/references/adopt.md @@ -53,9 +53,9 @@ python3 $tk adopt apply --plan tasks-adopt-plan.json \ - **английские слаги.** Перевести `taj-brejk-pri-ravnoj-polnote` в `tie-break-equal-completeness` может только тот, кто понимает смысл. `scan` честно говорит: проверить надо **все** слаги, признаки транслита — эвристика; -- **цели.** Шаги плана — готовые цели **линии** (порядок и обоснование у них уже - есть); тематические скопления задач — **кусты** («прочность слияния», «журнал - и пересборка»). Предлагаешь ты, назначает человек; +- **цели.** Шаги плана — готовые цели из **«порядка»** (очередь и обоснование у + них уже есть); тематические скопления задач — **«темы»** («прочность слияния», + «журнал и пересборка»). Предлагаешь ты, назначает человек; - **что вообще не задача.** Обоснование порядка шагов, абзац прозой, заголовок раздела — это не пункты беклога, и они уходят в «не разложилось» с причиной. @@ -69,11 +69,11 @@ python3 $tk adopt apply --plan tasks-adopt-plan.json \ 2. **`adopt scan`** по всем источникам разом. Один прогон, одна карта: два прохода дадут два несогласованных состояния. 3. **Заполни карту**: `slug` (английский), `section`, `goal` у каждой записи; - список `goals` — из шагов плана и из кустов. Закрытый шаг плана целью не + список `goals` — из шагов плана и из тем. Закрытый шаг плана целью не заводится. Пустой `goal` — законный исход только у идеи. 4. **Покажи человеку карту** через `AskUserQuestion`, ≤3 вопроса за итерацию, рекомендация первым вариантом. Показывается: сколько записей, предлагаемые - цели (линия и кусты) с обоснованием, спорные отнесения, список «не + цели (порядок и темы) с обоснованием, спорные отнесения, список «не разложилось». Массовые механические решения (слаги, порядок строк) не выносятся — это механика. 5. **`adopt apply`.** `--refs` перечисляет **всё**, где могут стоять ссылки на @@ -113,7 +113,7 @@ take` такую задачу не возьмёт). Закрывается эт ## Доклад - Источники и что в каждом распознано (раскладка, индекс, кладбище, секции). -- Сколько записей перенесено, сколько целей заведено (линия / кусты) и откуда +- Сколько записей перенесено, сколько целей заведено (порядок / темы) и откуда каждая выведена. - **Переименования**: сколько слагов, сколько ссылок поправлено и в скольких файлах — числом, а не «поправлены ссылки». diff --git a/av-dev-pm/skills/tasks/references/from-review.md b/av-dev-pm/skills/tasks/references/from-review.md index 51918ff..2435c52 100644 --- a/av-dev-pm/skills/tasks/references/from-review.md +++ b/av-dev-pm/skills/tasks/references/from-review.md @@ -42,9 +42,9 @@ существующий файл. Нашлось в `REJECTED.md` — это сигнал: причина отказа могла устареть, выноси пользователю, а не заводи молча заново. 4. **Разложи по целям.** У каждой заводимой задачи должен быть `goal:<слаг>`. - Половина находок ревью не служит ничему из линии продукта — их цель это - **куст** («прочность слияния», «журнал и пересборка», «наблюдаемость»). - Подходящего куста нет — заведи его целью (`add --type goal --section кусты`) + Половина находок ревью не служит ничему из порядка — их цель **тематическая** + («прочность слияния», «журнал и пересборка», «наблюдаемость»). + Подходящей темы нет — заведи её целью (`add --type goal --section темы`) в том же проходе: без цели задача не попадёт ни в один спринт, а значит не будет сделана никогда. 5. **Покажи карту до создания файлов.** Кластер → задача / идея / строка в diff --git a/av-dev-pm/skills/tasks/references/task-format.md b/av-dev-pm/skills/tasks/references/task-format.md index fa209ed..43bea6b 100644 --- a/av-dev-pm/skills/tasks/references/task-format.md +++ b/av-dev-pm/skills/tasks/references/task-format.md @@ -107,7 +107,7 @@ ```markdown # [goal] Прочность слияния -**Секция:** кусты · **Теги:** decomposed +**Секция:** темы · **Теги:** decomposed Ради чего: точки из разных доставок сходятся в один часовой объект, и сегодня исход столкновения зависит от порядка доставки, а не от содержания. @@ -156,7 +156,7 @@ | Файл | Что отвечает | Секции | | --- | --- | --- | -| `PLAN.md` | какие есть цели, в каком порядке идёт линия и почему | линия (упорядоченная) и кусты | +| `PLAN.md` | какие есть цели, в какой очереди идут и почему | порядок (очередь значима) и темы (порядка нет) | | `BACKLOG.md` | что **можно взять** — только задачи | секции проекта (по умолчанию ядро/инфра) | | `SPRINT.md` | какая цель и какой набор под неё | одна: «Набор» | | `REJECTED.md` | что ушло без реализации и почему | — | @@ -169,9 +169,9 @@ ответа человека, а следы остаются вопросами в файлах задач распущенного спринта. Постоянно пустая секция со старой семантикой «разбираются пачками» противоречила бы правилу «эскалируем немедленно», поэтому `init` её не заводит, а `check` -говорит о ней в чужом беклоге. Переезжаешь с такой секцией — удали её. В **линии** плана порядок значим и -обосновывается прозой; двигают строку `move --section линия --after -<другой>`. +говорит о ней в чужом беклоге. Переезжаешь с такой секцией — удали её. В секции +**«порядок»** очередь значима и обосновывается прозой; двигают строку +`move --section порядок --after <другой>`. Индексы **производны**: расходятся с файлом — правим индексы (`check --fix`). Строку руками не пишут. diff --git a/av-dev-pm/skills/tasks/scripts/tasks.py b/av-dev-pm/skills/tasks/scripts/tasks.py index 31da9ba..1d0d503 100755 --- a/av-dev-pm/skills/tasks/scripts/tasks.py +++ b/av-dev-pm/skills/tasks/scripts/tasks.py @@ -12,7 +12,7 @@ av-dev, и подгоняется под него проект. Имена вн docs/tasks/ items/ задачи и цели файлами, .md - PLAN.md оглавление целей: линия (упорядоченная) и кусты + PLAN.md оглавление целей: порядок (значим) и темы (без порядка) BACKLOG.md что можно взять — только задачи, целей здесь нет SPRINT.md текущий спринт: цель, набор, дата, слаг REJECTED.md ушедшее БЕЗ реализации, с причиной и датой @@ -110,7 +110,7 @@ DEFAULTS = { PATH_KEYS = ("items", "backlog", "plan", "sprint", "rejected") DEFAULT_SECTIONS = "ядро,инфра" -DEFAULT_PLAN_SECTIONS = "линия,кусты" +DEFAULT_PLAN_SECTIONS = "порядок,темы" META_FIELD = re.compile(r"^\*\*(.+?):\*\*\s*(.*)$") INDEX_ENTRY = re.compile(r"^- \[(.+?)\]\((.+?\.md)\)\s*(?:—\s*(.*))?$") @@ -1838,8 +1838,8 @@ def init_files(lay: Layout, sections: list[str], plan_sections: list[str], "# План\n\n" f"Оглавление целей. Цель — файл `[goal]` в `{lay.cfg['items']}/`; её задачи\n" "здесь **не перечисляются** — перечень даёт `tasks.py list --goal <слаг>`.\n" - f"Первая секция («{plan_sections[0]}») упорядочена, и порядок обосновывается\n" - "прозой; остальные — тематические кусты без порядка.\n\n" + f"В первой секции («{plan_sections[0]}») очередь значима и обосновывается\n" + "прозой; в остальных порядка нет — это тематические цели.\n\n" + "".join(f"## {s}\n\n" for s in plan_sections)) out[lay.index("sprint")] = empty_sprint(lay) out[lay.index("rejected")] = ( @@ -1976,8 +1976,8 @@ STEP = re.compile(r"^\**\s*(\d+)[.)]\s*\**\s*(.+?)\**\s*$") def scan_list_file(path: Path) -> dict: """TODO.md, «планы» в README, список шагов в плане проекта. - **Нумерованный шаг плана → кандидат в цель линии** (готовая цель: у него уже - есть порядок и обоснование), прочий пункт списка → кандидат в задачу. Ничего + **Нумерованный шаг плана → кандидат в цель из «порядка»** (готовая цель: у + него уже есть очередь и обоснование), прочий пункт → кандидат в задачу. Ничего не решает: и то и другое едет в карту предложением, назначает человек. """ found: dict = {"kind": "list-file", "source": str(path), "items": [], @@ -2043,7 +2043,7 @@ def cmd_adopt_scan(a: argparse.Namespace) -> int: rejected += sc.get("rejected", []) unclassified += sc.get("unclassified", []) goals += [{"slug": "", "title": g["title"], - "section": (a.plan_sections.split(",")[0].strip() or "линия"), + "section": (a.plan_sections.split(",")[0].strip() or "порядок"), "from": g["from"], "step": g.get("step"), "done": g.get("done"), "body": f"Выведена из шага «{g['title']}» ({g['from']})." + ("\n\nШаг помечен закрытым — цель, скорее всего,"