Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changes/260812-0946.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
bump: patch
section: Changed
---
docs(architecture): сховище relay — інтерфейс store із дозволеними реалізаціями SQLite і PostgreSQL замість жорсткої привʼязки до PostgreSQL; нормативна умова — спільний контрактний набір тестів
2 changes: 2 additions & 0 deletions .cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,8 @@
"низьковажільні",
"ноди",
"облікується",
"одноінстансний",
"одноінстансного",
"однопакетний",
"однопострільні",
"опробувані",
Expand Down
7 changes: 4 additions & 3 deletions docs/architecture/stack.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Changelog:
| Desktop-додатки (macOS) | Tauri v2 — тонкий клієнт + lifecycle agent-server | планується |
| Mobile (Android) | Tauri v2 — ЛИШЕ клієнт через relay | планується |
| `ui/` — спільний фронтенд поверхонь | Vue 3 + Vite, plain JS + JSDoc (БЕЗ TypeScript) | планується |
| `relay/` | Bun-сервіс, plain JS + JSDoc; PostgreSQL | планується |
| `relay/` | Bun-сервіс, plain JS + JSDoc; store — SQLite або PostgreSQL за спільним контрактом | планується |

## Правило одного коду контракту

Expand Down Expand Up @@ -83,9 +83,10 @@ Changelog:

## Relay-інфраструктура

- Bun + PostgreSQL; auth — інтерфейс `verifySession(token) → {account_id}` із dev-реалізацією (magic tokens), продакшн — Ory Kratos за тим самим інтерфейсом;
- Bun; сховище — **інтерфейс store** зі схемою за [access.md](access.md), дозволені реалізації: in-memory (dev, без персистентності), **SQLite** і **PostgreSQL**. Вибір — питання деплою, не архітектури: SQLite (єдиний файл, без інфраструктури) достатній для одноінстансного relay, PostgreSQL — коли інстансів кілька або сховище має бути керованим окремо від процесу. Обов'язкова умова для будь-якої реалізації — проходити **спільний контрактний набір тестів**: взаємозамінність доводиться однаковою поведінкою, а не однаковим переліком методів. Це не суперечить принципу «один код контракту» ([principles.md](principles.md), №10): контракт store — це схема й семантика операцій ([access.md](access.md), шар `contract`), а бекенд зберігання належить шару реалізації, і саме контрактний набір не дає реалізаціям розійтись;
- Auth — інтерфейс `verifySession(token) → {account_id}` із dev-реалізацією (magic tokens), продакшн — Ory Kratos за тим самим інтерфейсом;
- Push: FCM (data-повідомлення трьох типів — див. [access.md](access.md)); модуль за інтерфейсом, dev-заглушка;
- Деплой: Dockerfile (oven/bun) + k8s (Deployment + Service; Postgres — CNPG);
- Деплой: Dockerfile (oven/bun) + k8s (Deployment + Service; SQLite — PVC, PostgreSQL — CNPG);
- Ліміти: rate limit на з'єднання, кадр ≤ 2 MB, буфер ≤ 200 Envelope/run.

## Демонізація agent-server
Expand Down
4 changes: 4 additions & 0 deletions docs/log.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Журнал змін документації

## 2026-08-12

* **Update**: [architecture/stack.md](architecture/stack.md) — сховище relay перестає бути одним названим продуктом: замість «Bun + PostgreSQL» зафіксовано **інтерфейс store** зі схемою за [architecture/access.md](architecture/access.md) і три дозволені реалізації — in-memory (dev), SQLite і PostgreSQL. Привід — реалізація в `nitra/mt-rust`: персистентний store зроблено на SQLite (вбудований `bun:sqlite`, без зовнішньої залежності), і канон розійшовся з кодом. Розв'язання не «переписати PostgreSQL → SQLite», а зняти хибну прив'язку: вибір бекенда — питання деплою (одноінстансний relay проти кількох інстансів), а не архітектури, і `stack.md` за власним фронтматером — шар `reference`, де реалізація вільна. Нормативна умова натомість одна й перевірна: будь-яка реалізація мусить проходити **спільний контрактний набір тестів** — взаємозамінність доводиться однаковою поведінкою, а не однаковим переліком методів (у реалізації цей набір уже відпрацював: він упіймав, що `setMemberRole` мусить бути upsert-ом, інакше accept запрошення тихо ламається). Явно зафіксовано, що це не суперечить принципу «один код контракту» ([architecture/principles.md](architecture/principles.md), №10): один раз існує **семантика** операцій store, а не спосіб їх зберігання. Рядок деплою уточнено (SQLite — PVC, PostgreSQL — CNPG). Запис від 2026-07-11 нижче («PostgreSQL — окрема задача») лишається як історія рішення, а не як чинна норма.

## 2026-08-09

* **Update**: [architecture/operations.md](architecture/operations.md), [architecture/graph.md](architecture/graph.md), [architecture/runtime.md](architecture/runtime.md) — другий прохід поділу «контракт ↔ реалізація» (перший — запис нижче): конкретні значення виїхали з глав контракту в довідник. Нова підсекція «Дефолти, на які посилаються глави» в operations.md збирає те, що раніше було розсипане інлайн: `model_tier` (`AVG`), `agent_cli`/`MT_AGENT_CLI` (`claude`), `agent_retry_max` (`3`), дефолтний склад `retry_ladder` (базова → `diagnose-first` → `alternative-approach`), ліміт кадру протоколу (2 MB). Туди ж переїхав блок `~/.zshenv` з ENV виконавців — operations.md і так є главою конфігурації, а runtime.md лишає семантику змінних і посилання. Глави тепер називають **ім'я** ключа й дають посилання на значення: у graph.md прибрано «(3)» біля `agent_retry_max`, склад щаблів драбини та приклад мапи моделей; у runtime.md — «(дефолт)» біля `claude`, `→ claude` у ланцюжку резолву та «2 MB» у backpressure. Канонічним джерелом baseline-дефолтів лишається `CONFIG_DEFAULTS` у коді — таблиця в довіднику явно позначена як довідкове дзеркало шару `reference`. Свідомо не чіпали: дефолти полів файлового контракту (`export: true` у `## Children`) — це схема, а не конфіг, і блок ACP-адаптерів у runtime.md — він уже під маркером «Реалізація (не контракт)».
Expand Down
Loading