Files
portal/docs/superpowers/specs/2026-05-18-parallel-sessions-coordination-design.md
T
Дмитрий 235b1d4e8c docs(superpowers): parallel sessions coordination — design spec
Brainstorm (экономия 5%) с Дмитрием: лечим два класса инцидентов параллельных сессий —
(A) субагенты теряются между worktree (Sprint 6 паттерн);
(B) нормативка/MEMORY дрейфует (Tooling v2.11 collision 17.05.2026).

Решение из 4 артефактов, 0 новых плагинов/MCP:
1. Pravila §15 (новое hard-rule): §15.1 субагенты+git (Sonnet/Opus only),
   §15.2 нормативка+pre-flight sync (фиксированный список 8 файлов).
2. docs/sessions/CURRENT.md — заявочный лог активных сессий + claim/check/release.
3. .claude/hooks/subagent-prompt-prefix.mjs — PreToolUse-хук, инжектит cwd/branch/HEAD заголовок в каждый Task-prompt.
4. Verify-протокол в скиле subagent-driven-development — pre/post-subagent чеклист
   + обязательный GIT REPORT блок от субагента.

Acceptance в §8 spec'а. Spec — черновик → ревью заказчика → writing-plans.

+cspell-words: коммитит / инвокейшн / парсимый (валидные транслитерации).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 09:40:10 +03:00

23 KiB
Raw Blame History

Параллельные сессии: координация — дизайн

Дата: 2026-05-18 Автор: Claude (Opus 4.7, brainstorming с Дмитрием, экономия 5%) Статус: черновик → ревью заказчика → writing-plans Связано: Pravila §12 / §14 (hard rules), memory feedback_subagent_git_reliability.md, Sprint 6 инцидент.


0. Контекст и проблема

При параллельной работе нескольких Claude-сессий на одном репозитории — что является ежедневной нормой проекта (на 18.05.2026 в git worktree list 16 активных worktrees) — наблюдаются два класса инцидентов:

Класс A — субагенты теряются между worktree. Запущенный из контроллера субагент (особенно Haiku) путает рабочую директорию или ветку: коммитит в чужую ветку, делает orphan-коммит, не возвращает git-state в отчёте. Прецедент — Sprint 6: Haiku-субагенты угнали ветку параллельной сессии, инцидент устранён через git reflog + reset. Корневая причина — контроллер не верифицирует HEAD/branch после Task-инвокации.

Класс B — нормативка/MEMORY дрейфует. Параллельные сессии правят один и тот же набор файлов (Pravila / CLAUDE.md / Tooling / PSR_v1 / MEMORY.md / Открытые_вопросы_*.md) и претендуют на один version-номер. Прецедент — 17.05.2026: ADR-006 D4 и C10 одновременно претендовали на Tooling v2.11, C10 пришлось переномеровать в v2.12 (видно в шапке CLAUDE.md). За неделю 18.05.2026 разделы A11/A3/A4/A6/C9/C10/discovery-interview — все 7 — трогали один набор из 4 нормативных файлов.

Обе проблемы — следствие одного: параллельность без явного контракта на scope.

1. Архитектура

Решение из 4 артефактов, без новых плагинов / MCP-серверов:

  1. Pravila §15 (новое hard-rule) — два пункта: §15.1 (субагенты + git), §15.2 (нормативка + pre-flight sync). Hard-rule = §9 «Отступления» не применяется (как §12 и §14).
  2. docs/sessions/CURRENT.md — заявочный лог активных параллельных сессий.
  3. .claude/hooks/subagent-prompt-prefix.mjs — PreToolUse-хук, инжектящий в каждый Task-prompt заголовок git-safety.
  4. Verify-протокол в скиле superpowers:subagent-driven-development — pre-spawn + post-subagent чеклист контроллера.

Зависимости: артефакт 1 (Pravila §15) — корень всех правил; артефакты 2–4 ссылаются на §15.1 / §15.2 как enforcement floor.

