Skip to content

feat(budget): Safe-to-Spend / живой конверт (ADR-007) - #61

Merged
Tarasusrus merged 3 commits into
mainfrom
feature/safe-to-spend-adr007
Jul 23, 2026
Merged

feat(budget): Safe-to-Spend / живой конверт (ADR-007)#61
Tarasusrus merged 3 commits into
mainfrom
feature/safe-to-spend-adr007

Conversation

@Tarasusrus

Copy link
Copy Markdown
Owner

Что

Safe-to-Spend (ADR-007): по приходу денег из сообщения и горизонту бот показывает
сколько реально свободно после известных обязательств и на что уйдут
повседневные траты — чтобы можно было решить, сколько отложить/где сэкономить.

Флоу

  • пришло 127000, сколько свободно за 2 недели? → вердикт (можно/нельзя отложить),
    раскладка (обязательные / запланированные покупки / повседневные по статистике с
    разбивкой по категориям), советы по экономии.
  • запомни приход 127000 на 2 недели → живой конверт; позже сколько осталось?
    остаток пересчитывается по фактическим тратам (не хранится).

Ключевые решения

  • Приход НЕ пишется в ledger (был баг: пришло X уходило в add_income).
  • Числа считаются детерминированно в Go, LLM только нарратив (тест-мутация).
  • Нет двойного учёта: обязательства / плановые / прогноз — из непересекающихся
    источников; fixed-категории (аренда/подписки) вне прогноза «переменных».
  • Чистый якорь дохода (без разовых поступлений) — фикс завышения ~на 57%.
  • Горизонт по умолчанию — 2 недели; курс ₽/฿ показывается явно.

Состав

  • internal/skills/safetospend/ — новый read-only reasoning-plugin.
  • internal/budget/ — период-агрегация, planned_expense, envelope, доменные
    помощники (ResolveHorizon, ToTHB, классификация категорий).
  • Миграции 00015_budget_planned_expense, 00016_budget_envelope.
  • budget actions: add_planned_expense, start_envelope.
  • internal/appwiring + cmd/botclient — прямой тест-клиент к ядру бота.
  • Реплика прод-БД (scripts/refresh-replica.sh, launchd) для оффлайн-прогонов.
  • Evals: routing golden-кейсы + clarity-бенчмарк.

Проверки

  • go build ./..., весь go test ./... — зелёные (юнит + integration на реплике).
  • golangci-lint run ./... — 0 issues.
  • Каждый инвариант покрыт тест-мутацией (формула, LLM-независимость чисел,
    chat-scope изоляция, denylist категорий, недвойной учёт).
  • Живой прогон на реплике: acceptance 127000 → ~27300 свободно после известных.

Заметки

  • LLM-модели / секреты / таймауты не менялись.
  • Миграции применятся на проде при деплое.

…нверт

Новый read-only skill safe_to_spend (ADR-007): по приходу из сообщения и
горизонту (по умолчанию 2 недели) детерминированно считает свободный остаток
после обязательств и разбивку ожидаемых переменных трат по категориям —
приход НЕ пишется в ledger. LLM только нарратив/советы, числа считаются в Go.

- Store: GetPeriodSnapshot (произвольный период, chat-scoped),
  GetRegularMonthlyIncomeAvg (чистый якорь без разовых), planned_expense и
  envelope CRUD, миграции 00015/00016.
- budget actions add_planned_expense, start_envelope; режим остатка по конверту
  (остаток производный из фактических трат, не хранится).
- Доменные помощники budget: ResolveHorizon, ToTHB, классификация категорий
  (consumption / variable-daily / one-off income) — единый источник.
- Вывод: вердикт-first (можно/нельзя отложить), явный курс, раскрытые плановые.
… реплика

- internal/appwiring: переиспользуемая сборка registry+Service (вынесено из cmd/app).
- cmd/botclient + internal/botclient: read-only клиент к agent.Service в обход
  Telegram; write-safety на уровне БД-роли (--allow-writes + отдельный URL).
- scripts/refresh-replica.sh + launchd: почасовой graceful рефреш локальной
  read-only реплики боевой БД (прод не мутируется, только pg_dump).
- evals: golden-кейсы роутинга safe_to_spend/add_planned_expense/start_envelope,
  clarity-бенчмарк подачи.
@Tarasusrus
Tarasusrus merged commit 72f09ea into main Jul 23, 2026
2 checks passed
@Tarasusrus
Tarasusrus deleted the feature/safe-to-spend-adr007 branch July 23, 2026 11:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant