# Trace пишет ядро, показывает плагин

Владелец хочет видеть ход целиком: как сообщение идёт через Bridge, Inbound pipeline,
Gate, контекст, шаги модели, тулы, память, субагентов, Outbox и обратно в Telegram —
живьём и повтором. Это первый плагин Ивы и первый потребитель рельсов ADR-0009.

## Что решено

**Журнал хода (Trace) — в ядре.** `data/trace/YYYY-MM-DD.jsonl`, append-only, одна
строка = событие `{ts, turn, session, kind, name, data}`. Пишут два места: хук
`agent/hooks/trace.ts` (все события eve: `turn.*`, `step.*`, `actions.requested`,
`action.result`, `subagent.*`, `message.*`, `reasoning.*`) и швы Ивы — Bridge принял
апдейт, Inbound pipeline (allowlist, вердикт Gate, сборка контекста), Outbox (доставка,
outbound-Gate). Ночные ходы пишутся так же. Почему ядро: швы Ивы видит только Ива, а
плагин видит только eve; и это доставка/безопасность — территория кода (philosophy §2).
Второй потребитель журнала — `iva trace tail|show|open`, поэтому это механизм, а не
функция (philosophy §5).

**Содержимое пишем, с потолком.** Аргументы и результаты тулов, текст модели — да,
каждое поле обрезано по лимиту, как `CONTENT_ATTRIBUTE_LIMIT` у eve. Тумблер
`captureContent`, по умолчанию включён: вьюер локальный, владелец один. Хранение
14 дней, чистка по дате в имени файла, не по mtime.

**Вьюер — плагин `trace`, отдельный сервис.** `plugin.json` + `skills/trace/` (как
читать журнал, как открыть вьюер) + `sh.iva/services/viewer` — node http + SSE,
читает `data/trace/`, слушает `127.0.0.1`. Юнит генерит Ива по рельсам ADR-0009.
Отдельный процесс переживает рестарт агента, показывает «агент перезапускается» и не
грузит процесс модели. eve Extension плагину не нужен.

**Доступ — только SSH-туннель.** Наружу ничего; `iva trace open` печатает готовую
`ssh -N -L`. Трейс — личные данные, auth = SSH-ключ.

**Ввода на странице нет.** Пишешь в Telegram, смотришь на странице. Вход внутрь
остаётся один — Inbound pipeline; веб-чат через eve-канал обошёл бы allowlist и Gate.

**Страница — один HTML-файл без сборки.** Схема Ивы с подсветкой узлов и рёбер по
событиям, справа лента хода чипами, сверху равные плитки за период (без «hero»-цифры,
решение владельца). У каждого хода кнопка «Повторить»: события проигрываются заново с
реальными интервалами и ускоренно — владелец переключается с Telegram на браузер и
успевает не всегда. Планка для критиков — референсный скриншот дашборда Waku.

## Что отвергнуто

- Хук трейса внутри плагина: не видит швов Ивы; ядро всё равно писало бы свою часть —
  два писателя одного журнала.
- OTel-экспортёр через `defineInstrumentation.setup()`: даёт спаны eve, но не швы Ивы,
  и тянет OTel-стек ради локального файла.
- Вьюер внутри процесса агента: умирает с ним, сайд-эффект на import, и механизм
  сервисов всё равно нужен для MCP proxy.
- Публичный адрес с токеном: личные данные за одним секретом в интернете.

**Пересмотрено 06.10.2026.** Поле содержимого — до 4096 знаков: входящее сообщение Telegram ложится целиком.
Строка, не влезшая в 16 КБ, сначала пересобирается с полями по 2000 знаков и только потом теряет
содержимое, поэтому ни одно событие не теряет больше, чем раньше; атомарность одной записи не меняется.
Результат инструмента пишется одной строкой JSON: вложенность не съедает выдачу, а размер строки держит
одно поле. Хук ставит `failure` — класс сбоя без текста — и `exitCode`; у `bash` хранится конец вывода, там
стоит ошибка. Чатовый ход склеивается по паре «сессия + turn», имя хода — `<session>/<turn>`. Хранение
30 дней: сравнить можно с прошлым месяцем. Откат на версию до этой правки дочищает журнал до 14 дней — это
диагностика, а не данные владельца из ADR-0002. Отвергнуто: строка больше 16 КБ (атомарность больших
записей не проверена) и результаты в отдельных файлах (ломают «один файл на день» и всех читателей).

Статус: решение принято 17.08.2026, реализация — вместе с волной «плагины».
