claude-harness/docs/superpowers/specs/2026-10-11-roles-and-memory-design.md
Andrey Epifancev 6744d40fb8 fix: согласовать шаблоны и link-roles со спайком памяти агентов
link-roles.sh больше не создаёт симлинки agent-memory (спека, раздел 11:
симлинк делает память read-only), doctor не проверяет их; шаблоны
workspace и role-repo описывают запасной вариант 6.5 (notes/agent-memory.md).
В спеке разделы 2, 6.5, 8 получили указатель на раздел 11. Заодно --map
без значения даёт русскую ошибку и exit 2.

Refs #2

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MzkPQWjfA7RpqYWkjnqJwt
2026-10-12 00:47:47 +04:00

32 KiB
Raw Blame History

Роли и память: дизайн

Дата: 11.10.2026. Источник: ретроспектива docs/retro/2026-10-11.md, находки RT-11, RT-13, RT-14, RT-15, бэклог B5+B6. Полигон: workspace awp-ca. Решение должно подходить и для следующих проектов.

1. Цель

Одна сессия Claude Code работает в одной из четырёх ролей: разработчик (dev), руководитель/администратор проекта (admin), аналитик требований (analyst), QA (qa). Сессия получает только контекст, правила и память своей роли, без ручных просьб «перечитай». Знания роли живут в git-репозитории направления, а не в локальной auto-memory, и переживают смену машины.

Критерии успеха:

  • владелец начинает сессию одной фразой или заголовком, роль определяется и объявляется без вопроса, когда она очевидна;
  • в сессии admin не загружаются инварианты DBML и процесс superpowers→Gitea→OpenSpec; в сессии dev не загружается Jira;
  • ни одно правило из нынешних ~/.claude/CLAUDE.md и awp-ca/CLAUDE.md не потеряно: у каждого абзаца есть новый адрес;
  • глобальный CLAUDE.md ≤ 3 КБ, проектный ≤ 5 КБ, индекс auto-memory ≤ 3 КБ;
  • стартовый контекст не-dev сессий меньше текущей медианы 56 К токенов (замер скриптом ретро);
  • хуки guard-main, require-plan, harness-check не меняются.

2. Модель workspace

Все сессии запускаются из корня workspace (не git). Рядом лежат репозитории направлений.

<project>/                    workspace, не git, cwd всех сессий
  CLAUDE.md                   общий минимум: что за проект, таблица репозиториев с ролью-владельцем, источники истины, «роли → /role»
  .claude/
    settings.json             как сейчас (хуки workspace, разрешения)
    roles/<r>.md              проектный слой ролей (dev — файл; admin/analyst/qa — симлинки в репозитории направлений)
    agents/<name>.md          симлинки на агентов из репозиториев направлений
    agent-memory/<name>/      симлинки на память агентов (не работает, см. раздел 11)
  <code repos>/               роль dev
  docs/                       витрина: контекст, модель, контракты, гайды, инструкции. Читают все, пишут через PR
  admin/      → arm-ka-admin      кухня admin: Jira, Гант, спринты, документы заказчику, notes/, .claude/
  qa/         → arm-ka-qa         кухня qa: сценарии, прогоны, скриншоты, находки, notes/, .claude/
  analysis/   → arm-ka-analysis   кухня analyst: черновики OQ, протоколы, сверки ТЗ с кодом, notes/, .claude/

Правило: docs/ публикует, репозиторий направления работает. У каждого раздела docs/ есть роль-владелец: context/, model/ — analyst; dev/, contracts/ — dev; user/, dev/qa-guide.md — qa; source/ — никто (экспорт). Рабочий материал (журналы прогонов, скриншоты, выгрузки Jira, черновики решений) в витрину не попадает или попадает после обработки.

Репозиторий направления содержит:

<dir>/
  CLAUDE.md                   что это за репозиторий, 5–10 строк (загружается лениво при чтении файлов из него)
  .claude/role                имя роли по умолчанию (одна строка) — для будущего режима запуска из репозитория
  .claude/roles/<r>.md        проектный слой роли
  .claude/agents/<name>.md    агенты роли
  .claude/agent-memory/<name>/MEMORY.md   память агентов (коммитится; см. раздел 11: симлинк не работает, применяется запасной вариант)
  notes/                      уроки, решения владельца, рецепты роли (markdown, коммитится)
  <рабочие каталоги>

