opencode-config/docs/decisions/070-pr-167-memory-cleanup-and-self-maintaining.md
Sergey 6977a9130a
fix(memory): cleanup bloat and make memory-syncer self-maintaining (#167)
* fix(memory-syncer): enforce dedup, strict distillation, 100KB compaction, frontmatter fix

* docs(handoff): add handoff and ADR-070 for memory cleanup and self-maintaining

* docs(handoff): set PR number 167

* docs(handoff): fix Pending/Watch out sections + remove stale ADR comment

* fix(memory-syncer): encoding artifact and trailing newlines

---------

Co-authored-by: opencode-agent <agent@opencode.local>
2026-07-31 19:01:26 +03:00

4.4 KiB
Raw Blame History

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-записей)» остаются).