# Pipeline

> Дисциплинированный пайплайн разработки проекта по стадиям 0–10 — context load → idea → plan + criteria → risk spikes → contracts → vertical slice → tasks → implementation → audit → feedback → release. Используй, когда пользователь начинает новый проект, говорит "запусти пайплайн", "по нашему процессу", "следующая стадия", или когда в проекте есть docs/pipeline/state.md и надо продолжить работу.

- Skill: `magerko/pipeline` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add magerko/pipeline`
- Raw SKILL.md: https://api.skillmd.com/api/skills/magerko/pipeline/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: DevOps & Infra
- Author: Magerko (https://skillmd.com/u/magerko)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/magerko/pipeline

---


# Pipeline: проект от идеи до выката

Сегодня: !`date +%F`. **Все даты в артефактах берёшь отсюда**, а не по памяти —
своей текущей даты ты не знаешь.

Одиннадцать стадий с **жёсткими воротами** между ними. Ты ведёшь пользователя по стадиям,
материализуя каждую в файл. Файлы — единственный источник правды: контекст сессии
умирает, `docs/pipeline/` живёт.

```
0. context load    — project brief подгружается, не пересказывается
1. idea            — что и зачем, в 3–5 предложениях
2. plan + criteria — шаги + явное «готово = ...»
3. risk spikes     — только реально неизвестное, код на выброс
4. contracts       — модели, сигнатуры, схемы ответов, формат ошибок
5. vertical slice  — один сквозной путь end-to-end
6. tasks           — атомарные, у каждой свой критерий готовности
7. implementation  — по одной задаче за сессию
8. audit           — в свежем контексте: тесты + ручные проверки
9. feedback        — находки аудита → обратно в brief + decision log
10. release        — выкат: пред-запусковые проверки, доступы, бэкапы, откат
```

Стадии 0–9 — цикл разработки, он повторяется. Стадия 10 проходится не каждый круг,
а перед реальной публикацией.

## Артефакты

Всё в `docs/pipeline/` в корне проекта:

| Файл | Стадия | Природа |
|---|---|---|
| `state.md` | все | текущая стадия + статус ворот. Обновляй **каждый** раз |
| `brief.md` | 1, 5, 9 | живой документ: что строим, зачем, ограничения, стек, как запускать |
| `plan.md` | 2 | шаги + acceptance criteria (проверяемые) |
| `spikes/` | 3 | код на выброс + `spikes/FINDINGS.md` с ответами |
| `contracts.md` | 4 | модели данных, сигнатуры, схемы, конфиг, ошибки |
| `tasks.md` | 6 | атомарные задачи с DoD-чекбоксами |
| `audit.md` | 8 | отчёт аудита свежим контекстом |
| `decisions.md` | 9 (append) | лог решений: дата, решение, альтернативы, почему |
| `release.md` | 10 | что выкачено, куда, чем проверено, как откатить |

Шаблоны — в `references/templates.md`. Детали по стадиям — в `references/stages.md`.
Читай нужный раздел `stages.md` **перед** началом стадии, а не по памяти.

## Правило ворот (нарушать нельзя)

В конце каждой стадии:
1. Запиши артефакт на диск.
2. Обнови `state.md`.
3. Покажи **сжатую** сводку: суть + что решили. Не пересказ файла.
4. Задай явный вопрос про переход и **остановись**. Следующую стадию не начинаешь,
   пока пользователь не сказал «да / дальше / поехали».

Исключение: пользователь явно сказал «не спрашивай, гони до конца». Тогда идёшь подряд,
но артефакты всё равно пишешь и в конце показываешь их список.

## Правило нулевой стадии

`brief.md` **подгружается, не пересказывается.** Прочитал — работай с этим знанием молча.
Пересказ brief пользователю запрещён: он его писал. Максимум — одна строка
«brief загружен: <проект>, стадия N, следующая задача T-xx».

## Старт сессии

1. Есть `docs/pipeline/state.md`? → стадия 0: прочитай `brief.md`, `state.md`, и артефакт
   текущей стадии. Одна строка подтверждения → продолжай с зафиксированной стадии.
2. Нет? → новый проект: создай `docs/pipeline/`, разведай окружение (стадия 0),
   переходи к стадии 1.
3. Пользователь назвал стадию явно («давай контракты») — прыгай туда, но сначала
   прочитай артефакты предыдущих стадий. Не выдумывай контекст, которого не читал.

## Проект, где код уже есть (brownfield)

Пайплайн написан под чистый лист. В существующем проекте стадии те же, но три из них
работают наоборот — не проектируешь, а **извлекаешь**:

- **1 idea.** Brief пишется по факту: что система делает **сейчас**, и отдельным разделом —
  что мы хотим изменить. Не переписывай замысел автора, ты его не знаешь.
- **4 contracts.** Контракты вычитываются из кода: реальные сигнатуры, реальные модели,
  реальный формат конфига. Расхождение «как написано» и «как задумано» — находка,
  её в `decisions.md`, а не молчаливое «исправление».
- **5 vertical slice.** Слайс уже существует. Вместо написания — **запусти** имеющийся
  сквозной путь и покажи вывод. Не запускается — это первая задача, а не повод идти дальше.

Скоуп при этом сужается до изменения: пайплайн ведём по той части системы, которую трогаем,
а не по всему репозиторию. Полная инвентаризация чужого кода — отдельная работа,
и её не делают «заодно».

## Стадии (кратко; развёрнуто — в references/stages.md)

**0. Context load.** Повторная сессия: подгрузить brief + state молча. Новый проект:
разведка инструментами — что в репо, версии рантаймов, git/CI/тесты, ОС-специфика.
Не спрашивай пользователя о том, что можешь проверить сам.

**1. Idea → brief.md.** Вытащи суть вопросами пачкой (AskUserQuestion, не по одному).
Кто пользователь, какую боль решаем, что считается успехом, что явно вне скоупа,
жёсткие ограничения. Итог — 3–5 предложений, подтверждённых пользователем, плюс
изученные внешние зависимости (доки, лицензии, ToS). Кладётся в `brief.md`.

**2. Plan + criteria → plan.md.** 3–7 крупных шагов. К каждому — «готово = ...»
в форме «дано → когда → тогда». Критерий проверяй вопросом «как я проверю это,
не спрашивая мнения?». Нет ответа — переписывай. Отдельно — non-goals.

**3. Risk spikes → spikes/.** Только то, чего мы не знаем и что может обрушить план.
Один спайк — один вопрос да/нет + факты. Код в `spikes/` **на выброс**: не рефачить,
прод-код его не импортирует. Ответы — в `spikes/FINDINGS.md`. Спайк убил допущение —
возврат на стадию 2, это успех спайка, а не провал.

**4. Contracts → contracts.md.** Модели данных, публичные сигнатуры, схемы хранения
и ответов, формат конфига, таксономия ошибок. Пиши как код, не прозой. Реализации нет —
только формы. Проверка: по контрактам можно написать заглушки, и они состыкуются типами.
Здесь же — **секреты и окружение**: какие ключи нужны, откуда берутся, что лежит
в `.env.example`, что закрыто `.gitignore`. Ни один секрет в контракт не вписывается
значением, только именем переменной.

**5. Vertical slice.** Один сквозной путь: вход → обработка → выход, реально работающий.
Самый узкий из возможных, всё постороннее захардкожено. Реальные зависимости, не моки.
**Запусти и покажи вывод.** Стадия не закрыта, пока слайс не отработал вживую.
Сработало — сразу впиши в `brief.md` раздел «Как запускать» теми командами, которые
только что отработали. Дальше по ним работают и будущие сессии, и аудитор на стадии 8.

**6. Tasks → tasks.md.** Атомарные: одна задача по объёму = один осмысленный коммит.
У каждой — файлы, что делаем, DoD, зависимости. Порядок в файле = порядок выполнения.

**7. Implementation.** **По одной задаче за сессию.** Сделал → проверил DoD фактически
(запуск/тест, не «выглядит правильно») → отметил `[x]` → отчёт в 1–3 строки → остановился
и спросил. Задача разрослась — стоп, дроби в `tasks.md`, потом делай.

**Правило трёх попыток.** DoD не сходится после трёх заходов — прекрати чинить.
Это не задача не решается, это задача поставлена неверно: не хватает знания (→ спайк,
стадия 3), неверен контракт (→ стадия 4) или DoD непроверяем (→ стадия 6). Доложи
пользователю, что перепробовал и какой из трёх случаев видишь. Четвёртая попытка тем же
способом — самый дорогой способ потратить сессию.

**8. Audit → audit.md.** Субагент (Agent, `general-purpose`) со свежим контекстом.
Он не видел, как писался код, — в этом смысл. Проверяет acceptance criteria **запуском**:
тесты + ручные проверки. Промпт — по шаблону из `references/stages.md`. Сам аудит не проводишь.

**9. Feedback.** Находки аудита → обратно в `brief.md` (привести к тому, что построено)
и в `decisions.md` (append-only, абсолютные даты). Оставшиеся дефекты — задачами в `tasks.md`.
Следующий проход начинается со стадии 7, а не с 1.

**10. Release → release.md.** Только если проект реально куда-то выкатывается. Аудит
проверял, что код делает обещанное; выкат проверяет, что он **переживёт встречу
с внешним миром**: секреты, доступы, лимиты, бэкапы, откат.
Прогоняется отдельными скиллами, а не по памяти: `/launch-security` для любого
приложения с сервером или чужими данными, `/launch-web` для публичного сайта.
Их отчёты ложатся в `docs/launch/`, находки P1 идут задачами в `tasks.md` и чинятся
до выката, остальное — в бэклог. В `release.md` фиксируешь: что выкачено, куда, какой
версией/коммитом, чем проверено после выката, как откатить и у кого доступы.
Скиллы `/launch-*` **вызывает пользователь** — сам ты их не запускаешь, скажи одной
строкой, что пора.

## Роутинг: кто выполняет стадию

Модель главного цикла переключить изнутри нельзя — её задаёт пользователь через `/model`.
Поэтому роутинг устроен так: **мышление остаётся в главном цикле, рутина уходит
субагентам, у которых модель прибита в их определении.** Имена моделей живут там,
а не здесь: скилл говорит про роли и переживает смену поколений моделей.

| Стадия | Кто выполняет | Почему |
|---|---|---|
| 0 context load | главный цикл | дёшево, пара команд |
| 1 idea | главный цикл | диалог с пользователем, делегировать нечего |
| 2 plan + criteria | главный цикл, сильная модель | здесь решается судьба проекта |
| 3 risk spikes | субагент `pipeline-spike` | замкнутая механика: скрипт → запуск → факты |
| 4 contracts | главный цикл, сильная модель | архитектура; ошибка тут стоит дороже всего |
| 5 vertical slice | главный цикл | проверяем контракты собой, не чужими руками |
| 6 tasks | главный цикл | разбиение требует всей картины |
| 7 implementation | по типу задачи, см. ниже | |
| 8 audit | субагент `pipeline-auditor` | нужен свежий контекст, а не дешёвая модель |
| 9 feedback | главный цикл | |
| 10 release | главный цикл + скиллы `/launch-*` | проверки вызывает пользователь |

**Стадия 7 — исполнитель задачи решается на стадии 6, не на бегу.** У каждой задачи
в `tasks.md` проставляй поле `Исполнитель:`:

- `субагент` — рутина: boilerplate, тесты по готовому контракту, CLI-обвязка, парсинг
  по описанной схеме, механические правки. Отдаёшь субагенту `pipeline-task`.
- `главный цикл` — задача трогает архитектуру, требует решений или диалога с пользователем.
  Делаешь сам. **Если сомневаешься — главный цикл**: делегирование не бесплатно,
  субагент заново поднимает контекст, и на неоднозначной задаче это дороже, чем сделать самому.

Что сказать пользователю про его сторону: на стадиях 2 и 4 держать самую сильную доступную
модель, на 7 при пачке рутины — можно переключиться на быструю. Актуальные имена он видит
в `/model`, там же есть комбинированные режимы «планирование сильной, исполнение быстрой».
Говори это **один раз на воротах** нужной стадии, не напоминай каждое сообщение.

## Стиль кода — действует на всех стадиях

### Комментарии

Комментарий объясняет **почему**, а не **что**. Что делает код — видно из кода.

Пиши комментарий, только если он несёт знание, которого в коде нет:
- неочевидное внешнее ограничение («у OLX `private_business` возвращает 200 и молча
  не фильтрует — рабочий параметр `owner_type`»)
- причина обходного пути и что сломается без него
- откуда взялось магическое значение (ссылка на спайк, тикет, замер)
- намеренный отказ от очевидного решения и его причина

**Не пиши никогда:**
```python
# Увеличиваем счётчик на единицу
counter += 1