Симлинки из <workspace>/.claude/ в репозитории направлений создаёт скрипт link-roles.sh (раздел 8), проверяет doctor.sh. Claude Code находит агентов и skills только в <cwd>/.claude/, поэтому без ссылок конфигурация направлений из корня не видна.

3. Слои ролей

Два слоя, оба в git:

Слой Где в источнике Куда ставится Что содержит
Общий claude-harness/roles/<r>.md ~/.claude/roles/<r>.md (install.sh) процесс роли, не зависящий от проекта
Проектный <repo направления>/.claude/roles/<r>.md, для dev — <workspace>/.claude/roles/dev.md симлинк в <workspace>/.claude/roles/ пути, инструменты, люди, ограничения проекта

При конфликте побеждает проектный слой. Общий слой roles/dev.md получает целиком нынешний процесс разработки из global/CLAUDE.md (маршрутизация, исполнение, завершение, маркировка, стиль). Проектный roles/dev.md в awp-ca получает из awp-ca/CLAUDE.md инварианты, стек, зеркальный worktree .wt/, DBML, 05-domain-rules, стенд, «чего не делать».

3.1 Формат файла роли

Одинаков для обоих слоёв. Четыре раздела, заголовки фиксированы, чтобы /role мог их склеить:

# Роль: admin — руководитель/администратор проекта
Эта роль заменяет предыдущую роль сессии целиком.

## Процесс
- какие skills и чеклисты действуют; что по умолчанию bounded; где трекер задач этой роли

## Читать на старте
- пути (относительно workspace) и команды; строки с префиксом `brief:` уходят агенту briefing, остальные читаются в контекст

## Не делать
- явные запреты роли

## Делегировать
- агент → для чего

3.2 Содержание общих файлов ролей (обвязка)

  • dev — нынешний глобальный CLAUDE.md без изменений по смыслу, плюс уроки из ретро, не зависящие от проекта: не cd в основной checkout, пока работает фоновый контроллер; абсолютные пути worktree в планах; trailer коммита проверяет ревьюер задачи; архив OpenSpec всегда отдельным PR (решение владельца 11.10.2026); пункт 4 чеклиста закрытия — через allow-правило проекта. Bounded-чеклист дополняется: «если меняется поведение API или схемы, спека обновляется в том же PR».
  • admin — задачи ведутся в трекере заказчика (Jira) или в репозитории направления, Gitea-issue и OpenSpec не заводятся; brainstorming остаётся входом, задачи по умолчанию bounded; код только в репозитории направления (скрипты, TDD); тексты для внешних людей самодостаточны (без внутренних маркеров, номеров PR и путей); артефакты для передачи — в deliverables/.
  • analyst — работа с требованиями: спеки, открытые вопросы, решения владельца, сверка ТЗ с кодом; код не пишется; публикация в docs/ через PR; противоречия документов не решаются молча, а фиксируются вопросом.
  • qa — стенд, прогоны сценариев, сверка каждого экрана с макетом, гайды и инструкции; код не меняется; находки — списком со скриншотами, issue в кодовый репозиторий заводит dev по решению владельца.

