mcp__mappa__handoff_write (per-project, append-only, versioned-история, поля session_id/date/status/summary/open_treks/ask_user/guards/recent_commits, решение 14/гриллинг Q5). Чтение — entity_search(type=handoff). Без лиза, без файлов, без git-стеджинга. Ритуал закрытия сохранён (propose-only).
10 KiB
name, author, version, description
| name | author | version | description |
|---|---|---|---|
| session-handoff | ours | 1.0.0 | Sliding handoff между сессиями через handoff-сущность Mappa (решение 14, гриллинг Q5): per-project, versioned-история, замена .tasks/NEXT_SESSION.md. Read on session start: orient agent, ask user before action. Write on session-end phrase or substantive commit. On session-end the agent ALSO runs the closing ritual on its own (idea 7: no invitation needed): handoff write + PROPOSE wiki-ingest + PROPOSE task-board closes — mutations only after user confirmation. Session-end phrases: «завершаем сессию», «сворачиваемся», «закругляемся», «wrap up session», «end session», «we're done for now». Trigger-line in AGENTS.md: `session handoff: read on start, write on end`. Skip task-zone phrases: «закрываем эту таску», «pause», «отбой», «разбегаемся». |
session-handoff
Sliding handoff между сессиями. Канал — handoff-сущность Mappa (mcp__mappa__handoff_write, тип h:, per-project): поля session_id/date/status/summary/open_treks[]/ask_user[]/guards[]/recent_commits[]. Каждый write = новая версия (append-only, versioned-история) — файлового .tasks/NEXT_SESSION.md больше нет, git-история не нужна.
На старте — читает последний handoff проекта, ориентирует агента и спрашивает user'а перед действиями. При substantive commit'е или session-end фразе — пишет новый handoff для следующей сессии.
Forward-looking, не timeline: handoff = связка новых вещей конкретно для следующего разворота, не overview всего проекта. STATUS.md-эквиваленты (борд mappa) / вики остаются авторитетными для своего scope'а.
MCP-поверхность
| Операция | Тул | Примечание |
|---|---|---|
| Запись handoff | mcp__mappa__handoff_write(project, session_id, status, summary, open_treks?, ask_user?, guards?, recent_commits?) |
append-only; без лиза (как инбокс) |
| Чтение последнего | mcp__mappa__entity_search(q, type='handoff', project=<имя>, limit=1) |
ORDER BY created_at DESC → первый = последний |
| Полное чтение версии | mcp__mappa__entity_get(id) |
id internal из search |
status ∈ active | paused | done. Поля-массивы (open_treks/ask_user/guards/recent_commits) — строковые массивы; пустые секции передавать как [] (аналог пометки «(нет на этом раунде)» — next агент видит: пусто, не забыто).
When to use
Read mode (session start):
- AGENTS.md проекта содержит trigger-строку
session handoff: read on start, write on end. - В mappa есть handoff-сущности проекта (search не пуст).
Write mode (session end / substantive commit):
- User'ская фраза из whitelist:
- русский: «завершаем сессию», «сворачиваемся», «закругляемся»
- английский: «wrap up session», «end session», «we're done for now»
- ИЛИ — agent только что сделал substantive commit. Эвристика:
- prefix НЕ в (
meta:|docs:|style:|chore:|fix typo) - AND (body length > 200 символов OR files changed > 3)
- prefix НЕ в (
- Плюс: первый non-trivial commit сессии — всегда триггерит, даже если ниже порога (старт работы = context shift).
Skip (false-positive guards):
- «закрываем эту таску» — task close, не session. Это зона using-tasks.
- «pause», «приостанови» — task-pause, не session-end.
- «отбой», «разбегаемся» — слишком broad.
- «сейчас завершу одну задачу и тогда поговорим» — частичное завершение.
- Проект не в mappa / нет handoff-сущностей — silent exit.
- AGENTS.md проекта НЕ содержит trigger-строку — silent exit.
При неоднозначности — ASK, не угадывать: «закрываем сессию или таску?»
Steps
Read mode
- Detect.
mcp__mappa__entity_search(q='', type='handoff', project=<имя проекта>, limit=1)— если пусто, silent exit (первая сессия проекта). - Staleness check.
meta.dateпоследнего handoff'а. Возраст > 7 дней → отметить user'у:Дождаться ответа перед продолжением.handoff от <date> (N дней назад) — возможно устарел. Оверрайдить или продолжить? - Summarize. Прочитать мета последнего: summary / open_treks / ask_user / guards / recent_commits.
- Orient. Пересказать user'у одним блоком: «прошлая сессия предложила X (open треки + ask-items + guards). Делаем?»
- Wait. Не делать никаких действий до подтверждения user'ом. Default = orient + ask, никакого auto-execute.
Write mode
- Scope check. Это текущий проект (cwd). Никаких global мутаций, никаких других проектов.
- Mid-task capture. Если есть 🔴 active таска проекта (борд mappa /
.tasks/) — захватить в summary:left mid-task: <slug> where_stopped: <одна строка> - Compose content. Собрать поля handoff:
session_id—<ISO дата>или идентификатор сессии;status—active(работа продолжается) /paused(заморожено) /done(завершено);summary— связка: где остановились, mid-task, ключевые решения;open_treks— массив открытых треков (готовность + entry-point);ask_user— pending решения / ожидаемые разрешения;guards— «не делать» (preemptive guards);recent_commits— 3–5 последних коммитов (<slug>: <subject>).
- Append.
mcp__mappa__handoff_write(project=<имя>, ...)— сервис создаёт новую версиюh:N(versioned-история; предыдущие версии остаются,entity_searchвернёт свежую). - Closing ritual (idea 7). На session-end фразе (НЕ на substantive commit) после handoff-write агент сам, без приглашения, предлагает закрытие:
- (2) Propose wiki-ingest. Если за сессию появилось durable-знание — ПРЕДЛОЖИТЬ ingest (using-wiki v2: mappa wiki_create/update под лизом), перечислив кандидатов. Ничего не писать без подтверждения.
- (3) Propose task-board closes. Если есть задачи, выглядящие закрытыми — ПРЕДЛОЖИТЬ закрытия (using-tasks / mappa task_close под лизом). Уважать ralph-loop: verifier-задачи закрывать только через verifier.
- Формат — один блок: «Ритуал закрытия: (а) заингестить X в вики? (б) закрыть Y? (в) ничего.» Ждать ответа. Отказ = пропуск.
Failure modes
- AGENTS.md без trigger-строки → silent exit. Скил project-opt-in.
- Проект не в mappa / нет handoff-сущностей → silent exit.
- Stale handoff (> 7 дней) в read mode → не silent, спросить user'а оверрайдить или продолжить.
- Неоднозначная фраза → ASK «закрываем сессию или таску?», не угадывать.
- Secret detected. Контент матчит паттерны секретов (
AKIA...,sk-...,ghp_...,ssh-rsa,BEGIN PRIVATE KEY,password=/token=) → abort write. Сообщить user'у с указанием подозрительной строки. - Mid-task без борда → писать handoff без mid-task секции, не блокировать.
- Ритуал: user отказал → пропустить, не настаивать, не повторять в этой сессии.
Side effects
- Пишет handoff-сущность проекта (append-only, versioned-история). Никаких файлов, никаких git-коммитов за handoff.
- Ритуал закрытия предлагает wiki-ingest и закрытия тасок — но НЕ пишет их.
- Никаких global мутаций, никаких других проектов, никаких user-level config writes.
What NOT to do
- Не auto-execute действия из read handoff'а. Default = orient + ask.
- Не писать в вики / не закрывать таски по ритуалу молча. Ритуал = предложения. Каждая мутация — после явного «да».
- Не гонять ритуал на substantive commit. Только session-end фраза.
- Не писать секреты в handoff. Если контент матчит secret-patterns — abort.
- Не на каждом commit'е. Только substantive (см. эвристику).
- Не дублировать борд / вики. Handoff = forward-looking связка, не overview.
- Не cross-project. Per-project scope.
- Не считать handoff авторитетным на стороне читателя. Это рекомендация прошлой сессии, не директива. User может override любую её часть.