ADR 0045: Persistence истории чата — append-only события + проекции¶
Статус: Accepted · Implemented
Дата: 2026-04-14
Связанные ADR¶
| ADR | Роль |
|---|---|
| 0031 | модель пакетов уточнений |
| 0044 | модель первична, UI вторичен |
| 0043 | транспорт не равен хранению истории |
Контекст¶
Чат в CIDE перестаёт быть «одноразовым полем» и становится рабочей поверхностью с:
- сообщениями и стримингом;
- пакетами уточнений (
ClarificationBatch); - потенциальными ветками/тредами;
- связями с инструментами и артефактами.
Для такой формы нужна persistence, которая:
- не привязана к конкретному UI;
- переживает эволюцию схемы;
- восстанавливается детерминированно после рестарта.
Решение (направление)¶
- Канон хранения — append-only event log в NDJSON (
*.events.ndjson), одно событие на строку. - Метаданные сессии — отдельный
*.meta.json(id, created/updated, title, версия). - UI работает через проекции (in-memory сейчас; индекс/поиск можно добавить позже), а не напрямую через «файлы сообщений».
- Payload у события хранится как JSON-объект (строка JSON в модели) с
schema_version, чтобы расширять поля без миграции всей истории. - Вложения и тяжёлые данные — отдельными файлами; в событии хранить только ссылку/идентификатор.
Формат v1 (минимум)¶
Каталог: workspace/.cascade-ide/chat-sessions/
session-<id>.events.ndjsonsession-<id>.meta.json
Типы событий v1:
message_addedmessage_stream_deltamessage_completedclarification_batch_openedclarification_answer_submittedmessage_edited— компенсирующее событие: новый текст для существующегоmessage_idв payload (message_added/message_completedне переписываются).
Полезная нагрузка message_added и message_completed v1 включает стабильный message_id (строка без дефисов), role, content.
Экспорт для агента: читаемый Markdown из текущей проекции (команда chat_export_readable, опционально запись в chat-sessions/exports/).
Почему не «сразу SQLite как источник правды»¶
- На ранней фазе продукта event log проще отлаживать, diff-ить и мигрировать.
- Проекции можно менять без переписывания канона.
- SQLite-индекс можно добавить как ускоритель, не ломая формат истины.
Последствия¶
- Появляется единый слой восстановления истории для человека и агента.
- Появляется дисциплина версионирования payload.
- Нужен retention/архив (политика размера и возраста) отдельным шагом.
Открытые вопросы¶
- Политика очистки/архива (
Nдней,MМБ, ручной pin). - Политика редактирования старых сообщений (компенсирующее событие vs hard rewrite).
- Минимальный набор редактирования секретов (redaction event).