Peer Conversation (DP.SC.154)

SkillWeb & browsing

Multi-turn dialogue between a writer (Claude) and one or more partners (any set of kimi/codex/hermes/claude-headless) on a pilot task (DP.SC.154). Runs a turn-loop (2 participants) or round-loop (3+, WP-509), detects CONSENSUS/ESCALATE, and after consensus holds a Decision Gate (record vs re

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Peer Conversation (DP.SC.154) skill

What this skill tells your AI

The instructions your AI receives, as published by tserentserenov/fmt-exocortex-template in .claude/skills/peer-conversation/SKILL.md and read by ahel’s review.

Задача: $ARGUMENTS

Архитектура: я (Claude) = писатель всегда (Skill tool доступен только мне в этой сессии). Напарник(и) — параметр --peer (default kimi), список из одного или нескольких зарегистрированных вендоров (§0в). При 2+ напарниках (N>2 участников целиком) — расширение WP-509, см. §0в и §3р. Каждый напарник вызывается через свой <vendor>-peer-adapter.sh напрямую — Bash tool, stdin pipe. Контракт одинаковый у всех: stdin = промпт, stdout = реплика, exit 0-5 (см. §0в). Напарнику запрещено писать файлы своими инструментами внутри SESSION_DIR — только stdout (гонка file-write vs stdout-capture портит журнал, найдено WP-509 2026-07-30). list_peer_statuses (Local Gateway) — координация файлов, не проверка доступности напарника CLI. Gateway offline ≠ напарник недоступен.


When to use

Многотуровый диалог писателя (Claude) с одним или несколькими напарниками (любой набор зарегистрированных вендоров — Kimi, Codex, Hermes, второй Claude-инстанс headless) по задаче пилота (DP.SC.154). При одном напарнике — turn-loop (пара реплик). При двух и более напарниках — round-loop (WP-509): каждый раунд высказывается каждый участник, с явной role-discovery фазой (раунды 0–2), валидацией реплик по 4 критериям, лимитом повторных вызовов и классификацией результата agreed|partial|escalated|not-agreed. Обнаруживает CONSENSUS/ESCALATE, после консенсуса — Decision Gate (зафиксировать vs реализовать → ревью → проверить → задеплоить), синтезирует report.md через Agent tool.

Scope boundary — не подменяет решения, зарезервированные за пилотом (найдено 2026-07-07)

Peer-сессия пригодна для: технических решений, дизайна, code review, поиска компромисса между подходами, подготовки кандидатов к решению. НЕ пригодна для решений, которые процесс явно закрепляет за человеком (например, R15 Валидатор в /apply-captures — accept/reject/defer кандидатов знания; R1 Стратег — приоритеты месяца). Согласие двух агентов между собой — не решение пилота, даже единогласное и хорошо обоснованное.

Если задача внутри пир-сессии требует такого решения — писатель обязан остановиться и спросить пилота напрямую в текущем чате (не через turn-файл), прежде чем фиксировать результат. См. .claude/skills/apply-captures/SKILL.md раздел «R15 = живой пилот, не агент» и ${IWE_GOVERNANCE_REPO:-DS-strategy}/inbox/bugs/bug-2026-07-07-r15-decisions-bypassed-pilot.md — прецедент, из-за которого добавлено это ограничение.

Шаг 0. Режим

Определить режим из $ARGUMENTS:

  • --list → прочитать ${IWE_GOVERNANCE_REPO:-DS-strategy}/sessions/00-index.md, вывести таблицу. Файла нет → явно сообщить «индекс сессий ещё не создан (его создаст первая пир-сессия, шаг 1.3); прошлые сессии смотри в дереве sessions/YYYY-MM/DD/» — не молчать (issue #568). Стоп.
  • --interrupt <id> → перейти к Шагу 5 (interrupt-режим). Стоп после.
  • --finalize <id> → перейти к Шагу 6 (finalize-режим). Стоп после.
  • Иначе → новая сессия, продолжать к Шагу 0в.

Шаг 0в. Выбор напарника(ов) (--peer)

Добавлено 2026-07-29 (АрхГейт: вариант «параметризовать» против «отдельный скилл на вендора» — эволюционируемость заблокировала копипаст, см. sessions/2026-07/2026-07-29-*-wp401-peer-vendor.md). Расширено 2026-07-30 (WP-509): список из N>1 напарников вместо одного.

Извлечь --peer <vendor1,vendor2,...> из $ARGUMENTS (через запятую, без пробелов). Нет флага → PEER_VENDORS=(kimi) (обратная совместимость с версией до 1.4.0). Один vendor без запятой → PEER_VENDORS=(<vendor>), поведение идентично версии 1.4.0 — отдельного code path для одного напарника не заводить, PEER_COUNT=${#PEER_VENDORS[@]} управляет веткой (turn loop §3 при PEER_COUNT==1, round loop §3р при PEER_COUNT>=2).

Реестр вендоров (единственное место маппинга — OwnerIntegrity; новый вендор добавляется только здесь):

PEER_VENDORАдаптерpeer_agent (meta.yaml)Поддерживает --add-dirПоддерживает --modelОсобый флаг
kimiscripts/kimi-peer-adapter.shkimi-headlessдада
codexscripts/codex-peer-adapter.shcodexдада
hermesscripts/hermes-peer-adapter.shhermesнетнет--session-id <id> вместо
claudescripts/claude-peer-adapter.shclaude-code-headlessнетдаtext-only; контекст в stdin

Каждый элемент PEER_VENDORS валидировать отдельно. Неизвестный PEER_VENDOR в списке → СТОП на этом элементе, не на всём списке: сообщить пилоту, какой конкретно vendor не распознан («Напарник <vendor> не зарегистрирован. Известные: kimi, codex, hermes, claude.»), предложить продолжить с оставшимися распознанными или прервать целиком. Добавление нового вендора — правка таблицы выше + написание <vendor>-peer-adapter.sh по контракту §0в.1.

§0в.1 Общий контракт адаптера (для добавления нового вендора): stdin = полный промпт хода (Bash pipe, не inline echo — inline попадает в командную строку и хук B7.7c может ложно заблокировать повторные вызовы); stdout = одна реплика с frontmatter; exit 0 = OK, 1 = general error, 2 = content-filter/PII violation, 3 = PII hard block, 5 = уже идёт сессия (pidfile lock). Для claude действует усиленный контракт WP-458: --add-dir запрещён, peer получает только минимальную текстовую проекцию в stdin и не имеет файловых или shell-инструментов. Коды 2-5 — не обязательны для нового адаптера, но 0/1 обязательны (Шаг 3.1/3р.1 проверяет exit ≠ 0 как «напарник не ответил»).

Построить для каждого vendor в PEER_VENDORS: ADAPTER_PATH[$vendor]="$HOME/IWE/${IWE_GOVERNANCE_REPO:-DS-strategy}/<адаптер из таблицы>" и PEER_AGENT_ID[$vendor]="<peer_agent из таблицы>" (bash associative arrays; порядок вызова = порядок PEER_VENDORS). Используются везде ниже вместо хардкода kimi-peer-adapter.sh/kimi-headless.

§0в.2 Проверка доступности vendor'ов (capability-check, WP-509 Ф5). После построения ADAPTER_PATH, до анонса напарников:

  1. Дубликаты в списке (--peer codex,codex) → отклонить: N участников не подменяется повторными вызовами одного напарника; сообщить пилоту, стоп до исправления списка.
  2. Проверка каждого vendor (накопить доступных в remaining):
    remaining=()
    for vendor in "${PEER_VENDORS[@]}"; do
      ok=true
      if [[ ! -x "${ADAPTER_PATH[$vendor]}" ]]; then ok=false; fi  # адаптер отсутствует/не исполняем
      if [[ "$vendor" == hermes ]] && ! command -v hermes >/dev/null 2>&1; then ok=false; fi  # CLI hermes недоступен
      $ok && remaining+=("$vendor") || :  # недоступный — кандидат на исключение (п. 3)
    done
    
    Живой probe-вызов CLI НЕ делать: ошибки всплывут при вызове по контракту адаптера (exit ≠ 0, Шаг 3.1/3р.1); vendor-specific знания сверх hermes в скилл не добавлять (иначе Шаг 0в расходится с адаптерами).
  3. Недоступный vendor → сообщить пилоту какой именно и почему (нет адаптера / нет CLI), предложить продолжить с оставшимися или прервать — тот же UX, что для незарегистрированного vendor (стоп на элементе, не на списке).
  4. Нормализация после исключений (атомарно):
    PEER_VENDORS=("${remaining[@]}")
    PEER_COUNT=${#PEER_VENDORS[@]}
    round_order=("${PEER_VENDORS[@]}")
    
    Режим выбирается заново: PEER_COUNT>=2 → round-loop (§3р), ==1 → turn-loop (§3 — сценарий «запрошены codex,hermes, остался codex» идёт классическим диалогом вдвоём, не усечённым кругом), ==0 → безусловный стоп с сообщением пилоту.

Анонсировать пилоту:

Напарник: <PEER_VENDOR> (<peer_agent>)                    # PEER_COUNT == 1, как раньше

или при PEER_COUNT >= 2:

Напарники (<PEER_COUNT>):
  1. kimi (kimi-headless)
  2. codex (codex)

Шаг 0б. Открытие (WP Gate — только для новой сессии)

Найти WP по задаче: прочитать ${IWE_GOVERNANCE_REPO:-DS-strategy}/WP-REGISTRY.md (grep по ключевым словам) и ${IWE_GOVERNANCE_REPO:-DS-strategy}/current/WeekPlan W{N}.md.

Анонс пилоту:

Открываю peer-сессию (DP.SC.154)
Роль: Писатель (Claude) | Напарник(и): <PEER_VENDOR (PEER_AGENT_ID)>[, ...]
Задача: <задача>
РП: WP-NNN «<название>» | или: не найден в плане
Метод: turn-loop ≤10 ходов (PEER_COUNT==1) | round-loop ≤rounds_limit раундов (PEER_COUNT>=2, WP-509)

Если РП не найден в плане недели → полный WP Gate Ритуал (memory/protocol-open.md §Сессия): объявить артефакт + дождаться подтверждения пилота → только после «да» переходить к Шагу 1.

Если РП найден → продолжать без ожидания.

Определение рекомендуемой модели писателя (WP-394 Ф4.6):

# informational — pilot selects model at Claude Code startup, not auto-applied here
verification_class = из WP контекста или из описания задачи
WRITER_MODEL_RECOMMENDED = "sonnet"   # default: закрытые задачи с тестами/чёткой проверкой
if verification_class in ("open-loop", "problem-framing"):
    WRITER_MODEL_RECOMMENDED = "opus"

Анонсировать пилоту:

Модель писателя (рекомендуется): <WRITER_MODEL_RECOMMENDED>
(Класс задачи: <verification_class>. Выбери модель при запуске Claude Code.)

Подсказка маршрутизации агента (WP-383, информационная — не enforcement). По классу работы есть рекомендуемый инициатор/агент. Это подсказка пилоту, не блокировка:

Класс работыРекомендуемый агент
Уборка / форматирование / триажKimi (дёшево, быстро)
Верификация shallow (формат/чеклист/drift)Kimi
Верификация deep (cross-file invariant)Claude (statefulness)
Реализация multi-file / tight-loopClaude (держит состояние сессии)
Дизайн / scope / планированиесильная модель (Claude/Opus или Kimi)

Trigger эскалации (лог, не блок): если пилот 2 раза подряд выбирает агента вопреки подсказке — записать сигнал «routing-таблица устарела или классификация неверна» в inbox/WP-383/routing-drift.log (создать при первом срабатывании). Не блокировать выбор пилота.

Источник таблицы: ${IWE_GOVERNANCE_REPO:-DS-strategy}/inbox/WP-383/routing-design-v1.md §3. Statefulness-пробел Kimi закрыт автопередачей git-diff в kimi-peer-adapter.sh (§8).


Шаг 1. Инициализация

SESSIONS_DIR="$HOME/IWE/${IWE_GOVERNANCE_REPO:-DS-strategy}/sessions"
TODAY=$(date +%Y-%m-%d)
MONTH=$(date +%Y-%m)
DAY=$(date +%d)
DAY_DIR="$SESSIONS_DIR/$MONTH/$DAY"
mkdir -p "$DAY_DIR"
NUM=$(printf "%02d" $(( $(find "$DAY_DIR" -maxdepth 1 -type d -name "${TODAY}-[0-9][0-9]-*" 2>/dev/null | wc -l | tr -d ' ') + 1 )))

Slug = первые 4 латинских слова из задачи строчными буквами через дефис (не-латиница и дата убираются). Никакой даты в slug — она уже в SESSION_ID. Если латиницы нет → session.

SESSION_ID="${TODAY}-${NUM}-${SLUG}" SESSION_DIR="${DAY_DIR}/${SESSION_ID}"

1.0 Session-guard open (WP-398, обязательно, ДО любых Write/Edit в сессии). Синхронизирует пир-сессию с session-guard.sh Scope gate — без этого коммит на Шаге 4.5 будет заблокирован pre-commit хуком (mtime файлов сессии старше семафора). WP берётся из Шага 0б (найденный или «day-close»/«unknown», если РП не назначен):

IWE_AGENT=claude-code bash "${IWE_SCRIPTS:-$HOME/IWE/scripts}/session-guard.sh" open \
  --wp "<WP-NNN из Шага 0б>" --agent claude-code --close-path peer-session \
  --task "<задача одной строкой>" --slug "$SESSION_ID"

Не хардкодить ~/IWE/scripts/session-guard.sh. Пир-сессия 2026-07-31-16-wp484-new-order-cutover сначала внесла такой хардкод по образцу day-close/SKILL.md, но холодный ревью нашёл: у обычного пользователя шаблона setup.sh НЕ копирует корневую scripts/ — существует только каталог скриптов внутри шаблона, и ${IWE_SCRIPTS:-...} резолвится именно туда намеренно (issue #266, commit 835d5ea — тот же хардкод уже один раз чинили этим фоллбэком). Хардкод в day-close/SKILL.md — недокументированный долг, ждущий той же поломки при промоции, не образец для копирования. Для author-mode расхождение реальное (FMT-копия session-guard.sh отстаёт от корневой на фиксы WP-484 Нить1) — но лечится синком template-sync.sh (с отдельного разрешения пилота, S-33) или личной правкой ~/.iwe-paths, не хардкодом в файле, который промотируется всем пользователям шаблона.

Если команда упала (exit ≠ 0) — не блокировать сессию: сообщить пилоту одной строкой «session-guard open не сработал (<причина>), продолжаю без семафора — на Шаге 4.5 возможна ручная разблокировка через touch/note-file» и идти дальше. Semaphore-файл session-guard создаёт СВОЙ ORZ-скаффолд-заготовку по пути sessions/<MONTH>/<TODAY>-<CLEAN_SLUG>.md — тот же путь, что закрывающий файл пир-сессии из Шага 4.4/4.5.0 (до 2026-08-03 эти два места ошибочно считали разные пути, см. пометку на Шаге 4.4); Шаг 4.5.0 дописывает в этот же файл финальное содержимое, а не создаёт новый.

1.1 Создать папку:

mkdir -p "$SESSION_DIR"

1.2 Записать meta.yaml (Write):

task_id: ""
date: "<TODAY>"
session_id: "<SESSION_ID>"
start_time: "<ISO-8601 UTC>"
end_time: ""
writer_agent: "claude-code"
personality: "<unassigned|UUID>"   # WP-510 Патч 4, слой 3: writer_agent = конструктивная реализация; personality = какая ИИ-личность (если есть авторитетная запись в `current/AI Personalities Registry.md` для текущего хоста/раннера) вела сессию. Ищи по хосту/раннеру в реестре — не выдумывай; нет однозначного совпадения → "unassigned". Маршрутизирующая метка, не допуск к памяти.
peer_agent: "<первый PEER_AGENT_ID из §0в>"      # backward-compat (PEER_COUNT==1: единственный); полный список — peer_agents
peer_cmd: "<первый PEER_VENDOR>-peer-adapter"     # backward-compat; полный список — peer_cmds
peer_agents: ["<PEER_AGENT_ID>", "..."]   # WP-509: в порядке PEER_VENDORS, длина 1 при PEER_COUNT==1 (дублирует peer_agent); §4.2 читает ТОЛЬКО это поле для report.md peer: при PEER_COUNT>=2
peer_cmds: ["<vendor>-peer-adapter", "..."]   # WP-509: та же длина/порядок, что peer_agents
round_order: ["<vendor>", "..."]   # WP-509: фиксированный порядок раунда (= PEER_VENDORS), только при PEER_COUNT>=2
write_token_holder: "writer_agent"   # WP-509: держатель write token сейчас; default = writer_agent, меняется только через подтверждённый ACCEPT_HANDOFF (см. §3р.3)
peer_model: ""
status: "started"
turns_count: 0
turns_limit: 10        # PEER_COUNT==1: лимит реплик, без изменений с v4
rounds_limit: 6         # WP-509: лимит раундов, применяется только при PEER_COUNT>=2, НЕ переопределяет turns_limit
round_skips: {}        # WP-509: {round_NN: [vendor, ...]} — кто не ответил/пропустил раунд; исключаются из требования "консенсус у каждого" в §3р.3
participant_status: {}  # WP-509: {vendor: active|failed} — финальный статус участника после исчерпания попыток
max_peer_attempts: 2    # WP-509: лимит повторных вызовов одного peer подряд
peer_attempts: {}     # WP-509: {vendor: N} — счётчик вызовов в текущем раунде
peer_failures: []      # WP-509: [{round, vendor, reason}] — зафиксированные отказы участников
handoff_history: []    # WP-509: [{round, from, to, reason}] — журнал OFFER_HANDOFF/ACCEPT_HANDOFF (write token, DP.SC.154 «Write token ≠ process_position»)
escalations_count: 0
extensions: []
result_path: ""
task_description: "<задача>"
implementation_pipeline: false
review_iterations: 0
verify_status: ""
deploy_shas: {}
writer_model_recommended: "sonnet"  # informational — pilot selects model at startup, not auto-applied; opus only for open-loop|problem-framing
# Sequential role-discovery (WP-367) — заполняется во время Opening:
# Если пилот задал явно — сразу заполни `roles`.
# Если не задал — initiator в ход 0 заполняет `proposed_roles` в frontmatter 00-writer.md;
#                  после согласования (ход 2) переноси в `roles`.
roles: {}            # финальное: {agent_id: [DP.ROLE.NNN, ...]} после consensus
discovery_turns: 0   # сколько ходов ушло на role-discovery (не считается в turns_limit)
# Двухосная модель (WP-367 Ф5, DP.SC.154 v4):
ad_hoc_roles: {}     # {role_name: {agent_id, rationale, first_used_turn}} — для каскада audit
swap_history: []     # [{turn, from, to, reason}] — журнал SWAP_WRITER переходов

Если пилот не назначил роли при запуске сессии — initiator в ход/раунд 0 предлагает свою роль и роль каждого напарника (см. DP.SC.154 раздел «Opening сессии: Sequential role-discovery», при PEER_COUNT>=2 — раздел «Role-discovery для N>2»). Discovery-ходы/раунды (0-2) не входят в turns_limit/rounds_limit.

In-session ad-hoc role signal (DP.SC.154 v4, каскад Pack-расширения уровень 1). При использовании ad-hoc роли (нет в Pack DP.ROLE.NNN/MIM.R.NNN/VR.R.NNN) агент обязан сразу объявить пилоту — формат:

Беру ad-hoc роль «<имя>». В каталоге Pack такой нет.
Обязанности: <одной строкой>. Метод: <одной строкой>.
Предлагаю создать РП на формализацию (~30 мин: passport + scenarios + templates).
Выбери:
  А. Создать сейчас → отдельный РП «pack-gap-<имя>» через create-wp.sh.
  Б. Отложить → продолжу как ad-hoc, сторож напомнит при Week Close.

Запись в meta.yaml.ad_hoc_roles идёт независимо от выбора (для back-up на уровне 2 — Week Close audit). Если пилот выбрал А — после сессии писатель открывает отдельный РП и делает формализацию.

1.3 Добавить строку в sessions/00-index.md сверху таблицы (первая строка таблицы после |---|). Колонка «Агенты» — при PEER_COUNT>=2 напарники соединяются через +:

Файла нет — создать его сейчас (issue #568: установка индекс не создаёт, и до этой правки шаг молча не исполнялся — восемь сессий подряд без единой записи). Временная мера до РП-526 (семейство MC переведёт индекс на snapshot-механику — при миграции этот блок удалить). Создаваемый файл обязан честно объявлять свою неполноту прямо в себе (не в stdout — вывод теряется, а файл читают через недели):

IDX="${IWE_GOVERNANCE_REPO:-DS-strategy}/sessions/00-index.md"
if [ ! -f "$IDX" ]; then
  mkdir -p "$(dirname "$IDX")"
  {
    echo "# Индекс пир-сессий"
    echo ""
    echo "<!-- index regenerated on $(date +%Y-%m-%d): created empty by peer-conversation step 1.3 (issue #568) — sessions before this date exist on disk but are NOT backfilled here; the folder tree sessions/YYYY-MM/DD/ is the authoritative record -->"
    echo ""
    echo "| Дата | Сессия | Задача | Агенты | Ходы | Эскалации | Статус | Отчёт |"
    echo "|------|--------|--------|--------|------|-----------|--------|-------|"
  } > "$IDX"
fi
| <TODAY> | <SESSION_ID> | <задача ≤50 симв> | claude-code / <PEER_VENDOR1>[+<PEER_VENDOR2>...] | 0 | 0 | started | — |

Шаг 2. Реплика писателя 00-writer.md

Записать ${SESSION_DIR}/00-writer.md (Write):

---
turn: 0
role: writer
agent_id: claude-code
timestamp: <ISO-8601 UTC>
consensus: none
---

<Моя начальная позиция — анализ задачи, тезисы, конкретные вопросы к напарнику(ам).
При `PEER_COUNT>=2` — предложить содержательную роль каждому напарнику отдельно (не только «роль для группы»), с обоснованием на каждого (DP.SC.154 «Role-discovery для N>2»).
НЕ пересказ задачи. Позиция с аргументами.>

Показать пилоту краткое резюме: что написал в 00-writer.md.


Шаг 2.5. Role-discovery для N>2 (PEER_COUNT >= 2, WP-509)

Пропустить, если PEER_COUNT == 1. Для двух участников discovery сводится к предложению ролей в 00-writer.md и согласованию в turn-loop.

После 00-writer.md запустить раунды 0–2, которые не входят в rounds_limit.

2.5.1 Раунд 0 — писатель предлагает роли

В 00-writer.md (Шаг 2) писатель уже предлагает содержательную роль каждому напарнику. Дополнительно записать в frontmatter 00-writer.md:

proposed_roles: { "<PEER_AGENT_ID>": "<role_name>", ... }
suggested_initiator_role: "<role_name>"

2.5.2 Раунд 1 — каждый peer подтверждает или спорит роль

Вызвать каждого напарника по порядку round_order с промптом, аналогичным §3р.1, но с единственной задачей:

  • прочитать 00-writer.md;
  • согласиться с предложенной ролью, предложить правку или запросить уточнение у пилота;
  • явно подтвердить, что понимает ограничение «ответ только в stdout, никаких файловых операций в SESSION_DIR».

Формат реплики:

---
turn: 0
role: peer
agent_id: <PEER_AGENT_ID>
content_role: <согласованная/предложенная роль>
process_position: peer
timestamp: <ISO-8601 UTC>
consensus: none
role_accepted: true | false | clarify
---

<Обоснование принятия роли или запрос уточнения>

Если role_accepted: clarify — писатель уточняет у пилота и повторяет раунд 1 только для этого участника (не считается отдельным раундом discovery).

2.5.3 Раунд 2 — фиксация agreed_roles

Писатель записывает 01-writer.md (turn: 0, role: writer) с итоговой таблицей ролей:

---
turn: 0
role: writer
agent_id: claude-code
consensus: none
agreed_roles: { "<PEER_AGENT_ID>": "<role_name>", ... }
writer_role: "<role_name>"
discovery_turns: 1   # сколько дополнительных проходов раунда 1 потребовалось
---

Обновить meta.yaml:

roles: { "claude-code": ["<writer_role>"], "<PEER_AGENT_ID>": ["<role_name>"], ... }
discovery_turns: <N>

Только после этого переходить к Шагу 3р (ROUND=1) с содержательными раундами.


Шаг 3. Turn loop (PEER_COUNT == 1)

При PEER_COUNT >= 2 — пропустить этот шаг целиком, перейти к Шагу 3р (round loop, WP-509). Этот шаг не менялся с версии 1.4.0 — один напарник, поведение идентично.

Переменные: TURN=1, ESCALATIONS=0, DONE=false.

3.1 Вызов напарника

Прочитать все предыдущие реплики из SESSION_DIR в порядке нумерации. Составить промпт:

Ты — напарник (peer agent) в диалоговой сессии (DP.SC.154).
Сессия: <SESSION_ID>
Ход: <TURN> из 10
Задача: <задача>

Контекстная проекция ниже — единственный источник о сессии. Не читай файлы и не используй инструменты:
<минимальная текстовая проекция предыдущих реплик и проверяемых фактов>

Напиши реплику в stdout с frontmatter:
---
turn: <TURN>
role: peer
agent_id: <PEER_AGENT_ID>
timestamp: <ISO-8601 UTC>
consensus: none | proposed | reached | escalate
---

<Твой ответ>

Правило критика: найди ХОТЯ БЫ ОДИН тезис или допущение писателя, с которым не согласен. Не сдавайся после первого возражения — держись аргументированно. Если всё действительно ОК — объясни почему конкретно, не просто «согласен».

Маркеры (строго в начале строки):
CONSENSUS: <резюме> — если считаешь что договорились
ESCALATE_TO_USER: <причина> — если писатель игнорирует существенное возражение

Вызов напарника через Bash — флаги зависят от вендора (таблица §0в):

PEER_FILE="${SESSION_DIR}/$(printf '%02d' $TURN)-peer.md"
if [ "$PEER_VENDOR" = "hermes" ]; then
  # hermes-peer-adapter.sh не принимает --add-dir/--model — свой --session-id.
  # НЕ путать с $SESSION_ID пир-сессии: адаптер всегда шлёт переданный --session-id
  # как `--resume <id>` в hermes CLI — на самом первом вызове этой пир-сессии
  # у Hermes ещё не существует диалога с ID пир-сессии (это два разных
  # пространства идентификаторов), `hermes chat --resume <несуществующий>`
  # падает молча (set -euo pipefail в адаптере гасит его же диагностику до того,
  # как она успевает напечататься) — найдено живьём 2026-07-31/08-01, WP-484/WP-509.
  # Родной session_id Hermes читаем С ДИСКА (последний уже записанный NN-peer.md),
  # не из shell-переменной — агент делает каждый вызов отдельным Bash-тулом, и
  # переменные не переживают границу между вызовами (найдено code review 01.08).
  HERMES_LAST_ID=$(grep -h "^session_id: " "${SESSION_DIR}"/[0-9][0-9]-peer.md 2>/dev/null | tail -1 | sed 's/^session_id: //')
  if [ -z "$HERMES_LAST_ID" ]; then
    echo "<промпт>" | bash "$ADAPTER_PATH" > "$PEER_FILE" 2>/dev/null
  else
    echo "<промпт>" | bash "$ADAPTER_PATH" --session-id "$HERMES_LAST_ID" > "$PEER_FILE" 2>/dev/null
  fi
else
  printf '%s\n' "<промпт с минимальной текстовой проекцией>" | bash "$ADAPTER_PATH" \
    > "$PEER_FILE" 2> "${PEER_FILE%.md}.err"
fi

Если файл пустой или exit ≠ 0 → сообщить пилоту: «<PEER_VENDOR> не ответил. Повторить или прервать?»

3.2 Показать пилоту

Shortened here. Read the whole file on GitHub.

Signals

GitHub stars
54
Forks
150
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
peer-conversation
Source
github.com/tserentserenov/fmt-exocortex-template