# Dev Workflow

> |

- **Type:** Skill
- **Install:** `agentstack add skill-ymuromcev-claude-dev-workflow-claude-dev-workflow`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [ymuromcev](https://agentstack.voostack.com/s/ymuromcev)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [ymuromcev](https://github.com/ymuromcev)
- **Source:** https://github.com/ymuromcev/claude-dev-workflow

## Install

```sh
agentstack add skill-ymuromcev-claude-dev-workflow-claude-dev-workflow
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# dev-workflow — правила разработки кода

Скилл применяется ко всем проектам Jared, где пишем код. Для продакт-задач
(Notion, Jira, Confluence, тексты, оформление гипотез) не применяется — там
работаем как раньше, без церемоний.

## Core invariant — BL status transitions (ВСЕГДА)

Это правило выполняется **на каждой задаче из бэклога**, без исключений. Не
часть pre-flight (тот про сессию целиком) — это про **каждый BL отдельно**.

**При взятии BL в работу** (перед первым изменением файла / Edit / Write /
Bash-action, относящимся к задаче):

1. Прочитать BL целиком (frontmatter + Context + DoD).
2. Отметить `status: in_progress` в frontmatter BL-файла.
3. Добавить (если нет) `claimed_by: @` и `claimed_at: `.

**При закрытии BL** (после того как DoD выполнен и изменения закоммичены):

1. Отметить `status: done`.
2. Добавить `closed: `.
3. Заполнить секцию `## Done` или `## Progress` с итогом (что сделано,
   commits / PR).

**Worktree caveat**: если работаешь из `.claude/worktrees//`, BL-файлы
живут в main checkout (`private/backlog/`). Используй `python3` или `sed`
через **Bash с absolute path** к main checkout — Edit/Write упадут из-за
worktree-path хука. Детали в секции «Алгоритм завершения BL» ниже.

**Failure mode**: если начал работу над BL без отметки `in_progress` —
**ты нарушил invariant**. Сразу остановись, проставь статус, продолжай.
Запрещено: «допишу статус в конце», «отмечу при закрытии». Транзишн
`planned/open → in_progress` происходит **до** первого изменения, не после.

Этот invariant обязателен потому что:
- Параллельные сессии без видимого `in_progress` приводят к дубликату работы.
- Закрытие BL без `done` — пропадает audit-trail, BL остаётся в `planned`
  навсегда.
- Эту дисциплину невозможно обеспечить hook'ом (нет надёжного триггера
  «начало работы по BL-N»), поэтому она в скилле как правило для LLM.

## Pre-flight (перед Шагом 0) — branch + backlog audit

Адресует два класса повторяющихся проблем:

1. **Stale-branch trap**: запуск команды со ветки, отстающей от `main`,
   даёт wrong результат → диагностируется как баг в коде → часы на
   ложный фикс. Реальный кейс 2026-05-17 в `ai-job-searcher`:
   `feat/reclassify-imap-bl44` отставала на 4 коммита (RFC 030), bridge-
   роли wrongly Weak'нулись (BL-67 / BL-68).
2. **Параллельные сессии + общий бэклог**: Jared часто работает в 2-3
   сессиях одновременно. Между ними меняется `private/backlog/` и
   состояние веток. Если новая BL берётся без re-read'а — риск
   дублирующей работы или conflict'ов.

### Когда запускать

| Момент | Branch audit | Backlog audit |
|---|---|---|
| Первое касание dev-репо в сессии | ✅ обязательно | ✅ обязательно |
| Между задачами в одной сессии (закрыл BL, иду за следующей) | ✅ обязательно | ✅ обязательно |
| Перед merge / push / большой prep-командой (`prepare`, миграция) | ✅ обязательно | — |
| На каждое сообщение | ❌ нет | ❌ нет |

### A) Branch audit

```bash
git rev-parse --abbrev-ref HEAD                   # current branch
git status -sb                                     # tree state + ahead/behind tracking
git fetch origin main --quiet
git rev-list --count HEAD..origin/main             # # of commits behind main
git log --oneline HEAD..origin/main | head -10     # what's in those commits
git worktree list                                   # other active worktrees
gh pr list --state open --json number,title,headRefName,baseRefName 2>/dev/null
```

**Когда докладывать юзеру (обязательный отчёт)**:

- Ветка отстаёт от `main` на >0 коммитов → одно сообщение: какая ветка,
  на сколько, **что в недостающих коммитах** (короткими описаниями), и
  предложить путь (merge main / rebase / switch to main). Не начинать
  основную работу до согласования стратегии.
- Working tree содержит правки в файлах, которые меняет open PR →
  упомянуть возможный дубликат работы.
