# ADR-070: Make memory-syncer self-maintaining (dedup, strict distillation, 100KB compaction)

## Статус
Accepted (2026-07-31)

## Контекст

Memory-файлы в `~/.local/share/opencode/opencode-memory/` раздулись до неконтролируемых размеров:
- `video_uniq.md` = 623 KB / 1104 строк (584 changelog-дампов на 60 PR)
- `opencode.md` = 135 KB / 298 строк (20 HTML-комментариев-мусора)
- 4 файла-дубликата в `repos/` (старый путь) вместо `repos/github.com/slaid098/` (правильный путь per SKILL.md)
- Битый frontmatter в 3 файлах (отступы 2 пробела, `importance: 3`/`5` вместо `high`/`medium`/`low`)

Корень проблемы: `memory-syncer.md` агент имел секцию «Edit instead of duplicate» как рекомендацию (не обязательное правило), не имел критерия durable (что записывать vs что НЕ записывать), не имел лимита размера файла и процедуры компрессии. Каждый PR добавлял changelog-дампы («PR#N: добавили X») вместо durable knowledge (gotchas, паттерны, root causes), receipts дублировали содержание записей.

## Решение

1. **Дедуп перед записью — ОБЯЗАТЕЛЬНО**: перед добавлением записи memory-syncer читает существующий файл. Если похожая запись уже есть (та же гоча/паттерн/root cause) → обновляет существующую (bump `updated`), НЕ добавляет новую. Дубликаты = root cause раздутия.

2. **Строгая дистилляция с критерием durable**: «поможет ли это в следующий раз когда я полезу в этот код?» Да → durable. Нет → НЕ пиши. Явный запрет changelog-дампов («PR#N: добавили X» — это changelog, код уже документирует), метрик PR (тестов passed, coverage %), хроники событий.

3. **Лимит 100 KB + Compaction**: если после записи файл > 100 KB → компрессировать (прочитать все старые записи, оставить durable, выкинуть не-durable, объединить дубликаты, усечь tags/summary). Цель — держать файл < 100 KB.

4. **Фронт-матч фикс при записи**: если frontmatter сломан (битые отступы, невалидные importance) → починить. Valid `importance`: `high` | `medium` | `low`.

5. **SKILL.md синхронизирован**: правило «править вместо дублирования» сделано обязательным (было рекомендацией), добавлен лимит 100 KB.

6. **Зеркало `~/.config/opencode/`** синхронизировано с repo-local `.opencode/` (cp + diff проверка).

## Альтернативы

1. **Только разовая чистка без фикса корня** — отклонено: файлы раздуются снова при следующем PR. Issue #166 явно требовал оба типа работы.
2. **Автоматическая компрессия в memory-save tool** — отклонено: memory-save = commit + reindex, не должен модифицировать содержимое файлов. Компрессия = ответственность memory-syncer агента (контекст handoff нужен для решения что durable).
3. **Лимит 50 KB** (жёстче) — отклонено: video_uniq.md после дистилляции = 25 KB, но репо с 60+ PR могут legitimately иметь ~80 KB durable knowledge. 100 KB = баланс.
4. **Запрет receipts** — отклонено: receipts обязательны (audit trail что memory-sync фаза выполнена). Убрано только дублирование содержания в receipts (receipts с повторяющимся содержанием выкидываются при компакции, короткие receipts «— (нет durable-записей)» остаются).
