каталог задач уехал из docs/ в корень репозитория
Версия 8 отпустила задачи из канона — перестала требовать каталог и перестала в него смотреть, — но место он занимал всё то же, docs/tasks/. Полдела: каталог, принадлежащий одному плагину, лежал внутри дерева, которым владеет другой. Проекту, поставившему учёт работ без канона документов, приходилось заводить docs/ ради одной вложенной папки. Дом задач теперь tasks/ в корне. tasks.py ищет его там первым, docs/tasks и doc/tasks остались в списке поиска для непереехавших проектов, init заводит только в корне, --target у adopt тоже. Настройки лежат рядом, tasks/.tasks.json — после версии 8 они уже были в своём файле, теперь и файл вне чужого дерева. docs.py продолжает терпеть docs/tasks/ в списке нечитаемого: непереехавший проект не должен получать выдуманную ошибку «файл вне канона» вдобавок к записи журнала, которая и так велит ему переехать. Адреса упразднённых слотов (plan.md, backlog/) теперь ведут в tasks/ и называют плагин. Тридцать три живых упоминания пути разведены по смыслу, а не заменой строки: в раскладке канона tasks/ вышел из-под docs/ и стоит на своём уровне; у doc-consistency каталог перестал быть исключением внутри docs/** и стал чужой территорией, названной в обеих формах; у review-scope и review-pipeline процессный список поехал вместе с путём. В журнале версий тринадцать упоминаний оставлены как есть — они описывают прошлое состояние. Канон повышен до версии 11. В записи названа тихая часть переезда: файл tasks/items/x.md стал на уровень ближе к корню, и ../../passport.md в теле записи теперь ../docs/passport.md. Битую относительную ссылку внутри записи tasks.py check не ловит вовсе — её видит только docs.py и только у документов канона, так что этот шаг делается руками и тем же коммитом, что git mv. Фикстура переехала, поиск вверх по дереву находит новый путь, гейт зелёный. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -26,7 +26,7 @@ color: yellow
|
|||||||
| почему решено так | `adr/`, источник — архивный `design.md` |
|
| почему решено так | `adr/`, источник — архивный `design.md` |
|
||||||
| граница домена, «чем не является» | `passport.md` |
|
| граница домена, «чем не является» | `passport.md` |
|
||||||
| инвариант и его severity | `CLAUDE.md` |
|
| инвариант и его severity | `CLAUDE.md` |
|
||||||
| что приложение умеет и чего не умеет; порядок работ | `docs/tasks/ROADMAP.md` |
|
| что приложение умеет и чего не умеет; порядок работ | `tasks/ROADMAP.md` |
|
||||||
| измеренное число | `research/` |
|
| измеренное число | `research/` |
|
||||||
| настройка с числовым значением | `database.md` |
|
| настройка с числовым значением | `database.md` |
|
||||||
| периметр и модель угроз | `security.md` |
|
| периметр и модель угроз | `security.md` |
|
||||||
@@ -45,8 +45,10 @@ color: yellow
|
|||||||
|
|
||||||
## Что тебе дают
|
## Что тебе дают
|
||||||
|
|
||||||
Корень проекта. Твоё чтение — `docs/**` (кроме `docs/tasks/`, его ведёт
|
Корень проекта. Твоё чтение — `docs/**`, `CLAUDE.md`, `openspec/specs/**` и
|
||||||
`tasks.py`), `CLAUDE.md`, `openspec/specs/**` и `openspec/config.yaml`. Плюс
|
`openspec/config.yaml`. **Каталог задач не твой** — он лежит в `tasks/` (или в
|
||||||
|
`docs/tasks/` на непереехавшем проекте), принадлежит другому плагину и ведётся
|
||||||
|
своим скриптом; не открывай его ни в той форме, ни в другой. Плюс
|
||||||
`openspec/changes/archive/`, когда проверяешь ADR: там лежат `design.md`, из
|
`openspec/changes/archive/`, когда проверяешь ADR: там лежат `design.md`, из
|
||||||
которых записи промоутятся.
|
которых записи промоутятся.
|
||||||
|
|
||||||
|
|||||||
@@ -75,8 +75,8 @@ docs/
|
|||||||
adr.md | adr/ почему решено так; статусы, правило замены
|
adr.md | adr/ почему решено так; статусы, правило замены
|
||||||
review.md | review/ настройка конвейера под проект + журнал дефектов
|
review.md | review/ настройка конвейера под проект + журнал дефектов
|
||||||
<своя тема>.md | <своя тема>/ всё, что проект счёл нужным проверять
|
<своя тема>.md | <своя тема>/ всё, что проект счёл нужным проверять
|
||||||
tasks/ каталог задач — плагин av-dev-tasks, не канон:
|
tasks/ каталог задач — плагин av-dev-tasks, не канон;
|
||||||
место зарезервировано, наличия канон не требует
|
лежит в корне, вне docs/, и канон его не требует
|
||||||
openspec/
|
openspec/
|
||||||
config.yaml только нужды генерации артефактов + ссылки
|
config.yaml только нужды генерации артефактов + ссылки
|
||||||
specs/<capability>/spec.md что система делает — нормативно
|
specs/<capability>/spec.md что система делает — нормативно
|
||||||
@@ -456,7 +456,7 @@ kebab-case.** Причина не эстетическая: имя файла с
|
|||||||
| почему решено так | `adr/`, источник — архивный `design.md` |
|
| почему решено так | `adr/`, источник — архивный `design.md` |
|
||||||
| граница домена, «чем не является» | `passport.md` |
|
| граница домена, «чем не является» | `passport.md` |
|
||||||
| инвариант и его severity | `CLAUDE.md` |
|
| инвариант и его severity | `CLAUDE.md` |
|
||||||
| что приложение умеет и чего не умеет; порядок работ | `docs/tasks/ROADMAP.md` |
|
| что приложение умеет и чего не умеет; порядок работ | `tasks/ROADMAP.md` |
|
||||||
| измеренное число | `research/` |
|
| измеренное число | `research/` |
|
||||||
| настройка с числовым значением | `database.md` |
|
| настройка с числовым значением | `database.md` |
|
||||||
| периметр и модель угроз | `security.md` |
|
| периметр и модель угроз | `security.md` |
|
||||||
@@ -491,9 +491,9 @@ kebab-case.** Причина не эстетическая: имя файла с
|
|||||||
| `docs/review-brief.md` | документы канона и есть бриф; остаток — в `review.md` |
|
| `docs/review-brief.md` | документы канона и есть бриф; остаток — в `review.md` |
|
||||||
| `docs/specs/` | `openspec/specs/` (поведение) и `architecture.md` (обзор) |
|
| `docs/specs/` | `openspec/specs/` (поведение) и `architecture.md` (обзор) |
|
||||||
| `docs/drafts/` | идея → запись `research`; отказ → ADR; порядок → `ROADMAP.md`; размышление → `opsx:explore` |
|
| `docs/drafts/` | идея → запись `research`; отказ → ADR; порядок → `ROADMAP.md`; размышление → `opsx:explore` |
|
||||||
| `docs/plan.md` | `docs/tasks/ROADMAP.md` |
|
| `docs/plan.md` | `tasks/ROADMAP.md` |
|
||||||
| `BRIEF.md` | `passport.md` |
|
| `BRIEF.md` | `passport.md` |
|
||||||
| `docs/backlog/` | `docs/tasks/` |
|
| `docs/backlog/` | `tasks/` в корне репозитория |
|
||||||
| `docs/review-journal.md`, `docs/review/journal.md` | `docs/review.md` |
|
| `docs/review-journal.md`, `docs/review/journal.md` | `docs/review.md` |
|
||||||
|
|
||||||
## Что проверяет машина, а что человек
|
## Что проверяет машина, а что человек
|
||||||
@@ -539,7 +539,7 @@ kebab-case.** Причина не эстетическая: имя файла с
|
|||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"canon": 10,
|
"canon": 11,
|
||||||
"migrations": "internal/store/migrations"
|
"migrations": "internal/store/migrations"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -13,6 +13,37 @@ upgrade` идёт по записям снизу вверх от версии п
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Версия 11 — 2026-08-09
|
||||||
|
|
||||||
|
Каталог задач уехал из `docs/` в корень репозитория. Версия 8 отпустила его из
|
||||||
|
канона — перестала требовать, перестала проверять, — но место он занимал всё то
|
||||||
|
же, `docs/tasks/`. Полдела: каталог, принадлежащий одному плагину, лежал внутри
|
||||||
|
дерева, которым владеет другой. Проекту, поставившему учёт работ без канона
|
||||||
|
документов, приходилось заводить `docs/` ради одной вложенной папки.
|
||||||
|
|
||||||
|
**Что изменилось.** Дом задач — `tasks/` в корне репозитория. `tasks.py` ищет его
|
||||||
|
там первым; `docs/tasks/` и `doc/tasks/` остаются в списке поиска для
|
||||||
|
непереехавших проектов, а `init` заводит только в корне. Настройки — там же,
|
||||||
|
`tasks/.tasks.json`.
|
||||||
|
|
||||||
|
**Что осталось терпимым.** `docs.py` по-прежнему не считает `docs/tasks/` файлом
|
||||||
|
вне канона: непереехавший проект не должен получать выдуманную ошибку вдобавок к
|
||||||
|
этой записи, которая и так велит ему переехать.
|
||||||
|
|
||||||
|
**Что сделать проекту.**
|
||||||
|
|
||||||
|
1. `git mv docs/tasks tasks` — одним коммитом вместе с шагом 2, чтобы ссылки не
|
||||||
|
жили битыми между коммитами.
|
||||||
|
2. **Починить относительные ссылки внутри записей.** Файл `tasks/items/x.md`
|
||||||
|
стал на уровень ближе к корню: `../../passport.md` в теле записи теперь
|
||||||
|
`../docs/passport.md`. Тот же сдвиг у ссылок из индексов. Это самая тихая
|
||||||
|
часть переезда: битая относительная ссылка не мешает `tasks.py check`, её
|
||||||
|
ловит только `docs.py check` и только у документов канона.
|
||||||
|
3. Проверить ссылки **на** задачи снаружи: `CLAUDE.md`, `README.md`, гейт,
|
||||||
|
`docs/review.md`. Путь `docs/tasks/...` в них теперь ведёт в никуда.
|
||||||
|
4. Поправить путь в гейте: `tasks.py check --dir tasks`.
|
||||||
|
5. `docs/.pm.json`: `"canon": 11`.
|
||||||
|
|
||||||
## Версия 10 — 2026-08-09
|
## Версия 10 — 2026-08-09
|
||||||
|
|
||||||
Проверка формы `config.yaml` ушла к тому, кто файл заводит. Версия 9 перенесла в
|
Проверка формы `config.yaml` ушла к тому, кто файл заводит. Версия 9 перенесла в
|
||||||
|
|||||||
@@ -431,7 +431,7 @@ severity стоит здесь, а не выводится каждым прох
|
|||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"canon": 10
|
"canon": 11
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ from dataclasses import dataclass, field
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import NoReturn
|
from typing import NoReturn
|
||||||
|
|
||||||
CANON_VERSION = 10
|
CANON_VERSION = 11
|
||||||
|
|
||||||
OK, DRIFT, USAGE, ENV, INTERNAL = 0, 1, 2, 3, 4
|
OK, DRIFT, USAGE, ENV, INTERNAL = 0, 1, 2, 3, 4
|
||||||
|
|
||||||
@@ -76,12 +76,15 @@ DOC_EXTRA = {
|
|||||||
"adr": {"template.md": "шаблон записи ADR"},
|
"adr": {"template.md": "шаблон записи ADR"},
|
||||||
}
|
}
|
||||||
|
|
||||||
# Служебное в docs/ и каталог задач. Формы у них скрипт не проверяет, и по разным
|
# Служебное в docs/ и каталог задач, оставшийся там от прежней раскладки. Формы
|
||||||
# причинам: `.pm.json` не markdown, а `tasks/` **принадлежит другому плагину** —
|
# у них скрипт не проверяет, и по разным причинам: `.pm.json` не markdown, а
|
||||||
# `av-dev-tasks`, со своим скриптом, своим конфигом и своей версией формата.
|
# задачи **принадлежат другому плагину** — `av-dev-tasks`, со своим скриптом,
|
||||||
# Канон резервирует за ним место в `docs/`, но наличия не требует и внутрь не
|
# своим конфигом и своей версией формата.
|
||||||
# смотрит: проект, поставивший только этот плагин, задач не ведёт вовсе, и
|
#
|
||||||
# отказом это быть не может.
|
# Дом задач с версии 11 — `tasks/` в корне репозитория, то есть вне `docs/`
|
||||||
|
# вовсе. `docs/tasks/` здесь терпится потому, что непереехавший проект не должен
|
||||||
|
# получать «файл вне канона» вдобавок к записи журнала, которая и так велит ему
|
||||||
|
# переехать. Внутрь скрипт не смотрит ни в том, ни в другом случае.
|
||||||
NOT_DOCS = {".pm.json", "tasks"}
|
NOT_DOCS = {".pm.json", "tasks"}
|
||||||
|
|
||||||
# Слоты, которых в каноне нет, — с адресом, куда уезжает содержимое. Имена,
|
# Слоты, которых в каноне нет, — с адресом, куда уезжает содержимое. Имена,
|
||||||
@@ -90,11 +93,11 @@ NOT_DOCS = {".pm.json", "tasks"}
|
|||||||
RETIRED = {
|
RETIRED = {
|
||||||
"review-brief.md": "документы канона и есть бриф; остаток — в review",
|
"review-brief.md": "документы канона и есть бриф; остаток — в review",
|
||||||
"review-journal.md": "→ документ review",
|
"review-journal.md": "→ документ review",
|
||||||
"plan.md": "→ docs/tasks/ROADMAP.md",
|
"plan.md": "→ tasks/ROADMAP.md (плагин av-dev-tasks)",
|
||||||
"local-research.md": "→ документ research",
|
"local-research.md": "→ документ research",
|
||||||
"specs": "поведение → openspec/specs/, обзор → тема architecture",
|
"specs": "поведение → openspec/specs/, обзор → тема architecture",
|
||||||
"drafts": "идея → запись research, отказ → ADR, порядок → ROADMAP.md",
|
"drafts": "идея → запись research, отказ → ADR, порядок → ROADMAP.md",
|
||||||
"backlog": "→ docs/tasks/",
|
"backlog": "→ tasks/ в корне репозитория (плагин av-dev-tasks)",
|
||||||
}
|
}
|
||||||
|
|
||||||
# --- Слаги в именах файлов --------------------------------------------------
|
# --- Слаги в именах файлов --------------------------------------------------
|
||||||
@@ -211,7 +214,7 @@ def strip_code(text: str) -> str:
|
|||||||
"""Выкинуть блоки кода и вставки в обратных кавычках.
|
"""Выкинуть блоки кода и вставки в обратных кавычках.
|
||||||
|
|
||||||
Путь в примере или в шаблоне — не ссылка, и краснеть на нём значит краснеть
|
Путь в примере или в шаблоне — не ссылка, и краснеть на нём значит краснеть
|
||||||
на каждом образце документа. Инлайн-код тоже: `[docs/backlog](docs/tasks/…)`
|
на каждом образце документа. Инлайн-код тоже: `[docs/backlog](tasks/…)`
|
||||||
в тексте про подписи ссылок — иллюстрация, а не ссылка."""
|
в тексте про подписи ссылок — иллюстрация, а не ссылка."""
|
||||||
out, inside = [], False
|
out, inside = [], False
|
||||||
for line in text.splitlines():
|
for line in text.splitlines():
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ description: "Завести новый проект — сессия вопро
|
|||||||
| `passport.md` | `architecture.md` |
|
| `passport.md` | `architecture.md` |
|
||||||
| `CLAUDE.md` | `database.md` |
|
| `CLAUDE.md` | `database.md` |
|
||||||
| `security.md` | `conventions/` |
|
| `security.md` | `conventions/` |
|
||||||
| `docs/tasks/ROADMAP.md` — первые цели | `research/`, `adr/` |
|
| `tasks/ROADMAP.md` — первые цели | `research/`, `adr/` |
|
||||||
| `docs/.pm.json` | `review.md` — журнал пуст, настройка появится с первым ревью |
|
| `docs/.pm.json` | `review.md` — журнал пуст, настройка появится с первым ревью |
|
||||||
|
|
||||||
Честная строка информативна, а не «TBD»: «архитектуры пока нет: кода нет,
|
Честная строка информативна, а не «TBD»: «архитектуры пока нет: кода нет,
|
||||||
|
|||||||
@@ -333,7 +333,7 @@ security docs/security.md разбор basics
|
|||||||
operations docs/architecture.md, «Эксплуатация» разбор basics
|
operations docs/architecture.md, «Эксплуатация» разбор basics
|
||||||
дома нет: docs/database.md отсутствует
|
дома нет: docs/database.md отсутствует
|
||||||
|
|
||||||
процессные: docs/tasks/, docs/review.md, docs/adr/, docs/research/
|
процессные: tasks/, docs/review.md, docs/adr/, docs/research/
|
||||||
директивы: CLAUDE.md найден, AGENTS.md отсутствует
|
директивы: CLAUDE.md найден, AGENTS.md отсутствует
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ description: "Конвейер ревью изменения, устроенны
|
|||||||
|---|---|---|
|
|---|---|---|
|
||||||
| **тема** | заводит направление проверки и требует исполнителя | `conventions.*`, `security.*`, `architecture.*`, свои документы проекта |
|
| **тема** | заводит направление проверки и требует исполнителя | `conventions.*`, `security.*`, `architecture.*`, свои документы проекта |
|
||||||
| **источник темы** | читает как материал чужой темы, своей не порождает | `passport.*`, `database.*`, `CLAUDE.md`/`AGENTS.md`, `openspec/specs/` |
|
| **источник темы** | читает как материал чужой темы, своей не порождает | `passport.*`, `database.*`, `CLAUDE.md`/`AGENTS.md`, `openspec/specs/` |
|
||||||
| **процессный документ** | не судит по нему изменение | `docs/tasks/`, `docs/review.*`, `docs/adr.*`, `docs/research.*`, `docs/.pm.json` |
|
| **процессный документ** | не судит по нему изменение | `tasks/`, `docs/review.*`, `docs/adr.*`, `docs/research.*`, `docs/.pm.json` |
|
||||||
|
|
||||||
**Одна процессная запись всё же читается — `docs/review.*`.** В ней лежит
|
**Одна процессная запись всё же читается — `docs/review.*`.** В ней лежит
|
||||||
настройка самого конвейера: вопросы по темам, журнал дефектов, типовые узлы,
|
настройка самого конвейера: вопросы по темам, журнал дефектов, типовые узлы,
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ color: green
|
|||||||
|
|
||||||
## Что тебе дают
|
## Что тебе дают
|
||||||
|
|
||||||
Список файлов записей (`docs/tasks/items/<slug>.md`) или каталог задач целиком.
|
Список файлов записей (`tasks/items/<slug>.md`) или каталог задач целиком.
|
||||||
Каталог тебе нужен и сам по себе: задача несёт тег `goal:<слаг>`, и **файл цели
|
Каталог тебе нужен и сам по себе: задача несёт тег `goal:<слаг>`, и **файл цели
|
||||||
ты открываешь**, иначе седьмое правило не проверить.
|
ты открываешь**, иначе седьмое правило не проверить.
|
||||||
|
|
||||||
|
|||||||
@@ -200,7 +200,7 @@ python3 $tk sprint close --dir D # конец спринта; --d
|
|||||||
python3 $tk reopen <слаг> --dir D --reason … # приёмка не сошлась после закрытия
|
python3 $tk reopen <слаг> --dir D --reason … # приёмка не сошлась после закрытия
|
||||||
```
|
```
|
||||||
|
|
||||||
`D` — каталог задач проекта, по канону всегда `docs/tasks`; `--dir` передаётся
|
`D` — каталог задач проекта, всегда `tasks/` в корне; `--dir` передаётся
|
||||||
явно каждой командой. Вызов из чужого контекста описан в скилле `tasks`
|
явно каждой командой. Вызов из чужого контекста описан в скилле `tasks`
|
||||||
(«Переносимость»). **Коды выхода** — там же: 1 это дрейф в беклоге, 3 это
|
(«Переносимость»). **Коды выхода** — там же: 1 это дрейф в беклоге, 3 это
|
||||||
«каталога нет», и ветвиться на них надо по-разному.
|
«каталога нет», и ветвиться на них надо по-разному.
|
||||||
|
|||||||
@@ -60,13 +60,14 @@ description: Ведение задач и целей как каталога mar
|
|||||||
|
|
||||||
## Раскладка
|
## Раскладка
|
||||||
|
|
||||||
Каталог задач — **`docs/tasks`, жёстко**: это часть канона документов, и
|
Каталог задач — **`tasks/` в корне репозитория, жёстко.** Он принадлежит этому
|
||||||
подгоняется под него проект, а не наоборот. Канон ведёт другой плагин
|
плагину, а не канону документов: `docs/` ведёт другой плагин (`av-dev-docs`), и
|
||||||
(`av-dev-docs`), и **путь известен скиллу сам** — ссылки в чужое дерево здесь
|
проект, поставивший учёт работ без него, каталога `docs/` не имеет вовсе. Внутри
|
||||||
нет намеренно: скилл работает и там, где того плагина не поставили.
|
`docs/` задачи лежали до версии канона 11; непереехавший проект скрипт
|
||||||
|
по-прежнему находит, но новый заводит только в корне.
|
||||||
|
|
||||||
```
|
```
|
||||||
docs/tasks/
|
tasks/
|
||||||
items/ задачи и цели файлами, <slug>.md, слаги английские
|
items/ задачи и цели файлами, <slug>.md, слаги английские
|
||||||
ROADMAP.md состояние проекта: что уже умеет и чего ещё не умеет
|
ROADMAP.md состояние проекта: что уже умеет и чего ещё не умеет
|
||||||
BACKLOG.md что можно взять — только задачи, целей здесь нет
|
BACKLOG.md что можно взять — только задачи, целей здесь нет
|
||||||
@@ -133,7 +134,7 @@ docs/tasks/
|
|||||||
**У сделанной задачи записи не остаётся** — файл и строка удаляются (`close
|
**У сделанной задачи записи не остаётся** — файл и строка удаляются (`close
|
||||||
--implemented`). Ей хватает коммита и документации проекта; вторая запись была
|
--implemented`). Ей хватает коммита и документации проекта; вторая запись была
|
||||||
бы вторым домом для того же факта. Вопрос «что было в спринте N» отвечается
|
бы вторым домом для того же факта. Вопрос «что было в спринте N» отвечается
|
||||||
даром: `SPRINT.md` лежит под git, `git log -p docs/tasks/SPRINT.md` отдаёт историю
|
даром: `SPRINT.md` лежит под git, `git log -p tasks/SPRINT.md` отдаёт историю
|
||||||
всех наборов без отдельного журнала.
|
всех наборов без отдельного журнала.
|
||||||
|
|
||||||
**У достигнутой цели запись остаётся, и это единственное исключение.** Файл
|
**У достигнутой цели запись остаётся, и это единственное исключение.** Файл
|
||||||
@@ -359,7 +360,7 @@ stateDiagram-v2
|
|||||||
## Инструмент (`tasks.py`)
|
## Инструмент (`tasks.py`)
|
||||||
|
|
||||||
Пусть `tk="$CLAUDE_PLUGIN_ROOT/skills/tasks/scripts/tasks.py"`, а `D` —
|
Пусть `tk="$CLAUDE_PLUGIN_ROOT/skills/tasks/scripts/tasks.py"`, а `D` —
|
||||||
`docs/tasks` от корня проекта. `--dir` стоит в примерах намеренно: вызов из
|
`tasks` от корня проекта. `--dir` стоит в примерах намеренно: вызов из
|
||||||
подкаталога — обычное дело.
|
подкаталога — обычное дело.
|
||||||
|
|
||||||
```
|
```
|
||||||
@@ -618,7 +619,7 @@ python3 $tk adopt scan --from … | apply --plan … # разовая адап
|
|||||||
просто каталог markdown. Текст задач — русский (язык документации проекта);
|
просто каталог markdown. Текст задач — русский (язык документации проекта);
|
||||||
зашита только латиница слага. OpenSpec ему тоже не нужен.
|
зашита только латиница слага. OpenSpec ему тоже не нужен.
|
||||||
|
|
||||||
- **Каталог задач — `docs/tasks`, жёстко**, и `--dir` передаётся явно всегда:
|
- **Каталог задач — `tasks/` в корне, жёстко**, и `--dir` передаётся явно всегда:
|
||||||
раскладка канона одинакова во всех проектах, и искать больше нечего. Каталога
|
раскладка канона одинакова во всех проектах, и искать больше нечего. Каталога
|
||||||
нет — код 3 и вопрос человеку; `init` заводит его **только** когда проект
|
нет — код 3 и вопрос человеку; `init` заводит его **только** когда проект
|
||||||
действительно новый, а перевод чужой раскладки делает `av-dev-docs:canon`.
|
действительно новый, а перевод чужой раскладки делает `av-dev-docs:canon`.
|
||||||
|
|||||||
@@ -38,7 +38,7 @@
|
|||||||
tk="$CLAUDE_PLUGIN_ROOT/skills/tasks/scripts/tasks.py"
|
tk="$CLAUDE_PLUGIN_ROOT/skills/tasks/scripts/tasks.py"
|
||||||
|
|
||||||
python3 $tk adopt scan --from docs/backlog docs/plan.md TODO.md \
|
python3 $tk adopt scan --from docs/backlog docs/plan.md TODO.md \
|
||||||
--target docs/tasks --out tasks-adopt-plan.json # только чтение
|
--target tasks --out tasks-adopt-plan.json # только чтение
|
||||||
python3 $tk adopt apply --plan tasks-adopt-plan.json \
|
python3 $tk adopt apply --plan tasks-adopt-plan.json \
|
||||||
--refs docs openspec CLAUDE.md README.md # запись
|
--refs docs openspec CLAUDE.md README.md # запись
|
||||||
```
|
```
|
||||||
@@ -63,7 +63,7 @@ python3 $tk adopt apply --plan tasks-adopt-plan.json \
|
|||||||
## Порядок
|
## Порядок
|
||||||
|
|
||||||
1. **Осмотрись.** Где лежат задачи, роадмап, заметки. Каталог задач по канону —
|
1. **Осмотрись.** Где лежат задачи, роадмап, заметки. Каталог задач по канону —
|
||||||
всегда `docs/tasks`. Секции беклога (`--sections`) — по умолчанию
|
всегда `tasks`. Секции беклога (`--sections`) — по умолчанию
|
||||||
`Ядро,Инфра`; если у проекта деление другое по существу, оно называется
|
`Ядро,Инфра`; если у проекта деление другое по существу, оно называется
|
||||||
здесь, а не подгоняется под умолчание, и становится **заголовками `##`
|
здесь, а не подгоняется под умолчание, и становится **заголовками `##`
|
||||||
индекса** — их единственным домом. В `docs/.pm.json` секции не пишутся.
|
индекса** — их единственным домом. В `docs/.pm.json` секции не пишутся.
|
||||||
@@ -106,7 +106,7 @@ take` такую задачу не возьмёт). Закрывается эт
|
|||||||
|
|
||||||
- **Не удаляет источники.** Старый каталог остаётся на месте: сверить и убрать —
|
- **Не удаляет источники.** Старый каталог остаётся на месте: сверить и убрать —
|
||||||
дело человека, удалять чужое молча нельзя. В доклад идёт готовая команда.
|
дело человека, удалять чужое молча нельзя. В доклад идёт готовая команда.
|
||||||
- **Не переписывает подписи ссылок.** `[docs/backlog](docs/tasks/BACKLOG.md)` —
|
- **Не переписывает подписи ссылок.** `[docs/backlog](tasks/BACKLOG.md)` —
|
||||||
цель поправлена, текст остался; это правится глазами, и таких мест немного.
|
цель поправлена, текст остался; это правится глазами, и таких мест немного.
|
||||||
- **Не сочиняет критерии приёмки и не придумывает цели**, которых в материале
|
- **Не сочиняет критерии приёмки и не придумывает цели**, которых в материале
|
||||||
нет. Придуманная цель хуже отсутствующей: под неё соберут спринт.
|
нет. Придуманная цель хуже отсутствующей: под неё соберут спринт.
|
||||||
|
|||||||
@@ -6,11 +6,12 @@
|
|||||||
спринт — замороженный набор задач, обычно под одну цель. Индексов теперь
|
спринт — замороженный набор задач, обычно под одну цель. Индексов теперь
|
||||||
четыре, и задача живёт ровно в одном из них за раз.
|
четыре, и задача живёт ровно в одном из них за раз.
|
||||||
|
|
||||||
Раскладка. Путь каталога — `docs/tasks`, жёстко: это часть канона документов
|
Раскладка. Путь каталога — `tasks/` в корне репозитория, жёстко. Каталог
|
||||||
av-dev, и подгоняется под него проект. Имена внутри настраиваются через
|
принадлежит этому плагину, а не канону документов: `docs/` ведёт другой плагин, и
|
||||||
`docs/.pm.json`, ключ `tasks`.
|
проект, поставивший учёт работ без него, каталога `docs/` не имеет вовсе. Имена
|
||||||
|
внутри настраиваются через `tasks/.tasks.json`.
|
||||||
|
|
||||||
docs/tasks/
|
tasks/
|
||||||
items/ задачи и цели файлами, <slug>.md
|
items/ задачи и цели файлами, <slug>.md
|
||||||
ROADMAP.md состояние проекта: что уже умеет и чего ещё не умеет.
|
ROADMAP.md состояние проекта: что уже умеет и чего ещё не умеет.
|
||||||
Секции канонические и в этом порядке: Запланировано |
|
Секции канонические и в этом порядке: Запланировано |
|
||||||
@@ -75,9 +76,9 @@ goal | feature | fix | chore | research, по-английски, как и пр
|
|||||||
tasks.py adopt scan --from PATH [PATH …] [--target DIR] [--out PLAN.json]
|
tasks.py adopt scan --from PATH [PATH …] [--target DIR] [--out PLAN.json]
|
||||||
tasks.py adopt apply --plan PLAN.json [--refs PATH …] [--dry-run]
|
tasks.py adopt apply --plan PLAN.json [--refs PATH …] [--dry-run]
|
||||||
|
|
||||||
Каталог задач: `--dir` (обязан быть внутри рабочего каталога) → `docs/tasks`
|
Каталог задач: `--dir` (обязан быть внутри рабочего каталога) → `tasks/` вверх
|
||||||
вверх от текущего каталога. Прежние раскладки (`tasks`, `doc/tasks`) читаются,
|
от текущего каталога. Прежние раскладки (`docs/tasks`, `doc/tasks`) читаются,
|
||||||
пока живы непереехавшие проекты; переводит их скилл av-dev-docs:canon.
|
пока живы непереехавшие проекты; переезд — запись 11 журнала версий канона.
|
||||||
|
|
||||||
Коды выхода (единый словарь, на нём ветвятся скиллы):
|
Коды выхода (единый словарь, на нём ветвятся скиллы):
|
||||||
|
|
||||||
@@ -572,7 +573,7 @@ def resolve_layout(explicit: str | None) -> Layout:
|
|||||||
return Layout(root, load_config(root))
|
return Layout(root, load_config(root))
|
||||||
here = Path.cwd().resolve()
|
here = Path.cwd().resolve()
|
||||||
for base in (here, *here.parents):
|
for base in (here, *here.parents):
|
||||||
for candidate in (base, base / "docs/tasks", base / "tasks", base / "doc/tasks"):
|
for candidate in (base, base / "tasks", base / "docs/tasks", base / "doc/tasks"):
|
||||||
if looks_like_tasks(candidate):
|
if looks_like_tasks(candidate):
|
||||||
try:
|
try:
|
||||||
rel = candidate.relative_to(here)
|
rel = candidate.relative_to(here)
|
||||||
@@ -581,10 +582,10 @@ def resolve_layout(explicit: str | None) -> Layout:
|
|||||||
return Layout(rel if str(rel) != "." else candidate, load_config(candidate))
|
return Layout(rel if str(rel) != "." else candidate, load_config(candidate))
|
||||||
if (base / ".git").exists():
|
if (base / ".git").exists():
|
||||||
break # выше корня репозитория не ищем
|
break # выше корня репозитория не ищем
|
||||||
raise Env("каталог задач не найден: ни --dir, ни docs/tasks вверх от"
|
raise Env("каталог задач не найден: ни --dir, ни tasks/ вверх от"
|
||||||
f" {here}. По канону путь всегда docs/tasks; чужую раскладку"
|
f" {here}. Путь всегда tasks/ в корне репозитория; прежний"
|
||||||
" переводит скилл av-dev-docs:canon, новый проект —"
|
" docs/tasks переезжает по записи 11 журнала версий канона,"
|
||||||
" tasks.py init --dir docs/tasks")
|
" новый проект — tasks.py init --dir tasks")
|
||||||
|
|
||||||
|
|
||||||
# --- Чтение индексов ---
|
# --- Чтение индексов ---
|
||||||
@@ -3090,9 +3091,9 @@ def cmd_adopt_scan(a: argparse.Namespace) -> int:
|
|||||||
def requalify_links(text: str, old_dir: Path, new_dir: Path) -> str:
|
def requalify_links(text: str, old_dir: Path, new_dir: Path) -> str:
|
||||||
"""Относительные ссылки тела после переезда файла глубже.
|
"""Относительные ссылки тела после переезда файла глубже.
|
||||||
|
|
||||||
`docs/backlog/x.md` знал соседей как `../passport.md`; из
|
`docs/backlog/x.md` знал соседей как `../passport.md`; из `tasks/items/x.md`
|
||||||
`docs/tasks/items/x.md` тот же файл — уже `../../passport.md`. Молча
|
тот же файл — уже `../docs/passport.md`. Молча съехавшая на уровень ссылка —
|
||||||
съехавшая на уровень ссылка — самый дешёвый способ развалить документацию.
|
самый дешёвый способ развалить документацию.
|
||||||
"""
|
"""
|
||||||
delta = len(new_dir.parts) - len(old_dir.parts)
|
delta = len(new_dir.parts) - len(old_dir.parts)
|
||||||
if delta <= 0:
|
if delta <= 0:
|
||||||
@@ -3420,7 +3421,7 @@ def main() -> int:
|
|||||||
asub = p.add_subparsers(dest="adopt_command", required=True)
|
asub = p.add_subparsers(dest="adopt_command", required=True)
|
||||||
s = asub.add_parser("scan", help="только карта: что найдено и как разложилось")
|
s = asub.add_parser("scan", help="только карта: что найдено и как разложилось")
|
||||||
s.add_argument("--from", dest="sources", nargs="+", required=True)
|
s.add_argument("--from", dest="sources", nargs="+", required=True)
|
||||||
s.add_argument("--target", default="docs/tasks")
|
s.add_argument("--target", default="tasks")
|
||||||
s.add_argument("--out", default="tasks-adopt-plan.json")
|
s.add_argument("--out", default="tasks-adopt-plan.json")
|
||||||
s.add_argument("--sections", default=DEFAULT_SECTIONS)
|
s.add_argument("--sections", default=DEFAULT_SECTIONS)
|
||||||
|
|
||||||
@@ -3431,7 +3432,7 @@ def main() -> int:
|
|||||||
|
|
||||||
a = ap.parse_args()
|
a = ap.parse_args()
|
||||||
if a.command == "init":
|
if a.command == "init":
|
||||||
return cmd_init(Path(a.dir or "docs/tasks"), a)
|
return cmd_init(Path(a.dir or "tasks"), a)
|
||||||
if a.command == "adopt":
|
if a.command == "adopt":
|
||||||
return cmd_adopt_scan(a) if a.adopt_command == "scan" else cmd_adopt_apply(a)
|
return cmd_adopt_scan(a) if a.adopt_command == "scan" else cmd_adopt_apply(a)
|
||||||
lay = resolve_layout(a.dir)
|
lay = resolve_layout(a.dir)
|
||||||
|
|||||||
Reference in New Issue
Block a user