diff --git a/.changes/260809-1605.md b/.changes/260809-1605.md new file mode 100644 index 0000000..e2b85a0 --- /dev/null +++ b/.changes/260809-1605.md @@ -0,0 +1,5 @@ +--- +bump: patch +section: Added +--- +docs(architecture): principles.md — зведення 26 принципів канону і три шари обовʼязковості (normativity: principle/contract/reference) у фронтматері кожної глави diff --git a/.cspell.json b/.cspell.json index 4d85147..d0a2259 100644 --- a/.cspell.json +++ b/.cspell.json @@ -59,6 +59,7 @@ "NAPI", "NCURSOR", "nitralabs", + "normativity", "nowarn", "ollama", "Ollama", diff --git a/docs/architecture/access.md b/docs/architecture/access.md index bfd072f..bde1d97 100644 --- a/docs/architecture/access.md +++ b/docs/architecture/access.md @@ -1,5 +1,6 @@ --- type: architecture +normativity: contract description: 'Акаунти і ключі пристроїв, relay та membership, ролі, три approval-гейти з Ed25519-підписами, push' tags: [access, relay, membership, approvals, security] timestamp: 2026-07-07 diff --git a/docs/architecture/git.md b/docs/architecture/git.md index 6c6b6e7..531839b 100644 --- a/docs/architecture/git.md +++ b/docs/architecture/git.md @@ -1,5 +1,6 @@ --- type: architecture +normativity: contract description: 'CAS claim як єдине «перо», run ref із журналом сесії, fenced publish і паралельне виконання' tags: [git, claim, lease, publish] timestamp: 2026-07-07 @@ -69,6 +70,8 @@ Run ref: `refs/mt/runs//` — гілка робочого ст **Wrapper** (`mt run`; у цільовій картині — роль Runner всередині agent-server): перевіряє deps resolved + відсутність pending-audit → CAS claim → detached worktree від `base_sha` → run ref → запускає агента → watchdog → пише `run_NNN.md` → publish. +> **Реалізація (не контракт).** Імена ENV нижче — інтерфейс усередині однієї реалізації (wrapper → агент), а не межа між реалізаціями: інша реалізація може назвати їх інакше, не порушивши сумісності git-стану. Нормативна тут лише семантика `generation` як fencing token. + **ENV-контракт wrapper → агент:** `MT_BUDGET_SEC`, `MT_HARD_BUDGET_SEC`, `MT_STARTED_AT`, `MT_RUN_NNN`, `MT_ATTEMPT`, `MT_CLAIM_TOKEN`, `MT_CLAIM_GENERATION`. `MT_CLAIM_GENERATION` — fencing token для non-idempotent side effects: single publish owner гарантує лише один запис результату в `main`, не mutual exclusion виконання. ## Fenced publish diff --git a/docs/architecture/graph.md b/docs/architecture/graph.md index a043640..0c63f9e 100644 --- a/docs/architecture/graph.md +++ b/docs/architecture/graph.md @@ -1,5 +1,6 @@ --- type: architecture +normativity: contract description: 'Вузли й ОАГ, файловий контракт, derived-стани, два етапи виконання, retry ladder і аудит' tags: [graph, contract, states, audit] timestamp: 2026-07-07 @@ -131,7 +132,7 @@ parent: research/collect-data # відносно mt/; відсутній у ко --- schema_version: 1 created_at: ISO8601 -model_tier: AVG # MIN | AVG | MAX; default AVG +model_tier: AVG # MIN | AVG | MAX; дефолт — довідник operations.md agent_cli: codex # опціонально; claude | codex | cursor | pi — підписочний CLI (runtime.md) skills: [bash, write-files] secrets: [STRIPE_KEY] # опціонально; wrapper інжектить через ENV @@ -142,7 +143,7 @@ interactive: false # НОВЕ: true → вузол очікує інтера --- ``` -`model_tier` — джерело істини виконавця. Runner резолвить tier у **конкретну модель обраного CLI** через user-level env `MT_AGENT_CLI_MODEL_MAP[][tier]` (напр. codex: MIN→luna / AVG→terra / MAX→sola); CLI без мапінгу резолвить модель сам за підпискою користувача, tier завжди передається hint-ом env `MT_MODEL_TIER` ([runtime.md](runtime.md#підписочні-cli-виконавці-agent_cli)). +`model_tier` — джерело істини виконавця. Runner резолвить tier у **конкретну модель обраного CLI** через user-level env `MT_AGENT_CLI_MODEL_MAP[][tier]` ([operations.md](operations.md#конфігурація-mtjson)); CLI без мапінгу резолвить модель сам за підпискою користувача, tier завжди передається hint-ом env `MT_MODEL_TIER` ([runtime.md](runtime.md#підписочні-cli-виконавці-agent_cli)). `agent_cli` (який підписочний CLI виконує вузол) — **per-node** прапор `a.md` з user-level дефолтом env `MT_AGENT_CLI`. Per-node вибір CLI — це крос-програмковий вимір [мети](../vision.md): спеціалізований тул на вузол. @@ -331,7 +332,9 @@ context = [task.md] + [a.md|h.md] + [deps/] + [plan_*.md] + ## Retry ladder, engineer, unresolvable -До `agent_retry_max` (3) вузол лишається `waiting`; агент ретраїть за драбиною (`MT_ATTEMPT` = failed_streak + 1): 1 — базова; 2 — diagnose-first; 3 — alternative-approach (`model_tier: +1`, `skills_add`). Коротша драбина → останній щабель повторюється. +> **Реалізація (не контракт).** Контрактні тут — механізм драбини, лічильник `failed_streak` і три умови `unresolvable`. Значення `agent_retry_max` і склад щаблів `retry_ladder` — референсні: реалізація може мати інші, лишаючись сумісною. Дефолти — [довідник](operations.md#дефолти-на-які-посилаються-глави). + +До `agent_retry_max` вузол лишається `waiting`; агент ретраїть за драбиною `retry_ladder` (`MT_ATTEMPT` = failed_streak + 1). Щабель може змінювати стратегію промпта, `model_tier` і `skills_add`; коротша драбина → останній щабель повторюється. **EngineerAgent:** `failed_streak ≥ agent_retry_max` → `mt run --actor engineer`: отримує task + deps + повний run-history + `.mt/engineer-prompt.md`; може `mt stop`/`invalidate`/`kill`/GraphPatch. diff --git a/docs/architecture/i18n.md b/docs/architecture/i18n.md index 9ccdc6e..2d237ea 100644 --- a/docs/architecture/i18n.md +++ b/docs/architecture/i18n.md @@ -1,5 +1,6 @@ --- type: architecture +normativity: contract description: 'Багатомовність: base-канон і derived-переклади у refs/mt/i18n, worktree-матеріалізація, contract-aware перекладач, authored-захист' tags: [i18n, translations, languages, worktree] timestamp: 2026-07-07 @@ -111,6 +112,8 @@ claim → worktree від base_sha ## Конфігурація +> **Реалізація (не контракт).** Імена ключів і дефолтні значення — референсні; контрактне — існування base-мови, `source_hash` у схемі перекладу і триступенева схема «що перекладається». + ```jsonc // .mt.json { diff --git a/docs/architecture/index.md b/docs/architecture/index.md index 59f2d57..b949b2f 100644 --- a/docs/architecture/index.md +++ b/docs/architecture/index.md @@ -4,6 +4,7 @@ ## Глави (за порядком читання) +* [Принципи і шари обовʼязковості](principles.md) - зведення інваріантів канону і критерій `principle` / `contract` / `reference` * [Огляд: рішення злиття і шари системи](overview.md) - шість нормативних рішень обʼєднання і чотиришарова діаграма * [Ядро: рекурсивний граф задач](graph.md) - вузли й ОАГ, файловий контракт, derived-стани, два етапи виконання, retry ladder, аудит * [Координація через git](git.md) - CAS claim (create/renewal/takeover/handoff), run ref і журнал сесії, fenced publish, паралелізм @@ -20,3 +21,5 @@ * [Референсний стек](stack.md) - конкретні технологічні рішення реалізації; зміна стеку не змінює архітектуру * [Журнал змін](../log.md) - хронологія редакцій + +Кожна глава несе у фронтматері поле `normativity` — шар обовʼязковості її змісту; секції, що відхиляються від рівня своєї глави, позначені блок-цитатою «Реалізація (не контракт)». Значення шарів і критерій віднесення — [principles.md](principles.md). diff --git a/docs/architecture/mandates.md b/docs/architecture/mandates.md index b81e1bf..fbafee5 100644 --- a/docs/architecture/mandates.md +++ b/docs/architecture/mandates.md @@ -1,5 +1,6 @@ --- type: architecture +normativity: contract description: 'Карта мандатів, профілі людей і моделей, decision-request, ескалація за важелем, прецедентний рушій — людина як власник рішень свого горизонту, не exception-handler' tags: [mandates, escalation, decision-request, competencies, human-in-the-loop] timestamp: 2026-07-12 diff --git a/docs/architecture/operations.md b/docs/architecture/operations.md index 4d1eff5..473771f 100644 --- a/docs/architecture/operations.md +++ b/docs/architecture/operations.md @@ -1,5 +1,6 @@ --- type: architecture +normativity: contract description: 'CLI-контракт, конфігурація, монорепо, security model, відмовостійкість, bootstrap і наскрізні сценарії' tags: [operations, cli, config, security, scenarios] timestamp: 2026-07-07 @@ -46,6 +47,8 @@ mt template run ← позачергова матеріалі ## Конфігурація (`.mt.json`) +> **Реалізація (не контракт).** Нормативні тут — межа «repo-scoped `.mt.json` vs user-level ENV», порядок пріоритету і `schema_version` як fail-closed-гейт. Імена ключів, їх дефолтні значення і довідник нижче — референсні. + До конфігурації 0.2.0 (claim/publish/budget/retry/audit/model/skill_profiles — без змін) додаються: ```json @@ -63,7 +66,14 @@ mt template run ← позачергова матеріалі } ``` -Конфігурація **виконавців** (провайдери/моделі) — не тут: вона user-level, спільна для всіх репозиторіїв, і живе в ENV (`MT_AGENT_CLI`, `MT_CLOUD_AGENT_CLIS`, `MT_AGENT_CLI_MODEL_MAP` — [runtime.md](runtime.md#підписочні-cli-виконавці-agent_cli)). `.mt.json` — виключно repo-scoped. +Конфігурація **виконавців** (провайдери/моделі) — не тут: вона user-level, спільна для всіх репозиторіїв, і живе в ENV. Семантику цих змінних задає [runtime.md](runtime.md#підписочні-cli-виконавці-agent_cli); значення — тут. `.mt.json` — виключно repo-scoped. + +```bash +# ~/.zshenv (рівень користувача — усі репозиторії) +export MT_AGENT_CLI="claude" # дефолтний виконавець +export MT_CLOUD_AGENT_CLIS="codex,cursor" # каскад хмарних підписок (порядок = пріоритет) +export MT_AGENT_CLI_MODEL_MAP='{"codex":{"MIN":"gpt-5.6-luna","AVG":"gpt-5.6-terra","MAX":"gpt-5.6-sola"},"pi":{"MIN":"omlx/gemma-4-e2b-it-4bit"}}' +``` **Модель виконавця:** канон тирів MIN/AVG/MAX резолвиться у конкретну модель обраного CLI через env `MT_AGENT_CLI_MODEL_MAP` ([runtime.md](runtime.md#підписочні-cli-виконавці-agent_cli)). Автономні run-и обирають за `model_tier` з `a.md`; інтерактивні можуть перевизначати CLI per-turn за `surface`-hint (`surface_profiles`). Транспорт AI-викликів — виключно **ACP** (конкретика — у [stack.md](stack.md)). @@ -89,6 +99,18 @@ Baseline-ключі 0.2.0 з конкретними дефолт-значенн | Relay/хост | `relay_url`, `server_port_file` | тут, [runtime.md](runtime.md) | | i18n | `i18n.{base_lang, eager, publish_langs, include, exclude, model_tier, ttl_days}` | [i18n.md](i18n.md) | +### Дефолти, на які посилаються глави + +Глави описують **семантику** ключа й посилаються на його ім'я; конкретне значення живе тут. Канонічне джерело baseline-дефолтів — `CONFIG_DEFAULTS` у коді (вище); таблиця нижче — довідкове дзеркало для читача спеки, і як усе в шарі `reference` розбіжність із нею не є порушенням контракту. + +| Ключ / параметр | Дефолт | Семантику описує | +| --- | --- | --- | +| `model_tier` (`a.md`) | `AVG` | [graph.md](graph.md) | +| `agent_cli` (`a.md`) / `MT_AGENT_CLI` | `claude` | [runtime.md](runtime.md#підписочні-cli-виконавці-agent_cli) | +| `agent_retry_max` | `3` | [graph.md](graph.md) | +| `retry_ladder` | три щаблі: базова спроба → `diagnose-first` → `alternative-approach` (`model_tier: +1`, `skills_add`) | [graph.md](graph.md) | +| Ліміт кадру протоколу подій | 2 MB (спільний з relay) | [runtime.md](runtime.md), [access.md](access.md) | + ## Монорепо: множинні `mt/` ``` diff --git a/docs/architecture/principles.md b/docs/architecture/principles.md new file mode 100644 index 0000000..a446f5a --- /dev/null +++ b/docs/architecture/principles.md @@ -0,0 +1,106 @@ +--- +type: architecture +normativity: principle +description: 'Зведення архітектурних принципів MT і три шари обовʼязковості: принцип, контракт, реалізація' +tags: [principles, invariants, normativity, contract] +timestamp: 2026-08-09 +--- + +# Принципи і шари обовʼязковості + +> Частина цільової архітектури **0.3.0-draft** — [зміст](index.md) · [огляд](overview.md). Зведення: кожен принцип нижче вже діє в одній або кількох главах — тут вони зібрані в один нумерований перелік, щоб на них можна було посилатись і перевіряти нове рішення проти них. + +## Суть + +Документ виконує дві роботи. Перша — зводить розсипані по главах нормативні принципи в один перелік із коротким обґрунтуванням кожного і посиланням на главу, що його реалізує. Друга — фіксує **три шари обовʼязковості** (принцип, контракт, реалізація) і критерій, за яким будь-який рядок канону відносять до одного з них: без цього неможливо відрізнити розбіжність реалізації зі спекою від дозволеної свободи реалізації. + +## Три шари обовʼязковості + +| Шар | Що це | Хто зобовʼязаний | Ціна зміни | +| --- | --- | --- | --- | +| **Принцип** (`principle`) | «навіщо» і незмінні інваріанти; змінюються лише разом із метою продукту | усі реалізації й усі майбутні глави | перегляд архітектури | +| **Контракт** (`contract`) | те, що **мусить збігатись** між реалізаціями, інакше вони несумісні: файловий контракт вузла, derived-стани, простір `refs/mt/*`, fenced publish, Envelope і схеми фронтматеру | усі реалізації | major контракту, міграція даних | +| **Реалізація** (`reference`) | те, що одна реалізація може зробити інакше, не створивши розбіжності: дефолтні значення, імена ENV, прапорці CLI, стек, CI, перевірені адаптери | референсна реалізація | звичайна правка | + +**Критерій віднесення** — два питання поспіль: + +1. *Чи зміниться цей рядок, якщо переписати MT на іншому стеку?* Ні → принцип або контракт. +2. *Чи може інша реалізація зробити тут інакше, а обидві лишаться сумісними на рівні git-стану і протоколу?* Так → реалізація. + +Наслідок для звірки зі станом коду: розбіжність із рядком шару `reference` — **не** порушення спеки, а вибір реалізації; порушенням є лише розбіжність із `principle`/`contract`. + +## Як шар позначено в главах + +- **Глава цілком** — поле `normativity` у фронтматері (`principle` | `contract` | `reference`). +- **Окрема секція, що відхиляється від рівня своєї глави** — блок-цитата одразу під заголовком секції: + + ```markdown + > **Реалізація (не контракт).** Конкретні значення і назви нижче — референсні. + ``` + +Мапу глав за шарами див. [нижче](#мапа-глав-за-шарами). + +## Принципи + +### Субстрат і стан + +1. **Git — субстрат, а не інтерфейс.** Надійність, офлайн, audit trail і відсутність lock-in беруться з git; зручність роботи людей і машин будується **понад** ним — жоден сценарій для не-розробника не має вимагати роботи з git напряму. → [vision.md](../vision.md), [overview.md](overview.md) +2. **Усе нове — файли в git, а не сервіси.** Нові механізми (мандати, шаблони повторюваності, рішення, інновації) матеріалізуються файлами й refs; нові сутності не потребують нових сервісів — process watcher і агрегатор компетенцій є node actors, планувальник повторюваності — частина wake-логіки orchestrator-а. → [mandates.md](mandates.md), [recurrence.md](recurrence.md), [retro.md](retro.md) +3. **Стан — derived, лічильників немає.** Стан вузла виводиться з його артефактів і claim-refs; стан планувальника — зі скану інстансів; момент увімкнення шаблона — з git-історії. Джерело істини одне: спостережувані артефакти. → [graph.md](graph.md), [recurrence.md](recurrence.md) +4. **Immutable-артефакт і version chain.** Результат ніколи не перезаписується: виправлення — це новий артефакт із наступним NNN, а не редагування старого. Повторення задачі отримує власну ідентичність, а не оновлений результат одного вузла. → [graph.md](graph.md), [recurrence.md](recurrence.md) +5. **Fail closed.** Невідома `schema_version`, невідома схема файлу для перекладу, відсутній branch protection, двозначний розклад шаблона, несумісна `protocol_version` — відмова, а не здогадка. → [graph.md](graph.md), [i18n.md](i18n.md), [operations.md](operations.md), [runtime.md](runtime.md) + +### Координація + +6. **Одне перо — git CAS claim.** `refs/mt/claims/*` авторитетні для всіх режимів, автономних і інтерактивних; relay lease **не видає**. Право писати у вузол має лише тримач claim. → [git.md](git.md), [overview.md](overview.md) +7. **Межа атомарності — remote.** Єдиний шлях запису результату в `main` — fenced publish (атомарний push із `--force-with-lease` на `main`, claim і run ref одночасно). Другого шляху запису не існує, включно з protected-`main`-сценарієм через integration bot. → [git.md](git.md) +8. **Деградація замість поломки.** Система лишається коректною без ефемерного шару: без relay (git-polling), без жодного перекладу (показується base), без сервера (`mt watch`/`mt run --auto`), без preview. Ефемерне ніколи не претендує на істину. → [operations.md](operations.md), [i18n.md](i18n.md), [access.md](access.md) +9. **Інкапсуляція чорної скриньки.** Для батьківського вузла інтерфейс дитини однаковий незалежно від того, атомарна вона чи підграф: він чекає `resolved` і бачить лише `fact`. Декомпозиція — рішення всередині вузла, а не властивість, видима ззовні. → [graph.md](graph.md) +10. **Один код контракту.** Логіка claim/publish/scan існує в **одній** реалізації; інші компоненти викликають її, а не дублюють. Дві імплементації контракту неминуче розходяться. → [overview.md](overview.md), [stack.md](stack.md) +11. **Технологічна нейтральність.** Архітектура technology-agnostic: зміна стеку не змінює архітектуру. Конкретні технології живуть в окремій главі й позначені як реалізація. → [stack.md](stack.md) + +### Люди і ШІ + +12. **Взаємозамінність виконавців.** Людина й агент — виконавці одного вузла з тим самим контрактом: життєвий цикл, бюджети, аудит, ескалація. Це передумова інверсії делегування: оркестратор може призначити будь-кого лише тоді, коли контракт спільний. → [vision.md](../vision.md), [graph.md](graph.md) +13. **Retry-before-escalate.** До людини не приходить «зламалось»: система зобовʼязана вичерпати retry ladder і engineer-щабель сама. Нагору доходить лише **розвилка** — контекст, варіанти, ціна зволікання, рекомендація агента. → [mandates.md](mandates.md), [graph.md](graph.md) +14. **Фрактальне власництво.** На кожному рівні людина володіє «що і навіщо» свого горизонту (мандат), а система забирає «як» і транспорт інформації між рівнями. Людина — власник рішень, не exception-handler. Влада (мандат) не слідує за компетенцією автоматично. → [vision.md](../vision.md), [mandates.md](mandates.md) +15. **Директорська модель відповідальності.** ШІ може ухвалювати рішення і володіти мандатами, але відповідальність несе людина-директор — за те, що не організувала роботу так, щоб протиправних рішень не було. Відповідальність привʼязана до організації системи, а не до акту рішення. → [vision.md](../vision.md), [mandates.md](mandates.md) +16. **Остання константа.** Розширення ШІ-мандата підписує **лише людина, завжди**. Це єдине правило, яке система ніколи не автоматизує: інакше межа рухає сама себе. → [mandates.md](mandates.md) +17. **Інваріант reversible.** Незворотне рішення ніколи не виконується в режимі «мовчання = згода»: мінімум ask-and-wait, незалежно від решти фасетів. Звідси ж межа зухвалості агента: goal-driven агресивність дозволена лише там, де найгіршу помилку можна відкотити. → [mandates.md](mandates.md) +18. **Машинне судження лише додає безпеку.** Помилки маршрутизації асиметричні, тому вгору ескалація вільна, а вниз — лише підписаними актами (прецедент, `delegate_down`, policy-рядок). Автомат може підняти рішення, але не знизити. → [mandates.md](mandates.md) +19. **Підпис легітимізує, а не «перевіряє розумнішого».** Гейт стоїть там, де рішення потребує носія відповідальності, і вимагає доведеного розуміння (квіз-гейт) — інакше вироджується в rubber-stamping. → [vision.md](../vision.md), [mandates.md](mandates.md) +20. **Один криптографічний механізм на всі гейти.** Ed25519-підписи пристроїв обслуговують plan-review, аудит-вердикти і mid-run approvals; підпис матеріалізується у файл вузла — git отримує криптографічний audit trail. Підпис можливий із пристрою **без git-доступу**. → [access.md](access.md), [overview.md](overview.md) +21. **Дані про людей — тільки позитивні, і не для нагляду.** Негативних оцінок людини не існує ніде: відсутність підтвердження ≠ зафіксоване «не вміє». Мета-цикл працює **на виконавця**, opt-in; крос-виконавча аналітика і «рейтинги виконавців» заборонені. Профілі моделей цього обмеження не мають — у моделі немає гідності, яку треба берегти. → [retro.md](retro.md), [mandates.md](mandates.md) +22. **Пропозиція ≠ дія.** Ретроспектива, аналізатор ескалацій і агрегатор нічого не змінюють самі: вихід — пропозиція або draft-PR, застосування — штатна правка з людським підписом. → [retro.md](retro.md), [mandates.md](mandates.md) + +### Мови і поверхні + +23. **Один канон.** Base-мова — єдине джерело істини: `fact`-hash, derived-стани, scanner і `## Check` читають **тільки** base; переклади — derived-дані і ніколи не впливають на стан графа. → [i18n.md](i18n.md) +24. **Поверхні — тонкі клієнти одного протоколу.** Уся логіка виконання живе в `agent-server`; жоден клієнт не викликає ядро агента напряму. Нова поверхня додається конфігом і не змінює протокол. → [runtime.md](runtime.md), [surfaces.md](surfaces.md) +25. **Спеціалізація не розширює прав.** Ефективний набір тулів = перетин surface-профілю і sandbox-стелі вузла: surface не може дати агенту більше, ніж дозволяє задача. Той самий принцип у мандатах — `inherit_capped`. → [surfaces.md](surfaces.md), [mandates.md](mandates.md) +26. **Ефемерне не персиститься.** Скріншоти прев'ю, `.nitra/`, чернетки й журнали сесій ніколи не потрапляють у `main`; у канон іде лише дистильований результат. → [git.md](git.md), [runtime.md](runtime.md) + +## Мапа глав за шарами + +| Глава | Шар | Примітка | +| --- | --- | --- | +| [vision.md](../vision.md) | `principle` | «навіщо»; кожне архітектурне рішення має його підтримувати | +| principles.md (цей файл) | `principle` | зведення інваріантів і критерій шарів | +| [overview.md](overview.md) | `principle` | нормативні рішення злиття, шари системи, глосарій | +| [graph.md](graph.md) | `contract` | файловий контракт, derived-стани; дефолтні числа — реалізація | +| [git.md](git.md) | `contract` | claim, run ref, fenced publish; ENV-імена wrapper-а — реалізація | +| [runtime.md](runtime.md) | `contract` | Envelope v4, сесії, міграція; ACP-адаптери і CLI-мапи — реалізація | +| [surfaces.md](surfaces.md) | `contract` | surface-профіль, MCP як механізм тулів | +| [access.md](access.md) | `contract` | ролі, гейти, підписи, межі relay | +| [mandates.md](mandates.md) | `contract` | draft-розширення: мандати, `decision-request`, маршрутизація | +| [i18n.md](i18n.md) | `contract` | base-канон, derived-переклади, contract-aware перекладач | +| [retro.md](retro.md) | `contract` | suggestion, `innovation`/`impact`-артефакти | +| [recurrence.md](recurrence.md) | `contract` | шаблон і інстанси, детермінований id | +| [operations.md](operations.md) | `contract` | CLI-контракт, security model; довідник ключів і дефолти — реалізація | +| [stack.md](stack.md) | `reference` | конкретні технології; зміна стеку не змінює архітектуру | + +## Як цим користуватись + +- **Нове архітектурне рішення** — звірити проти переліку вище; конфлікт із принципом означає або відмову від рішення, або свідомий перегляд принципу через ADR, а не мовчазний виняток. +- **Звірка зі станом коду** — розбіжність позначати шаром: `principle`/`contract` → конфлікт, який треба закривати; `reference` → зафіксувати як вибір реалізації. +- **Нова глава** — обовʼязково має поле `normativity` у фронтматері; секції, що відхиляються від рівня глави, позначаються блок-цитатою (див. вище). diff --git a/docs/architecture/recurrence.md b/docs/architecture/recurrence.md index 4770866..50e1304 100644 --- a/docs/architecture/recurrence.md +++ b/docs/architecture/recurrence.md @@ -1,5 +1,6 @@ --- type: architecture +normativity: contract description: 'Повторювані задачі: мутабельний шаблон поза графом, матеріалізація інстансів планувальником wake, політики overlap/catchup/retention' tags: [recurrence, templates, scheduler] timestamp: 2026-07-22 diff --git a/docs/architecture/retro.md b/docs/architecture/retro.md index 5ef38ac..af83d8e 100644 --- a/docs/architecture/retro.md +++ b/docs/architecture/retro.md @@ -1,5 +1,6 @@ --- type: architecture +normativity: contract description: 'Мета-цикл: ретроспективний аналіз audit trail графа, приватні пропозиції виконавцю (opt-in), застосування через штатні механізми' tags: [retro, meta-cycle, suggestions, privacy] timestamp: 2026-07-08 @@ -93,6 +94,8 @@ impact: ## Конфігурація +> **Реалізація (не контракт).** Імена ключів і дефолтні значення — референсні; контрактне — opt-in за замовчуванням (принцип «працює на виконавця») і схеми `suggestion`/`innovation`/`impact`. + ```jsonc // .mt.json { diff --git a/docs/architecture/runtime.md b/docs/architecture/runtime.md index b00b6f4..1fa6125 100644 --- a/docs/architecture/runtime.md +++ b/docs/architecture/runtime.md @@ -1,5 +1,6 @@ --- type: architecture +normativity: contract description: 'agent-server як єдиний хост-процес, протокол подій v3, інтерактивні сесії, міграція між хостами, preview' tags: [runtime, agent-server, protocol, sessions] timestamp: 2026-07-07 @@ -35,23 +36,16 @@ Runner виконує agent-вузол **єдиним** шляхом — headles | `agent_cli` | Виконавець | Модель тиру | | --- | --- | --- | -| `claude` (дефолт) | Claude Code (підписка Anthropic) | `MT_AGENT_CLI_MODEL_MAP.claude[tier]` | +| `claude` | Claude Code (підписка Anthropic) | `MT_AGENT_CLI_MODEL_MAP.claude[tier]` | | `codex` | Codex CLI (підписка OpenAI) | `MT_AGENT_CLI_MODEL_MAP.codex[tier]` | | `cursor` | Cursor CLI (підписка Cursor) | `MT_AGENT_CLI_MODEL_MAP.cursor[tier]` | | `pi` | pi.dev CLI — **локальні моделі**: обгортає omlx-сервер | `MT_AGENT_CLI_MODEL_MAP.pi[tier]` | -**Конфігурація виконавців — user-level, через ENV.** Підписки, CLI і мапи моделей — властивість **користувача**, спільна для всіх його репозиторіїв, тому вона живе в оточенні користувача, а не в repo-scoped `.mt.json`: - -```bash -# ~/.zshenv (рівень користувача — усі репозиторії) -export MT_AGENT_CLI="claude" # дефолтний виконавець -export MT_CLOUD_AGENT_CLIS="codex,cursor" # каскад хмарних підписок (порядок = пріоритет) -export MT_AGENT_CLI_MODEL_MAP='{"codex":{"MIN":"gpt-5.6-luna","AVG":"gpt-5.6-terra","MAX":"gpt-5.6-sola"},"pi":{"MIN":"omlx/gemma-4-e2b-it-4bit"}}' -``` +**Конфігурація виконавців — user-level, через ENV.** Підписки, CLI і мапи моделей — властивість **користувача**, спільна для всіх його репозиторіїв, тому вона живе в оточенні користувача (`MT_AGENT_CLI`, `MT_CLOUD_AGENT_CLIS`, `MT_AGENT_CLI_MODEL_MAP`), а не в repo-scoped `.mt.json`. Значення і приклад запису — [operations.md](operations.md#конфігурація-mtjson). **Тир-алгоритм резолвить конкретну модель per-CLI.** Канон MIN/AVG/MAX — спільний для всіх виконавців; мапу «тир → модель CLI» задає `MT_AGENT_CLI_MODEL_MAP`. Retry ladder ескалює тир — отже, і конкретну модель — тією самою мапою. Без мапінгу прапор моделі не передається (CLI резолвить сам за підпискою), тир завжди йде hint-ом env `MT_MODEL_TIER`. Правило однакове для всіх транспортів: headless-виклик і ACP-сесія отримують ту саму резолвнуту модель. -Вибір CLI: `a.md` секція `## Agent cli` (per-node — крос-програмковий вимір [мети](../vision.md)) → env `MT_AGENT_CLI` → `claude`. Невідоме значення → fail-fast до створення worktree. Обраний CLI повідомляється у env run-а як `MT_AGENT_CLI`. Success = `fact_NNN.md` існує **і** `## Check` пройдено. +Вибір CLI: `a.md` секція `## Agent cli` (per-node — крос-програмковий вимір [мети](../vision.md)) → env `MT_AGENT_CLI` → дефолт із [довідника](operations.md#дефолти-на-які-посилаються-глави). Невідоме значення → fail-fast до створення worktree. Обраний CLI повідомляється у env run-а як `MT_AGENT_CLI`. Success = `fact_NNN.md` існує **і** `## Check` пройдено. **Правило підписки (нормативне).** Run виконується **на хості, де owner вузла сам авторизував CLI**. Підписки не пулюються і не проксюються через relay чи сервер — relay передає лише події та approvals; міграція сесії «перенести сюди» — це перенесення виконання на девайс із підпискою її власника. Rate limits підписки — зовнішній ресурс: оркестратор при них робить backoff, а не паралелить глибше. @@ -59,6 +53,8 @@ export MT_AGENT_CLI_MODEL_MAP='{"codex":{"MIN":"gpt-5.6-luna","AVG":"gpt-5.6-ter **ACP — єдиний транспорт AI-викликів.** **Усі** виклики ШІ йдуть виключно через **ACP (Agent Client Protocol)**: один ACP-клієнт в agent-server, без вендорських адаптерів і без власного provider-шару; хмарні CLI підключаються своїми ACP-адаптерами, **локальні моделі — через pi.dev CLI**, який обгортає omlx-сервер і виставляє той самий ACP. `permission-request` ACP мапиться на `ApprovalRequest` (Ed25519-підписи) — mid-run гейти працюють поверх будь-якого виконавця, включно з локальним; структуровані ACP-помилки лімітів живлять каскад замість текстової евристики. +> **Реалізація (не контракт).** Три абзаци нижче — таблиця ACP-адаптерів, версії пакетів і звіт про виправлення банера `pi` — стан референсної реалізації на дату перевірки. Нормативне тут — лише сам принцип «ACP — єдиний транспорт AI-викликів» і мапінг `permission-request` → `ApprovalRequest` (абзац вище). + **ACP-адаптери за `agent_cli` (перевірено живими сесіями 2026-07-16).** Жоден з чотирьох CLI не має вбудованого ACP-режиму у `--help`, крім Cursor: | `agent_cli` | Команда для `MT_ACP_AGENT_CMD` | Статус | @@ -165,7 +161,7 @@ ClientHello { ### Помилкові гілки і backpressure - **Reconnect:** клієнт зберігає останній оброблений `seq` і реконектиться з `want_replay_from`; `seq` монотонний — розривів у журнальованих подіях не буває. Глибина поза буфером → хост дочитує з `session.jsonl` run ref-а. -- **Backpressure:** для повільного клієнта хост **скидає лише ефемерні** події (`AgentTextDelta`, `PreviewScreenshot`) — журнальовані доставляються завжди; переповнення черги надсилання → примусовий disconnect з `Error`, клієнт повертається реплеєм. Ліміт кадру — 2 MB (спільний з relay). +- **Backpressure:** для повільного клієнта хост **скидає лише ефемерні** події (`AgentTextDelta`, `PreviewScreenshot`) — журнальовані доставляються завжди; переповнення черги надсилання → примусовий disconnect з `Error`, клієнт повертається реплеєм. Ліміт кадру — спільний з relay; значення — [довідник](operations.md#дефолти-на-які-посилаються-глави). - **`PreviewScreenshot` байти:** подія несе лише `ref_id`; байти клієнт тягне окремим запитом до хоста (локальний HTTP preview-модуля або бінарний WS-кадр за `ref_id`) — великі бінарі не проходять крізь стрічку подій і relay-буфер. - **Невідомий `Event`-варіант** у межах сумісної мажорної версії клієнт **ігнорує** (forward-compatibility мінорних розширень); несумісна `protocol_version` → відмова на хендшейку. diff --git a/docs/architecture/stack.md b/docs/architecture/stack.md index 31cac0c..9dde2b1 100644 --- a/docs/architecture/stack.md +++ b/docs/architecture/stack.md @@ -1,5 +1,6 @@ --- type: stack +normativity: reference description: 'Конкретні технологічні рішення реалізації архітектури 0.3.0-draft; зміна стеку не змінює архітектуру' tags: [stack, rust, bun, tauri] timestamp: 2026-07-07 diff --git a/docs/architecture/surfaces.md b/docs/architecture/surfaces.md index 677e473..9100f68 100644 --- a/docs/architecture/surfaces.md +++ b/docs/architecture/surfaces.md @@ -1,5 +1,6 @@ --- type: architecture +normativity: contract description: 'Спеціалізовані поверхні: surface-профіль як обʼєкт, MCP як нормативний механізм тулів, звʼязка з sandbox, референсні surface' tags: [surfaces, tools, mcp, profiles] timestamp: 2026-07-07 diff --git a/docs/index.md b/docs/index.md index 694eeda..a7b2d00 100644 --- a/docs/index.md +++ b/docs/index.md @@ -31,6 +31,7 @@ Обʼєднання графа задач (mt.md 0.2.0) і scaffold-spec v4 (пристрої/сесії) в одну систему. Читати по порядку: +* [Принципи і шари обовʼязковості](architecture/principles.md) - зведення інваріантів канону і критерій «принцип / контракт / реалізація» * [Огляд](architecture/overview.md) - нормативні рішення злиття і чотиришарова загальна картина * [Ядро: граф задач](architecture/graph.md) - вузли й ОАГ, файловий контракт, derived-стани, retry ladder, аудит * [Координація через git](architecture/git.md) - CAS claim як єдине «перо», run ref із журналом сесії, fenced publish diff --git a/docs/log.md b/docs/log.md index cb5ce02..9921bf7 100644 --- a/docs/log.md +++ b/docs/log.md @@ -1,5 +1,10 @@ # Журнал змін документації +## 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 — він уже під маркером «Реалізація (не контракт)». +* **Creation**: [architecture/principles.md](architecture/principles.md) — зведення принципів і **три шари обовʼязковості** канону. Проблема: вісь «принцип / реалізація» в каноні вже була (vision.md — «навіщо», глави — «як», [architecture/stack.md](architecture/stack.md) — «на чому», з прямою заявою technology-agnostic), але протікала — реалізаційний матеріал (дефолтні числа, імена ENV, прапорці CLI, перевірені ACP-адаптери) сидів усередині глав контракту, а самі принципи були розсипані по чотирьох файлах (6 «рішень злиття» в [architecture/overview.md](architecture/overview.md), «Принципи (нормативні)» в [architecture/i18n.md](architecture/i18n.md) і [architecture/retro.md](architecture/retro.md), директорська модель у [vision.md](vision.md)). Поділ надвоє, «принципи vs деталі», відхилено: для репозиторію специфікації файловий контракт вузла, derived-стани, `refs/mt/*` і Envelope — не деталі реалізації, а **межа між реалізаціями**. Тому вісь тришарова — `principle` (незмінні інваріанти) / `contract` (мусить збігатись між реалізаціями) / `reference` (одна реалізація може зробити інакше без розбіжності), із критерієм віднесення у два питання. Нова глава містить 26 нумерованих принципів у чотирьох групах (субстрат і стан, координація, люди і ШІ, мови й поверхні) — кожен із обґрунтуванням і посиланням на главу, що його реалізує — та мапу всіх глав за шарами. Механіка позначення: поле `normativity` у фронтматері **кожної** глави (додано в 13 файлів) і блок-цитата «Реалізація (не контракт)» для секцій, що відхиляються від рівня своєї глави — позначено 6 таких: retry-числа ([architecture/graph.md](architecture/graph.md)), ENV-контракт wrapper→агент ([architecture/git.md](architecture/git.md)), ACP-адаптери і звіт про виправлення `pi`-банера ([architecture/runtime.md](architecture/runtime.md)), конфіг-довідник ([architecture/operations.md](architecture/operations.md)), конфіг-секції i18n і retro. Нової директорії свідомо не заводимо: наявна вісь дерева — глибина (`index.md` → `overview/` → `architecture/`), а другий поділ на осі обовʼязковості дав би матрицю й подвійну навігацію; `docs/layers.json` не змінюється — принципи вже течуть у шари через свої глави-джерела. Практичний наслідок для зняття `-draft`: розбіжність спека↔код тепер класифікується — конфлікт із `principle`/`contract` треба закривати, розбіжність із `reference` фіксується як вибір реалізації. Оновлено: [index.md](index.md), [architecture/index.md](architecture/index.md). + ## 2026-07-22 * **Creation**: [architecture/recurrence.md](architecture/recurrence.md) — глава повторюваних задач (закриває прогалину: ОАГ ациклічний, `resolved` термінальний — повторюваність у графі не виражалась). Механізм — **шаблон + інстанси**: мутабельний шаблон у `.mt/templates//` (task.md без `created_at`/`parent`, прапор `a.md`/`h.md`, `recurrence.md` із розкладом — повноцінний 5-польний cron `schedule` у `tz` АБО інтервальний `every` («кожні 90 хв»), відв'язаний від календаря; хвилинна гранулярність як свідома нижня межа — і політиками, опційні `deps/`) — не вузол, scan його не бачить; на спрацювання планувальник (частина wake-логіки orchestrator-а, cron-fallback гарантує без always-on) матеріалізує **звичайний кореневий вузол** `mt/-YYYYMMDD-hhmm/` (уніфікований id, occurrence у UTC) одним fenced atomic commit — детермінований id від occurrence робить створення ідемпотентним, гонка хостів вирішується штатним fenced publish. Стан планувальника derived (нові поля фронтматеру `template:`/`occurrence:` в task.md інстанса, жодних лічильників). Політики: `overlap: skip | chain | parallel` (chain = auto-dep на попередній інстанс — серіалізація + потік даних між повтореннями через штатний `deps/`), `catchup: collapse | all`, пауза `enabled: false` (період паузи не породжує catchup-боргу; момент ввімкнення — derived з git-історії `recurrence.md`), retention `keep` через розширення `mt cleanup` (kill-архів; `failed`/`unresolvable` GC не чіпає). Нові CLI `mt template list|run`, ключ `templates_dir`. Відхилені альтернативи зафіксовано у главі: freshness/TTL прийнятого fact (втрата окремої ідентичності повторень; може повернутись для refresh-класу) і періодичний `mt invalidate` (семантично хибний — засмічує audit trail). Оновлено: [architecture/index.md](architecture/index.md), [index.md](index.md), [architecture/overview.md](architecture/overview.md) (2 терміни глосарію), [architecture/operations.md](architecture/operations.md) (CLI-блок, `mt cleanup`, довідник ключів). diff --git a/docs/vision.md b/docs/vision.md index cb236b3..ca60981 100644 --- a/docs/vision.md +++ b/docs/vision.md @@ -1,5 +1,6 @@ --- type: vision +normativity: principle description: 'Мета проєкту: платформа управління проєктами/задачами, де виконавці — і люди, і ШІ; пʼять крос-вимірів' tags: [vision, mission, goals] timestamp: 2026-07-07