2. Pravila §15 — текст обоих пунктов

§15.1 Субагенты + git

Git-коммит-задачи субагенту (любой Task-инвокейшн, чей prompt содержит git commit, git push, git stage, git checkout, git switch, git merge, git rebase, либо где явно ожидается коммит в результате) — только модель Sonnet или Opus, никогда Haiku. Контроллер, делегирующий git-операцию Haiku-субагенту — нарушение §15.1, фиксируется в feedback того же уровня, что §12.

Исключение — read-only git-операции (git log, git status, git diff, git rev-parse, git branch --show-current, git worktree list) — разрешены любой модели.

§15.2 Нормативные правки + pre-flight sync

Любая правка файлов из списка «нормативка» (см. ниже) выполняется только на актуальной базе origin/main. Pre-flight обязателен: git fetch origin && git log HEAD..origin/main --oneline — если есть untracked commits на origin/main, ребейз/merge до начала правки, не после.

Параллельная нормативная правка на устаревшей базе — нарушение §15.2. Признак нарушения: коммит правит файл, чья последняя версия на origin/main новее, чем версия в parent коммите правки.

Список «нормативка» — 8 позиций:

  1. docs/Pravila_raboty_Claude_v1_1.md
  2. CLAUDE.md
  3. docs/Tooling_v8_3.md
  4. docs/Plugin_stack_rules_v1.md
  5. memory/MEMORY.md (и все memory/*.md)
  6. docs/Открытые_вопросы_v8_3.md
  7. docs/adr/*.md (glob — collision на ADR-NNN номере = тот же класс, что version-bump нормативки)
  8. db/schema.sql (параллельные миграции из разных сессий = реальный риск; запись в db/CHANGELOG_schema.md сама не защищает от version-base дрейфа)

Расширение списка — отдельная правка §15.2, не «по ощущениям».

§15.3 Cross-refs в других файлах

  • CLAUDE.md §1 priority chain — упомянуть §15 рядом с §12 и §14 как hard-rules (footer-абзац после цепочки).
  • PSR_v1 — не правится (§15 не про координацию плагинов, а про координацию сессий).
  • Tooling — не правится.

3. docs/sessions/CURRENT.md — заявочный лог

3.1 Формат

Один markdown-файл, append-only, парсимый. Запись на каждую активную параллельную сессию:

## session: 2026-05-18-discovery-interview
- branch: worktree-discovery-interview
- worktree: c:/моя/проекты/портал crm/Документация-discovery
- started: 2026-05-18T14:30+03:00
- scope-files:
  - docs/Tooling_v8_3.md §4.30
  - docs/Pravila_raboty_Claude_v1_1.md §13.2
  - docs/Plugin_stack_rules_v1.md R10.1
  - CLAUDE.md §3.3 #55
  - docs/adr/009-*.md (new)
- version-claims:
  - Tooling: 2.12 → 2.13
  - Pravila: 1.25 → 1.26
  - PSR_v1: 3.11 → 3.12
  - CLAUDE.md: 2.12 → 2.13
- status: in-progress
- closes: docs/superpowers/plans/2026-05-18-discovery-interview-integration.md

3.2 Жизненный цикл записи

  • claim — на старте сессии (до первой нормативной правки) контроллер добавляет запись + атомарный коммит sessions: claim <topic>. Отдельный коммит от plan-документа.
  • check — pre-flight перед своей правкой: Read docs/sessions/CURRENT.md + scan записей со status: in-progress. Конфликт = пересечение scope-files ИЛИ version-claims с активной соседней сессией.
  • release — на закрытии (push на main) контроллер меняет status: closed-<commit-sha>. Append-only-вариант (closed-записи остаются). Closed-записи переезжают в docs/sessions/archive/YYYY-MM.md через ≥30 дней после закрытия (ручная архивация раз в месяц, не cron).

3.3 Конфликт-резолюция

  1. Файловое пересечение (две сессии правят один и тот же файл, не обязательно одну секцию) — soft-warn, продолжать можно, но pre-flight fetch перед каждым коммитом обязателен (§15.2).
  2. Section-пересечение (одна и та же секция §X.Y) — hard-stop, координация с заказчиком до начала правки.
  3. Version-claim collision (две сессии заявили один номер) — hard-stop, кто claim'нул раньше (по timestamp в CURRENT.md) — тот его и берёт; вторая сессия сдвигается на +1.

3.4 Что НЕ включаем (YAGNI)

  • TTL / auto-expire записей — добавим, если файл реально засорится.
  • Machine-readable JSON-формат — markdown достаточен, парсится grep/sed.
  • Интеграция с GitHub Issues — отдельная тема, не блокер.
  • Pre-commit hook на проверку CURRENT.md — добавим только если будут зафиксированы инциденты игнорирования.

3.5 Pre-flight snippet (для plan-документов и скила)

# Перед нормативной правкой:
git fetch origin && git log HEAD..origin/main --oneline
grep -A 20 'status: in-progress' docs/sessions/CURRENT.md

4. Хук .claude/hooks/subagent-prompt-prefix.mjs

4.1 Тип и matcher

Тип хука — PreToolUse, matcher Task. Перехватывает tool_input.prompt, дописывает в начало обязательный заголовок git-safety, возвращает модифицированный prompt через стандартный JSON-output API хук-системы Claude Code:

{
  "hookSpecificOutput": {
    "hookEventName": "PreToolUse",
    "permissionDecision": "allow",
    "permissionDecisionReason": "git-safety header injected (Pravila §15.1)",
    "updatedInput": { "prompt": "<header>\n\n<original prompt>" }
  }
}

Точный формат API подтвердить против реально работающих tools/ruflo-queen-hook.mjs / tools/ruflo-recall-hook.mjs на этапе имплементации.

4.2 Тело заголовка

=== SUBAGENT GIT-SAFETY HEADER (Pravila §15.1, auto-injected) ===
Working directory (cwd): <absolute path>
Branch (git branch --show-current): <branch-name>
Parent commit (git rev-parse HEAD): <sha>
Worktree root (git rev-parse --show-toplevel): <path>

ОБЯЗАТЕЛЬНЫЕ ПРАВИЛА:
1. Все git-операции выполняй ТОЛЬКО внутри cwd выше. Если pwd ≠ cwd — STOP, верни ошибку.
2. ЗАПРЕЩЕНО: `git checkout <branch>`, `git switch <branch>`, `git checkout -b`, `git branch -m`, `git worktree add/remove`, `git push --force`, `git reset --hard`.
3. После КАЖДОГО `git commit` — выполни `git rev-parse HEAD` и `git branch --show-current`, выпиши результат в ответ. Это обязательная часть отчёта.
4. Если обнаружил, что находишься не в той ветке/worktree — STOP, не правь ничего, верни ошибку с raw output `git status` и `git branch --show-current`.
5. Если задача не требует git-операций (только Edit/Read/Grep) — этот блок информационный, follow rule 1.

=== END SUBAGENT GIT-SAFETY HEADER ===
<здесь — оригинальный prompt контроллера>

4.3 Резолюция переменных

Хук резолвит 4 значения сам в момент инжекта — не из контроллера. Резолв через стандартный Node child-process API c fixed-string git-командами (без подстановки user-input в shell — все аргументы статичны: git rev-parse HEAD, git rev-parse --show-toplevel, git branch --show-current, pwd/process.cwd()). Контроллер мог быть запущен в одной директории, но Task инвокируется по факту в ней же — хук берёт process.cwd() рантайма.

4.4 Какие модели затрагиваются

Заголовок инжектится для всех Task-инвокаций (универсально). §15.1 (Sonnet-only для git) — не в хук, а в Pravila + чеклист скила (Секция 5). Хук не знает, является ли задача git-задачей: анализ prompt'а — ненадёжный signal, пусть это решает контроллер.

4.5 Edge-cases

  1. Task без git (только read/edit) — заголовок присутствует, безвреден (rule 5 нейтрализует).
  2. Контроллер уже включил похожий заголовок — двойная защита, не проблема.
  3. Хук упал (например, git не в PATH) — возвращает {"continue": true} без модификации prompt'а + логирует stderr. Не блокирующий: лучше Task без заголовка, чем сломанный Task.
  4. Несколько worktree в разных терминалах — каждый запуск Claude Code имеет свой cwd, хук резолвит локально.

4.6 Объём и latency

~60 строк JS, паттерн один-в-один с tools/ruflo-queen-hook.mjs / tools/ruflo-recall-hook.mjs. Latency ~510 мс на Task (3 локальных git-вызова).

5. Verify-протокол в скиле subagent-driven-development

5.1 Где живёт

Добавочный чеклист-блок в скиле superpowers:subagent-driven-development:

  • если скил вендорится в .claude/skills/ — патчится напрямую;
  • если только marketplace-скил без локальной копии — добавляем references/git-safety-checklist.md рядом + одну строку «обязательный verify-блок после каждого субагента» в проектную обёртку. Фактический способ решается при имплементации (см. §7 ограничения).

5.2 Pre-spawn чеклист (до Task-инвокации)

  1. Резолвить и записать: cwd, branch, parent SHA, worktree root — те же 4 значения, что инжектит хук. Контроллер хранит их у себя для post-check.
  2. Если задача git-коммит → выбрать model sonnet или opus. Никогда haiku (§15.1).
  3. Если задача правит нормативку из списка §15.2 → pre-flight git fetch && git log HEAD..origin/main --oneline. Не пусто → ребейз до инвокации, не после.

5.3 Post-subagent чеклист (сразу после возврата)

  1. git rev-parse HEAD — сравнить с pre-spawn parent SHA. Ожидание: либо равно (субагент не коммитил), либо отличается ровно одним коммитом на pre-spawn HEAD.
  2. git branch --show-current — сравнить с pre-spawn branch. Не равно → STOP, разбор инцидента (Sprint 6 паттерн).
  3. git log -1 --format='%s%n%P' — проверить subject (соответствует задаче?) + parent (родитель = pre-spawn HEAD?).
  4. Если субагент коммитил несколько коммитов — не запрещено, но требует ручной проверки subject'ов.

5.4 Red-flag-список (любой = hard-stop разбор)

  • branch ≠ ожидаемая;
  • parent коммита ≠ pre-spawn HEAD (= висячий коммит / попадание на чужую ветку);
  • HEAD двинулся, но субагент в отчёте об этом не упомянул;
  • в diff'е есть файлы вне scope задачи.

5.5 Формат отчёта субагента

Субагент обязан выписать в конце ответа блок:

=== GIT REPORT ===
cwd: <pwd>
branch: <git branch --show-current>
HEAD: <git rev-parse HEAD>
HEAD^: <git rev-parse HEAD^>
status: <git status --short>
=== END GIT REPORT ===

Отсутствие блока = контроллер считает результат недостоверным и запускает 5.3-чеклист сам через Bash.

5.6 Соотношение с code-review

Двухстадийное review сохраняется (Pravila §4.5 / R10 PSR_v1): сильная модель делает code-review артефакта субагента. Git-safety-чеклист не заменяет code-review, он стоит до него (нет смысла ревьюить diff, если он не в той ветке).

6. Тесты, migration, контракт записи

6.1 Тесты самих защит

Защита Тест Ожидание
Хук (inject) echo '{"tool_input":{"prompt":"X"}}' | node .claude/hooks/subagent-prompt-prefix.mjs updatedInput.prompt начинается с === SUBAGENT GIT-SAFETY HEADER ===; cwd/branch/HEAD — реальные
Хук — failure-mode временно сломать (mv .git → .git.bak) → запустить хук {"continue":true}, без модификации; Task не должен крашиться
Verify-протокол (5.3) Task субагенту с prompt "do nothing, run git status, return" в ответе субагента — блок === GIT REPORT ===; контроллер сверяет HEAD до/после — должны быть равны
§15.1 enforcement Ручной dry-run: попытаться делегировать git commit Haiku-субагенту согласно чеклисту контроллер отказывается и перенаправляет Sonnet'у
§15.2 pre-flight Симулировать diverged state: git fetch + сделать divergence → попытаться правнуть Pravila pre-flight snippet ловит, требует rebase
CURRENT.md claim collision Две параллельные сессии: добавить запись с тем же version-claim вторая сессия должна вручную увидеть конфликт через grep version-claims

Никакой автоматизации сверх этого (no pre-commit hook, no CI check) — YAGNI. Если CURRENT.md начнёт игнорироваться — добавим pre-commit grep отдельной правкой.

6.2 Migration существующих параллельных worktrees

На момент 18.05.2026 — 16 активных worktree (git worktree list). Шаги:

  1. После merge §15 + хука + CURRENT.md на main — каждая активная worktree-сессия делает git fetch + ребейз на свежий main (получает §15 + хук).
  2. Каждая активная сессия дописывает свою запись в CURRENT.md одним коммитом (sessions: backfill claim <topic>) — не блокирует работу, retro-claim.
  3. Существующие version-collision'ы (A11 / C9 / A4 / discovery — последние 2 недели) не пересматриваем; §15 действует с момента введения, не ретроактивно.

6.3 Что НЕ делаем сейчас (явный YAGNI)

  • Реестр зарезервированных версий — пропущен;
  • pre-commit hook на CURRENT.md — пропущен;
  • машинно-читаемый JSON-формат CURRENT.md — пропущен;
  • запрет параллельных сессий — нет, параллельность — норма проекта;
  • изменения PSR_v1 / Tooling — не требуются, §15 — внутри Pravila;
  • subagent-без-git (вариант C из брейншторма) — отложен до повторного инцидента после A+B.

7. Ограничения / что не верифицировано в дизайне

  • Не верифицировал через grep, что в Pravila нет пересекающихся правил под номером §15 — проверено в формате headings ## 13. ... / ## 14. ..., §15 свободен. Подтверждено на этапе brainstorming.
  • Не верифицировал API хук-системы Claude Code на актуальной версии CLI — формат updatedInput в PreToolUse для Task tool требует подтверждения против реально работающих tools/ruflo-queen-hook.mjs / tools/ruflo-recall-hook.mjs перед написанием хука. Задача имплементации, не дизайна.
  • Не верифицировал, что subagent-driven-development скил вендорится в .claude/skills/. Может быть только маркетплейс-скил без локальной копии — фактический способ патчинга решится при имплементации (Секция 5.1).
  • Не верифицировал Windows-специфику резолва git-команд через Node child-process в хуке — на Windows работало для ruflo-queen-hook.mjs, должно работать и здесь.

8. Acceptance criteria (для writing-plans)

Дизайн считается реализованным, когда:

  1. Pravila §15 (15.1 + 15.2) добавлен, версия Pravila bumped, CHANGELOG entry есть.
  2. docs/sessions/CURRENT.md создан, формат описан в README рядом, в нём есть retro-claim запись для всех активных worktrees на момент имплементации (Migration §6.2; на дату дизайна — 16 штук).
  3. .claude/hooks/subagent-prompt-prefix.mjs написан, зарегистрирован в .claude/settings.json, прошёл тесты 6.1 (рукопись + failure-mode + e2e Task).
  4. Скил subagent-driven-development патчен (5.1) — verify-протокол доступен контроллеру.
  5. CLAUDE.md §1 cross-ref на §15 добавлен.
  6. Pre-commit gitleaks + Pest/Vitest GREEN; gitleaks-full-history + lychee — перед push.
  7. Регрессия Pest --parallel / Vitest — 0 регрессий vs baseline.