dev-workflow — правила разработки кода
Скилл применяется ко всем проектам Jared, где пишем код. Для продакт-задач (Notion, Jira, Confluence, тексты, оформление гипотез) не применяется — там работаем как раньше, без церемоний.
Core invariant — BL status transitions (ВСЕГДА)
Это правило выполняется на каждой задаче из бэклога, без исключений. Не часть pre-flight (тот про сессию целиком) — это про каждый BL отдельно.
При взятии BL в работу (перед первым изменением файла / Edit / Write / Bash-action, относящимся к задаче):
- Прочитать BL целиком (frontmatter + Context + DoD).
- Отметить
status: in_progressв frontmatter BL-файла. - Добавить (если нет)
claimed_by: <branch>@<HH:MM>иclaimed_at: <ISO>.
При закрытии BL (после того как DoD выполнен и изменения закоммичены):
- Отметить
status: done. - Добавить
closed: <YYYY-MM-DD>. - Заполнить секцию
## Doneили## Progressс итогом (что сделано, commits / PR).
Worktree caveat: если работаешь из .claude/worktrees/<name>/, 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
Адресует два класса повторяющихся проблем:
- 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). - Параллельные сессии + общий бэклог: Jared часто работает в 2-3
сессиях одновременно. Между ними меняется
private/backlog/и состояние веток. Если новая BL берётся без re-read'а — риск дублирующей работы или conflict'ов.
Когда запускать
| Момент | Branch audit | Backlog audit |
|---|---|---|
| Первое касание dev-репо в сессии | ✅ обязательно | ✅ обязательно |
| Между задачами в одной сессии (закрыл BL, иду за следующей) | ✅ обязательно | ✅ обязательно |
Перед merge / push / большой prep-командой (prepare, миграция) | ✅ обязательно | — |
| На каждое сообщение | ❌ нет | ❌ нет |
A) Branch audit
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: <name>, in sync with main.
B) Backlog audit
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/<name>/. Если
cwd — это worktree (см. git rev-parse --show-toplevel против
git worktree list), то ls private/ вернёт "No such file" — это не
значит, что BL'ов нет.
Правильное действие:
# Определить 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 занята сессией<branch>@<HH:MM>, не беру». - BL
status: in_progressсclaimed_at > 24h agoбез активности → возможен stale claim, спросить юзера сбросить ли.
C) Claim mechanism (при взятии новой BL)
Identity сессии: <current-branch>@<HH:MM>, например
feat/reclassify-imap-bl44@18:10. Простой формат, человекочитаемый.
Branch уникален per-worktree, время отличает разные сессии на одной
ветке.
Алгоритм взятия BL:
- Прочитать BL целиком (включая Plan, DoD, refs).
- Грепнуть
^claimed_by:в BL — если уже claimed другой сессией иclaimed_atсвежий → не брать, спросить юзера. - Если free — отредактировать frontmatter BL:
status: in_progress claimed_by: <branch-name>@<HH:MM> claimed_at: <ISO-datetime> - Если frontmatter ранее не содержал этих полей — добавить их.
- Только после этого начинать первое действие по задаче.
Алгоритм завершения BL:
status: in_progress → done.- Добавить
closed: <YYYY-MM-DD>. claimed_byоставить (полезно для истории/debug — кто закрыл).- Заполнить
## Progressитогом: что сделано, ссылки на commits / PR.
Worktree caveat при закрытии. Если работаешь из .claude/worktrees/<name>/,
файл 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 — проверить свежесть ветки и состояние бэклога.
Когда не запускать
- С