---
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: <action>`.
2. Если вывод содержит `Status: COMPLETE` → финальный репорт пользователю, exit.
3. Если вывод содержит `AMBIGUOUS` → репорт пользователю с причиной, STOP.
4. Иначе — выполни action из строки `NEXT:` (используй prompt templates A-I ниже).
5. 1 строка прогресса пользователю (формат: `✅ <phase> — <action executed>`).
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: <project>_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: <module 1> — ...
3. core: <module 2> — ...
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 в репо <cwd>.
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: <today YYYY-MM-DD>
   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=<type>, project=<name>, description=<desc>, owner=<owner>.
1. Прочитай docs/spec/meta.md.
2. edit frontmatter: type=<type>, project=<name>, created=<today>, phase=1.
3. Создай файл docs/spec/context.md с описанием проекта из ответа юзера.
4. Верни: "done: type=<type>, project=<name>".
```

### Template C (stack / Phase 2)

```
Создай файл docs/spec/stack.md для Phase 2 (STACK).
Ответы юзера: <answers>.
Тип проекта: <type> (из 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, <N>/<M> mandatory items".
```

### Template D (modules / Phase 3, с memory-search)

```
Контекст: Phase 3 (modules) для проекта типа <type>.
Ответ юзера: <answers>.
1. memory-search("reference repo <module>") — доберёт паттерны из 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).
Ответы юзера: <answers> (или "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).
Ответы юзера: <answers>.
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).
Ответы юзера: <answers>.
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: "<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.