- Несколько активных worktree'ев → перечислить.
- Всё чисто, ветка up-to-date → одной строкой `branch: ,
  in sync with main`.

### B) Backlog audit

```bash
ls -lt private/backlog/*.md | head -15                              # what changed recently
grep -l "^status: in_progress" private/backlog/*.md 2>/dev/null      # active claims
grep -A1 "^status: in_progress" private/backlog/*.md 2>/dev/null     # who claimed
```

**Worktree caveat (важно).** `private/` gitignored — он живёт **только в
main checkout**, не реплицируется в `.claude/worktrees//`. Если
cwd — это worktree (см. `git rev-parse --show-toplevel` против
`git worktree list`), то `ls private/` вернёт "No such file" — это **не**
значит, что BL'ов нет.

Правильное действие:

```bash
# Определить main checkout (первая строка `git worktree list` — main)
MAIN=$(git worktree list | head -1 | awk '{print $1}')
ls -lt "$MAIN"/private/backlog/*.md | head -15
grep -l "^status: in_progress" "$MAIN"/private/backlog/*.md 2>/dev/null
```

Или гонять команды из main checkout напрямую через absolute path. Тот же
caveat применяется к **закрытию BL** — см. «Алгоритм завершения BL» ниже.

**Когда докладывать юзеру**:

- BL'ы изменены за последние ~60 минут не моей сессией → перечислить
  (другая сессия что-то сделала — стоит понять что, прежде чем
  планировать).
- BL `status: in_progress` с `claimed_by != моя сессия` → flag в отчёте:
  «BL-X занята сессией `@`, не беру».
- BL `status: in_progress` с `claimed_at > 24h ago` без активности →
  возможен stale claim, спросить юзера сбросить ли.

### C) Claim mechanism (при взятии новой BL)

**Identity сессии**: `@`, например
`feat/reclassify-imap-bl44@18:10`. Простой формат, человекочитаемый.
Branch уникален per-worktree, время отличает разные сессии на одной
ветке.

**Алгоритм взятия BL**:

1. Прочитать BL целиком (включая Plan, DoD, refs).
2. Грепнуть `^claimed_by:` в BL — если уже claimed другой сессией и
   `claimed_at` свежий → не брать, спросить юзера.
3. Если free — отредактировать frontmatter BL:
   ```yaml
   status: in_progress
   claimed_by: @
   claimed_at: 
   ```
4. Если frontmatter ранее не содержал этих полей — добавить их.
5. Только после этого начинать первое действие по задаче.

**Алгоритм завершения BL**:

1. `status: in_progress → done`.
2. Добавить `closed: `.
3. `claimed_by` оставить (полезно для истории/debug — кто закрыл).
4. Заполнить `## Progress` итогом: что сделано, ссылки на commits / PR.

**Worktree caveat при закрытии.** Если работаешь из `.claude/worktrees//`,
файл `private/backlog/BL-NN.md` физически лежит в main checkout, не в
worktree. Поэтому:

- Edit/Write по worktree-relative пути либо упадёт с "file not found",
  либо (если хук `check_worktree_path.sh` настроен) заблокируется при
  попытке Edit'ить absolute path в main.
- Делать через **`Bash` с absolute path**: `sed -i ''` для замены статуса /
  `cat >> "$MAIN/private/backlog/BL-NN.md"` для дописки Progress.
  Хук не трогает Bash, а файл gitignored — это не часть PR, обычное
  housekeeping.
- Альтернатива — переключить cwd в main checkout, но обычно избыточно
  ради одного файла.

Не пропускать закрытие, увидев "no private/" в worktree — это **гарантированная**
ошибка, а не отсутствие BL.

**Если задача abandon'ится посреди работы**:

- `status: in_progress → open`.
- Удалить `claimed_by` и `claimed_at` (либо переписать в `last_claimed_by`
  если хочется audit-trail).
- Дописать в `## Progress`: почему abandon, что успели.

### Анти-паттерны

- Молча начать работу с непроверенной ветки.
- Взять BL без claim → другие параллельные сессии не увидят что она
  занята → дубликат работы.
- Между задачами полагаться на in-memory кэш бэклога. Между BL'ами
  re-read обязателен, особенно если сессия идёт >1 часа.
- При неожиданном результате (`prepare wrong`, `test fails по
  необъяснимой причине`, «фича не работает хотя точно сделана») первая
  мысль — диагностировать код. Должно быть наоборот: **first thought —
  проверить свежесть ветки и состояние бэклога**.

### Когда не запускать

- Сессия про продакт-задачу (Notion, Jira, тексты, гипотезы) — dev-workflow
  не применяется в принципе.
- Папка без `.git/` — branch audit пропускается, backlog audit остаётся
  если есть `private/backlog/`.
