8 atomic tasks per spec 2026-05-18-parallel-sessions-coordination-design.md:
1. Pravila §15 hard-rule (15.1 субагенты+git, 15.2 нормативка+pre-flight, 15.3 cross-refs) + v1.26→v1.27.
2. docs/sessions/ — README + CURRENT.md с retro-claim для 16 worktrees.
3. tools/subagent-prompt-prefix.test.mjs — TDD red-фаза (5 тестов).
4. tools/subagent-prompt-prefix.mjs — TDD green (PreToolUse Task auto-inject).
5. CLAUDE.md cross-ref через /claude-md-management:claude-md-improver (§5 п.10).
6. .claude/settings.json — регистрация хука matcher:'Task'.
7. .claude/skills/subagent-driven-development/ — wrapper-skill + git-safety-checklist.
8. Final regression + push (manual /push gate).
Все шаги с exact paths, exact commands, expected outputs.
TDD red→green разнесён по двум task'ам (3 → 4) с RED-коммитом между.
Branch: feat/parallel-sessions-coordination (от origin/main b40f2c8).
Spec: docs/superpowers/specs/2026-05-18-parallel-sessions-coordination-design.md
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
48 KiB
Parallel Sessions Coordination — Implementation Plan
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: Лечим два класса параллельных-сессий инцидентов (субагенты теряются между worktree / нормативка дрейфует) — добавляем Pravila §15 hard-rule, заявочный лог docs/sessions/CURRENT.md, PreToolUse-хук tools/subagent-prompt-prefix.mjs, references-wrapper к скилу subagent-driven-development.
Architecture: 4 артефакта, 0 новых плагинов / MCP. Pravila §15 — корневое правило. CURRENT.md — координация scope/version-claims. Хук — авто-инжект git-safety заголовка в каждый Task-prompt. Wrapper-скил — verify-чеклист контроллера.
Tech Stack: Markdown (нормативка + лог), Node 22 ESM (tools/*.mjs с node --test), git, lefthook (pre-commit), Bash (на Windows через Git Bash).
Spec: docs/superpowers/specs/2026-05-18-parallel-sessions-coordination-design.md
Branch: feat/parallel-sessions-coordination (создана от origin/main b40f2c8, верифицирована pre-flight — git log HEAD..origin/main пуст).
File Structure
Создаются:
docs/sessions/README.md— описание формата CURRENT.md, лайфциклов, конфликт-резолюции.docs/sessions/CURRENT.md— заявочный лог + retro-claim для активных worktrees на момент имплементации.tools/subagent-prompt-prefix.mjs— PreToolUse-хук на Task, инжектит cwd/branch/HEAD заголовок.tools/subagent-prompt-prefix.test.mjs—node --testtest-suite..claude/skills/subagent-driven-development/SKILL.md— wrapper-скил с проектным verify-протоколом (references-обёртка над marketplace-скилом)..claude/skills/subagent-driven-development/references/git-safety-checklist.md— pre/post-subagent чеклист, формат GIT REPORT.
Модифицируются:
docs/Pravila_raboty_Claude_v1_1.md— добавить §15 (15.1 + 15.2 + 15.3), bump header v1.26 → v1.27, add §10 changelog entry.CLAUDE.md— §1 priority chain footer-абзац (cross-ref на §15), §0 row Pravila version v1.26 → v1.27. Через/claude-md-management:claude-md-improver..claude/settings.json— добавить PreToolUse blockmatcher: "Task".cspell-words.txt— добавить транслитерации появляющиеся в хуке/wrapper-скиле (по факту падений).
Task 1: Pravila §15 hard-rule
Files:
-
Modify:
docs/Pravila_raboty_Claude_v1_1.md(add §15 after §14, bump header version, add §10 changelog entry) -
Step 1.1: Verify §15 still free
Run:
grep -nE '^## 1[5-9]\.|^## 2[0-9]\.' docs/Pravila_raboty_Claude_v1_1.md
Expected: empty (no §15 collision). If non-empty — STOP, разбор.
- Step 1.2: Find insertion point after §14
Run:
grep -nE '^## (14|15|11)\.' docs/Pravila_raboty_Claude_v1_1.md
Expected: line for ## 14. Ruflo Queen routing — hard rule (триггер queen/королева) (was line 820 at design time; verify актуально). Find end-of-§14 boundary (next ^## heading или EOF).
- Step 1.3: Add §15 content
Insert after the closing line of §14 (before next ## heading or EOF). Exact text:
## 15. Параллельные сессии — hard rule (субагенты + git, нормативка + pre-flight sync)
Действует с 18.05.2026. **Hard rule**: §9 «Отступления» к §15 не применяется (как §12 и §14).
### 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`) — разрешены любой модели.
Прецедент-источник: Sprint 6 (17.05.2026) — Haiku-субагенты угнали ветку параллельной сессии, устранено через `git reflog` + `reset`. Корневая причина — отсутствие верификации HEAD/branch после Task-инвокации. Verify-протокол — `.claude/skills/subagent-driven-development/references/git-safety-checklist.md`.
### 15.2 Нормативные правки + pre-flight sync
Любая правка файлов из списка «нормативка» (см. ниже) выполняется **только** на актуальной базе `origin/main`. Pre-flight обязателен:
```bash
git fetch origin && git log HEAD..origin/main --oneline
Если есть untracked commits на origin/main, ребейз/merge до начала правки, не после.
Параллельная нормативная правка на устаревшей базе — нарушение §15.2. Признак нарушения: коммит правит файл, чья последняя версия на origin/main новее, чем версия в parent коммите правки.
Список «нормативка» — 8 позиций:
docs/Pravila_raboty_Claude_v1_1.mdCLAUDE.mddocs/Tooling_v8_3.mddocs/Plugin_stack_rules_v1.mdmemory/MEMORY.md(и всеmemory/*.md)docs/Открытые_вопросы_v8_3.mddocs/adr/*.md(glob — collision на ADR-NNN номере = тот же класс, что version-bump нормативки)db/schema.sql(параллельные миграции из разных сессий = реальный риск; запись вdb/CHANGELOG_schema.mdсама не защищает от version-base дрейфа)
Расширение списка — отдельная правка §15.2, не «по ощущениям».
Дополнительно: при параллельных активных сессиях контроллер обязан добавить запись в docs/sessions/CURRENT.md до первой нормативной правки (claim) — формат и жизненный цикл записи описаны в docs/sessions/README.md. Конфликт-резолюция (file overlap / section overlap / version-claim collision) — там же.
15.3 Cross-refs в других файлах
- CLAUDE.md §1 priority chain — §15 рядом с §12 и §14 как hard-rule (см. footer-абзац после цепочки).
- PSR_v1 — не правится: §15 не про координацию плагинов, а про координацию сессий.
- Tooling — не правится.
- [ ] **Step 1.4: Bump Pravila header v1.26 → v1.27**
Find first occurrence of `v1.26` in the file header (~lines 1–10) and replace one instance with `v1.27`. Update date if needed — `от 18.05.2026` stays.
Run check после правки:
```bash
head -10 docs/Pravila_raboty_Claude_v1_1.md
Expected: header содержит v1.27 от 18.05.2026.
- Step 1.5: Add §10 changelog entry
Find ## 10. История версий (was line 561). Add at the top of the version list (newest first per existing pattern; verify pattern in §10 head — if oldest-first, append at bottom; the entry text is the same):
**v1.27 от 18.05.2026** — Параллельные сессии: координация. +§15 hard-rule (15.1 субагенты+git Sonnet/Opus only, 15.2 нормативка+pre-flight sync, 15.3 cross-refs). §15 третье hard-rule после §12 и §14; список «нормативка» — 8 позиций. Лечит два класса инцидентов параллельных-сессий: (A) субагенты теряются между worktree (Sprint 6 прецедент), (B) нормативка/MEMORY дрейфует (Tooling v2.11 collision 17.05.2026). Спек — `docs/superpowers/specs/2026-05-18-parallel-sessions-coordination-design.md`, план — `docs/superpowers/plans/2026-05-18-parallel-sessions-coordination.md`.
- Step 1.6: Verify Pravila correctness
Run:
grep -cE '^## 15\.' docs/Pravila_raboty_Claude_v1_1.md
grep -cE '^### 15\.[123]' docs/Pravila_raboty_Claude_v1_1.md
grep -c 'v1.27' docs/Pravila_raboty_Claude_v1_1.md
Expected: 1, 3, ≥2 (header + §10 entry).
- Step 1.7: Commit
git add docs/Pravila_raboty_Claude_v1_1.md
git commit -m "feat(pravila): §15 hard-rule — параллельные сессии (субагенты+git, нормативка+pre-flight sync)
Bump Pravila v1.26 → v1.27 + §10 changelog entry. §15 третье hard-rule
после §12 (Superpowers) и §14 (Ruflo Queen). §15 лечит два класса
инцидентов параллельных Claude-сессий — субагенты путают ветки/worktree
(Sprint 6) и нормативка/MEMORY дрейфует (Tooling v2.11 collision 17.05.2026).
Cross-refs to CLAUDE.md §1 — отдельная правка через
/claude-md-management:claude-md-improver (Task 5 плана).
Spec: docs/superpowers/specs/2026-05-18-parallel-sessions-coordination-design.md
Plan: docs/superpowers/plans/2026-05-18-parallel-sessions-coordination.md
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>"
Pre-commit chain должен пройти: gitleaks 0, markdownlint 0, cspell 0 (если новые транслитерации появятся — добавить в cspell-words.txt отдельным fixup-commit'ом до основного коммита).
Task 2: docs/sessions/ — каталог + README + CURRENT.md retro-claim
Files:
-
Create:
docs/sessions/README.md -
Create:
docs/sessions/CURRENT.md -
Step 2.1: Resolve active worktrees
Run:
git worktree list --porcelain
Expected: список worktree (на 18.05.2026 — 16 штук). Сохранить вывод для retro-claim записей.
- Step 2.2: Create docs/sessions/README.md
Полное содержимое (никаких placeholder'ов):
# docs/sessions/ — координация параллельных Claude-сессий
**Источник правила:** Pravila §15.2 (раздел про CURRENT.md в конце текста §15.2).
## Назначение
`docs/sessions/CURRENT.md` — заявочный лог активных параллельных Claude-сессий проекта. Решает класс инцидентов «нормативка/MEMORY дрейфует» (см. spec — `docs/superpowers/specs/2026-05-18-parallel-sessions-coordination-design.md`).
## Когда писать в CURRENT.md
Перед **первой** нормативной правкой в сессии (правки файлов из списка §15.2 — Pravila, CLAUDE.md, Tooling, PSR_v1, MEMORY.md, Открытые_вопросы, docs/adr/*, db/schema.sql). Запись добавляется отдельным атомарным коммитом `sessions: claim <topic>` — до plan-документа и до первой содержательной правки.
## Формат записи
```markdown
## session: YYYY-MM-DD-<topic-kebab>
- branch: <git branch --show-current>
- worktree: <git rev-parse --show-toplevel>
- started: <ISO 8601 with timezone>
- scope-files:
- <relative path> [§/раздел/строка]
- ...
- version-claims:
- <file-or-topic>: <from> → <to>
- ...
- status: in-progress | closed-<commit-sha>
- closes: <relative path к plan-документу>
scope-files — какие нормативные файлы и в каких секциях правит сессия. version-claims — какие новые версии (Tooling 2.X, Pravila 1.Y и т.п.) или номера (ADR-NNN) сессия резервирует.
Жизненный цикл
- claim — добавить запись со
status: in-progress+ атомарный коммитsessions: claim <topic>. - check — pre-flight перед нормативной правкой:
Read docs/sessions/CURRENT.md+ проверить пересечениеscope-files/version-claimsс активными записями. - release — на закрытии (после push на main) изменить
status: closed-<commit-sha>(запись остаётся в CURRENT.md — append-only-вариант).
Closed-записи переезжают в docs/sessions/archive/YYYY-MM.md через ≥30 дней после закрытия (ручная архивация раз в месяц, не cron).
Конфликт-резолюция
| Тип пересечения | Реакция |
|---|---|
| Файловое пересечение (одинаковый файл, разные секции) | soft-warn — продолжать можно, но pre-flight fetch перед каждым коммитом обязателен (§15.2). |
| Section-пересечение (одна и та же секция §X.Y) | hard-stop — координация с заказчиком до начала правки. |
| Version-claim collision (две сессии заявили один номер) | hard-stop — кто claim'нул раньше (по started-timestamp), тот его и берёт. Вторая сессия сдвигается на +1. |
Pre-flight snippet (для plan-документов и скила subagent-driven-development)
# Перед нормативной правкой:
git fetch origin && git log HEAD..origin/main --oneline
grep -A 20 'status: in-progress' docs/sessions/CURRENT.md
Что мы НЕ делаем (явный YAGNI)
- Pre-commit hook на CURRENT.md — добавим только если будут зафиксированы инциденты игнорирования.
- TTL / auto-expire записей — добавим, если файл реально засорится.
- Machine-readable JSON-формат — markdown достаточен, парсится grep/sed.
- Интеграция с GitHub Issues — отдельная тема, не блокер.
- [ ] **Step 2.3: Create docs/sessions/CURRENT.md с retro-claim**
Структура с заголовком + текущей сессией parallel-sessions-coordination + retro-claim записями для каждой активной worktree из Step 2.1.
Для текущей сессии (заполнить gотовыми значениями):
```markdown
# CURRENT.md — активные Claude-сессии
> Формат и жизненный цикл записей: [docs/sessions/README.md](README.md).
> Pravila §15.2 — описание правила в нормативке.
## session: 2026-05-18-parallel-sessions-coordination
- branch: feat/parallel-sessions-coordination
- worktree: c:/моя/проекты/портал crm/Документация
- started: 2026-05-18T09:30+03:00
- scope-files:
- docs/Pravila_raboty_Claude_v1_1.md §15 (new)
- CLAUDE.md §1 (cross-ref), §0 (Pravila version row)
- tools/subagent-prompt-prefix.mjs (new)
- .claude/settings.json (PreToolUse Task block)
- .claude/skills/subagent-driven-development/ (new wrapper-skill)
- docs/sessions/README.md, CURRENT.md (new — этот файл)
- version-claims:
- Pravila: 1.26 → 1.27
- status: in-progress
- closes: docs/superpowers/plans/2026-05-18-parallel-sessions-coordination.md
---
## Retro-claim'ы активных worktrees (snapshot 2026-05-18)
Per Pravila §15.2 — backfill для существующих параллельных сессий. Эти записи retroactive, scope/version-claims заполнены best-effort из последних коммитов worktree-веток. Активные сессии при возобновлении работы обновляют свой блок.
Дальше — по одной записи на каждую worktree из Step 2.1 (кроме основной Документация, которая = текущая сессия). Для каждой записи:
branch: имя ветки изgit worktree listworktree: путьstarted:2026-05-18T00:00+03:00(best-effort backfill, не точный)scope-files: best-effort из последнего коммита ветки (git log -1 --name-only <branch>). Если scope непонятен —- <unknown — backfill>version-claims:- <none verified — backfill>если непонятноstatus:in-progress (backfilled)если HEAD ветки не на origin/main, иначеclosed-<sha> (backfilled)
Например (шаблон для одной retro-записи; повторить для каждой worktree):
## session: 2026-05-XX-<topic-from-branch-name>
- branch: <worktree-branch-name>
- worktree: <worktree path>
- started: 2026-05-18T00:00+03:00 (backfill)
- scope-files:
- <best-effort from git log -1 --name-only>
- version-claims:
- <none verified — backfill>
- status: in-progress (backfilled) | closed-<sha> (backfilled)
- closes: <unknown — backfill>
- Step 2.4: Verify created files
Run:
ls -la docs/sessions/
wc -l docs/sessions/README.md docs/sessions/CURRENT.md
grep -c '^## session:' docs/sessions/CURRENT.md
Expected: оба файла существуют; CURRENT.md содержит ≥1 запись (текущая) + retro-claim для каждой worktree из Step 2.1.
- Step 2.5: Commit
git add docs/sessions/
git commit -m "feat(sessions): CURRENT.md + README — заявочный лог параллельных Claude-сессий
Создаём docs/sessions/ — координация per Pravila §15.2 (claim/check/release
жизненный цикл, конфликт-резолюция). CURRENT.md содержит текущую сессию
parallel-sessions-coordination + retro-claim записи для существующих
активных worktrees (16 штук на 2026-05-18).
Backfill scope/version-claims заполнен best-effort; активные сессии
обновят свой блок при возобновлении работы.
Spec: docs/superpowers/specs/2026-05-18-parallel-sessions-coordination-design.md
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>"
Task 3: Hook tests (TDD — failing first)
Files:
-
Create:
tools/subagent-prompt-prefix.test.mjs -
Step 3.1: Write the failing test file
Полное содержимое (node --test runner, паттерн один-в-один с tools/ruflo-recall-hook.test.mjs):
#!/usr/bin/env node
/**
* Tests for tools/subagent-prompt-prefix.mjs — PreToolUse Task git-safety header inject.
*
* Per Pravila §15.1 — hook injects cwd/branch/HEAD/worktree-root into каждый Task-prompt.
* FAIL-OPEN: any error → return {continue: true} без модификации.
*
* Spec: docs/superpowers/specs/2026-05-18-parallel-sessions-coordination-design.md §4
*/
import { test } from 'node:test';
import { strict as assert } from 'node:assert';
import { spawnSync } from 'node:child_process';
import { fileURLToPath } from 'node:url';
import { dirname, join } from 'node:path';
const __dirname = dirname(fileURLToPath(import.meta.url));
const HOOK_PATH = join(__dirname, 'subagent-prompt-prefix.mjs');
function runHook(stdinJson) {
return spawnSync('node', [HOOK_PATH], {
input: JSON.stringify(stdinJson),
encoding: 'utf8',
timeout: 5000,
});
}
test('hook injects SUBAGENT GIT-SAFETY HEADER into Task prompt', () => {
const result = runHook({
tool_name: 'Task',
tool_input: { prompt: 'do something' },
});
assert.equal(result.status, 0, `stderr: ${result.stderr}`);
const out = JSON.parse(result.stdout);
assert.ok(out.hookSpecificOutput, 'has hookSpecificOutput');
assert.equal(out.hookSpecificOutput.hookEventName, 'PreToolUse');
assert.equal(out.hookSpecificOutput.permissionDecision, 'allow');
const newPrompt = out.hookSpecificOutput.updatedInput.prompt;
assert.match(newPrompt, /=== SUBAGENT GIT-SAFETY HEADER/);
assert.match(newPrompt, /=== END SUBAGENT GIT-SAFETY HEADER ===/);
assert.match(newPrompt, /do something/, 'preserves original prompt');
});
test('hook injects real cwd, branch, HEAD values', () => {
const result = runHook({
tool_name: 'Task',
tool_input: { prompt: 'noop' },
});
assert.equal(result.status, 0);
const out = JSON.parse(result.stdout);
const newPrompt = out.hookSpecificOutput.updatedInput.prompt;
// cwd — absolute path
assert.match(newPrompt, /Working directory \(cwd\): [A-Za-z]:[\\/]|Working directory \(cwd\): \//);
// branch — non-empty
assert.match(newPrompt, /Branch \(git branch --show-current\): \S+/);
// HEAD — 40-char SHA
assert.match(newPrompt, /Parent commit \(git rev-parse HEAD\): [0-9a-f]{40}/);
});
test('hook passes through non-Task tools without modification', () => {
const result = runHook({
tool_name: 'Edit',
tool_input: { file_path: '/foo', old_string: 'a', new_string: 'b' },
});
assert.equal(result.status, 0);
const out = JSON.parse(result.stdout);
// Non-Task → either {continue: true} OR no updatedInput
if (out.hookSpecificOutput) {
assert.equal(out.hookSpecificOutput.updatedInput, undefined);
} else {
assert.equal(out.continue, true);
}
});
test('hook fail-open on malformed stdin', () => {
const result = spawnSync('node', [HOOK_PATH], {
input: 'not-json',
encoding: 'utf8',
timeout: 5000,
});
assert.equal(result.status, 0, `should not crash; stderr: ${result.stderr}`);
// Either {continue: true} or empty output — both acceptable fail-open
});
test('hook fail-open when git not available', () => {
const result = spawnSync('node', [HOOK_PATH], {
input: JSON.stringify({ tool_name: 'Task', tool_input: { prompt: 'x' } }),
encoding: 'utf8',
timeout: 5000,
env: { ...process.env, PATH: '' }, // strip PATH → git not found
});
assert.equal(result.status, 0, `should not crash when git missing; stderr: ${result.stderr}`);
});
- Step 3.2: Verify tests FAIL (hook doesn't exist yet)
Run:
node --test tools/subagent-prompt-prefix.test.mjs
Expected: ALL tests FAIL — Cannot find module '.../subagent-prompt-prefix.mjs' or similar ENOENT. Это ожидаемое — TDD red-phase.
- Step 3.3: Commit (TDD: failing test первым)
git add tools/subagent-prompt-prefix.test.mjs
git commit -m "test(hooks): subagent-prompt-prefix — failing tests (TDD red)
5 тестов для Task git-safety inject хука:
- inject SUBAGENT GIT-SAFETY HEADER в Task-prompt
- inject real cwd/branch/HEAD/worktree-root
- passes through non-Task tools
- fail-open on malformed stdin
- fail-open when git unavailable
Tests FAIL — hook implementation в следующем коммите (TDD green-phase).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>"
Task 4: Hook implementation (TDD green)
Files:
-
Create:
tools/subagent-prompt-prefix.mjs -
Step 4.1: Write hook implementation
Полное содержимое (паттерн из tools/ruflo-recall-hook.mjs — execFile, FAIL-OPEN, ESM):
#!/usr/bin/env node
/**
* PreToolUse hook — git-safety header inject for Task tool.
*
* For каждый Task-инвокейшн контроллера: дописывает в начало tool_input.prompt
* заголовок с cwd / branch / parent SHA / worktree-root + правилами поведения
* (rule 1–5). Это компенсирует класс инцидентов «субагент путает ветку/worktree»
* (Sprint 6, Pravila §15.1).
*
* FAIL-OPEN: любая ошибка / тайм-аут / git-не-в-PATH → {continue: true} без
* модификации; хук НИКОГДА не блокирует Task.
*
* Non-Task tools — pass-through без модификации.
*
* Spec: docs/superpowers/specs/2026-05-18-parallel-sessions-coordination-design.md §4
* Rule: docs/Pravila_raboty_Claude_v1_1.md §15.1
*/
import { execFile } from 'node:child_process';
import { promisify } from 'node:util';
const execFileP = promisify(execFile);
const GIT_TIMEOUT_MS = 1500;
/** Read all stdin into a string. */
async function readStdin() {
let buf = '';
for await (const chunk of process.stdin) buf += chunk;
return buf;
}
/** Parse hook input JSON; return null on any parse error. */
function parseHookInput(raw) {
try { return JSON.parse(raw); } catch { return null; }
}
/** Run a single fixed-args git command; return trimmed stdout, or null on any error. */
async function gitCmd(args) {
try {
const { stdout } = await execFileP('git', args, { timeout: GIT_TIMEOUT_MS, encoding: 'utf8' });
return stdout.trim();
} catch {
return null;
}
}
/** Build the safety header block. Returns null if any of the 4 git values can't be resolved. */
async function buildHeader() {
const cwd = process.cwd();
const [branch, head, top] = await Promise.all([
gitCmd(['branch', '--show-current']),
gitCmd(['rev-parse', 'HEAD']),
gitCmd(['rev-parse', '--show-toplevel']),
]);
if (!branch || !head || !top) return null;
return [
'=== SUBAGENT GIT-SAFETY HEADER (Pravila §15.1, auto-injected) ===',
`Working directory (cwd): ${cwd}`,
`Branch (git branch --show-current): ${branch}`,
`Parent commit (git rev-parse HEAD): ${head}`,
`Worktree root (git rev-parse --show-toplevel): ${top}`,
'',
'ОБЯЗАТЕЛЬНЫЕ ПРАВИЛА:',
'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 ===',
'',
].join('\n');
}
/** Emit fail-open response and exit 0. */
function failOpen() {
process.stdout.write(JSON.stringify({ continue: true }));
process.exit(0);
}
async function main() {
const raw = await readStdin();
const input = parseHookInput(raw);
if (!input) return failOpen();
// Non-Task — pass-through
if (input.tool_name !== 'Task') return failOpen();
const originalPrompt = input.tool_input?.prompt;
if (typeof originalPrompt !== 'string') return failOpen();
const header = await buildHeader();
if (!header) {
// git unavailable / not in worktree — fail-open per spec §4.5 edge-case 3
process.stderr.write('[subagent-prompt-prefix] git resolution failed — passing through\n');
return failOpen();
}
const newPrompt = header + originalPrompt;
process.stdout.write(JSON.stringify({
hookSpecificOutput: {
hookEventName: 'PreToolUse',
permissionDecision: 'allow',
permissionDecisionReason: 'git-safety header injected (Pravila §15.1)',
updatedInput: { prompt: newPrompt },
},
}));
}
main().catch(() => failOpen());
- Step 4.2: Run tests — verify GREEN
Run:
node --test tools/subagent-prompt-prefix.test.mjs
Expected: ALL 5 tests PASS (# pass 5 / # fail 0).
Если какой-то тест падает — STOP, фикс реализации (НЕ теста), повторить.
- Step 4.3: Smoke test inject вручную
Run:
echo '{"tool_name":"Task","tool_input":{"prompt":"hello"}}' | node tools/subagent-prompt-prefix.mjs | python -m json.tool
Expected: JSON с hookSpecificOutput.updatedInput.prompt, начинающимся === SUBAGENT GIT-SAFETY HEADER, с реальными cwd/branch/HEAD значениями.
- Step 4.4: Commit
git add tools/subagent-prompt-prefix.mjs
git commit -m "feat(hooks): subagent-prompt-prefix — PreToolUse git-safety inject (TDD green)
Per Pravila §15.1 — инжектит cwd/branch/HEAD/worktree-root + правила
поведения в каждый Task-prompt. FAIL-OPEN на любой ошибке (git
не в PATH, malformed stdin, non-Task tools).
Все 5 тестов из subagent-prompt-prefix.test.mjs PASS.
Регистрация в .claude/settings.json — Task 6 плана.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>"
Task 5: CLAUDE.md cross-ref через claude-md-management
Files:
-
Modify:
CLAUDE.md(через плагин, не прямой Edit) -
Step 5.1: Запустить /claude-md-management:claude-md-improver
Через слэш-команду в Claude Code. Передать конкретные правки:
Обнови CLAUDE.md под добавление Pravila §15:
§0 cross-ref row Pravila —
v1.26→v1.27. Сводный комментарий в скобках после версии: «(v1.27 от 18.05.2026 — §15 hard-rule: параллельные сессии (15.1 субагенты+git, 15.2 нормативка+pre-flight sync, 15.3 cross-refs); третье hard-rule после §12 и §14)».§1 priority chain — добавить footer-абзац после блок-схемы цепочки (после слов «...alongside CLAUDE.md как корневая карта Claude Code.»). Текст footer-абзаца:
Hard-rules вне §9 «Отступления» (Pravila): §12 (Superpowers — инвокация skill ПЕРВОЙ), §14 (Ruflo Queen routing — триггер queen/королева), §15 (параллельные сессии — 15.1 субагенты+git Sonnet/Opus only, 15.2 нормативка+pre-flight sync с 8-позиционным списком, 15.3 cross-refs). Эти три параграфа Pravila — explicit override-floor под §9; transitive hard-rule через §13 — координация Plugin_stack_rules_v1.
- §9 «История версий» — добавить запись v2.14 (или next-free version) с описанием изменений согласно §6 шаблону предыдущих записей.
Плагин сам бамп'нет шапку CLAUDE.md (v2.13 → v2.14) и сделает commit per §5 п.10.
- Step 5.2: Verify after plugin run
Run:
git log -1 --stat
grep -c 'v1.27' CLAUDE.md
grep -c '§15' CLAUDE.md
Expected: latest коммит трогает только CLAUDE.md; v1.27 встречается ≥1 раз; §15 встречается ≥2 раз (§0 + §1 footer).
Task 6: Register hook в .claude/settings.json
Files:
-
Modify:
.claude/settings.json— добавить новыйPreToolUseblock сmatcher: "Task" -
Step 6.1: Найти существующий PreToolUse секцию
Run:
grep -n '"PreToolUse"' .claude/settings.json
Expected: одна строка (например "PreToolUse": [).
- Step 6.2: Добавить новый matcher block
Внутри массива PreToolUse добавить новый объект-block (НЕ внутри существующего matcher: "Edit|Write" block, отдельный объект массива):
{
"matcher": "Task",
"hooks": [
{
"type": "command",
"command": "node \"C:/моя/проекты/портал crm/Документация/tools/subagent-prompt-prefix.mjs\""
}
]
}
Точный путь — абсолютный (паттерн из существующих ruflo-хуков в этом же файле). Запятая после предыдущего объекта массива обязательна — Edit|Write объект должен оканчиваться },.
- Step 6.3: Validate JSON
Run:
node -e "JSON.parse(require('fs').readFileSync('.claude/settings.json','utf8')); console.log('OK')"
Expected: OK. Если ошибка — STOP, ловить trailing comma / unbalanced brace.
- Step 6.4: Smoke test end-to-end
Перезапустить Claude Code (хук перечитывается на старте сессии). В новой сессии запустить тривиальный Task — субагент должен в ответе содержать === SUBAGENT GIT-SAFETY HEADER === в начале промпта (можно проверить, попросив субагента выписать первые 10 строк своего промпта).
Если перезапуск Claude Code невозможен в текущем рабочем потоке — отметить шаг как «verified at next session start» в коммит-сообщении.
- Step 6.5: Commit
git add .claude/settings.json
git commit -m "chore(hooks): register subagent-prompt-prefix PreToolUse Task hook
Регистрирует tools/subagent-prompt-prefix.mjs как PreToolUse-хук
matcher:'Task'. JSON валиден (node -e JSON.parse). End-to-end smoke
verified at next session start (хук перечитывается на старте сессии).
Per Pravila §15.1 (третье hard-rule).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>"
Task 7: Wrapper-скил subagent-driven-development
Files:
-
Create:
.claude/skills/subagent-driven-development/SKILL.md -
Create:
.claude/skills/subagent-driven-development/references/git-safety-checklist.md -
Step 7.1: Create SKILL.md (wrapper)
Полное содержимое:
---
name: subagent-driven-development
description: Project-local wrapper для superpowers:subagent-driven-development — добавляет обязательный git-safety verify-протокол per Pravila §15.1. Использовать вместо marketplace-варианта при работе с git-коммит-задачами в субагентах.
---
# Subagent-Driven Development (project wrapper)
Этот скил — проектная обёртка над marketplace-скилом `superpowers:subagent-driven-development`. Дополняет его обязательным git-safety verify-протоколом per Pravila §15.1.
## Когда использовать
Когда нужно делегировать задачу субагенту через Task tool — особенно git-коммит-задачи (Sprint 6 прецедент: Haiku-субагенты угнали ветку параллельной сессии).
## Что делать
1. **Откройте marketplace-скил** `superpowers:subagent-driven-development` для общего workflow (fresh subagent per task + two-stage review).
2. **Перед каждой Task-инвокацией** прочитайте и выполните pre-spawn-чеклист — [references/git-safety-checklist.md](references/git-safety-checklist.md) §A.
3. **После каждой Task-инвокации** прочитайте и выполните post-subagent-чеклист — там же §B.
4. **Hard-rule §15.1** — git-коммит-задача = модель Sonnet/Opus, никогда Haiku. Read-only git-операции (`log`, `status`, `diff`, `rev-parse`, `branch --show-current`, `worktree list`) разрешены любой модели.
Хук `tools/subagent-prompt-prefix.mjs` (зарегистрирован в `.claude/settings.json`) автоматически инжектит git-safety заголовок в каждый Task-prompt — это **первая** линия защиты. Чеклист из этого скила — **вторая** линия (защита со стороны контроллера).
## Cross-refs
- Pravila §15.1 — hard-rule субагенты + git.
- Spec: `docs/superpowers/specs/2026-05-18-parallel-sessions-coordination-design.md` §5.
- Memory: `memory/feedback_subagent_git_reliability.md`.
- Step 7.2: Create references/git-safety-checklist.md
Полное содержимое:
# Git-safety Checklist для контроллера субагентов
Per Pravila §15.1 — выполнять каждый раз при делегировании задачи через Task tool.
## §A. Pre-spawn чеклист (до Task-инвокации)
1. **Резолвите 4 значения** (запишите у себя для post-check):
```bash
git branch --show-current # → ожидаемая ветка
git rev-parse HEAD # → pre-spawn parent SHA
git rev-parse --show-toplevel # → worktree root
pwd # → cwd
-
Выберите модель субагенту:
- Задача требует
git commit/push/stage/checkout/switch/merge/rebase? → Sonnet или Opus, никогда Haiku (§15.1). - Только read-только
git log/status/diff/rev-parseИЛИ только Edit/Read/Grep? → любая модель.
- Задача требует
-
Если задача правит нормативку из списка §15.2 (Pravila / CLAUDE.md / Tooling / PSR_v1 / MEMORY.md / Открытые_вопросы / docs/adr/* / db/schema.sql):
git fetch origin && git log HEAD..origin/main --onelineНе пусто → ребейз/merge до инвокации, не после. Pre-flight также проверить
docs/sessions/CURRENT.mdна конфликт scope-files / version-claims.
§B. Post-subagent чеклист (сразу после возврата субагента)
git rev-parse HEAD— сравнить с pre-spawn parent SHA.- Равно → субагент не коммитил (OK для Edit-задач без commit).
- Отличается ровно одним коммитом, чей parent = pre-spawn HEAD → OK для commit-задач.
- Иначе → STOP, разбор инцидента.
git branch --show-current— сравнить с pre-spawn branch.- Не равно → STOP, разбор инцидента (Sprint 6 паттерн).
git log -1 --format='%s%n%P'— проверить subject + parent последнего коммита.- Subject соответствует задаче?
- Parent = pre-spawn HEAD?
- Если несколько коммитов — ручная проверка subject'ов каждого.
§C. Red-flag-список — любой = hard-stop разбор
branch ≠ ожидаемая;parent коммита ≠ pre-spawn HEAD(висячий коммит / попадание на чужую ветку);- HEAD двинулся, но субагент в отчёте об этом не упомянул;
- в diff'е есть файлы вне scope задачи.
§D. Обязательный формат отчёта субагента
Субагент в конце ответа выписывает блок:
=== 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 ===
Отсутствие блока = контроллер считает результат недостоверным и запускает §B-чеклист сам через Bash.
§E. Соотношение с code-review
Двухстадийное review (Pravila §4.5 / PSR_v1 R10) сохраняется. Git-safety-чеклист не заменяет code-review — он стоит до него (нет смысла ревьюить diff, если он не в той ветке).
- [ ] **Step 7.3: Verify скил**
Run:
```bash
ls -la .claude/skills/subagent-driven-development/
ls -la .claude/skills/subagent-driven-development/references/
Expected: SKILL.md + references/git-safety-checklist.md существуют.
- Step 7.4: Commit
git add .claude/skills/subagent-driven-development/
git commit -m "feat(skills): subagent-driven-development project wrapper + git-safety-checklist
Project-local обёртка над marketplace-скилом superpowers:subagent-driven-development.
Добавляет обязательный pre/post-subagent git-safety verify-протокол
per Pravila §15.1 (Sprint 6 прецедент-источник: Haiku-субагенты
угнали ветку параллельной сессии).
Состав:
- SKILL.md — точка входа, ссылка на marketplace + §A/§B/§C из checklist.
- references/git-safety-checklist.md — pre-spawn / post-subagent / red-flags / GIT REPORT format / code-review boundary.
Хук tools/subagent-prompt-prefix.mjs — первая линия защиты (auto-inject),
этот checklist — вторая линия (контроллер verify).
Spec: docs/superpowers/specs/2026-05-18-parallel-sessions-coordination-design.md §5.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>"
Task 8: Final regression + push
Files: none (verification + push only)
- Step 8.1: Update CURRENT.md status — release
Прочитать docs/sessions/CURRENT.md, изменить запись текущей сессии:
status: in-progress→status: closed-<последний commit SHA из git log -1>
Это append-only правка в смысле жизненного цикла — запись остаётся, только меняется статус.
- Step 8.2: Commit status change
git add docs/sessions/CURRENT.md
git commit -m "chore(sessions): release parallel-sessions-coordination session
status: in-progress → closed-<sha>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>"
- Step 8.3: Verify everything is staged correctly
Run:
git status
git log --oneline origin/main..HEAD
Expected: working tree clean (кроме dirty файлов вне нашего scope: .gitignore, app/dev-indices.json, _demo_* — не трогаем); git log показывает 8 atomic commits (по одному на task'у, + spec-commit 235b1d4 из brainstorming).
- Step 8.4: Pre-push full regression
Run параллельно (в одном tool-сообщении):
./bin/gitleaks.exe detect --source . --redact -v
Expected: 0 leaks (full history scan).
./bin/lychee.exe --no-progress 'docs/**/*.md' '*.md'
Expected: 0 broken links.
(Pest --parallel / Vitest — пропускаем: scope не трогает PHP/JS-код приложения, только tools/+docs/+.claude/. Если settings.json правка влияет на запуск сессии — это не testable в этом репо.)
- Step 8.5: Push to origin (только после явного «делай push» от заказчика)
git push origin feat/parallel-sessions-coordination:feat/parallel-sessions-coordination
Затем — либо PR через GitHub MCP, либо прямой FF-merge на main по решению заказчика. PR-вариант предпочтителен из-за объёма (8 atomic commits + новая нормативка §15).
- Step 8.6: Update memory
MEMORY.md
Через /claude-md-management:revise-claude-md (capture session-learnings) ИЛИ ручной Edit memory/MEMORY.md + создание memory/project_parallel_sessions.md. Важные факты:
- Pravila §15 — третье hard-rule (после §12, §14).
docs/sessions/CURRENT.md— claim/check/release координация.- Хук
tools/subagent-prompt-prefix.mjs— PreToolUse Task auto-inject. - Wrapper-скил
.claude/skills/subagent-driven-development/. - Прецедент Sprint 6 → исторический корень §15.1.
Self-Review
1. Spec coverage — каждая секция spec'а покрыта:
- spec §0 Контекст — упомянут в Goal плана.
- spec §1 Архитектура — 4 артефакта → tasks 1, 2, 3+4+6, 7.
- spec §2 Pravila §15 — Task 1 целиком (15.1/15.2/15.3 + список 8).
- spec §3 CURRENT.md — Task 2 (формат + lifecycle + retro-claim).
- spec §4 Хук — Tasks 3 (TDD red) + 4 (green) + 6 (register).
- spec §5 Verify-протокол — Task 7 (wrapper-skill + references).
- spec §6 Тесты+migration — Tasks 3+4 (хук-тесты), Task 2 (retro-claim migration), Task 8 (final regression).
- spec §7 Ограничения — учтены в pre-flight (§15 свободен verified) и в Task 7 (references-wrapper вместо vendor-патча — confirmed
.claude/skills/subagent-driven-development/отсутствует). - spec §8 Acceptance — все 7 пунктов адресованы tasks.
2. Placeholder scan — все шаги содержат конкретный код / точную команду / ожидаемый вывод. Никаких «TBD / implement later / add validation».
3. Type consistency — формат хука (JSON output структура) consistent между Task 3 (тесты) и Task 4 (имплементация): hookSpecificOutput.updatedInput.prompt, hookEventName: 'PreToolUse', permissionDecision: 'allow'. GIT REPORT формат (cwd / branch / HEAD / HEAD^ / status) consistent между Task 4 (header instructs subagent) и Task 7 (checklist §D).
4. Гарантии TDD — Task 3 явно требует RED-фазу (тесты падают), Task 4 — GREEN. Атомарные коммиты RED-then-GREEN сохраняют TDD-историю.
Risks / Out-of-scope
- Smoke-test перезапуска сессии (Task 6 Step 6.4) — может не сработать в текущем рабочем потоке (если плановщик хочет провести все таски в одной сессии). Mitigation: «verified at next session start» отметка в commit'е.
- Retro-claim accuracy (Task 2 Step 2.3) —
scope-filesдля existing worktrees заполнены best-effort изgit log -1 --name-only. Точность ограничена; активные сессии при возобновлении обновят свой блок. Spec §6.2 явно фиксирует «§15 действует с момента введения, не ретроактивно». - CLAUDE.md правки через плагин (Task 5) —
/claude-md-management:claude-md-improverможет предложить другие версии bump'а или другую формулировку footer-абзаца — это нормально, плагин — owner CLAUDE.md (§5 п.10). - Out-of-scope (явный YAGNI из spec §6.3): реестр зарезервированных версий, pre-commit hook на CURRENT.md, JSON-формат CURRENT.md, запрет параллельных сессий, изменения PSR_v1/Tooling, subagent-без-git (вариант C).