---
name: feature-spec
description: Lightweight SDD-style Q&A skill for feature planning. Guides the agent through Spec-Driven Development questions before implementation. Runs an explore subagent to find related/linked components (oracle scripts, validators, agents, prompts) before Q&A, then produces a structured plan with 8 SDD sections (Контекст, Задача, Контракты, Инварианты, Граничные случаи, Влияние на связанные компоненты, Вне scope, Критерии приемки). Also when user says "спека фичи", "feature spec", "план фичи", "обсудим фичу", "spec feature", "спецификация фичи".
---

# Feature Spec

Лёгкий SDD-скилл: Q&A с юзером по SDD-шаблону → план в чате → issue через `issue` скилл.

## Когда использовать

| Ситуация | Инструмент |
|----------|-----------|
| 1 файл, очевидное поведение | Прямой чат, без формальностей |
| 2+ компонента, бизнес-правила, diff >400 строк | `/feature-spec` |
| Новый проект с нуля | `/spec` (9 фаз) |

## ПРОТОКОЛ

### 1. Анализ

Юзер описывает фичу. Агент читает SDD-шаблон (ниже) и определяет, каких данных не хватает.

### 1.5. Поиск связанных компонентов

ДО Q&A — автоматический search по репо, чтобы найти связанные компоненты и дать вводные для 8-й SDD-секции.

- Запустить `explore` subagent с `rg` по репо.
- Найти: кто ссылается на изменяемый файл/функцию/формат/литерал/frontmatter key.
- Категории для поиска:
  - oracle-скрипты (`pipeline-status`, `spec-status`, `project-status`)
  - валидаторы (`create-issue`, `create-readme`)
  - агенты (`memory-syncer`, `reviewer`)
  - промпты (skills)
- Для каждого найденного компонента — отметить: как изменение повлияет, нужен ли paired update.
- Результат — вводные для 8-й секции SDD (`## Влияние на связанные компоненты`).
- Если связанных компонентов нет — явно отметить (explore search не нашёл).

### 2. Q&A

Агент задаёт вопросы списком — НЕ гадает. Пример:

```
Не хватает информации по:
1. Контракты: какой формат запроса/ответа? Какие коды ошибок?
2. Инварианты: какие лимиты? Какой TTL? Какая модель/библиотека?
3. Граничные случаи: что если внешний сервис недоступен? Что если данных нет?
4. Влияние на связанные компоненты: какие детерминированные связи (oracle-скрипты, валидаторы, парсеры, промпты-агенты) зависят от этого изменения? Что может сломаться если поменять X? Нужны ли paired updates в других файлах? (explore subagent уже нашёл candidates на шаге 1.5 — юзер подтверждает/дополняет)
5. Вне scope: что точно НЕ делаем в этой итерации?
```

Юзер отвечает. Если ответ неполный — агент уточняет. Q&A продолжается пока все 8 секций не заполнены.

### 3. План

Когда все данные собраны, агент выводит структурированный план:

```
## Контекст
Зачем: [мотивация]
Контекст: [текущее состояние]

## Задача
[Что делаем — архитектурный подход, пошагово]

## Контракты
[API, форматы, коды ошибок]

## Инварианты
[Правила без исключений: лимиты, ограничения, выбор технологий]

## Граничные случаи
[Что при ошибках: невалидный вход, отказ сервиса, превышение лимита]

## Влияние на связанные компоненты
[Файлы/оракулы/агенты/промпты/валидаторы, которые зависят от изменения; нужен ли paired update. Если нет — явно «нет связанных компонентов»]

## Вне scope
[Что НЕ делаем]

## Критерии приемки
- [ ] Сценарий 1: "пользователь делает X → видит Y"
- [ ] Сценарий 2
```

### 4. Handoff

После готовности плана:
- Агент: "План готов. Скажи 'создай issue' чтобы создать issue, потом запусти /run-pipeline."
- Юзер: "создай issue" → загружается `issue` скилл → `create-issue` tool (8 секций) → issue создан
- Юзер: `/run-pipeline` → реализация

## Правила

- **Не гадай** — если данных не хватает, задай вопрос
- **Будь конкретным** — не "используй кеш", а "Redis с TTL 7 дней"
- **Спека описывает ЧТО, не КАК** — контракты и решения, не алгоритмы
- **Каждый пункт 1-3 предложения** — если больше, это две задачи
- **Если фича простая** (1 файл, очевидное поведение) — скажи юзеру что спека не нужна
- **Не создавай issues сам** — только планируй. Issues через `issue` скилл по команде юзера
- **Не запускай /run-pipeline** — юзер делает это сам
- **Не создавай файлы** — план живёт в чате, потом в issue
- **1 issue = 1 PR** — если фича большая, предложи разбить на подзадачи

## SDD-шаблон (8 секций)

Совпадает с `create-issue` validation (PR #169, расширено в #249):

| # | Секция | Что содержит |
|---|--------|-------------|
| 1 | `## Контекст` | Зачем (мотивация) + текущее состояние |
| 2 | `## Задача` | Что делаем — пошагово, с путями к файлам |
| 3 | `## Контракты` | Ожидаемое поведение: API, форматы, коды ошибок |
| 4 | `## Инварианты` | Правила без исключений: лимиты, ограничения, технологии |
| 5 | `## Граничные случаи` | Что при ошибках: edge cases, отказы сервисов |
| 6 | `## Влияние на связанные компоненты` | Файлы/оракулы/агенты/промпты/валидаторы, зависящие от изменения; paired updates; «нет связанных компонентов» для тривиальных фич |
| 7 | `## Вне scope` | Что НЕ делаем в этой итерации |
| 8 | `## Критерии приемки` | Проверяемые сценарии: "X → видит Y" |

## Пример: кейс #238 (memory-syncer ↔ pipeline-status)

Реальный кейс, который мотивировал 8-ю секцию. PR #239 изменил `memory-syncer.md` (файл-ротация: пишет в `{repo}-002.md` при заморозке). `pipeline-status.py::check_memory()` читал только `{repo}.md` → не нашёл receipt → pipeline завис. Связь writer↔reader детерминированная, но feature-spec её не увидел.

Шаг 1.5 (explore subagent) нашёл бы:
- `pipeline-status.py::check_memory()` / `get_memory_file_path()` — читает `{repo}.md` для поиска `PR#N` receipt. Если memory-syncer пишет в `{repo}-002.md` → оракул не найдёт receipt → MEMORY фаза зависает. Нужен paired update: `get_memory_file_path()` должен сканировать `{repo}*.md` glob.
- `memory` skill — ссылается на формат memory-файлов, обновить примеры ротации.

8-я секция SDD для такой фичи:
```
## Влияние на связанные компоненты

- `pipeline-status.py:check_memory()` / `get_memory_file_path()` — читает `{repo}.md` для поиска `PR#N` receipt. Если memory-syncer пишет в `{repo}-002.md` → оракул не найдёт receipt → MEMORY фаза зависает. Нужен paired update: `get_memory_file_path()` должен сканировать `{repo}*.md` glob.
- `memory` skill — ссылается на формат memory-файлов, обновить примеры ротации.
```

Для тривиальной фичи (cosmetic README update):
```
## Влияние на связанные компоненты

Нет связанных компонентов (cosmetic README update).
```