- Чисто read-only лукапы по коду — необязательно, но желательно при
  первом обращении к репо в сессии.

### Cost

~10 команд, ~3 секунды, ~500 токенов. Окупается одним предотвращённым
phantom-багом или одним предотвращённым дубликатом работы между
сессиями.

## Шаг 0 — классификация

В начале задачи Claude определяет тир. Если неочевидно — называет предполагаемый
тир и спрашивает пользователя, согласен ли он.

| Тир | Триггер | Процесс |
|---|---|---|
| **XS** | 7) — пускаются волнами, чтобы не топить контекст PM.
- Если стоимость токенов критична — PM явно предупреждает: «4 агента
  фоном — примерно в N раз дороже последовательного режима, но
  быстрее. Идём?». Решает пользователь.

### Чего PM-Claude НЕ делегирует

Чтобы режим не выродился в «Claude нажимает кнопки», PM сохраняет
ownership на:

- **Образ результата всей задачи.** Юниты — это раздробленный продукт,
  но продукт всё ещё в голове PM.
- **Декомпозицию и интерфейсные контракты.** Архитектура и границы
  юнитов — это PM, не агенты.
- **Финальную интеграцию и DOD-проверку.** Сборка, кросс-юнитный
  smoke, ревью собранного диффа.
- **Решение «параллелим или нет».** Гейт остаётся явным.
- **Коммуникацию с пользователем.** Агенты не пишут пользователю
  напрямую — всё через PM.

Агенты — это руки. Голова и продукт — PM.

### Антипаттерны

- **«Распараллелим всё».** Если юниты не независимы — overhead съест
  выигрыш. PM обязан честно говорить «не разлепляется».
- **«PM пишет код сам, потому что агент тупит».** Это нарушение роли.
  Либо переоткрытие юнита, либо честный возврат к последовательному
  режиму. Микс ломает ответственность.
- **«Контракт согласован агентами между собой».** Никогда. Контракт —
  только PM. Если агенты «договариваются» — это значит, PM забыл
  зафиксировать формат, и юниты разъедутся.
- **«Запустили и забыли».** PM обязан проверить каждый возвращённый
  юнит против его «что увидит пользователь», не просто принять «done»
  от агента.

## Шаг 1 — RFC (только M/L)

Короткий дизайн-док в `PROJECT/rfc/NNN-title.md` ДО кода.

```markdown
## Проблема
Что не работает / чего не хватает. 1–2 предложения.

## Варианты
- A: ...
- B: ...

## Выбрано + почему
Вариант X, потому что ...

## Identity & PII (обязательно, если фича касается user data)
- ID: формат, источник random (criteria по `feedback_pii_random_ids.md`).
- PII-поля: что считается PII, как помечены в schema (`pii_class`).
- Хранение: где живут (gitignored / encrypted), как gitnoring устроен.
- Логирование: что НЕ должно попасть в логи; redaction policy.
- Удаление: hard delete возможен? Как реализуется right-to-be-forgotten?
- Multi-user-ready: всё ли scope'ится по profile? Что меняется при SaaS-пивоте?
- Если фича не работает с user data — пишем «N/A — фича не касается user data».

## Риски / что может сломаться
- ...

## План проверки
Как поймём, что работает (тесты, ручной сценарий, метрика).
```

Claude пишет RFC и ЖДЁТ явного approve от пользователя перед кодом.
Для XS — RFC не нужен.

**Identity & PII секция в RFC обязательна для всех M/L фич.** Даже если
ответ «N/A» — это явное решение, зафиксированное. Полные правила —
в `~/.claude/skills/scaffold-project/SKILL.md` секция «Identity & PII
rules», или в memory `feedback_pii_random_ids.md`.

## Шаг 2 — код + тесты

**Стек тестов**:

| Язык | Фреймворк | Запуск |
|---|---|---|
| JavaScript / Node | `node --test` (встроено в Node 20+) | `node --test` в корне проекта |
| Python | `pytest` | `pip install pytest && pytest` |

Файлы тестов лежат рядом с кодом: `parser.js` → `parser.test.js`,
`loader.py` → `test_loader.py`.

**Testing pyramid**:
- **Юнит** — чистая логика без сети/диска. Пишем много.
- **Интеграционные** — внешние API (MCP, Superset, Jira, Notion). **Моки сети, не реальные запросы** — иначе флак и квоты.
- **E2E / ручная** — только для критичных прод-сценариев. Описываем чеклистом в RFC, не автоматизируем преждевременно.

**Smoke-тест обязателен даже для XS** — один простейший тест, доказывающий,
что основная функция вызывается, не падает, возвращает ожидаемый тип.
Ловит 80% поломок рефакторинга за 2 минуты работы.

