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

54 lines
4.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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`).