# Reflection: settings-ui-and-runtime-logs

**Task ID:** `settings-ui-and-runtime-logs`  
**Complexity:** Level 4  
**Дата reflection:** 2026-06-12  
**Статус BUILD:** фазы 1–7 завершены

---

## Summary

Задача объединила два независимых направления:

1. **Tenant settings UI** — вынос BIRD / revision / custom KV из Operations и Network в `/tenant-settings`; `/settings` остаётся только для браузера (токен, тема).
2. **Runtime logs** — контракт OpenAPI, audit в БД, безопасный FS-слой, HTTP API только на `evobgp-all`, compose volume, Web UI во вкладке Monitoring.

Реализация шла по 7 фазам (0–7 с creative): контракт → persistence → FS → HTTP → deploy → два UI-модуля → docs/QA. Все acceptance criteria закрыты автоматическими проверками; E2E на production-хосте оставлен ручным чеклистом.

---

## What Went Well

| Область | Наблюдение |
|---------|------------|
| **Creative до BUILD** | Четыре CP-документа зафиксировали спорные точки (tabs vs routes, sync cleanup, path safety, Monitoring tab). В BUILD не было откатов по UX. |
| **Contract-first (P1)** | OpenAPI + миграция `000026` + `store.Backend` до FS/HTTP упростили параллельную работу и review. |
| **Паттерны репозитория** | Maintenance audit (`actor_prefix`, cursor list) и settings-api переиспользованы без новых абстракций. |
| **Guard FS** | `EVOBGP_SERVICE=evobgp-all` + `EVOBGP_RUNTIME_LOGS_DIR` + path regex/EvalSymlinks — единая точка в `internal/runtimelogs`. |
| **Поэтапный UI** | P5 (tenant) не зависел от runtime logs backend — можно было бы параллелить с P2–P4. |
| **503 + audit** | Разделение `filesUnavailable` и audit-only в UI: оператор видит историю очистки даже без volume. |
| **Production example** | `docker-compose.production.example.yaml` закрыл разрыв между repo `stack.microvps-full.yaml` и кастомным compose на сервере пользователя. |

---

## Challenges

| Challenge | Как решали |
|-----------|------------|
| **Prod compose без Phase 4 env/mount** | Пользовательский `/opt/evobgp/docker-compose.yaml` отставал от репозитория; подготовлен полный example с сохранением кастомных env (`BUNDLE_SEED_HEX`, `NODE_DISPATCH`). |
| **Windows dev** | `go test -race` и `bash scripts/lint-httpapi.sh` недоступны; gates выполнялись альтернативами (test без race, grep ERR-01/ARCH-01). |
| **Sidecar уже был, API — нет** | `stack-runtime-logs` писал в `./runtime-logs`, но `evobgp-all` не монтировал каталог — типичная «половинная» интеграция; Phase 4 явно связал оба mount через `EVOBGP_RUNTIME_LOGS_HOST_DIR`. |
| **Старые закладки Operations** | `?tab=system` → редирект на `/tenant-settings?tab=revision`. |
| **E2E не автоматизирован** | Нет compose в CI с реальным volume и sidecar; manual checklist в `tasks.md`. |

---

## Lessons Learned

1. **Deploy — часть фичи.** FS API без compose mount на целевом процессе даёт 503 и ощущение «баг в коде»; example для production обязателен при stack, который копируют на сервер вручную.
2. **Audit endpoint ≠ FS endpoint.** Cleanup audit в БД не должен зависеть от `requireRuntimeLogs` — иначе теряется ценность на `evobgp-api`/без volume.
3. **Разделение `/settings` и tenant** снижает путаницу ролей: browser config vs control plane KV — разные mental models и nav-пункты.
4. **Синхронный DELETE** при лимите 512 MiB и truncate-by-default — приемлемый trade-off для операторского UI без jobs; важно документировать в OpenAPI и ConfirmDialog.
5. **Memory Bank phased BUILD** хорошо масштабируется на Level 4: 7 фаз с чеклистами удерживают контекст между сессиями агента.

---

## Process Improvements

| Рекомендация | Действие |
|--------------|----------|
| После изменения compose в repo — **синхронизировать production.example** в той же фазе | Уже сделано для этой задачи; закрепить как правило в Phase 4 checklist |
| **E2E smoke** в `scripts/` или compose profile `test-runtime-logs` (temp dir + evobgp-all env) | Backlog: снизить зависимость от ручного prod |
| В PR template: «обновлены `docs/api.md` + `manual.md`?» для API/UI фич | Phase 7 не забывать при мелких задачах |
| Creative commit local без push — ок для итерации; перед prod нужен **CI image** с новым API | Напоминание в runbook E2E |

---

## Technical Improvements (backlog)

- **Operator role в UI:** сейчас `session?.role === 'operator'` — если появятся расширенные роли, вынести `canMutateSettings` / `canCleanupLogs` в один helper.
- **Monitoring URL tabs:** добавлен sync для `runtime-logs`; при новых вкладках — единый helper как в Operations/tenant-settings.
- **Удаление custom KV:** PATCH только перечисленных ключей; полное удаление ключа из tenant может требовать явного API (сейчас — операторская семантика через форму).
- **Метрики:** опционально `evobgp_runtime_logs_cleanup_total` в observability (PERF-03).

---

## Comparison to Plan

| План | Факт |
|------|------|
| 7 BUILD фаз | Выполнено |
| CP-1…CP-4 | Соблюдены |
| `/tenant-settings` Tabs | Да |
| Monitoring `?tab=runtime-logs` | Да + nested files/audit |
| Только evobgp-all FS | Да |
| Sync cleanup + audit | Да |
| `redocly`, go test, web check+lint | Pass локально |

**Отклонения:** нет существенных. E2E manual на prod — единственный незакрытый автоматический gate.

---

## Next Steps

1. **`/archive`** — архив задачи в `memory-bank/archive/`.
2. **На сервере:** применить `docker-compose.production.example.yaml` (или патч Phase 4), `pull evobgp-all`, пройти E2E checklist из `tasks.md` Phase 7.
3. **Коммит/PR:** сгруппировать изменения (backend, web, deploy, docs) или один feature PR — по предпочтению команды.
4. **Опционально:** smoke-скрипт для runtime logs API в dev compose.