3.3 Проектные файлы ролей awp-ca

  • dev (workspace): репозитории и их CLAUDE.md, зеркальный worktree .wt/<задача>/ с симлинками, .bounded, venv через uv venv --python 3.11, стенд :8000/:3000, DBML v5.18 и 05-domain-rules как источники истины, инварианты (первичка не мутируется, производные не хранятся, VERIFIED read-only, единственный писатель arm-core, права — данные, один файл = N документов, парсеры не по координатам, деньги numeric, append-only аудит), «чего не делать», синхронизация arm-core/web скриптом sync-web.sh, codegraph обязателен на период замера (решение владельца 11.10.2026).
  • admin (в admin/): admin/README.md, пакет jira-sync/ и его README, Jira AURORA (доска 4216, правила текстов задач, переходы статусов), Гант (source/*.mpp, читать mpxj, Ган не трогать), просмотрщик sprint-2-links.html, команда и зоны ответственности, текущие операционные ограничения: apply в реальную Jira выполняет только владелец на виртуалке (ограничение снимается вместе с мостом из jira-sync/next-session-bridge.md). brief: — admin/notes/, последний jira-sync/runs/<дата>/.
  • analyst (в analysis/): docs/context/05-domain-rules.md, 07-open-questions.md, 04-data-model-guide.md, DBML, docs/source/tz/ (имена v4, алгоритмы рабочие), 08-source-docs-index.md; как оформлять OQ и решения; brief: — analysis/notes/decisions.md, открытые OQ.
  • qa (в qa/): docs/dev/qa-guide.md (§8 чек-лист UI), стенд и его ловушки, Playwright (окно 1600×1000, макет через http.server, запасной runner), docs/mockup/screens/*.png, docs/user/user-guide.md и рецепт скриншотов и docx, контрольные цифры прогонов; brief: — qa/notes/, последний qa/runs/<дата>/.

4. Выбор роли

Три входа, от автоматического к ручному. Запуск всегда из корня workspace, git-корень для определения роли не используется.

  1. Заголовок сессии. claude -n "admin …" (алиасы cc-admin, cc-dev, cc-qa, cc-analyst в профиле shell — рекомендация в README, не часть install.sh). Хук hooks/role-hint.sh на SessionStart (все источники: startup, resume, clear, compact) читает session_title; если он начинается с имени роли, печатает в stdout одну строку: [claude-harness] Роль сессии: admin. Вызови /role admin до первого ответа. Без заголовка молчит. Ничего не блокирует.
  2. Вывод из первого сообщения. Правило в глобальном CLAUDE.md: если роль очевидна (Jira, Гант, спринт → admin; стенд, прогон, скриншот, макет → qa; ТЗ, OQ, спека, методика → analyst; срез, issue, PR, тест, миграция → dev), сессия объявляет её одной строкой «Роль: admin; если не так, скажи» и вызывает /role. Если неочевидна, один вопрос с четырьмя вариантами.
  3. Явно. /role <r> в любой момент. Новая роль заменяет предыдущую, первая строка файла роли это говорит.

5. Skill /role

Источник: claude-harness/skills/role/SKILL.md, ставится в ~/.claude/skills/role/. Frontmatter: name: role, description, argument-hint: dev|admin|analyst|qa, user-invocable: true. Шаги:

  1. Прочитать ~/.claude/roles/<r>.md и <workspace>/.claude/roles/<r>.md (если проектного нет — сказать об этом одной строкой и работать по общему).
  2. Прочитать раздел роли из индекса auto-memory (## <Роль>) и перечисленные в нём файлы.
  3. Собрать строки brief: из раздела «Читать на старте» обоих слоёв и, если они есть, запустить агента briefing в фоне (Agent, subagent_type: briefing, run_in_background), передав роль и список. Остальные строки прочитать в контекст.
  4. Ответить пятью строками: роль; действующий процесс; что прочитано; чего в этой роли не делать; что ждёт решения владельца (из памяти роли). Когда придёт выжимка briefing, добавить её одним сообщением без пересказа.

/role без аргумента печатает текущую роль и список доступных.

6. Агенты

Все агенты — markdown с frontmatter Claude Code (name, description, model, tools, memory). Модель указывается явно.

6.1 briefing (общий, обвязка)

claude-harness/agents/briefing.md → ~/.claude/agents/briefing.md. model: sonnet, tools: Read, Glob, Grep, Bash, без memory. Промпт: получает роль и список путей/команд; команды выполняет только читающие (tea issues ls, openspec list, git log, ls); возвращает выжимку до 60 строк в фиксированной форме: Активные задачи / Решения за последние дни / Открытые вопросы / Ловушки. Не предлагает действий, не редактирует файлы.

6.2 jira-admin (в admin/.claude/agents/)

model: sonnet, memory: project, tools: Read, Write, Edit, Bash, Glob, Grep. Промпт содержит только инварианты, не зависящие от инструмента:

  • CSV в admin/jira-sync/ — источник истины и единственное место ключей созданных задач; ключи пишутся обратно сразу;
  • задания декларативные (что сделать), не произвольные команды; пароль Jira нигде, кроме config.json виртуалки;
  • тексты задач по правилам README пакета (самодостаточные, структура h3 Контекст / Что сделать / Критерии готовности / Источники);
  • инструментарий берётся из admin/jira-sync/README.md и доступных MCP-инструментов; что можно выполнять против реальной Jira — из проектного файла роли admin. Задачи: discover/plan в сухом режиме, перегенерация CSV, сверка Ганта с выгрузкой, черновики описаний, разбор спринта по CSV. Память: customfield'ы, ловушки REST (направление issueLink), люди и зоны, история актуализаций.

6.3 qa-runner (в qa/.claude/agents/)

model: sonnet, memory: project, инструменты: Read, Bash, Glob, Grep и Playwright MCP (mcp__plugin_playwright_playwright__*), без Write/Edit в репозиториях кода (запись только в qa/runs/). Задачи: прогон сценария на локальном стенде, сверка каждого экрана с PNG макета при окне 1600×1000, список расхождений со скриншотами в qa/runs/<дата>/. Не меняет код; находки отдаёт списком. Память: ловушки стенда, порты, токены (sessionStorage['armka.token']), запасной runner playwright-core, контрольные цифры.

6.4 Что не меняется

SDD-контроллер и implementer-ы остаются описанием в roles/dev.md (superpowers запускает их сам). Аналитик без агента.

6.5 Память агентов через симлинк

memory: project пишет в <cwd-проект>/.claude/agent-memory/<name>/. Чтобы память оказалась в git репозитория направления, <workspace>/.claude/agent-memory/<name> — симлинк в <dir>/.claude/agent-memory/<name>. Проверяется первой (раздел 9). (см. раздел 11: симлинк не работает; применяется запасной вариант) Запасной вариант: поле memory не используется, промпт агента велит читать <dir>/notes/agent-memory.md при старте и дописывать в конце.

7. Память

7.1 Политика (в глобальный CLAUDE.md, три строки)

  • Состояние задачи живёт в трекере (Gitea issue, Jira), не в памяти.
  • В репозиторий направления (<dir>/notes/, память агента) пишутся уроки, решения владельца, рецепты. Коммит в той же ветке, что и работа.
  • В локальную auto-memory — только ловушки этой машины и обвязки и индекс со ссылками на notes/ направлений.

Чеклист закрытия, новый пункт 8: файл auto-memory задачи, если был, сворачивается в строку registry-closed.md (issue, PR, follow-up, дата); уроки из него переносятся в notes/ направления.

7.2 Индекс auto-memory после чистки

## Общее          — ловушки машины, обвязка, фидбек владельца по процессу
## Разработка     — ссылка на .claude/roles/dev.md и docs/dev/, активные уроки
## Администрирование — ссылка на admin/notes/, память jira-admin
## Аналитика      — ссылка на analysis/notes/decisions.md
## QA             — ссылка на qa/notes/, память qa-runner
## Закрытое       — registry-closed.md

7.3 Одноразовая чистка 47 файлов awp-ca

На копии памяти в песочнице; дифф показывается владельцу до замены; оригинал сохраняется как memory.bak-<дата>/.

Куда Что
registry-closed.md (auto-memory) 30 файлов «ЗАКРЫТ»: одна строка на задачу
admin/notes/jira.md + память jira-admin jira-backlog-actualization, трудозатраты из slice-0-proposals-state, рецепт Word из user-guide-85-state
qa/notes/ + память qa-runner qa-local-stand, q1-2025-run, pdfjs-legacy-yandex, рецепт скриншотов, feedback-compare-with-mockup (как правило роли qa)
analysis/notes/decisions.md решения владельца по OQ из oq-decisions-62, slice-1/2c/3a/3b/4-state, tech-debt-slice-1, osv-inn-mapping-rework, auto-confirm-64, statement-template-lines-state
<workspace>/.claude/roles/dev.md или docs/dev/ workspace-hooks-and-worktrees (уроки), nats-platform-fileworker, arm-web-repo, sync-web-script-state
claude-harness/roles/dev.md уроки без привязки к проекту (cwd и контроллер, пути в планах, trailer)
остаются в auto-memory feedback-no-harness-bypass, feedback-execution-mode-from-claude-md, harness-retro-and-roles, jetstream-check-later

admin/jira-sync/next-session-bridge.md после переноса ссылается на admin/notes/jira.md вместо памяти jira-backlog-actualization.

8. Изменения в обвязке (claude-harness)

Файл Изменение
global/CLAUDE.md сжать до ≤ 3 КБ: язык, хуки, worktree, маркировка, политика памяти (7.1), правило выбора роли (раздел 4), «процесс роли — в /role»
roles/{dev,admin,analyst,qa}.md новые, формат 3.1
skills/role/SKILL.md новый, раздел 5
agents/briefing.md новый, 6.1
hooks/role-hint.sh + hooks/settings.hooks.json новый SessionStart-хук; слияние блока в install.sh как у harness-check
link-roles.sh новый: по таблице репозиториев в CLAUDE.md workspace (или по аргументам) создаёт симлинки .claude/roles, .claude/agents (и .claude/agent-memory, см. раздел 11: симлинк не работает, в реализации не создаётся); идемпотентно; печатает, что сделано
install.sh ставит roles/, skills/role, agents/briefing.md, hooks/role-hint.sh, link-roles.sh в ~/.claude/harness/; --check проверяет их наличие
project-template/ .claude/roles/*.md заготовки; role-repo/ шаблон репозитория направления (CLAUDE.md, .claude/role, notes/README.md)
adopt-project.sh / new-project.sh режим --workspace: создать CLAUDE.md workspace, .claude/roles/, вызвать link-roles.sh; существующий режим не меняется
skills/harness-doctor/scripts/doctor.sh проверки: симлинки ролей целы, role-hint.sh отвечает на тестовый JSON, размеры CLAUDE.md и индекса памяти
docs/HARNESS.md, README.md, CHANGELOG.md раздел «Роли», версия 0.3.0

Хуки guard-main.sh, require-plan.sh, harness-check.sh не меняются (правки хуков — отдельная работа B1+B2).

9. Песочница, проверка, перенос

Песочница ~/projects/awp-ca-roles/: симлинки на все репозитории awp-ca, копии CLAUDE.md, .claude/, копия памяти (своя auto-memory из-за другого cwd). Репозитории admin/, qa/, analysis/ создаются настоящими git-репозиториями в awp-ca/ (git init не трогает файлы; репозитории в Gitea заводятся по команде владельца). Ветка обвязки ставится в песочницу не через ~/.claude/, а через CLAUDE_CONFIG_DIR только если это понадобится; по умолчанию общий слой проверяется копированием файлов ролей в .claude/ песочницы, а install.sh выполняется один раз при переносе.

Проверки (каждая — задача плана с ожидаемым результатом):

  1. Симлинки агентов и памяти: агент виден в списке Agent, запись в память попадает в admin/.claude/agent-memory/. Иначе — запасной вариант 6.5.
  2. role-hint.sh: JSON с session_title: "admin …" даёт строку подсказки; без заголовка — пустой вывод; тест в doctor.sh.
  3. Четыре сессии (claude -n admin|qa|analyst|dev): /context показывает файлы своей роли и не показывает чужие; стартовый контекст не-dev сессий меньше 56 К (скрипт docs/retro/scripts/retro_blocks.py по транскрипту песочницы).
  4. /role admin в dev-сессии переключает правила; briefing возвращает выжимку.
  5. Размеры: глобальный CLAUDE.md ≤ 3 КБ, проектный ≤ 5 КБ, индекс ≤ 3 КБ. Сверка «каждый абзац старых CLAUDE.md имеет адрес» — таблицей в PR.
  6. Чистка памяти: дифф на копии, таблица 7.3 выполнена, next-session-bridge.md обновлён.

Перенос по команде владельца: дифф ~/.claude/CLAUDE.md и памяти с состоянием на момент форка (11.10.2026) → install.sh из ветки обвязки → копирование .claude/ и CLAUDE.md из песочницы в awp-ca/ → замена памяти с бэкапом → удаление песочницы.

10. Вне объёма

  • Правки хуков guard-main/workspace (B1, B2, B10) — отдельная ветка после ролей.
  • Мост jira-sync (admin/jira-sync/next-session-bridge.md) — brainstorming в роли admin после переноса.
  • Skill /harness-retro (B12) — третий подпроект; сюда входит только размещение скриптов ретро в docs/retro/scripts/.
  • Запуск сессий из репозитория направления (.claude/role по git-корню) — файл создаётся, механизм не реализуется.

11. Открытые вопросы

  • Работает ли memory: project через симлинк каталога — проверено 2026-10-11 (план, Task 1): нет. Агент с memory: project в песочнице, где .claude/agent-memory/probe — симлинк на каталог вне рабочей копии, сообщил, что память только для чтения и MEMORY.md не загружен; ничего не записано ни в целевой каталог симлинка, ни в обход него (повтор через промпт «Используй агента probe» и с --add-dir на целевой каталог дал то же). Контроль с обычным каталогом .claude/agent-memory/probe записал MEMORY.md с probe-ok 2026-10-11. В части 2 применяется запасной вариант 6.5.
  • Имена репозиториев в Gitea: предложено RSHB/arm-ka-admin, RSHB/arm-ka-qa, RSHB/arm-ka-analysis; подтверждает владелец при создании.
  • Алиасы cc-<роль>: в профиле shell владельца, обвязка только документирует.

Decisions made without discussion

  • 11.10.2026. Файлы ролей общего слоя ставятся в ~/.claude/roles/, а не внутрь skill role. Обоснование: проектный слой лежит в .claude/roles/, одинаковый путь в обоих слоях проще объяснить и проверить в doctor. Цена ошибки: перенос каталога.
  • 11.10.2026. Агенты направлений объявляются в репозитории направления и подключаются симлинками, а не копируются в workspace. Обоснование: один источник в git, видимость из корня. Цена ошибки: если симлинки не работают, копирование скриптом link-roles.sh.
  • 11.10.2026. briefing запускается в фоне, а не блокирует /role. Обоснование: владелец может начать говорить сразу. Цена ошибки: выжимка приходит после первого ответа; если это мешает, флаг --wait.
  • 11.10.2026. Спека лежит в docs/superpowers/specs/ репозитория обвязки, а не в openspec/: обвязка к самой себе не подключена, OpenSpec в ней нет. Вопрос «подключать ли обвязку к обвязке» открыт, владельцу не задавался. Цена ошибки: перенос файла.
  • 11.10.2026 (план). Тесты пакета — tests/run.sh на bash в репозитории, в дополнение к самотесту doctor.sh (спека, раздел 8, упоминала только doctor). Обоснование: TDD по задачам плана невозможен против установленных копий. Цена ошибки: лишний каталог.
  • 11.10.2026 (план). Хук role-hint.sh регистрируется записью без matcher (документация: отсутствующий matcher = все источники), а не перечислением startup|resume|clear|compact. Цена ошибки: одна строка в settings.hooks.json.
  • 11.10.2026 (план). Формат таблицы репозиториев workspace зафиксирован: | Каталог | Репозиторий | Роль |; link-roles.sh и doctor.sh узнают workspace по заголовку этой таблицы. Цена ошибки: правка двух regex.
  • 11.10.2026 (план). role-hint.sh понимает заголовок без учёта регистра и с префиксом cc- (алиасы из README). Цена ошибки: нет.
  • 11.10.2026 (план). Часть 2 (awp-ca: проектные файлы ролей, агенты jira-admin/qa-runner, репозитории направлений, чистка памяти, песочница, перенос) — отдельный план в workspace awp-ca после merge этой ветки; каталог для роли analyst — analysis/. Цена ошибки: нет.
  • 11.10.2026 (план). Чеклист закрытия получил п. 7 (память задачи, спека 7.1) и новый п. 8 (итоговое сообщение); нумерация старых п. 1–6 сохранена.