Files
ratatoskr-go/.serena/memories/conventions.md
ki.sagidullin cd0619926e
Some checks failed
CI / test (push) Failing after 1m15s
CI / build-and-package (amd64, linux) (push) Failing after 58s
CI / build-and-package (amd64, windows) (push) Successful in 30s
perf(chat,update): пул воркеров per-user вместо сериальной очереди + HEAD-проба обновлений
- chat.Router: ограниченный пул chatWorkers=4 воркеров + FIFO-очереди
  per-user (userState/workerLoop/runUser). Порядок сообщений одного UserID
  сохраняется; разные пользователи обрабатываются параллельно (до 4
  одновременных LLM-вызовов), long-poll Telegram не блокируется чужим
  аналитиком. Backpressure по jobs — только на перегруженного пользователя.
- app.FreeChat: sessions под sync.Mutex (защита от data race при параллельных
  воркерах роутера).
- update: ResolveLatest проверяет наличие бинаря HEAD-пробой без скачивания
  тела (fallback GET Range 0-0 при 405/501), сортировка версий по id убыв.;
  один общий http.Client (keep-alive) вместо нового на каждый запрос.
- тесты: порядок/параллелизм per-user в router, HEAD-без-тела и фоллбэк на
  версию без бинаря в update.
- память Serena: инварианты Router/update, примечания по форматированию на Windows.
2026-08-22 11:44:34 +05:00

4.3 KiB
Raw Permalink Blame History

conventions

Стиль / кодстайл

  • Стандартный Go-стиль; gofmt/go fmt ./.... Документация-комментарии и package-doc на русском языке.
  • Типизация: строгие типы, интерфейсы для абстракций (Decider, ui.Store, events.Event, chat.Channel).
  • Свой тип config.Duration для времени (YAML-строки "5s"/"10m"), метод .Duration().
  • UI: uni-directional data flow — UI читает снапшоты (копии, ui.Store), не мутирует storage/core. Ядро публикует события в events.Bus, UI подписывается events.Hub → колбэки в UI-поток через fyne.Do.

Обработка ошибок

  • Ошибки классифицируются по идентификаторам классов в исходниках (см. ниже).
  • Ошибка-обёртка: fmt.Errorf("%w: %v", ErrXxx, err).
  • errors.Join для склейки нескольких ошибок валидации (config.Validate).

Классы ошибок (маркируются в коде, документированы в README)

Блок Коды Где
C C1C4 internal/config
A A1A4 internal/analyst; A (app): A1A4 в internal/app
M M1M5 internal/chat
D D1D5 internal/core (ErrDecideFailed, ErrMaxTurns, ErrCommandUnknown…)
O O1O5 internal/opencode
S S1S5 internal/storage
W W1W5 internal/worker
E E1E4 internal/worker (репозитории)
R R1R6 internal/worker/review_errors.go
U U1U6 internal/update

Архитектурные конвенции

  • Composition root — internal/app; подсистемы собираются там. UI-окно создаётся через newUIWindow(store) (build-tag: cgo → desktop.New, !cgo → nil/headless). Флаг --noui выключает окно.
  • Слои: model (домен) ← storage/events/UI зависят только от model; core не знает про UI.
  • Агенты (analyst.md/dev.md/reviewer.md) — markdown-промпты, go:embed, распаковка в config_dir. Вердикт — строгий JSON.
  • Репо-клонирование/воркеры — через gitops; ветки задач feat/<taskTag> (см. mem:core).
  • Обратная совместимость: поле Repo (одиночный) и Repos (список); EffectiveRepos/ SetReposFromDB/ReposJoined в storage/models.go.

Версии

  • app.Version — семантическая major.minor.patch (ручной инкремент: patch=фиксы, minor=новая обратно-совместимая функциональность, major=несовместимые изменения). Сейчас 0.2.2.
  • main.version (ldflag) — build-идентификатор commit-<sha7>, отдельно от app.Version.

Форматирование (важно на Windows)

  • Репо на Windows-чекауте: core.autocrlf=true → файлы в рабочей копии с CRLF; gofmt -l на CRLF-копии шумит (глобально ~60 файлов). Проверять формат только на LF-версии (напр. git -c core.autocrlf=false clone во временный каталог) — так дифы видны корректно.
  • gofmt 1.26 форматирует doc-comments (// перед go build ... в // go build → пустая строка //) и выравнивание структур; не все файлы отформатированы по новой версии (предсуществующе).
  • CI (go vet + go test) формат не проверяет → gofmt-дифы не ломают сборку.
  • Known race в тест-харнессе app: e2eChannel.Send (internal/app/e2e_test.go:213) пишет c.sent без лока, тест читает с главной горутины → -race ловит в TestE2ENotificationsOnTransitions. Путь worker→Notify→Send; предсуществует, ещё не чинили (fix — мьютекс в e2eChannel).