## Шаг 3 — линтеры (только где есть нетривиальный код)

Ставим по мере необходимости, локально в подпроект.

| Язык | Инструмент | Конфиг |
|---|---|---|
| JavaScript | `prettier` + `eslint` (`@eslint/js recommended`) | минимальный, zero-config |
| Python | `ruff` (lint + format в одном) | zero-config |

Для bash-скриптов и одноразовых утилит — проверяем глазами, линтер не нужен.

## Шаг 4 — pre-commit hook

Появляется только когда в подпроекте есть тесты или линтеры. До этого —
живём без хука.

Когда будет что гонять:
1. Скрипт в `.githooks/pre-commit` (коммитим в репо, чтобы пережил сессии).
2. `git config core.hooksPath .githooks` локально.
3. Первая версия — **warning-only**: прогоняет тесты + линтер для изменённых
   файлов, печатает результат, НЕ блокирует коммит. Когда привыкнем —
   переключаем в блокирующий режим.

Отдельно: **секрет-guard pre-commit hook** добавляем при подготовке к
публикации в паблик-репо — блокирует Notion tokens, Google OAuth secrets,
private keys, AWS keys, имя/email автора.

## Шаг 5 — мульти-агентное ревью

### Тир M
После кода — субагент (`general-purpose` с фокус-промптом) получает diff.
Фокус:
- Читаемость и именование.
- Edge cases, которые могли забыть.
- Простота — нет over-engineering, абстракций «на вырост».
- Соответствие DOD.
- Secrets / hardcoded credentials.

Критичные findings Claude исправляет сам. Остальное — summary пользователю.

### Тир L
Дополнительно:
- **`/security-review`** — уязвимости (injection, XSS, утечки, auth),
  секреты, небезопасные дефолты.
- **`/review`** — общий PR-review с точки зрения качества изменений.
- Для публичных фич — UX edge cases (пустые состояния, ошибки, обрывы сети).

### Финальный approve — всегда у пользователя
Claude **не коммитит код без ok** (для M/L). Для XS — показывает diff и
коммитит, если пользователь заранее дал зелёный свет.

### Commit и push — атомарно (2026-05-17)
После каждого `git commit` Claude **сразу же** делает `git push` без
отдельного вопроса. Локальное состояние и GitHub синхронизируются
автоматически. См. правило в проектном `CLAUDE.md` → раздел «Git push».

Исключения (НЕ пушим автоматически):
- pre-commit hook упал или тесты красные → сначала фиксим;
- коммит в WIP-состоянии (явно отмечен как промежуточный);
- force push в чужую ветку или `main`/`master` → требует явного approve.

Если ветки нет в origin — `git push -u origin ` (set upstream)
автоматически.

## Шаг 6 — уровни безопасности (S1/S2/S3)

Безопасность масштабируется инкрементально.

| Уровень | Триггер | Что подключаем |
|---|---|---|
| **S1 — базовый** | локальные скрипты, MCP, личные тулы | `/security-review` для L-тира, secret-detection в code-review, `npm audit` / `pip-audit` перед коммитом новых зависимостей, «секреты не в репо» |
| **S2 — pre-prod** | SaaS готов к внешнему доступу, появился auth / БД с данными | threat modeling в RFC для фич с auth + данными, SAST (`semgrep`), OWASP Top 10 чеклист, проверка secrets в CI, auto dependency scanning |
| **S3 — prod с пользователями** | публичный SaaS, реальные пользователи | **pentest-агент** против staging, регулярные прогоны перед релизом, внешний аудит перед платными клиентами / чужими данными / платежами |

**Дефолт по репо — S1.** Переход на S2 — когда появляется первый подпроект
с auth или публичным URL.

### Pentest-агент (S3, план на будущее)
Запускается против staging-инстанса (не против кода, не против prod).
Процесс: subagent получает URL + тестовые креды + HTTP/browser тулы → идёт
по OWASP Top 10 чеклисту (auth bypass, injection, XSS, IDOR, CSRF, SSRF,
rate limiting, secrets exposure, broken access control) → каждую попытку
логирует `payload → response → classification` → возвращает отчёт по severity.
**Critical/high — блокеры релиза. Medium/low — в бэклог с дедлайном.**

НЕ заменяет: внешний профпентест перед платным продуктом, bug bount

…

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [ymuromcev](https://github.com/ymuromcev)
- **Source:** [ymuromcev/claude-dev-workflow](https://github.com/ymuromcev/claude-dev-workflow)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** yes
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-ymuromcev-claude-dev-workflow-claude-dev-workflow
- Seller: https://agentstack.voostack.com/s/ymuromcev
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
