--- name: spec description: Autonomous spec generation executor for new projects. Deterministically guides the agent through 9 phases via spec-status tool. Main agent is orchestrator, delegates ALL work to subagents. Also when user says "создай спеку", "новый проект", "спецификация проекта", "spec", "project spec". --- # Spec Автономная процедура-loop для генерации спецификации нового проекта. Source of truth для порядка и действий — `spec-status` tool. На выходе — `docs/spec/` (директория с файлами по фазам) + N GitHub issues, готовых для `/run-pipeline`. ## ПРОТОКОЛ (ЖЁСТКО) Каждая итерация (БЕЗ ИСКЛЮЧЕНИЙ): 1. Вызови tool `spec-status({})` — вернёт текущую фазу + строку `NEXT: `. 2. Если вывод содержит `Status: COMPLETE` → финальный репорт пользователю, exit. 3. Если вывод содержит `AMBIGUOUS` → репорт пользователю с причиной, STOP. 4. Иначе — выполни action из строки `NEXT:` (используй prompt templates A-I ниже). 5. 1 строка прогресса пользователю (формат: `✅ `). 6. Re-loop (шаг 1). ### ЗАПРЕЩЕНО - ЛЮБОЙ action БЕЗ предшествующего вызова `spec-status` = protocol violation. - Импровизировать порядок. Решать сам какую фазу выполнять — читай `NEXT:`. - Пропускать вызов `spec-status`, даже если «кажется, что фаза уже ✅» — скрипт решает. - bash-запуск `python3 .opencode/scripts/spec-status.py` — детерминированный deny-rule (см. ADR-019). Только нативный tool `spec-status`. - Главному агенту: edit/write/read файлов (всё через subagent), memory-search (через subagent), gh issue create (через subagent). - Формулировать вопросы не из question templates ниже. - Предлагать стек вне hardcoded default stack по типу проекта. - Запускать /run-pipeline (стоп на issues — дальше юзер сам). ### Остановы - Subagent error → 1 retry, потом STOP + report пользователю. - `AMBIGUOUS` в выводе `spec-status` → STOP + report. - 3 итераций подряд без прогресса (та же фаза ❌) → STOP + report. ## Default stack по типам проекта (хардкод) Общий для всех типов: Python 3.12+, uv, hatchling, ruff, mypy strict, pytest 90% cov, xenon, pre-commit, .editorconfig, .gitignore, LICENSE MIT, dependabot, CI. - **backend**: FastAPI + uvicorn, Tortoise ORM (встроенные миграции `tortoise makemigrations`, НЕ Aerich — legacy), Pydantic v2 + pydantic-settings, Loguru, опц. JWT-auth (`passlib[bcrypt]` + `pyjwt`) - **fullstack**: backend + frontend/ (SvelteKit + Svelte 5 runes (TS) + Tailwind v4 + shadcn-svelte + Biome + Vitest + Knip) - **mcp-server**: FastAPI + MCP SDK, Patchright/Playwright over CDP, X-API-Key - **cli**: Typer (default) / click / argparse, hatchling build - **bot**: aiogram 3.x, FastAPI webhook/polling, Tortoise (опц.), Pydantic AI (опц.) - **worker**: Prefect flows + tasks, prefect.yaml, docker-compose worker profile ### Миграционная заметка (stack.md) Если существующий `docs/spec/stack.md` содержит `react` или `aerich` (устаревшие значения до issue #231), spec-status пометит Phase 2 как NOT_DONE (`STACK_REQUIRED` теперь требует `svelte`/`sveltekit` для fullstack и не требует `aerich`). Обнови stack.md: замени `react` → `svelte`/`sveltekit`, удали `aerich` (Tortoise 1.0+ имеет встроенные миграции `tortoise makemigrations`). ## 9 фаз ### Phase 0: DETECT (subagent, без вопроса юзеру) Prompt template A (см. ниже). ### Phase 1: PROJECT_TYPE (вопрос юзеру + subagent) Вопрос юзеру (один вопрос, multiple choice): ``` Выбери тип проекта: [1] backend — FastAPI + Tortoise, REST API, без frontend [2] fullstack — backend + SvelteKit/Svelte 5 + Tailwind v4 + shadcn-svelte dashboard (TypeScript, monorepo) [3] mcp-server — MCP + REST сервер (Patchright/Playwright over CDP) [4] cli — Python CLI tool (Typer) [5] bot — Telegram bot (aiogram 3) [6] worker — Prefect flows / background jobs Имя проекта (kebab-case): ___ Описание (1 строка): ___ GitHub owner: ___ ``` Prompt template B (см. ниже). ### Phase 2: STACK (вопрос юзеру + subagent) Вопрос юзеру — ТОЛЬКО развилки для выбранного типа: ``` backend: - DB: [1] Postgres prod / [2] SQLite dev / [3] both / [4] no DB - Auth: [1] none v1 / [2] JWT / [3] X-API-Key fullstack: - frontend: [1] SvelteKit + Svelte 5 + Tailwind v4 + shadcn-svelte (default) / [2] add later - DB: (same as backend) - Auth: (same as backend) mcp-server: - target: [1] BitBrowser / [2] custom / [3] generic - auth: [1] X-API-Key / [2] none cli: - interface: [1] Typer (default) / [2] click / [3] argparse - output: [1] rich / [2] plain / [3] loguru bot: - framework: [1] aiogram 3 (default) / [2] other - mode: [1] polling / [2] FastAPI webhook - Pydantic AI: [1] yes / [2] no - DB: [1] Tortoise + SQLite / [2] Tortoise + Postgres / [3] no DB worker: - scheduler: [1] Prefect (default) / [2] APScheduler - work_pool_name: ___ (default: _pool) - DB: [1] Tortoise + SQLite / [2] Tortoise + Postgres / [3] no DB ``` Prompt template C (см. ниже). ### Phase 3: MODULES (вопрос юзеру + subagent с добором) Вопрос юзеру (free-form): ``` Какие модули/домены нужны? Например: "YouTube uploader, Telegram notifier, channel management". Опиши модули (1 строка на модуль): ``` Prompt template D (см. ниже, с memory-search). ### Phase 4: DB_SCHEMA (вопрос юзеру + subagent) Если в Phase 2 выбрано "no DB" → пропустить вопрос, subagent ставит `no_db: true` в `docs/spec/meta.md` (db-schema.md НЕ создаётся). Иначе вопрос: ``` Опиши ключевые сущности и поля. Например: "Channel: id UUID, platform enum, name str, is_active bool, metadata json Upload: id UUID, channel_id FK, video_url str, status enum, ..." Стандартные поля (вшито, не спрашивай): id UUIDField pk, created_at, updated_at, status CharEnumField(StrEnum). Опиши сущности: ``` Prompt template E (см. ниже). ### Phase 5: INFRA (вопрос юзеру + subagent) Вопрос: ``` - Docker compose: [1] yes / [2] no - Prefect: [1] yes / [2] no (если worker или backend с background jobs) - MCP external: [1] yes (URL) / [2] no - Tunnel (demo): [1] yes / [2] no ``` Prompt template F (см. ниже). ### Phase 6: ROADMAP (вопрос юзеру + subagent) Вопрос (с default proposal): ``` Дефолтный roadmap (можешь править): 1. scaffolding — repo structure, CI, .gitignore, LICENSE (через project-template skill init flow) 2. core: — ... 3. core: — ... 4. auth (если выбран auth в Phase 2) 5. db migrations (если есть DB) 6. docker compose (если выбран в Phase 5) 7. frontend scaffolding (если fullstack) Подтверди или отредактируй: ``` Prompt template G (см. ниже). ### Phase 7: CONFIRM (subagent читает, вопрос юзеру) Prompt template H (см. ниже). Вопрос юзеру: ``` Подтверди spec? [1] confirm / [2] edit Phase N (укажи номер) ``` Если edit → вернуться на указанную фазу (3, 4, 5 или 6), повторить, снова Confirm. ### Phase 8: EXECUTE (subagent, без вопроса юзеру) Prompt template I (см. ниже, create issues). Финальный репорт юзеру (после Phase 8): ``` Spec complete. Issues: #N1, #N2, ... Запусти /run-pipeline для issue #<первый> чтобы начать реализацию. ``` ## Prompt templates ### Template A (detect / Phase 0) ``` Контекст: запуск spec в репо . 1. `git rev-parse --show-toplevel` → repo root. 2. Если docs/spec/meta.md существует → прочитай frontmatter, верни phase/status. 3. Если нет → создай docs/spec/meta.md с frontmatter: --- project: '' type: '' created: phase: 0 status: in_progress --- (создай директорию docs/spec/ через `mkdir -p docs/spec` если не существует) 4. `memory-search("reference repo")` → верни список релевантных memory paths. 5. Верни: {spec_exists: bool, current_phase: int, references: [...]}. ``` ### Template B (project_type / Phase 1) ``` Обнови docs/spec/meta.md frontmatter для Phase 1 (PROJECT_TYPE). Ответы юзера: type=, project=, description=, owner=. 1. Прочитай docs/spec/meta.md. 2. edit frontmatter: type=, project=, created=, phase=1. 3. Создай файл docs/spec/context.md с описанием проекта из ответа юзера. 4. Верни: "done: type=, project=". ``` ### Template C (stack / Phase 2) ``` Создай файл docs/spec/stack.md для Phase 2 (STACK). Ответы юзера: . Тип проекта: (из frontmatter meta.md). Default stack для типа (хардкод, добавить всегда): - Общий: Python 3.12+, uv, hatchling, ruff, mypy strict, pytest 90% cov, xenon, pre-commit, .editorconfig, .gitignore, LICENSE MIT, dependabot, CI - backend: FastAPI + uvicorn, Tortoise ORM (встроенные миграции `tortoise makemigrations`, НЕ Aerich), Pydantic v2 + pydantic-settings, Loguru, опц. JWT-auth (`passlib[bcrypt]` + `pyjwt`) - fullstack: + frontend/ (SvelteKit + Svelte 5 runes (TS) + Tailwind v4 + shadcn-svelte + Biome + Vitest + Knip) - mcp-server: FastAPI + MCP SDK, Patchright/Playwright over CDP, X-API-Key - cli: Typer (default) / click / argparse, hatchling build - bot: aiogram 3.x, FastAPI webhook/polling, Tortoise (опц.), Pydantic AI (опц.) - worker: Prefect flows + tasks, prefect.yaml, docker-compose worker profile 1. Создай docs/spec/stack.md с полным списком (default + choices). 2. edit docs/spec/meta.md frontmatter: phase=2. 3. spec-status валидирует mandatory items через содержимое stack.md — если FAIL, верни что не хватает. 4. Верни: "done: stack.md created, / mandatory items". ``` ### Template D (modules / Phase 3, с memory-search) ``` Контекст: Phase 3 (modules) для проекта типа . Ответ юзера: . 1. memory-search("reference repo ") — доберёт паттерны из reference repos. 2. Сформируй ## Модули (bullet list) + ## Структура (дерево) на основе ответа + референсов. 3. Создай docs/spec/modules.md с обеими секциями. edit docs/spec/meta.md frontmatter phase=3. 4. Верни summary (5-10 строк) для показа юзеру. ``` ### Template E (db_schema / Phase 4) ``` Обнови docs/spec для Phase 4 (DB_SCHEMA). Ответы юзера: (или "no_db" если выбрано). 1. Если no_db: edit docs/spec/meta.md frontmatter no_db=true (db-schema.md НЕ создаётся). 2. Иначе: создай docs/spec/db-schema.md со сущностями из ответа. 3. edit docs/spec/meta.md frontmatter phase=4. 4. Верни: "done: db-schema updated". ``` ### Template F (infra / Phase 5) ``` Обнови docs/spec для Phase 5 (INFRA). Ответы юзера: . 1. Создай docs/spec/infra.md. 2. edit docs/spec/meta.md frontmatter phase=5. 3. Верни: "done: infra.md updated". ``` ### Template G (roadmap / Phase 6) ``` Обнови docs/spec для Phase 6 (ROADMAP). Ответы юзера: . 1. Создай docs/spec/roadmap.md с N пунктами. 2. edit docs/spec/meta.md frontmatter phase=6. 3. Верни: "done: roadmap.md updated, N пунктов". ``` ### Template H (confirm / Phase 7) ``` Прочитай все файлы docs/spec/*.md (meta.md, context.md, stack.md, modules.md, db-schema.md если есть, infra.md, roadmap.md). 1. edit docs/spec/meta.md frontmatter confirmed=true, phase=7 (если юзер подтвердил). 2. Верни полный текст spec (все файлы конкатенированные) для показа юзеру. ``` ### Template I (execute / Phase 8, create issues) ``` Создай N GitHub issues по roadmap из docs/spec/roadmap.md. 1. Load `issue` skill via `skill({name: "issue"})`. 2. Прочитай docs/spec/stack.md, docs/spec/modules.md, docs/spec/db-schema.md (если есть), docs/spec/infra.md для контекста. 3. Для каждого пункта roadmap (по порядку): - Сформируй самодостаточный issue body (issue-skill format): ## Контекст (Зачем: мотивация; Контекст: текущее состояние) ## Задача (пошагово с путями к файлам) ## Контракты (ожидаемое поведение / API) ## Инварианты (правила без исключений) ## Граничные случаи (что при ошибках) ## Влияние на связанные компоненты (зависящие файлы/оракулы/агенты/промпты/валидаторы; paired updates; «нет связанных компонентов» для тривиальных задач) ## Вне scope (что НЕ делаем) ## Критерии приемки (как проверяем) ## Связанные ресурсы (Part of spec, ref к docs/spec/roadmap.md) - Issue #1 (scaffolding) body ДОЛЖЕН включать: "Используй project-template skill init flow для: cookiecutter по типу проекта (pyproject.toml, CI, .gitignore, LICENSE, dependabot, pre-commit). Структура — из ## Структура в docs/spec/modules.md." - `create-issue({ title: "type(scope): description", body: "", labels: ["enhancement", "from-spec"] })` tool (НЕ raw `gh issue create` — заблокирован deny) 4. Собери реальные номера issues из вывода tool. 5. Update docs/spec/roadmap.md: добавь реальные #N номера. Update docs/spec/meta.md: executed=true, phase=8. 6. Верни: [{number, url, title}, ...] для всех issues. ``` ## Rules - `spec-status` — единственный source of truth для порядка шагов и действий. - Скрипт read-only (только presence check в `docs/spec/*.md`, без мутаций). - После каждой фазы → 1 строка прогресса юзеру. - Если subagent error → 1 retry, потом STOP + report пользователю. - Главный агент = оркестратор: `spec-status` tool + вопрос юзеру + task(general) делегирование. Не делает edit/memory-search/gh сам. - Стоп на issues — дальше юзер сам /run-pipeline.