# Функция для получения объявлений
def get_listings(...):

# ---------- ХЕЛПЕРЫ ----------
```
Это шум: он повторяет код, устаревает первым и приучает не читать сам код.
Докстринги — только там, где неочевидны контракт, единицы измерения или побочные эффекты.
Тривиальной функции докстринг не нужен. **Докстринг, пересказывающий имя функции
(`"""Сколько спать до следующего опроса"""` над `seconds_until_next`), — чистый шум.**

**Измеримые ориентиры** (словесного «подгоняй под окружающий код» на практике не хватает):

- Комментариев в файле — примерно **5–8% от строк кода**. Выше 12% — почти наверняка
  объяснение самого себя, а не кода.
- **Над одиночным вызовом — не больше одной строки комментария.** Три строки обоснования
  над одной строкой кода — это сообщение коммита, а не комментарий.
- Разброс плотности между файлами одного проекта — признак поломки. Если в одном модуле
  25%, а в другом 3%, значит, комментировался ход мыслей: гуще там, где дольше думал.

Проверяй себя вопросом: **«это знание или мой мыслительный процесс?»** Про чужой API,
про грабли, про причину неочевидного выбора — знание, оставляй. Про то, как ты пришёл
к решению, — процесс, выкидывай.

**Не объясняй отсутствие.** «Справочники сюда не входят», «здесь намеренно нет ретрая» —
бесконечный жанр: к любой строке можно дописать, чего в ней нет. Комментируй то, что
есть. Исключение — если отсутствие выглядит как забытое и кто-то полезет «чинить».

**Не пересказывай общеизвестное.** «Зависимости отдельным слоем, чтобы не пересобирались»
в Dockerfile, «индекс ускоряет выборку» у CREATE INDEX — это знает всякий, кто читает
такой файл. Правило действует и вне кода: YAML, Dockerfile, конфиги — там та же норма.

В файле без комментариев не начинай их расставлять.

### Git

- **Не указывай себя в авторах или контрибьюторах.** Никаких `Co-Authored-By`,
  `Generated with`, упоминаний модели в теле коммита или PR. Автор — пользователь.
- Сообщение коммита — о сути изменения, в стиле, уже принятом в репозитории
  (посмотри `git log`, прежде чем писать первый коммит).
- **Коммитишь и пушишь только по явной просьбе.** «Одна задача = один коммит» из стадии 6 —
  это мера **размера** задачи, а не разрешение коммитить самому: задача должна быть такой,
  чтобы её изменения складывались в один осмысленный коммит.
- Закрыв задачу на стадии 7, в отчёте одной строкой предложи готовое сообщение коммита.
  Пользователь коммитит сам или говорит «коммить». Молчание — не согласие.
- Перед первым коммитом проверь, что в индекс не попали `.env`, ключи, дампы и мусор
  сборки. Секрет, попавший в историю, чистится ротацией ключа, а не `git rm`.

## Как себя вести внутри стадии

- **Не забегай вперёд.** На контрактах не пиши реализацию, на плане не пиши контракты.
  Самая частая поломка пайплайна — «я тут заодно уже накидал».
- **Не выдумывай факты.** Не знаешь, как ведёт себя внешний сервис или библиотека —
  это спайк (стадия 3) или веб-поиск, а не догадка в brief.
- **Решения фиксируй сразу** черновой строкой, на стадии 9 соберёшь в `decisions.md`.
- **Артефакты — на языке пользователя**, код и идентификаторы — по-английски.

